#35747 wallet: Fix FillPSBT failing to sign owned inputs when UTXOs disagree

ReviewabilityReviewsAgreementSize
#35747 nervana21 wallet: Fix FillPSBT failing to sign owned inputs when UTXOs disagreeReady1Strong9 + 85 tests
  • Ensure the wallet successfully signs owned inputs when a PSBT input has conflicting UTXO data
  • Prevents confusing signing failures caused by mismatched witness and non-witness UTXO records
  • Ready to review
  • Nothing known that would invalidate a review now
  • Verified by testing reproduction and fix on master (8144225309)
  • Confirmed script selection now aligns across PSBT signing steps (8144225309)
  • Clarified coordinator risks and failure modes after question (vicjuma)
  • 9 lines added or modified outside tests
  • 85 lines added or modified in tests
  • 7 lines removed in total
  • 4 files, 2 commits
Wallet#45 of 92
P3 · bug fix
  • P3 after comparing with the other PRs here (assessed alone as P2): Lowered from P2: only yields an incomplete PSBT, never a bad signature, matching #36577 and #36039 in consequence.
  • P2 because it fixes wallet signing failures on owned inputs during multi-step PSBT workflows
  • Prevents failures when buggy or malicious coordinators provide conflicting UTXO records
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

Updates DescriptorScriptPubKeyMan::FillPSBT to select signing providers via PSBTInput::GetUTXO instead of inspecting witness_utxo directly. This aligns FillPSBT with SignPSBTInput by prioritizing a verified non_witness_utxo over witness_utxo and immediately rejecting mismatched or malformed non-witness UTXOs.

Problem: When a PSBT input includes both witness_utxo and non_witness_utxo with conflicting scriptPubKeys, FillPSBT selected signing keys matching witness_utxo while SignPSBTInput attempted to sign for non_witness_utxo. As a result, the wallet would fail to produce a complete signature even if it owned the keys for the non_witness_utxo spend.

Evidence of importance:

  • PR description: 'When the two disagreed, FillPSBT loaded keys for the witness_utxo script while SignPSBTInput signed the non_witness_utxo spend. This could lead to an incomplete input even though the wallet owns the appropriate non_witness_utxo script.'
  • Regression test fillpsbt_signs_despite_conflicting_witness_utxo confirms that signing an owned input succeeded only after routing script selection through GetUTXO.

Risk of a mistake: medium (wallet). Flaws in UTXO extraction or key provider selection could cause the wallet to fail to sign legitimate PSBT inputs or mishandle malformed transactions.

Changed since the previous assessment: The core fix remains the same, organized into two commits that document and unit-test PSBTInput::GetUTXO resolution behavior before updating FillPSBT.

Reviewability

Ready

Nothing known that would invalidate a review now.

Waiting on (from the thread read):

  • nothing

Agreement

Strong

substantive support, no open objection (8144225309)

Thread notes: Recorded vicjuma's question regarding motivation/risks (answered by the author) and 8144225309's tested ACK. / vicjuma's question about conflicting UTXO motivations and risks was answered directly by nervana21. Added substantive Tested ACK from 8144225309.

Objections, suggestions, and questions:

ReviewerTypeHarm, request, or questionStatusMust beAuthor repliedQuote
vicjuma (contributor)question, usefulnessWhat is the motivation for someone intending to disagree non_witness_utxo and witness_utxo, and what are the risks involved?answered · author explained how a buggy or malicious coordinator could trigger it and clarified the failure modeansweredyes2026-08-03: 'Is there any motivation for someone intending to disagree `non_witness_utxo` and `witness_utxo`? Any risk involved?'
Status from: 2026-08-03: nervana21: 'IIUC, a malicious or otherwise buggy PSBT coordinator could add a faulty witness_utxo to an honest peer's already-existing non_witness_utxo.'

Support:

  • 8144225309 (contributor) (ACK, 2026-10-05) [both: scriptpubkeyman.cpp, src/wallet/scriptpubkeyman.cpp]: tested bug reproduction and fix on master, and verified routing FillPSBT through GetUTXO matches SignPSBTInput's script selection

Participants:

  • vicjuma (contributor, question, 1 statements 2026-08-03 to 2026-08-03): asked about the motivation and risks of conflicting UTXOs
  • 8144225309 (contributor, support, 1 statements 2026-10-05 to 2026-10-05): tested the reproduction and ACKed the fix

Files

85 lines under test/bench/ci.

  • src/test/psbt_tests.cpp +45/-0
  • src/wallet/test/psbt_wallet_tests.cpp +40/-0
  • src/wallet/scriptpubkeyman.cpp +4/-7
  • src/psbt.h +5/-0

Card

The short text the ranking pass compares across PRs.

Updates DescriptorScriptPubKeyMan::FillPSBT to use PSBTInput::GetUTXO for selecting signing keys instead of reading witness_utxo directly. Previously, an input with conflicting witness and non-witness UTXO fields caused FillPSBT to look up keys for the witness script while SignPSBTInput required keys for the non-witness script, leaving owned inputs unsigned. The change also ensures FillPSBT immediately returns MISSING_INPUTS when non_witness_utxo is malformed or txid-mismatched. No fund safety issues were involved as this bug only led to incomplete PSBTs rather than bad signatures.

Data

dossier JSON · extract JSON · model ledger, generated 2026-10-06T01:17, confidence high, input hash a9072c4c51f5f9e9
thread read through 2026-10-05 (4 statements), head 7aed7f8d17
labels: Wallet

Categories

Wallet

P3 · bug fix (assessed alone as P2; Lowered from P2: only yields an incomplete PSBT, never a bad signature, matching #36577 and #36039 in consequence.)

Fixes a bug where FillPSBT fails to complete signatures on owned inputs when witness_utxo and non_witness_utxo disagree. As noted in the description, 'FillPSBT loaded keys for the witness_utxo script while SignPSBTInput signed the non_witness_utxo spend', causing confusing signing failures during PSBT workflows.

Membership: Wallet label and modifications to DescriptorScriptPubKeyMan in src/wallet/scriptpubkeyman.cpp for PSBT signing.

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