#36577 psbt: accept taproot ALL sigs with sighash unset

ReviewabilityReviewsAgreementSize
#36577 fametrano psbt: accept taproot ALL sigs with sighash unsetReady1Strong8 + 79 tests
  • Accept valid 65-byte Taproot SIGHASH_ALL signatures when the PSBT sighash type is unset
  • Prevents false mismatch errors that block downstream signing and finalization with external signers
  • Ready to review
  • Support because SIGHASH_ALL and SIGHASH_DEFAULT commit to the identical BIP-341 digest (Husteem)
  • Verified by testing on Windows (Yudis-bit)
  • 8 lines added or modified outside tests
  • 79 lines added or modified in tests
  • 2 lines removed in total
  • 2 files, 1 commits
Wallet#43 of 92
P3 · bug fix
  • P3 because it fixes an interoperability bug where valid 65-byte Taproot signatures trigger SIGHASH_MISMATCH
  • Restores multi-signer and finalization workflows when external signers omit the sighash type field
  • Ranking pass: Moved up to sit with the other PSBT signing interoperability fixes (#36039, #35747).
Reviewability: ReadyStalePaused
Agreement: StrongPositivePositive w/ caveatsNeutralMildDisputedBlockedCrickets
Reviews: current code-review ACKs, then (+stale ACKs) and -NACKs; greener = more ACKs.
Size: lines added or modified outside tests, then in tests; greener = smaller.

Goal

Relaxes signature verification in `SignPSBTInput` to accept 65-byte Taproot signatures ending in `SIGHASH_ALL` when neither `PSBT_IN_SIGHASH_TYPE` nor an explicit `sighash_type` option is provided. Previously, unset sighash types strictly assumed 64-byte `SIGHASH_DEFAULT` signatures and rejected any existing 65-byte signatures with `SIGHASH_MISMATCH`. Mismatches remain rejected if an explicit sighash type or field is set, or if the 65-byte signature uses sighashes other than `SIGHASH_ALL`.

Problem: Taproot signers sometimes produce 65-byte signatures explicitly specifying `SIGHASH_ALL` while leaving `PSBT_IN_SIGHASH_TYPE` unset. When a subsequent signer or finalizer processes the PSBT without an explicit sighash parameter, `SignPSBTInput` falls back to `SIGHASH_DEFAULT` and rejects valid 65-byte `SIGHASH_ALL` signatures as invalid, preventing the transaction from being signed further or finalized.

Evidence of importance:

  • Fixes issue #36507: 'PSBT: SignPSBTInput rejects valid 65-byte taproot script signatures when PSBT_IN_SIGHASH_TYPE is absent'

Risk of a mistake: low (wallet, rpc_api). A flaw in PSBT input signature checks could mistakenly allow an unintended sighash type or break PSBT signing workflows.

Changed since the previous assessment: Unchanged in approach; provides the implementation and accompanying unit tests for the previously described change.

Reviewability

Ready

Nothing known that would invalidate a review now.

Waiting on (from the thread read):

  • nothing: nothing pending

Agreement

Strong

substantive support, no open objection (Husteem)

Thread notes: Added Husteem's Approach ACK / Tested ACK. No objections or suggestions were raised.

Objections, suggestions, and questions: none recorded.

Support:

  • Yudis-bit (none) (Tested ACK, 2026-10-20) [tested]: Tested ACK 1291d0e389 on Windows. [not substantive]
  • Husteem (none) (Approach ACK, 2026-10-22) [both: psbt_tests, rpc_psbt.py]: accepting 65-byte Taproot signatures ending in SIGHASH_ALL when sighash_type is unset is safe because it commits to the identical BIP-341 digest as SIGHASH_DEFAULT, while preserving safety checks for other variants

Participants:

  • Yudis-bit (none, support, 1 statements 2026-10-20 to 2026-10-20): tested ACK on Windows
  • Husteem (none, support, 1 statements 2026-10-22 to 2026-10-22): Approach ACK / Tested ACK with rationale and testing on Ubuntu

Files

79 lines under test/bench/ci.

  • src/test/psbt_tests.cpp +79/-0
  • src/psbt.cpp +8/-2

Card

The short text the ranking pass compares across PRs.

Relaxes SignPSBTInput to accept 65-byte Taproot signatures ending in SIGHASH_ALL when no sighash type is explicitly specified by the caller or PSBT input. Previously, omitting the sighash field caused SignPSBTInput to assume SIGHASH_DEFAULT and strictly demand 64-byte signatures, causing valid PSBTs with 65-byte SIGHASH_ALL signatures to fail validation and blocking them from being signed further or finalized. This fixes issue #36507.

Data

dossier JSON · extract JSON · model ledger, generated 2026-10-23T01:17, confidence high, input hash 22c91f2d7bc76dad
thread read through 2026-10-22 (2 statements), head 1291d0e389
labels: PSBT

Categories

Wallet

P3 · bug fix (ranking pass: Moved up to sit with the other PSBT signing interoperability fixes (#36039, #35747).)

Fixes an interoperability bug where SignPSBTInput rejects valid 65-byte Taproot SIGHASH_ALL signatures when PSBT_IN_SIGHASH_TYPE is unset. As noted in issue #36507, this incorrectly triggers SIGHASH_MISMATCH and blocks downstream signing or finalization.

Membership: src/psbt.cpp implements core PSBT handling and SignPSBTInput used by the wallet to process and sign transactions.

Factors: security/stability 0, bug 1, performance 0, user value 1, leverage 0