#36500 AssumeUTXO: reject duplicate coins and empty snapshot groups
| Reviewability | Reviews | Agreement | Size | ||||
|---|---|---|---|---|---|---|---|
| #36500 AssumeUTXO: reject duplicate coins and empty snapshot groups | Waiting on author | 1 | Strong | 11 + 25 tests | |||
|
|
|
|
| |||
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
Validates the announced coin count in AssumeUTXO snapshot metadata against the unique UTXO count produced during import, and rejects transaction groups specifying zero coins during deserialization. Content hash checks take precedence over coin count errors.
Problem: AssumeUTXO snapshot loading verifies content hash but does not check the metadata's announced coin count against the unique UTXOs imported into the chainstate. A malformed snapshot with duplicate records collapses outpoints into single entries, matching the serialized UTXO hash while reporting an inflated count in `loadtxoutset`. Furthermore, empty transaction groups (zero coins) pass deserialization without advancing the coin counter, which bypasses the loop interrupt check and can delay node shutdown.
Evidence of importance:
- PR description: 'Repeated outpoints collapse into one coin, so a snapshot can repeat every record, announce the doubled count, and still match the committed UTXO hash. loadtxoutset then reports the inflated count as coins_loaded.'
- Commit e8e8cbcaa2: 'Snapshots generated by dumptxoutset already contain only nonempty groups.'
Risk of a mistake: medium (validation). A flaw in snapshot validation could falsely reject valid AssumeUTXO snapshots or prevent users from loading them via RPC.
Changed since the previous assessment: The implementation and tests are now separated into characterization test commits and implementation commits, with no substantive changes to the validation logic.
Reviewability
Paused · Waiting on author
Open objection from cyb3ralbert with no author reply for 7 days; review would repeat what has been asked.
Waiting on (from the thread read):
- author: response to cyb3ralbert's suggestion to reuse nodes[1] 2026-10-15
Agreement
Strong
substantive support, no open objection (cyb3ralbert, fametrano)
Thread notes: Added fametrano's tested ACK; cyb3ralbert's suggestion on test node reuse remains open.
Objections, suggestions, and questions:
| Reviewer | Type | Harm, request, or question | Status | Must be | Author replied | Quote |
|---|---|---|---|---|---|---|
| cyb3ralbert (contributor) | suggestion, maintenance | Use the existing node (nodes[1]) instead of adding a fifth node to avoid test conflicts with #35307 | open | answered | no | 2026-10-15: 'Could the new cases use the existing `node` (`nodes[1]`) instead of adding a fifth node?' |
Support:
- cyb3ralbert (contributor) (2026-10-15) [tested]: verified on regtest that duplicate records and empty groups are properly rejected and fuzz targets ran with no crashes
- fametrano (contributor) (Tested ACK, 2026-10-25) [both: feature_assumeutxo.py]: verified on regtest and functional tests that duplicate records are rejected by coin count on head while passing on base
Participants:
- cyb3ralbert (contributor, support, 1 statements 2026-10-15 to 2026-10-15): tested on regtest and fuzz targets; suggested reusing nodes[1] in the functional test
- fametrano (contributor, support, 1 statements 2026-10-25 to 2026-10-25): tested ACK; verified rejection of duplicate coin records on head vs base
Files
34 lines under test/bench/ci.
- test/functional/feature_assumeutxo.py +25/-9
- src/validation.cpp +10/-0
- src/node/utxo_snapshot.h +1/-1
Card
The short text the ranking pass compares across PRs.
Validates AssumeUTXO snapshot metadata coin counts against unique coins imported and disallows empty transaction groups during snapshot deserialization. Previously, snapshots with duplicated records could match the committed UTXO hash while reporting an inflated coin count, and zero-coin transaction groups could bypass loop interrupt checks to delay node shutdown. Legitimate snapshots generated by dumptxoutset already only produce non-empty groups, preserving compatibility.
Data
thread read through 2026-10-25 (2 statements), head e8e8cbcaa2
labels: Validation
Categories
Validation
P3 · bug fix (ranking pass: Moved up: grouped with the other assumeutxo input-validation fixes it overlaps with)
Tightens AssumeUTXO snapshot validation by ensuring imported unique UTXOs match announced counts and preventing empty groups from delaying node shutdown. Because snapshot content hashes are already verified prior to this change, this is a modest sanity-check fix rather than a critical consensus or chainstate corruption issue.
Membership: Has the Validation label, edits src/validation.cpp and src/node/utxo_snapshot.h, and modifies AssumeUTXO snapshot validation logic.
Factors: security/stability 1, bug 1, performance 0, user value 0, leverage 0