-
Notifications
You must be signed in to change notification settings - Fork 37.7k
psbt: Actually use SIGHASH_DEFAULT for PSBT signing #22514
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
Conversation
de515bc
to
07d0ce7
Compare
Is this for backport? |
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
There is no explicit PSBT support for Taproot yet, so I don't think so. Although we do still sign PSBTs that have Taproot inputs, but only if we make those inputs final. |
352e00f
to
96f78ed
Compare
Concept + code review ACK 96f78e |
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 96f78ed
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.
Concept ACK
96f78ed
to
ed96401
Compare
Apparently without this, we may end up creating final transactions with a lower feerate than expected. |
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.
crACK ed96401
ed96401
to
32c9ab7
Compare
Mmm, the help text was changed from defaulting to Let's make the help text say The first commit 62621db looks good to me. |
Added a commit for that. |
c592939
to
322d117
Compare
@@ -86,9 +86,9 @@ struct PSBTInput | |||
} | |||
|
|||
// Write the sighash type | |||
if (sighash_type > 0) { | |||
if (sighash_type != std::nullopt) { |
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 commit "psbt: Make signhash_type std::optional"
Nit: I think the ideomatic way of writing this would be if (sighash_type.has_value())
or just if (sighash_type)
(here and further).
@@ -455,7 +455,7 @@ def run_test(self): | |||
wrpc = self.nodes[2].get_wallet_rpc("wallet{}".format(i)) | |||
for key in signer['privkeys']: | |||
wrpc.importprivkey(key) | |||
signed_tx = wrpc.walletprocesspsbt(signer['psbt'])['psbt'] | |||
signed_tx = wrpc.walletprocesspsbt(signer['psbt'], True, "ALL")['psbt'] |
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 commit "psbt: Actually use SIGHASH_DEFAULT"
What is this change for?
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.
At least one of the tests sets the sighash type in the PSBT. However when we sign, if the sighash type given in the RPC does not match the sighash type in the PSBT, we fail to sign. So this change is to make sure that we do sign those PSBTs.
utACK 322d117 |
re-utACK 3624dc5 after rebase |
It is better to ues an optional to determine whether the sighash type is set rather than using 0 as a magic number.
Make the behavior align with the help text by actually using SIGHASH_DEFAULT as the default sighash for signing PSBTs.
3624dc5
to
c0405ee
Compare
re-utACK c0405ee To my surprise, this still worked despite the rename: PREV=3624dc5 N=3 && git range-diff `git merge-base --all HEAD $PREV`...$PREV HEAD~$N...HEAD |
c0405ee rpc: Document that DEFAULT is for Taproot, ALL for everything else (Andrew Chow) d399266 psbt: Actually use SIGHASH_DEFAULT (Andrew Chow) eb9a1a2 psbt: Make sighash_type std::optional<int> (Andrew Chow) Pull request description: Make the behavior align with the help text by actually using SIGHASH_DEFAULT as the default sighash for signing PSBTs. ACKs for top commit: Sjors: re-utACK c0405ee Tree-SHA512: 5199fb41de416b2f10ac451f824e7c94b428ba11fdb9e50f0027c692e959ce5813a340c34a4e52d7aa128e12008303d80939a693eff36a869720e45442119828
…SBT signing 5b0c5b8 rpc: Document that DEFAULT is for Taproot, ALL for everything else (Andrew Chow) 61dde4b psbt: Actually use SIGHASH_DEFAULT (Andrew Chow) 94c5107 psbt: Make sighash_type std::optional<int> (Andrew Chow) Pull request description: Make the behavior align with the help text by actually using SIGHASH_DEFAULT as the default sighash for signing PSBTs. ACKs for top commit: Sjors: re-utACK 5b0c5b8 Tree-SHA512: 5199fb41de416b2f10ac451f824e7c94b428ba11fdb9e50f0027c692e959ce5813a340c34a4e52d7aa128e12008303d80939a693eff36a869720e45442119828
PSBT signing was changed to use SIGHASH_DEFAULT by default in bitcoin#22514. The signet miner script sets the sighash type of the created PSBT to SIGHASH_ALL, hence this leads to a sighash mismatch when the `walletprocesspsbt` RPC is called. Fix this by explicitly passing the correct sighash type. Note that the same change was needed in one of our functional tests, see commit d399266. Reported by gruve-pu.
PSBT signing was changed to use SIGHASH_DEFAULT by default in bitcoin#22514. The signet miner script sets the sighash type of the created PSBT to SIGHASH_ALL, hence this leads to a sighash mismatch when the `walletprocesspsbt` RPC is called. Fix this by explicitly passing the correct sighash type. Note that the same change was needed in one of our functional tests, see commit d399266. Reported by gruve-p.
PSBT signing was changed to use SIGHASH_DEFAULT by default in bitcoin#22514. The signet miner script sets the sighash type of the created PSBT to SIGHASH_ALL, hence this leads to a sighash mismatch when the `walletprocesspsbt` RPC is called. Fix this by explicitly passing the correct sighash type. Note that the same change was needed in one of our functional tests, see commit d399266. Reported by gruve-p.
12cc020 contrib: fix signet miner (sighash mismatch) (Sebastian Falbesoner) Pull request description: gruve-p reported that the signet miner doesn't work anymore (see bitcoin#24501 (comment)), failing with the following error of the `walletprocesspsbt` RPC: ``` error code: -22 error message: Specified sighash value does not match value stored in PSBT ..... subprocess.CalledProcessError: Command '['bitcoin-cli', '-signet', '-stdin', 'walletprocesspsbt']' returned non-zero exit status 22 ``` PSBT signing was changed to use SIGHASH_DEFAULT by default in bitcoin#22514. The signet miner script sets the sighash type of the created PSBT to SIGHASH_ALL (3 is the per-input type PSBT_IN_SIGHASH_TYPE, following a little-endian 32 unsigned integer of the sighash type): https://github.com/bitcoin/bitcoin/blob/e04720ec3336e3df7fce522e3b1da972aa65ff62/contrib/signet/miner#L169-L170 hence this leads to a sighash mismatch when the `walletprocesspsbt` RPC is called. Fix this by explicitly passing the correct sighash type. The same change was needed in one of our functional tests, see commit d399266. Note that instead of feeding the PSBT via `-stdin` it is directly passed as parameter, as I couldn't figure out a way to pass multiple parameters otherwise (separating by newline also didn't work). ACKs for top commit: kallewoof: ACK 12cc020 ajtowns: ACK 12cc020 ; code review only Tree-SHA512: 8509e768e96f85e28c0ca0dc2d35874aa29623febddc46bf90472ec38f38cb3a1b5407c563fd9101d07088775d0fdb18e9137cc38955e847885b83c16591c736
12cc020 contrib: fix signet miner (sighash mismatch) (Sebastian Falbesoner) Pull request description: gruve-p reported that the signet miner doesn't work anymore (see bitcoin#24501 (comment)), failing with the following error of the `walletprocesspsbt` RPC: ``` error code: -22 error message: Specified sighash value does not match value stored in PSBT ..... subprocess.CalledProcessError: Command '['bitcoin-cli', '-signet', '-stdin', 'walletprocesspsbt']' returned non-zero exit status 22 ``` PSBT signing was changed to use SIGHASH_DEFAULT by default in bitcoin#22514. The signet miner script sets the sighash type of the created PSBT to SIGHASH_ALL (3 is the per-input type PSBT_IN_SIGHASH_TYPE, following a little-endian 32 unsigned integer of the sighash type): https://github.com/bitcoin/bitcoin/blob/e04720ec3336e3df7fce522e3b1da972aa65ff62/contrib/signet/miner#L169-L170 hence this leads to a sighash mismatch when the `walletprocesspsbt` RPC is called. Fix this by explicitly passing the correct sighash type. The same change was needed in one of our functional tests, see commit d399266. Note that instead of feeding the PSBT via `-stdin` it is directly passed as parameter, as I couldn't figure out a way to pass multiple parameters otherwise (separating by newline also didn't work). ACKs for top commit: kallewoof: ACK 12cc020 ajtowns: ACK 12cc020 ; code review only Tree-SHA512: 8509e768e96f85e28c0ca0dc2d35874aa29623febddc46bf90472ec38f38cb3a1b5407c563fd9101d07088775d0fdb18e9137cc38955e847885b83c16591c736
PSBT signing was changed to use SIGHASH_DEFAULT by default in bitcoin#22514. The signet miner script sets the sighash type of the created PSBT to SIGHASH_ALL, hence this leads to a sighash mismatch when the `walletprocesspsbt` RPC is called. Fix this by explicitly passing the correct sighash type. Note that the same change was needed in one of our functional tests, see commit d399266. Reported by gruve-p. Github-Pull: bitcoin#24553 Rebased-From: 12cc020
PSBT signing was changed to use SIGHASH_DEFAULT by default in bitcoin#22514. The signet miner script sets the sighash type of the created PSBT to SIGHASH_ALL, hence this leads to a sighash mismatch when the `walletprocesspsbt` RPC is called. Fix this by explicitly passing the correct sighash type. Note that the same change was needed in one of our functional tests, see commit d399266. Reported by gruve-p. Github-Pull: bitcoin#24553 Rebased-From: 12cc020
PSBT signing was changed to use SIGHASH_DEFAULT by default in bitcoin#22514. The signet miner script sets the sighash type of the created PSBT to SIGHASH_ALL, hence this leads to a sighash mismatch when the `walletprocesspsbt` RPC is called. Fix this by explicitly passing the correct sighash type. Note that the same change was needed in one of our functional tests, see commit d399266. Reported by gruve-p. Github-Pull: bitcoin#24553 Rebased-From: 12cc020
@@ -1167,7 +1167,7 @@ RPCHelpMan walletprocesspsbt() | |||
{ | |||
{"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction base64 string"}, | |||
{"sign", RPCArg::Type::BOOL, RPCArg::Default{true}, "Also sign the transaction when updating (requires wallet to be unlocked)"}, | |||
{"sighashtype", RPCArg::Type::STR, RPCArg::Default{"DEFAULT"}, "The signature hash type to sign with if not specified by the PSBT. Must be one of\n" | |||
{"sighashtype", RPCArg::Type::STR, RPCArg::Default{"DEFAULT for Taproot, ALL otherwise"}, "The signature hash type to sign with if not specified by the PSBT. Must be one of\n" |
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.
How is it "ALL otherwise"? If a user wants ALL
, even for non-Taproot descriptor, they now have to explicitly set it. It's a (minor) breaking change which i think should have had a release note.
More confusing is that even if ALL
is set in the PSBT input, this will use DEFAULT
. A user has to specify it using the command line for the whole transaction.
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.
ALL
is the sighash type that is signed with by default for non-Taproot things. I don't see how this is incorrect?
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.
Hmm? That's the point. It's not.
You changed ParseSighashString
in this PR setting DEFAULT
for all types, not only Taproot.
Lines 255 to 277 in 19526d9
int ParseSighashString(const UniValue& sighash) | |
{ | |
int hash_type = SIGHASH_DEFAULT; | |
if (!sighash.isNull()) { | |
static std::map<std::string, int> map_sighash_values = { | |
{std::string("DEFAULT"), int(SIGHASH_DEFAULT)}, | |
{std::string("ALL"), int(SIGHASH_ALL)}, | |
{std::string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)}, | |
{std::string("NONE"), int(SIGHASH_NONE)}, | |
{std::string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY)}, | |
{std::string("SINGLE"), int(SIGHASH_SINGLE)}, | |
{std::string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)}, | |
}; | |
const std::string& strHashType = sighash.get_str(); | |
const auto& it = map_sighash_values.find(strHashType); | |
if (it != map_sighash_values.end()) { | |
hash_type = it->second; | |
} else { | |
throw std::runtime_error(strHashType + " is not a valid sighash parameter."); | |
} | |
} | |
return hash_type; | |
} |
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.
DEFAULT
is an alias for ALL
internally, and signing non-taproot things will result in a ALL
being appended to the signature.
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.
Right, i think the issue was because in my repro i had the sighash flag set in the PSBT input. Have i tried to reproduce it before reporting i could have been more precise, sorry about that.
It's still a (minor) API break since the PSBT was signed without failure in 22.0 but failed in 23.0 (as shown by the necessity to modify the functional test for it to pass in this PR https://github.com/bitcoin/bitcoin/pull/22514/files#r754474555). But since it was released like this already i agree with your comment in #25876 that this doesn't need "fixing" (not sure there could have been any reasonable fix anyways).
…nd` version for CI testing cd21ab8 Bump in `bitcoind` version used in CI. (Zshan0) 9dbda27 Made `sighash_type` explicit (Zshan0) Pull request description: Since the Bitcoin Core ignores the sighash type specified inside the PSBT inputs, `sign_psbt` relied on the default value of `sighash_type` which aligned with our requirements. bitcoin/bitcoin#22514 changed the default value from `SIGHASH_ALL` to `SIGHASH_DEFAULT`. Making `sighash_type` explicit fixes the minor breaking change caused by the update in the bitcoin wallet. Note that since `sighashtype` parameter comes after the `sign` parameter, the value of `sign` has been set to the default value, `true`. Along with the fix, `bitcoind` version used in CI has been bumped from `22.0` to `23.0`. This issue closes #414. ACKs for top commit: darosior: ACK cd21ab8 Tree-SHA512: fe89d31c06be74221f761349e7652ce3a4ce4cceb950e8f793e68eeb51f46d41771562c300581f403d0c9cd6585b0fb838cec4401f8f95458657ff0c6564face
Make the behavior align with the help text by actually using SIGHASH_DEFAULT as the default sighash for signing PSBTs.