-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Segwit for the trade protocol #4612
Conversation
a44285d
to
aae2d25
Compare
@@ -957,7 +1013,15 @@ public Transaction traderSignAndFinalizeDisputedPayoutTx(byte[] depositTxSeriali | |||
|
|||
// take care of sorting! | |||
Script redeemScript = get2of3MultiSigRedeemScript(buyerPubKey, sellerPubKey, arbitratorPubKey); | |||
Sha256Hash sigHash = payoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false); | |||
Sha256Hash sigHash; | |||
boolean hashedMultiSigOutputIsSegwit = !ScriptPattern.isP2SH(hashedMultiSigOutput.getScriptPubKey()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe better to use "hashedMultiSigOutputIsLegacy" to avoid the 2x negation. Makes it easier to read...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
// Since there is no way to check migration to bitcoinj 0.15, | ||
// Config.SEGWIT_TRADE_PROTOCOL_ACTIVE could be checked instead. | ||
// Actually, given the serialized tx is used just as the connected tx of an input, | ||
// we don't need the the connected tx's witness data. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
duplicate "the the"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't the input always from the users own wallet (not the peers input)? If so I don't understand the above comment. Then this code is only execute anyway if the user runs the new version and segwit could be used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
duplicate "the the"
fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't the input always from the users own wallet (not the peers input)? If so I don't understand the above comment. Then this code is only execute anyway if the user runs the new version and segwit could be used.
When creating the deposit tx, traders will have a tx with an input from her wallet and an input from the counterparty. Traders collaborate creating the deposit tx. They send RawTransactionInput over p2p. So, if you are trading with a node that was not upgraded to bitcoinj 0.15 and RawTransactionInput.parentTransaction is serialized with segwit data, the other node won't be able to parse RawTransactionInput.parentTransaction correctly.
Extra comments:
- RawTransactionInput.parentTransaction could be replaced with RawTransactionInput.parentTransactionHash since the tx is only used to obtain its hash.
- Since we upgraded the trade protocol version, it is not possible to take a trade from a not-upgraded node, but better be on the safe side. This comment made probably more sense for the previous release.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will update the comment to make it more clear.
// VERSION = 0.5.0 -> TRADE_PROTOCOL_VERSION = 1 | ||
// Version 1.2.2 -> TRADE_PROTOCOL_VERSION = 2 | ||
public static final int TRADE_PROTOCOL_VERSION = 2; | ||
// Version 1.4.1 -> TRADE_PROTOCOL_VERSION = 3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will be on 1.4.2 or more likely 1.5.0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
if (scriptProgram.length == 0) { | ||
throw new TransactionVerificationException("Inputs from maker not signed."); | ||
} | ||
|
||
return scriptProgram; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Variable is redundant now. Also does not throw exception anymore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This all started with scriptProgram.length == 0 being valid for a segwit input.
I just removed the method and moved its content to where it was being used, i.e. takerSignsDepositTx().
See takerSignsDepositTx():
byte[] makersScriptSigProgram = makersInput.getScriptSig().getProgram();
if (makersScriptSigProgram.length == 0 && TransactionWitness.EMPTY.equals(makersInput.getWitness())) {
throw new TransactionVerificationException("Inputs from maker not signed.");
}
See 7eb808d
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I saw. But now the method does not throw TransactionVerificationException anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw you removed the method. Good so...
Script scriptCode = new ScriptBuilder().data( | ||
ScriptBuilder.createOutputScript(LegacyAddress.fromKey(transaction.getParams(), sigKey)).getProgram()) | ||
.build(); | ||
Script scriptCode = ScriptBuilder.createP2PKHOutputScript(sigKey); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is createP2PKHOutputScript correct? Would expect a segwit method...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is correct.
I know it sounds weird.
To sign a P2WPKH input you have to serialize the tx with a specific format, hash it and then sign the hash.
That specific format includes something called the scriptCode which should be: OP_DUP OP_HASH160 pubKeyHash OP_EQUALVERIFY OP_CHECKSIG. That is the same script format used in P2PKH outputs.
Detailed info: https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. Maybe a comment would be good with backgorund info.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
NetworkParameters params = btcWalletService.getParams(); | ||
Transaction preparedDepositTx = new Transaction(params, processModel.getPreparedDepositTx()); | ||
Coin delayedPayoutTxInputValue = preparedDepositTx.getOutput(0).getValue(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not take the input from preparedDelayedPayoutTx? If that is not possible, I would prefer to pass over the deposit tx to the signDelayedPayoutTx method and do the deail work in the TradeWalletService to keep the transaction domain more isolated there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In bitcoin (the protocol) inputs do not include the amount.
In bitcoinj (the library) you can connect a TransactionInput to its related TransactionOutput and then ask the TransactionInput its value. But it is only possible if you connected both of them.
I moved the code to obtain the input value to TradeWalletService.
911ed77
to
1d79dfb
Compare
I deleted Config.SEGWIT_TRADE_PROTOCOL_ACTIVE |
@chimp1984 I addressed all your comments. |
// Actually, given the serialized tx is used just as the connected tx of an input, | ||
// we don't need the connected tx's witness data. | ||
// bitcoinSerialize(false) is used just in case the serialized tx is parsed by a bisq node still using | ||
// bitcoinj 0.14. The serialized tx is just used to obtain its hash, so the witness data is not relevant. | ||
return new RawTransactionInput(input.getOutpoint().getIndex(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getRawInputFromTransactionInput is used only by methods for creating the deposit tx. With the trade protocol update we do not have mixed cases of segwit/legacy here. Or do I miss something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, you are right, just fixed the comment to explain that.
if (scriptProgram.length == 0) { | ||
throw new TransactionVerificationException("Inputs from maker not signed."); | ||
} | ||
|
||
return scriptProgram; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw you removed the method. Good so...
is this ready to begin testing? |
@wiz Not really. You could test it locally but not with mainnet with real users.... |
@wiz I suggest you wait until I remove the WIP tag. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK
86a35b9
to
19bdf79
Compare
I just squashed commits and polished commit messages, but I had not updated the codebase. |
19bdf79
to
0dda9d4
Compare
This reverts commit b8f5c6e.
0dda9d4
to
dffa251
Compare
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK
Use segwit for trade protocol transactions.