kernel: Return btck_BlockValidationState from process_block_header API
What changed, and why it matters
This commit is a small cleanup of a Bitcoin Core programming interface (API) used by the experimental 'libbitcoinkernel' library. It removes a redundant integer return value from the function that processes new block headers, so callers now rely only on the structured validation-state object to tell whether a header is valid. The change is not a security fix and does not appear to introduce a vulnerability; it mainly makes error handling less ambiguous for developers.
No security action required. Treat as a normal code-quality/API-consistency change. Downstream consumers of libbitcoinkernel will need to update their use of process_block_header to the new signature and interpret validation results from the returned state object rather than an integer return code.
Security signals we found
API cleanup removing redundant dual-return pattern
Added assert(result == btck_BlockValidationState::get(state).IsValid())
No change to ProcessNewBlockHeaders consensus behavior
No input validation, memory safety, or cryptographic changes
No vendor security disclosure or CVE references present
Evidence from the diff
The patch refactors btck_chainstate_manager_process_block_header in the bitcoinkernel C API. Previously the function returned both an int (0/-1) and an out-parameter btck_BlockValidationState, which could be confused because -1 could mean either an invalid header or an internal failure. The new signature returns the btck_BlockValidationState pointer directly (or nullptr on exception). Internally it creates the state object, calls ProcessNewBlockHeaders, asserts that the bool result matches state.IsValid(), and returns the state. The C++ wrapper and a test are updated accordingly. No consensus logic is changed.
Changed components
src/kernel/bitcoinkernel.cppsrc/kernel/bitcoinkernel.hsrc/kernel/bitcoinkernel_wrapper.hsrc/test/kernel/test_kernel.cppInspect captured patch +18 / −17
diff --git a/src/kernel/bitcoinkernel.cpp b/src/kernel/bitcoinkernel.cpp
index ea646cd5..64545c6f 100644
--- a/src/kernel/bitcoinkernel.cpp
+++ b/src/kernel/bitcoinkernel.cpp
@@ -1298,19 +1298,20 @@ int btck_chainstate_manager_process_block(
return result ? 0 : -1;
}
-int btck_chainstate_manager_process_block_header(
+btck_BlockValidationState* btck_chainstate_manager_process_block_header(
btck_ChainstateManager* chainstate_manager,
- const btck_BlockHeader* header,
- btck_BlockValidationState* state)
+ const btck_BlockHeader* header)
{
try {
auto& chainman = btck_ChainstateManager::get(chainstate_manager).m_chainman;
- auto result = chainman->ProcessNewBlockHeaders({&btck_BlockHeader::get(header), 1}, /*min_pow_checked=*/true, btck_BlockValidationState::get(state), /*ppindex=*/nullptr);
- return result ? 0 : -1;
+ auto state = btck_BlockValidationState::create();
+ bool result{chainman->ProcessNewBlockHeaders({&btck_BlockHeader::get(header), 1}, /*min_pow_checked=*/true, btck_BlockValidationState::get(state))};
+ assert(result == btck_BlockValidationState::get(state).IsValid());
+ return state;
} catch (const std::exception& e) {
LogError("Failed to process block header: %s", e.what());
- return -1;
+ return nullptr;
}
}
diff --git a/src/kernel/bitcoinkernel.h b/src/kernel/bitcoinkernel.h
index 5427e776..efe8c206 100644
--- a/src/kernel/bitcoinkernel.h
+++ b/src/kernel/bitcoinkernel.h
@@ -1117,13 +1117,11 @@ BITCOINKERNEL_API const btck_BlockTreeEntry* BITCOINKERNEL_WARN_UNUSED_RESULT bt
*
* @param[in] chainstate_manager Non-null.
* @param[in] header Non-null btck_BlockHeader to be validated.
- * @param[out] block_validation_state The result of the btck_BlockHeader validation.
- * @return 0 if btck_BlockHeader processing completed successfully, non-zero on error.
+ * @return The btck_BlockValidationState containing validation result, or null on error.
*/
-BITCOINKERNEL_API int BITCOINKERNEL_WARN_UNUSED_RESULT btck_chainstate_manager_process_block_header(
+BITCOINKERNEL_API btck_BlockValidationState* BITCOINKERNEL_WARN_UNUSED_RESULT btck_chainstate_manager_process_block_header(
btck_ChainstateManager* chainstate_manager,
- const btck_BlockHeader* header,
- btck_BlockValidationState* block_validation_state) BITCOINKERNEL_ARG_NONNULL(1, 2, 3);
+ const btck_BlockHeader* header) BITCOINKERNEL_ARG_NONNULL(1, 2);
/**
* @brief Triggers the start of a reindex if the wipe options were previously
diff --git a/src/kernel/bitcoinkernel_wrapper.h b/src/kernel/bitcoinkernel_wrapper.h
index 064d0dd1..1f626834 100644
--- a/src/kernel/bitcoinkernel_wrapper.h
+++ b/src/kernel/bitcoinkernel_wrapper.h
@@ -939,7 +939,9 @@ class BlockValidationState : public Handle<btck_BlockValidationState, btck_block
public:
explicit BlockValidationState() : Handle{btck_block_validation_state_create()} {}
- BlockValidationState(const BlockValidationStateView& view) : Handle{view} {}
+ explicit BlockValidationState(const BlockValidationStateView& view) : Handle{view} {}
+
+ explicit BlockValidationState(btck_BlockValidationState* state) : Handle{state} {}
};
class ValidationInterface
@@ -1217,9 +1219,10 @@ public:
return res == 0;
}
- bool ProcessBlockHeader(const BlockHeader& header, BlockValidationState& state)
+ BlockValidationState ProcessBlockHeader(const BlockHeader& header)
{
- return btck_chainstate_manager_process_block_header(get(), header.get(), state.get()) == 0;
+ auto state = btck_chainstate_manager_process_block_header(get(), header.get());
+ return BlockValidationState{state};
}
ChainView GetChain() const
diff --git a/src/test/kernel/test_kernel.cpp b/src/test/kernel/test_kernel.cpp
index 5a380065..af299420 100644
--- a/src/test/kernel/test_kernel.cpp
+++ b/src/test/kernel/test_kernel.cpp
@@ -1013,10 +1013,9 @@ BOOST_AUTO_TEST_CASE(btck_chainman_regtest_tests)
for (const auto& data : REGTEST_BLOCK_DATA) {
Block block{hex_string_to_byte_vec(data)};
BlockHeader header = block.GetHeader();
- BlockValidationState state{};
- BOOST_CHECK(state.GetBlockValidationResult() == BlockValidationResult::UNSET);
- BOOST_CHECK(chainman->ProcessBlockHeader(header, state));
+ BlockValidationState state = chainman->ProcessBlockHeader(header);
BOOST_CHECK(state.GetValidationMode() == ValidationMode::VALID);
+ BOOST_CHECK(state.GetBlockValidationResult() == BlockValidationResult::UNSET);
BlockTreeEntry entry{*chainman->GetBlockTreeEntry(header.Hash())};
BOOST_CHECK(!chainman->GetChain().Contains(entry));
BlockTreeEntry best_entry{chainman->GetBestEntry()};
Why this scored 18/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.