#36280 validation: throw when a compressed script can't be decompressed
https://github.com/bitcoin/bitcoin/pull/36280 · · +61/-4 in 3 files, 2 commits · labels: Validation
Goal
- Fail explicitly on corrupted compressed scripts instead of silently treating them as empty scripts
- Prevents corrupt UTXO database or undo data from quietly yielding anyone-can-spend outputs
This pull request modifies `ScriptCompression::Unser` to throw `std::ios_base::failure` when `DecompressScript` fails, rather than ignoring the failure and leaving the output script empty. It also adds unit tests covering off-curve and invalid-pubkey P2PK decompression failure modes, plus an assertion round-trip in the script fuzz harness.
Problem: When deserializing compressed scripts from the UTXO database or undo data, decompression failures are currently ignored. If a compressed record is corrupted or improperly formed, it silently yields an empty script (anyone-can-spend) instead of signaling deserialization failure to the caller.
Category: Validation (#18 of 48)
P3 · bug fix
- P3 because it fixes error handling for corrupted UTXO and undo data
- Requires database corruption to trigger in practice, limiting real-world impact
- Prevents severe misinterpretation of corrupt records as anyone-can-spend coins
Hardens UTXO deserialization error handling against corrupted or non-decodable data. As noted by furszy, the bug requires data corruption to trigger today, but ignoring failure produces an empty anyone-can-spend script instead of raising an error.
Membership: Touches `src/compressor.h`, which handles UTXO script compression for the coins database and undo storage, carrying the Validation label.
Factors: security/stability 1, bug 1, performance 0, user value 0, leverage 0
Reviewability: Ready
- Ready for review with passing CI, unit tests, and fuzz coverage
The patch is small, passes CI, and includes unit and fuzz tests with no pending requests.
Author status: active
Agreement: Positive
- Positive early sentiment with no objections raised
- Concept approval without stated reasons (sedited)
Positive with early Approach ACK from sedited
Reviewer sedited provided an Approach ACK, with no objections raised.
- sedited left an Approach ACK on 2026-09-16
Review verdicts (DrahtBot): 0
- Approach ACK: sedited
Files
55 lines under test/bench/ci.
- src/test/compress_tests.cpp +46/-0
- src/compressor.h +7/-3
- src/test/fuzz/script.cpp +8/-1
Card
PR 36280 fixes error handling in ScriptCompression::Unser so that decompression failures throw std::ios_base::failure instead of silently leaving the script empty. Currently, a corrupted compressed record can deserialize into an empty script, which consensus evaluates as anyone-can-spend. While only reachable via corruption today, the change ensures clean deserialization failure and adds explicit test coverage for uncompressed off-curve pubkey scripts. Review is ready and has an initial Approach ACK.