#35662 script: prevent stale sighash caches across transactions
https://github.com/bitcoin/bitcoin/pull/35662 · · +82/-74 in 17 files, 4 commits · labels: Consensus
Goal
- Prevent stale sighash cache state from leaking across transactions or remaining uninitialized
- Avoid unnecessary memory allocation during assumevalid block connection
This pull request removes the default constructor and public `Init()` method of `PrecomputedTransactionData`, ensuring that sighash cache objects are constructed directly for a specific transaction. Validation call sites that require deferred precomputation now wrap the object in `std::optional`, and `ConnectBlock` skips allocating `txsdata` storage entirely when script verification is skipped under assumevalid.
Problem: Previously, `PrecomputedTransactionData` could be default-constructed and populated later with `Init()`, exposing a public reuse path where stale BIP143 and Taproot sighash cache state could be carried across transactions or left partially uninitialized.
Category: Validation (#36 of 48)
P3 · cleanup
- P3 because it hardens sighash cache lifetime against misuse and invalid reuse across transactions
- Saves an unnecessary vector allocation during assumevalid sync
Hardens the validation and script interpreter interface against misuse by guaranteeing that PrecomputedTransactionData is bound to a single transaction at construction time. It also avoids an unneeded vector allocation in ConnectBlock during assumevalid sync.
Membership: Modifies script interpreter precomputed transaction data structures and validation script check workflows in src/validation.cpp.
Factors: security/stability 1, bug 0, performance 1, user value 0, leverage 1
Reviewability: Ready
- Ready for review; author addressed feedback with a rework and CI passes
The author addressed all reviewer feedback in a rework, CI passes, and no further changes are pending.
Author status: Active; rebased and addressed review feedback.
Resolved concerns:
- sedited objected to resetting flags inside Init() and suggested requiring initialization at construction instead. The author reworked the PR to eliminate default construction and public Init().
Agreement: Neutral
- Resolved objection against re-initialization by adopting construction-time initialization (sedited)
- Awaiting follow-up review after the rework
Initial objection from sedited resolved by implementing their suggested architectural change; awaiting follow-up review.
sedited initially leaned NACK on re-initializing through Init() and suggested construction-time initialization. The author adopted that suggestion and reworked the PR, but no formal ACKs have been posted yet.
- sedited: 'I think rather than messing with Init, we should seriously reconsider whether this data can be initialized at construction.'
- l0rinc: reworked PR to remove default construction and public Init(), following sedited's suggestion.
Review verdicts (DrahtBot): 0
Files
74 lines under test/bench/ci.
- src/test/sighash_tests.cpp +30/-3
- src/validation.cpp +15/-14
- src/psbt.cpp +5/-9
- src/test/txvalidationcache_tests.cpp +8/-6
- src/kernel/bitcoinkernel.cpp +2/-7
- src/script/interpreter.h +4/-5
- src/script/interpreter.cpp +4/-4
- src/script/sign.cpp +2/-5
- src/test/fuzz/script_assets_test_minimizer.cpp +2/-4
- src/test/script_assets_tests.cpp +2/-4
- src/bench/verify_script.cpp +1/-2
- src/signet.cpp +1/-2
- src/test/descriptor_tests.cpp +1/-2
- src/test/fuzz/script_flags.cpp +1/-2
- src/test/fuzz/script_sigcache.cpp +2/-1
- src/test/script_tests.cpp +1/-2
- src/wallet/feebumper.cpp +1/-2
Card
This PR removes default construction and public Init() from PrecomputedTransactionData, enforcing that each instance is constructed explicitly for a single transaction. This closes an API reuse footgun where cached BIP143 and Taproot sighash data could theoretically persist across re-initializations. Validation now manages deferred precomputations via std::optional and skips allocating transaction data vectors during assumevalid. The changes incorporate reviewer suggestions from sedited and are ready for review.