#35906 First steps towards a stateless, side-effect free validation library
| Reviewability | Reviews | Agreement | Size | ||||
|---|---|---|---|---|---|---|---|
| #35906 First steps towards a stateless, side-effect free validation library | Ready | 1 (+1) | Strong | 46 + 809 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
Expose `CheckBlockHeader`, `ContextualCheckBlockHeader`, and `ContextualCheckBlock` in `validation.h`, decoupling them from `ChainstateManager` by passing `Consensus::Params` directly. In `ContextualCheckBlockHeader`, replace the internal system clock call with an explicit timestamp parameter. Extensive unit test suites are added for isolated header and block validity checks.
Problem: Contextual block and header validation functions were file-local static functions in `validation.cpp` tightly coupled to `ChainstateManager` and internal clock reads. This prevented using or unit-testing these consensus validation routines in isolation without heavy chainstate setup.
Evidence of importance:
- Part of tracking issue #35904 ('Factoring out a stateless, side-effect free validation library').
- Author description: 'Make the existing CheckBlockHeader, ContextualCheckBlockHeader, and ContextualCheckBlock functions part of the public validation interface... ContextualCheck* functions need a ChainstateManager only to access the consensus parameters. Pass Consensus::Params instead... Pass the validation time explicitly to ContextualCheckBlockHeader instead of reading the system clock internally.'
Scope: Over 90% of the diff (+807 of +855 lines) consists of new Boost unit tests in `src/test/validation_check_block_tests.cpp` and `src/test/validation_check_header_tests.cpp`.
Reviewability
Ready
Nothing known that would invalidate a review now.
Waiting on (from the thread read):
- reviewer: sedited to clarify their suggestion on declarative test style 2026-10-22
- reviewer: sedited to clarify their suggestion regarding declarative tests 2026-10-22
Agreement
Strong
substantive support, no open objection (janb84, josibake, optout21)
Thread notes: Converted maflcko's schema 1 objection to a suggestion fixed by the author. Added questions and suggestions from alexanderwiederin, optout21, and sedited. Waiting on sedited to clarify testing style suggestion. / Added inline questions from alexanderwiederin and a test refactoring suggestion from sedited under the re-read. Currently waiting on sedited to clarify their declarative testing suggestion after the author's response.
Objections, suggestions, and questions:
| Reviewer | Type | Harm, request, or question | Status | Must be | Author replied | Quote |
|---|---|---|---|---|---|---|
| maflcko (member) | objection, scope | include unit tests with the refactor to justify partially reverting earlier commit | fixed · fix pushed · author agreed and added tests | answered | yes | 2026-08-06: 'this partially reverts 78adef17536edef833a0bfca06b61ce28120e486. Maybe that is fine, but if the motivation is better tests, maybe the refactor change would come with better tests included?' Status from: 2026-08-07: purpleKarrot: 'Good point. Done.' |
| alexanderwiederin (member) | suggestion, interface | add a doc comment for context-dependent validity checks for consistency | answered · author noted comment was superseded by moving docs to header | answered | yes | 2026-08-20: 'I would suggest adding something like: `/** Context-dependent validity checks */` for consistency with line 394.' Status from: 2026-08-20: purpleKarrot: 'obsolete with the comment below.' |
| alexanderwiederin (member) | question, interface | whether doc comments should move to the header | answered · author agreed docs belong in declaration | answered | yes | 2026-08-20: 'Should these doc comments move to the header now?' Status from: 2026-08-20: purpleKarrot: 'You are right. the docs should be part of the declaration.' |
| alexanderwiederin (member) | suggestion, interface | align GetConsensus() calls between CheckBlock and ContextualCheckBlock | answered · author agreed | answered | yes | 2026-08-20: '`params.GetConsensus()` for CheckBlock and `GetConsensus()` for ContectualBlockCheck. Should they be aligned?' Status from: 2026-08-20: purpleKarrot: 'ok.' |
| alexanderwiederin (member) | question, approach | why BOOST_FIXTURE_TEST_SUITE is not used like other validation test suites | accepted · reviewer accepted explanation that stateless functions do not justify a fixture | answered | yes | 2026-08-20: 'Any reason we don't use `BOOST_FIXTURE_TEST_SUITE` like the other `validation_*_tests.cpp` do?' Status from: 2026-08-20: alexanderwiederin: 'Make sense - thank you!' |
| alexanderwiederin (member) | question, approach | whether BlockValidationState should be recreated rather than reused across CheckBlock calls | answered · author explained lack of strong opinion and long-term plan to make state a return type | answered | yes | 2026-08-20: 'This test reuses BlockValidationState across CheckBlock calls, the other tests create new ones. Should we make it consistent?' Status from: 2026-08-20: purpleKarrot: 'No strong opinion for this test. I think the state parameter is a smell anyway and it should (and will) become a return type in the long run, which will solve this.' |
| alexanderwiederin (member) | suggestion, approach | use BOOST_CHECK_EQUAL | accepted · reviewer dropped suggestion as not worth touching again | answered | yes | 2026-08-20: 'What about `BOOST_CHECK_EQUAL`?' Status from: 2026-08-20: alexanderwiederin: 'I think the error messages are better, but not worth touching again for this.' |
| optout21 (contributor) | suggestion, approach | strengthen test claim by showing invalid result with nNonce = 0 and no prior check | open | answered | no | 2026-09-07: 'The test claim could be made stronger, by showing that with `nNonce = 0` and no prior check the result is invalid' |
| sedited (member) | suggestion, approach | compress test files using a more declarative testing style instead of repeated boilerplate | answered · author explained current constraints and asked reviewer to clarify | answered | yes | 2026-10-22: 'Could these two test files be compressed a bit with that in mind?' Status from: 2026-10-22: purpleKarrot: 'I am not sure we use the same definition of the word "declarative"... But I assume this is not what you meant here. Please clarify.' |
Support:
- janb84 (member) (Tested ACK, 2026-08-12) [both: CheckBlockHeader, ContextualCheckBlock, ContextualCheckBlockHeader]: increases what is practical to test by allowing CheckBlockHeader, ContextualCheckBlockHeader, and ContextualCheckBlock to be called directly
- josibake (member) (Concept ACK, 2026-08-14) [read: ContextualCheckBlockHeader, tests]: welcomes the new tests and making ContextualCheckBlockHeader no longer read system time
- yuvicc (contributor) (Concept ACK, 2026-08-31): (no reason given) [not substantive]
- optout21 (contributor) (ACK, 2026-09-07) [read: CheckBlock, CheckBlockHeader, ContextualCheckBlock, ContextualCheckBlockHeader]: reduces complexity around ContextualCheckBlock/Header by taking consensus params and explicit time instead of chainstate manager, enabling tests of error cases with simple inputs
Participants:
- maflcko (member, objection, 2 statements 2026-08-06 to 2026-08-06): noted conflict and suggested refactor should include tests to justify reverting earlier commit; author resolved
- janb84 (member, support, 1 statements 2026-08-12 to 2026-08-12): Tested ACK; highlighted direct testability of validation functions as a big improvement
- josibake (member, support, 1 statements 2026-08-14 to 2026-08-14): Concept ACK; welcomed new tests and passing validation time explicitly
- alexanderwiederin (member, question, 8 statements 2026-08-20 to 2026-08-20): asked inline questions on docs, consistency, and test fixtures; satisfied with author's explanations
- yuvicc (contributor, support, 1 statements 2026-08-31 to 2026-08-31): Concept ACK without elaboration
- optout21 (contributor, support, 2 statements 2026-09-07 to 2026-09-07): ACK; noted reduced complexity and error testability, with minor test and prefix nits
- sedited (member, question, 1 statements 2026-10-22 to 2026-10-22): suggested compressing test files with declarative style; author asked for clarification
Dependencies
Enables:
Files
809 lines under test/bench/ci.
- src/test/validation_check_block_tests.cpp +462/-0
- src/test/validation_check_header_tests.cpp +345/-0
- src/validation.cpp +15/-37
- src/validation.h +25/-0
- src/deploymentstatus.h +6/-0
- src/test/CMakeLists.txt +2/-0
Card
The short text the ranking pass compares across PRs.
Refactors `CheckBlockHeader`, `ContextualCheckBlockHeader`, and `ContextualCheckBlock` into public functions in `validation.h`, replacing their `ChainstateManager` dependency with `Consensus::Params` and passing the current time explicitly into `ContextualCheckBlockHeader`. This addresses the tight coupling of block validation logic to chainstate management and system clocks, enabling isolated validation calls and direct unit testing. Over 800 lines of the PR consist of new unit tests covering header and block validation edge cases. The work implements initial steps toward the stateless validation library outlined in #35904.
Data
thread read through 2026-10-22 (24 statements), head 4d4f0331cf
labels: none
Categories
Validation
P3 · test coverage (ranking pass: Moved down: first step of a modularization project with no user-visible effect yet; ranks below measured fixes and speedups)
Decoupling block and header validation functions from chainstate and system clock state makes consensus verification safer to test in isolation and unblocks #35904. The PR adds extensive unit test coverage for isolated validity checks, providing clear and worthwhile architectural improvement that can be reviewed without urgency.
Membership: Changes src/validation.cpp, src/validation.h, and adds isolated consensus validation unit tests pinning block and header checking rules.
Factors: security/stability 1, bug 0, performance 0, user value 0, leverage 2