Skip to content

Conversation

achow101
Copy link
Member

Make the behavior align with the help text by actually using SIGHASH_DEFAULT as the default sighash for signing PSBTs.

@achow101 achow101 changed the title rpc: Acutally use SIGHASH_DEFAULT for PSBT signing rpc: Actually use SIGHASH_DEFAULT for PSBT signing Jul 21, 2021
@achow101 achow101 force-pushed the psbt-sighash-default branch from de515bc to 07d0ce7 Compare July 21, 2021 02:17
@fanquake fanquake added the PSBT label Jul 21, 2021
@fanquake fanquake changed the title rpc: Actually use SIGHASH_DEFAULT for PSBT signing psbt: Actually use SIGHASH_DEFAULT for PSBT signing Jul 21, 2021
@maflcko
Copy link
Member

maflcko commented Jul 21, 2021

Is this for backport?

@DrahtBot
Copy link
Contributor

DrahtBot commented Jul 21, 2021

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #21283 (Implement BIP 370 PSBTv2 by achow101)
  • #17034 ([BIP 174] PSBT version, proprietary, and xpub fields by achow101)

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.

@achow101
Copy link
Member Author

Is this for backport?

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.

@achow101 achow101 force-pushed the psbt-sighash-default branch 2 times, most recently from 352e00f to 96f78ed Compare July 21, 2021 19:10
@GeneFerneau
Copy link

Concept + code review ACK 96f78e

Copy link
Contributor

@meshcollider meshcollider left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 96f78ed

Copy link
Contributor

@theStack theStack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK

@achow101 achow101 force-pushed the psbt-sighash-default branch from 96f78ed to ed96401 Compare November 12, 2021 17:05
@achow101
Copy link
Member Author

Apparently without this, we may end up creating final transactions with a lower feerate than expected.

Copy link
Contributor

@benthecarman benthecarman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

crACK ed96401

@Sjors
Copy link
Member

Sjors commented Nov 19, 2021

Mmm, the help text was changed from defaulting to ALL to SIGHASH_DEFAULT in 458a345, but that change also made sure for non-taproot it's interpreted as ALL.

Let's make the help text say RPCArg::Default{"DEFAULT for Taproot, ALL otherwise"} and behave accordingly.

The first commit 62621db looks good to me.

@achow101
Copy link
Member Author

Let's make the help text say RPCArg::Default{"DEFAULT for Taproot, ALL otherwise"} and behave accordingly.

Added a commit for that.

@achow101 achow101 force-pushed the psbt-sighash-default branch from c592939 to 322d117 Compare November 19, 2021 18:15
@Sjors
Copy link
Member

Sjors commented Nov 22, 2021

utACK 322d117

Maybe swap the last two commits for clarity (or add "for taproot" to ff1ec7b)

@@ -86,9 +86,9 @@ struct PSBTInput
}

// Write the sighash type
if (sighash_type > 0) {
if (sighash_type != std::nullopt) {
Copy link
Member

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']
Copy link
Member

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?

Copy link
Member Author

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.

@sipa
Copy link
Member

sipa commented Nov 22, 2021

utACK 322d117

@Sjors
Copy link
Member

Sjors commented Dec 6, 2021

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.
@Sjors
Copy link
Member

Sjors commented Dec 9, 2021

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 

@maflcko maflcko merged commit 011d6e4 into bitcoin:master Dec 10, 2021
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Dec 10, 2021
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
RandyMcMillan pushed a commit to RandyMcMillan/mempool-tab that referenced this pull request Dec 23, 2021
…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
@gruve-p gruve-p mentioned this pull request Mar 8, 2022
5 tasks
theStack added a commit to theStack/bitcoin that referenced this pull request Mar 13, 2022
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.
theStack added a commit to theStack/bitcoin that referenced this pull request Mar 13, 2022
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.
theStack added a commit to theStack/bitcoin that referenced this pull request Mar 14, 2022
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.
maflcko pushed a commit to maflcko/bitcoin-core that referenced this pull request Mar 17, 2022
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
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Mar 18, 2022
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
jonatack pushed a commit to jonatack/bitcoin that referenced this pull request Mar 28, 2022
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
hebasto pushed a commit to hebasto/bitcoin that referenced this pull request Mar 31, 2022
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
jonatack pushed a commit to jonatack/bitcoin that referenced this pull request Mar 31, 2022
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"
Copy link
Member

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.

Copy link
Member Author

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?

Copy link
Member

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.

bitcoin/src/core_read.cpp

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;
}

Copy link
Member Author

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.

Copy link
Member

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).

darosior added a commit to revault/revaultd that referenced this pull request Jun 20, 2022
…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
jamesdorfman added a commit to jamesdorfman/elements that referenced this pull request Jun 13, 2023
@bitcoin bitcoin locked and limited conversation to collaborators Sep 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.