From b851ff6cae71934bf2389d109908339d60ec6e5b Mon Sep 17 00:00:00 2001 From: yuvicc Date: Wed, 12 Nov 2025 11:52:30 +0530 Subject: [PATCH] kernel: Add Handle/View pattern for BlockValidationState Add C API functions for managing BlockValidationState lifecycle: - btck_block_validation_state_create() - btck_block_validation_state_copy() - btck_block_validation_state_destroy() Introduce BlockValidationStateApi<> template to share common getter methods between BlockValidationState (Handle) and BlockValidationStateView (View) classes in the C++ wrapper. This enables external code to create and own BlockValidationState objects needed for the new process_block_header() API. Co-authored-by: TheCharlatan --- src/bitcoin-chainstate.cpp | 2 +- src/kernel/bitcoinkernel.cpp | 15 +++++++++++ src/kernel/bitcoinkernel.h | 24 +++++++++++++++-- src/kernel/bitcoinkernel_wrapper.h | 42 ++++++++++++++++++++---------- src/test/kernel/test_kernel.cpp | 2 +- 5 files changed, 67 insertions(+), 18 deletions(-) diff --git a/src/bitcoin-chainstate.cpp b/src/bitcoin-chainstate.cpp index 71d0f3e95cc..ae215c198ed 100644 --- a/src/bitcoin-chainstate.cpp +++ b/src/bitcoin-chainstate.cpp @@ -57,7 +57,7 @@ public: std::optional m_expected_valid_block = std::nullopt; - void BlockChecked(const Block block, const BlockValidationState state) override + void BlockChecked(Block block, BlockValidationStateView state) override { auto mode{state.GetValidationMode()}; switch (mode) { diff --git a/src/kernel/bitcoinkernel.cpp b/src/kernel/bitcoinkernel.cpp index 8c7abef59f1..497527edd10 100644 --- a/src/kernel/bitcoinkernel.cpp +++ b/src/kernel/bitcoinkernel.cpp @@ -885,6 +885,21 @@ const btck_BlockTreeEntry* btck_block_tree_entry_get_previous(const btck_BlockTr return btck_BlockTreeEntry::ref(btck_BlockTreeEntry::get(entry).pprev); } +btck_BlockValidationState* btck_block_validation_state_create() +{ + return btck_BlockValidationState::create(); +} + +btck_BlockValidationState* btck_block_validation_state_copy(const btck_BlockValidationState* state) +{ + return btck_BlockValidationState::copy(state); +} + +void btck_block_validation_state_destroy(btck_BlockValidationState* state) +{ + delete state; +} + btck_ValidationMode btck_block_validation_state_get_validation_mode(const btck_BlockValidationState* block_validation_state_) { auto& block_validation_state = btck_BlockValidationState::get(block_validation_state_); diff --git a/src/kernel/bitcoinkernel.h b/src/kernel/bitcoinkernel.h index 53a760cd2ff..94d90ceafe3 100644 --- a/src/kernel/bitcoinkernel.h +++ b/src/kernel/bitcoinkernel.h @@ -1251,17 +1251,37 @@ BITCOINKERNEL_API void btck_block_destroy(btck_Block* block); ///@{ /** - * Returns the validation mode from an opaque block validation state pointer. + * Create a new btck_BlockValidationState. + */ +BITCOINKERNEL_API btck_BlockValidationState* BITCOINKERNEL_WARN_UNUSED_RESULT btck_block_validation_state_create(); + +/** + * Returns the validation mode from an opaque btck_BlockValidationState pointer. */ BITCOINKERNEL_API btck_ValidationMode btck_block_validation_state_get_validation_mode( const btck_BlockValidationState* block_validation_state) BITCOINKERNEL_ARG_NONNULL(1); /** - * Returns the validation result from an opaque block validation state pointer. + * Returns the validation result from an opaque btck_BlockValidationState pointer. */ BITCOINKERNEL_API btck_BlockValidationResult btck_block_validation_state_get_block_validation_result( const btck_BlockValidationState* block_validation_state) BITCOINKERNEL_ARG_NONNULL(1); +/** + * @brief Copies the btck_BlockValidationState. + * + * @param[in] block_validation_state Non-null. + * @return The copied btck_BlockValidationState. + */ +BITCOINKERNEL_API btck_BlockValidationState* BITCOINKERNEL_WARN_UNUSED_RESULT btck_block_validation_state_copy( + const btck_BlockValidationState* block_validation_state) BITCOINKERNEL_ARG_NONNULL(1); + +/** + * Destroy the btck_BlockValidationState. + */ +BITCOINKERNEL_API void btck_block_validation_state_destroy( + btck_BlockValidationState* block_validation_state) BITCOINKERNEL_ARG_NONNULL(1); + ///@} /** @name Chain diff --git a/src/kernel/bitcoinkernel_wrapper.h b/src/kernel/bitcoinkernel_wrapper.h index 5c1b8d07eb3..14f29d03d3a 100644 --- a/src/kernel/bitcoinkernel_wrapper.h +++ b/src/kernel/bitcoinkernel_wrapper.h @@ -685,7 +685,7 @@ public: } }; -class BlockHashView: public View, public BlockHashApi +class BlockHashView : public View, public BlockHashApi { public: explicit BlockHashView(const btck_BlockHash* ptr) : View{ptr} {} @@ -831,36 +831,50 @@ public: virtual void FatalErrorHandler(std::string_view error) {} }; -class BlockValidationState +template +class BlockValidationStateApi { private: - const btck_BlockValidationState* m_state; + auto impl() const + { + return static_cast(this)->get(); + } + + friend Derived; + BlockValidationStateApi() = default; public: - BlockValidationState(const btck_BlockValidationState* state) : m_state{state} {} - - BlockValidationState(const BlockValidationState&) = delete; - BlockValidationState& operator=(const BlockValidationState&) = delete; - BlockValidationState(BlockValidationState&&) = delete; - BlockValidationState& operator=(BlockValidationState&&) = delete; - ValidationMode GetValidationMode() const { - return static_cast(btck_block_validation_state_get_validation_mode(m_state)); + return static_cast(btck_block_validation_state_get_validation_mode(impl())); } BlockValidationResult GetBlockValidationResult() const { - return static_cast(btck_block_validation_state_get_block_validation_result(m_state)); + return static_cast(btck_block_validation_state_get_block_validation_result(impl())); } }; +class BlockValidationStateView : public View, public BlockValidationStateApi +{ +public: + explicit BlockValidationStateView(const btck_BlockValidationState* ptr) : View{ptr} {} +}; + +class BlockValidationState : public Handle, public BlockValidationStateApi +{ +public: + explicit BlockValidationState() : Handle{btck_block_validation_state_create()} {} + + BlockValidationState(const BlockValidationStateView& view) : Handle{view} {} +}; + class ValidationInterface { public: virtual ~ValidationInterface() = default; - virtual void BlockChecked(Block block, const BlockValidationState state) {} + virtual void BlockChecked(Block block, BlockValidationStateView state) {} virtual void PowValidBlock(BlockTreeEntry entry, Block block) {} @@ -918,7 +932,7 @@ public: btck_ValidationInterfaceCallbacks{ .user_data = heap_vi.release(), .user_data_destroy = +[](void* user_data) { delete static_cast(user_data); }, - .block_checked = +[](void* user_data, btck_Block* block, const btck_BlockValidationState* state) { (*static_cast(user_data))->BlockChecked(Block{block}, BlockValidationState{state}); }, + .block_checked = +[](void* user_data, btck_Block* block, const btck_BlockValidationState* state) { (*static_cast(user_data))->BlockChecked(Block{block}, BlockValidationStateView{state}); }, .pow_valid_block = +[](void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry) { (*static_cast(user_data))->PowValidBlock(BlockTreeEntry{entry}, Block{block}); }, .block_connected = +[](void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry) { (*static_cast(user_data))->BlockConnected(Block{block}, BlockTreeEntry{entry}); }, .block_disconnected = +[](void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry) { (*static_cast(user_data))->BlockDisconnected(Block{block}, BlockTreeEntry{entry}); }, diff --git a/src/test/kernel/test_kernel.cpp b/src/test/kernel/test_kernel.cpp index 07f1d3cfc62..8d6a2287c0f 100644 --- a/src/test/kernel/test_kernel.cpp +++ b/src/test/kernel/test_kernel.cpp @@ -145,7 +145,7 @@ class TestValidationInterface : public ValidationInterface public: std::optional> m_expected_valid_block = std::nullopt; - void BlockChecked(Block block, const BlockValidationState state) override + void BlockChecked(Block block, BlockValidationStateView state) override { if (m_expected_valid_block.has_value()) { auto ser_block{block.ToBytes()};