#35906 First steps towards a stateless, side-effect free validation library
https://github.com/bitcoin/bitcoin/pull/35906 · · +855/-37 in 6 files, 7 commits · labels: none
Goal
- Allow consensus header and block validity checks to be tested directly without full node block ingestion
- Make validation logic stateless and free of hidden side effects to support a modular validation library
Exposes CheckBlockHeader, ContextualCheckBlockHeader, and ContextualCheckBlock as part of the public validation interface declared in validation.h. Refactors ContextualCheck* to accept Consensus::Params directly instead of ChainstateManager, and passes validation time explicitly to ContextualCheckBlockHeader rather than reading the system clock. Adds comprehensive unit tests covering header and block validity edge cases.
Problem: Core consensus header and block validation functions were static and tied to ChainstateManager and the system clock, preventing them from being unit tested directly without pushing full blocks through the node.
Category: Validation (#14 of 48)
P2 · test coverage
- P2 because it brings direct unit tests to core consensus checks that previously needed full block ingestion
- Removes hidden side effects from consensus checks and advances modular, stateless validation architecture
Directly unit tests core consensus checks (over 800 lines of tests covering proof-of-work, median-time-past, time-warp, and buried deployments) that previously could only be tested through full block ingestion. Removing ChainstateManager and system clock dependencies from ContextualCheck* eliminates hidden side effects and advances the project's goal of a modular, stateless validation library.
Membership: Refactors public block and block header validation functions in validation.h and validation.cpp and adds direct unit tests for them.
Factors: security/stability 1, bug 0, performance 0, user value 0, leverage 2
Reviewability: Ready
- Ready for review with passing CI and clean mergeability
- Only minor test nits remain open on the latest revision
The PR has clean CI and mergeability. The only feedback since the last push consists of nits from an ACK review that do not invalidate review.
Author status: silent since 2026-08-20 force-push addressing previous review feedback
Open concerns:
- optout21 noted minor commit prefix inconsistencies and suggested adding an explicit invalid test case assertion for CheckBlock.
Resolved concerns:
- alexanderwiederin requested moving doc comments from cpp to header and clarifying test fixture usage; author addressed in force-push.
Agreement: Strong
- Strong support for decoupling validation checks to enable direct testing (optout21, janb84, josibake)
- Support because it simplifies inputs and tests error cases cleanly (optout21)
- Verified by testing that direct validation testing is a major improvement (janb84)
- Support for comprehensive consensus tests and explicit validation timing (josibake)
- Concept approval without stated reasons (yuvicc)
Strong consensus on decoupling validation checks from ChainstateManager with direct tests (optout21, janb84, josibake)
Multiple contributors support the interface segregation and test additions, with an ACK and Concept ACKs and no dissenting opinions.
- optout21 ACKed 4d4f0331cf, noting it reduces complexity and enables testing of error cases with simple input combinations
- janb84 tested ACKed an earlier revision, calling direct testability of these functions a 'big improvement'
- josibake Concept ACKed, praising the new tests and explicit time passing
- yuvicc gave Concept ACK
Review verdicts (DrahtBot): 1 (+1)
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
This PR exposes CheckBlockHeader, ContextualCheckBlockHeader, and ContextualCheckBlock in validation.h, removes their dependency on ChainstateManager in favor of Consensus::Params, and passes the validation clock time explicitly. It adds over 800 lines of unit tests verifying consensus header and block checks directly, which previously required full block ingestion to exercise. Reviewers strongly support the interface segregation and test coverage (optout21, janb84, josibake). The code is ready for review with only minor nonblocking nits pending.