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 <seb.kung@gmail.com>
This commit is contained in:
yuvicc 2025-11-12 11:52:30 +05:30
parent 52096de212
commit b851ff6cae
No known key found for this signature in database
GPG Key ID: 9711CE1B203EAE8C
5 changed files with 67 additions and 18 deletions

View File

@ -57,7 +57,7 @@ public:
std::optional<std::string> 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) {

View File

@ -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_);

View File

@ -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

View File

@ -685,7 +685,7 @@ public:
}
};
class BlockHashView: public View<btck_BlockHash>, public BlockHashApi<BlockHashView>
class BlockHashView : public View<btck_BlockHash>, public BlockHashApi<BlockHashView>
{
public:
explicit BlockHashView(const btck_BlockHash* ptr) : View{ptr} {}
@ -831,36 +831,50 @@ public:
virtual void FatalErrorHandler(std::string_view error) {}
};
class BlockValidationState
template <typename Derived>
class BlockValidationStateApi
{
private:
const btck_BlockValidationState* m_state;
auto impl() const
{
return static_cast<const Derived*>(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<ValidationMode>(btck_block_validation_state_get_validation_mode(m_state));
return static_cast<ValidationMode>(btck_block_validation_state_get_validation_mode(impl()));
}
BlockValidationResult GetBlockValidationResult() const
{
return static_cast<BlockValidationResult>(btck_block_validation_state_get_block_validation_result(m_state));
return static_cast<BlockValidationResult>(btck_block_validation_state_get_block_validation_result(impl()));
}
};
class BlockValidationStateView : public View<btck_BlockValidationState>, public BlockValidationStateApi<BlockValidationStateView>
{
public:
explicit BlockValidationStateView(const btck_BlockValidationState* ptr) : View{ptr} {}
};
class BlockValidationState : public Handle<btck_BlockValidationState, btck_block_validation_state_copy, btck_block_validation_state_destroy>, public BlockValidationStateApi<BlockValidationState>
{
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_type>(user_data); },
.block_checked = +[](void* user_data, btck_Block* block, const btck_BlockValidationState* state) { (*static_cast<user_type>(user_data))->BlockChecked(Block{block}, BlockValidationState{state}); },
.block_checked = +[](void* user_data, btck_Block* block, const btck_BlockValidationState* state) { (*static_cast<user_type>(user_data))->BlockChecked(Block{block}, BlockValidationStateView{state}); },
.pow_valid_block = +[](void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry) { (*static_cast<user_type>(user_data))->PowValidBlock(BlockTreeEntry{entry}, Block{block}); },
.block_connected = +[](void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry) { (*static_cast<user_type>(user_data))->BlockConnected(Block{block}, BlockTreeEntry{entry}); },
.block_disconnected = +[](void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry) { (*static_cast<user_type>(user_data))->BlockDisconnected(Block{block}, BlockTreeEntry{entry}); },

View File

@ -145,7 +145,7 @@ class TestValidationInterface : public ValidationInterface
public:
std::optional<std::vector<std::byte>> 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()};