psbt: fix rendering for invalid long sighash type field #36113

pull Sjors wants to merge 1 commits into bitcoin:master from Sjors:2026/08/decode-sighash changing 4 files +18 −4
  1. Sjors commented at 10:48 AM on August 28, 2026: member

    The decodepsbt incorrectly truncates the (32 bit) sighash type field before looking up its human friendly name. It's not dangerous, as such a signature would be invalid, but potentially confusing.

    Fix that and add a test.

    I plan to use SighashToStr in another pull request to render an error message for invalid sighash type field values, but it seemed worth fixing in a standalone PR.

  2. psbt: fix rendering for invalid long sighash type field
    The PSBT sighash type field is a 32 bit unsigned integer in BIP 174,
    signed in PSBTInput, and it is not validated when deserialized.
    
    decodepsbt incorrectly truncates this field before looking up its
    name. Fix that and add a test.
    1fca81960a
  3. DrahtBot added the label PSBT on Aug 28, 2026
  4. DrahtBot commented at 10:48 AM on August 28, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/36113.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline and AI policy for information on the review process.

    Type Reviewers
    ACK winterrdog, jeanpablojp, rkrux, achow101

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #36114 (wallet: harden external signer psbt processing, revamp mock by Sjors)
    • #36076 (psbt: preserve sighash type when merging inputs by thomasbuilds)
    • #35984 (sign: skip signing SIGHASH_SINGLE inputs with no corresponding output by furszy)

    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.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  5. jeanpablojp commented at 10:40 PM on August 30, 2026: contributor

    Approach ACK

    Makes sense to have the guard in SighashToStr rather than at the call site.

  6. in test/functional/rpc_psbt.py:566 in 1fca81960a
     561 | +        self.log.info("Test that decodepsbt rejects invalid trailing bytes in the sighash type field")
     562 | +        node = self.nodes[0]
     563 | +        psbt = PSBT.from_base64(node.createpsbt([{"txid": "00" * 32, "vout": 0}], [{"data": "00"}]))
     564 | +        # The first byte of this sighash type is ALL, but the type itself is not
     565 | +        psbt.i[0].map[PSBT_IN_SIGHASH_TYPE] = (0x101).to_bytes(4, "little")
     566 | +        assert_equal(node.decodepsbt(psbt.to_base64())["inputs"][0]["sighash"], "")
    


    jeanpablojp commented at 10:40 PM on August 30, 2026:

    Nothing is rejected here, decodepsbt accepts the PSBT and returns an empty string. The guard has two halves and this case only trips > 0xff, so nothing in rpc_psbt.py covers the sighash_type < 0 || half. Dropping it leaves the file green. A value like 0xffffff01 would cover it, since it lands negative in PSBTInput, which keeps the field as an int.


    Sjors commented at 8:49 AM on August 31, 2026:

    Nothing is rejected here

    "rejects" isn't the best word, but I couldn't find a better term.

    sighash_type < 0

    Not sure if it's worth covering, other than for code coverage.

    The real fix for negative values is to use uint32_t everywhere, since that's how the BIP defines it, but that's too much churn.


    winterrdog commented at 8:57 AM on August 31, 2026:

    use uint32_t everywhere, since that's how the BIP defines it,

    nit: Correct! I was just wondering why you chose to go with a signed integer.

    🤔 Won't that introduce more confusion since it deviates from what is in the BIP?


    Sjors commented at 1:51 PM on August 31, 2026:

    A signed integer is consistent with the rest of the codebase, which annoyingly didn't follow the BIP from the start. I looked at how much code churn is involved in fixing that throughout the code, and it's not worth it imo. The code comment hopefully makes it clear.

  7. winterrdog commented at 3:41 AM on August 31, 2026: contributor

    Concept ACK

  8. winterrdog commented at 11:38 AM on August 31, 2026: contributor

    tACK 1fca81960abcd5331765842776909d4787929cea

    successfully built and tested on this toolchain: FreeBSD 15.0/clang++-19/x86_64. LGTM

  9. DrahtBot requested review from jeanpablojp on Aug 31, 2026
  10. jeanpablojp commented at 12:34 PM on August 31, 2026: contributor

    ACK 1fca81960abcd5331765842776909d4787929cea

  11. rkrux approved
  12. rkrux commented at 1:37 PM on September 7, 2026: contributor

    lgtm ACK 1fca81960abcd5331765842776909d4787929cea

    Fixes a non-dangerous but potentially confusing case.

  13. fanquake removed review request from jeanpablojp on Sep 7, 2026
  14. fanquake requested review from achow101 on Sep 7, 2026
  15. in src/core_io.cpp:345 in 1fca81960a
     342 | +std::string SighashToStr(int32_t sighash_type)
     343 |  {
     344 | -    const auto& it = mapSigHashTypes.find(sighash_type);
     345 | +    // Signatures encode the sighash type in a single byte, but the PSBT field
     346 | +    // for it is a 32 bit unsigned integer in BIP 174 (signed in PSBTInput)
     347 | +    if (sighash_type < 0 || sighash_type > 0xff) return "";
    


    rkrux commented at 2:30 PM on September 7, 2026:

    Ideally would have preferred to throw here instead of silently ignoring. But that might be a bit overkill I suppose in this case. Shall we update the doc as well mentioning that an incorrect sighash value will be ignored?

    https://github.com/bitcoin/bitcoin/blob/19b0ff2fa0500b7ab71ae60080c1daf98d722270/src/rpc/rawtransaction.cpp#L821


    Sjors commented at 10:25 AM on September 8, 2026:

    It might be worth a followup PR to decide how to handle unrecognized sighash types. They could come from malformed input, but also theoretically from future soft forks. As well as the distinction between absent and unknown.

  16. achow101 commented at 9:35 PM on September 7, 2026: member

    ACK 1fca81960abcd5331765842776909d4787929cea

  17. achow101 merged this on Sep 7, 2026
  18. achow101 closed this on Sep 7, 2026

  19. Sjors deleted the branch on Sep 8, 2026

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-09-09 07:56 UTC