#36555 rpc: return error when invalidateblock fails
| Reviewability | Reviews | Agreement | Size | |||||||
|---|---|---|---|---|---|---|---|---|---|---|
| #36555 rpc: return error when invalidateblock fails | Ready | 0 | Strong | 19 + 14 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
Populates BlockValidationState with an error message when Chainstate::InvalidateBlock fails to disconnect a block or encounters an active-chain conflict during invalidation. Adds an explicit RPC parameter check to invalidateblock to reject invalidating the genesis block with RPC_INVALID_PARAMETER. Extends unit tests for disconnect failures due to missing undo data and functional tests for genesis block invalidation.
Problem: When InvalidateBlock fails during block disconnection (for example, due to corrupted undo data), the chain is left partially rolled back while the invalidateblock RPC silently ignores the failure and returns success (null) to the caller. Additionally, attempting to invalidate the genesis block is not explicitly validated up front.
Evidence of importance:
- Issue #36546: 'rpc: invalidateblock reports success when a block can't be disconnected'
- PR description: 'If there is a problem disconnecting the block (for example, the undo data is corrupt), the chain remains partially rolled back when telling the user that the operation succeeded.'
Scope: CMakeLists.txt contains an apparent stray change adding src/pubkey.cpp to the core_interface target.
Risk of a mistake: medium (rpc_api, validation, build). Touches block disconnection and invalidation error handling in validation, and includes a stray change to CMake build definitions.
Changed since the previous assessment: Added an accidental modification to CMakeLists.txt linking src/pubkey.cpp to core_interface; the core logic for validation error reporting and genesis check remains the same.
Reviewability
Ready
Nothing known that would invalidate a review now.
Waiting on (from the thread read):
- author: response to l0rinc regarding documenting the limitation versus adding regression code 2026-10-20
- reviewer: yusufyildiz34 to review author's pushed fixes 2026-10-20
Agreement
Strong
substantive support, no open objection (yusufyildiz34)
Thread notes: Added review comments from l0rinc and yusufyildiz34. Yusufyildiz34's objections regarding the block name in the error message and the genesis block error code were addressed and fixed by ja7ad.
Objections, suggestions, and questions:
| Reviewer | Type | Harm, request, or question | Status | Must be | Author replied | Quote |
|---|---|---|---|---|---|---|
| pinheadmz (member) | question, usefulness | Can the author guarantee having read the AI policy, that the contribution conforms to it, and that real human users have encountered the problem being solved? | accepted · author confirmed writing the code and understanding the AI policy; reviewer accepted | answered | yes | 2026-10-16: 'can you guarantee us that you have read our AI Policy and this particular contribution conforms to that policy?' Status from: 2026-10-17: pinheadmz: 'Great!' |
| pinheadmz (member) | suggestion, maintenance | Add a thorough description to the pull request | open | answered | no | 2026-10-17: 'Please add a thorough description to the PR.' |
| l0rinc (member) | suggestion, approach | Document the partial rollback behavior as a known limitation instead of adding validation or regression code | open | answered | no | 2026-10-20: 'I think this remaining partial-state behavior should be documented as a known limitation instead of adding more AssumeUTXO-specific validation or regression code.' |
| l0rinc (member) | suggestion, maintenance | Simplify the tests and consider adding the AssumeUTXO reproducer in a collapsible section | open | answered | no | 2026-10-20: 'Please try to simplify the tests and maybe add the AssumeUTXO reproducer in a collapsible section in the PR' |
| yusufyildiz34 (none) | objection, correctness | The error message names the wrong block (pindex instead of to_mark_failed) | fixed · fix pushed · author updated the error message to name to_mark_failed | changed | yes | 2026-10-20: 'The error message in the third hunk names the wrong block.' Status from: 2026-10-20: ja7ad: 'It's to_mark_failed now.' |
| yusufyildiz34 (none) | objection, interface | Using state.Error() for the genesis block returns database error (-20) rather than an invalid parameter error (-8 / RPC_INVALID_PARAMETER) | fixed · fix pushed · author updated the RPC helper to reject the genesis block with -8 | changed | yes | 2026-10-20: 'Rejecting height 0 in the RPC helper next to the existing LookupBlockIndex() check, with RPC_INVALID_PARAMETER, would give a more accurate code' Status from: 2026-10-20: ja7ad: 'the RPC now rejects it with -8 next to "Block not found"' |
| yusufyildiz34 (none) | question, maintenance | Does this change need a release note? | answered · fix pushed · author confirmed adding a release note | answered | yes | 2026-10-20: 'Does this want a release note? invalidateblock now throws where it previously returned null.' Status from: 2026-10-20: ja7ad: 'Squashed the commits and added a body and a release note.' |
Support:
- yusufyildiz34 (none) (2026-10-20) [read: src/rpc/blockchain.cpp, consensus/validation.h]: invalidateblock reporting success after a partial rollback is clearly wrong, and routing the failures through state is cleaner than patching the RPC helper
Participants:
- pinheadmz (member, question, 2 statements 2026-10-16 to 2026-10-17): asked about AI policy compliance and requested a thorough PR description
- l0rinc (member, neutral, 1 statements 2026-10-20 to 2026-10-20): suggested documenting partial-state behavior as a known limitation and simplifying tests
- yusufyildiz34 (none, objection, 1 statements 2026-10-20 to 2026-10-20): supported the concept but objected to the error message naming the wrong block and returning database error for genesis
Files
15 lines under test/bench/ci.
- src/test/blockchain_tests.cpp +10/-1
- doc/release-notes-36555.md +9/-0
- src/validation.cpp +5/-2
- test/functional/rpc_invalidateblock.py +4/-0
- CMakeLists.txt +2/-1
- src/rpc/blockchain.cpp +3/-0
Card
The short text the ranking pass compares across PRs.
Ensures the invalidateblock RPC and validation layer properly report errors when block invalidation fails. Previously, if block disconnection failed midway (such as from missing or corrupt undo data), InvalidateBlock returned false without setting an error state, causing the RPC to report success despite leaving the active chain partially rolled back (issue #36546). The PR records specific error messages into BlockValidationState, adds an explicit RPC check preventing invalidation of the genesis block, and adds unit and functional test coverage.
Data
thread read through 2026-10-20 (6 statements), head 4aeb6a8fad
labels: RPC/REST/ZMQ
Categories
RPC / REST / ZMQ
P3 · bug fix (ranking pass: Moved up 6: an RPC reporting success after a partial chain rollback is a false-success bug of the same class as the ones ranked just above.)
Fixes a bug where invalidateblock silently returned success despite a failure disconnecting blocks that left the chain partially rolled back. Because invalidateblock is primarily an administrative and testing tool rather than a standard hot method, the impact on everyday RPC callers is limited.
Membership: Carries the RPC/REST/ZMQ label and modifies src/rpc/blockchain.cpp to report errors on failed invalidations and validate parameters.
Factors: security/stability 1, bug 1, performance 0, user value 1, leverage 0
Validation
P3 · bug fix (ranking pass: Moved up: fixes a reported bug (#36546) where invalidateblock reports success after a partial rollback, more concrete than the rest of P3)
Surfaces block disconnection failures in Chainstate::InvalidateBlock by populating BlockValidationState instead of silently ignoring them. The change improves internal state accounting during rollbacks without modifying consensus rules or core validation algorithms.
Membership: Changes Chainstate::InvalidateBlock error state propagation in src/validation.cpp and adds blockchain unit tests for disconnect failures.
Factors: security/stability 1, bug 1, performance 0, user value 1, leverage 0