From 6c26da3dc494cfbb290974e63231b86c07e47f51 Mon Sep 17 00:00:00 2001 From: TheCharlatan Date: Sun, 17 Nov 2024 15:11:55 +0100 Subject: [PATCH] kernel: Add functions to get the block hash from a block This is useful for a host block processing feature where having an identifier for the block is needed. Without this, external users need to serialize the block and calculate the hash externally, which is less efficient. --- src/kernel/bitcoinkernel.cpp | 18 ++++++++++++++++++ src/kernel/bitcoinkernel.h | 20 ++++++++++++++++++++ src/kernel/bitcoinkernel_wrapper.h | 24 +++++++++++++++++------- src/test/kernel/test_kernel.cpp | 5 ++++- 4 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/kernel/bitcoinkernel.cpp b/src/kernel/bitcoinkernel.cpp index 8f7414ef31f51..50b9f7b9f2b69 100644 --- a/src/kernel/bitcoinkernel.cpp +++ b/src/kernel/bitcoinkernel.cpp @@ -962,6 +962,24 @@ kernel_ByteArray* kernel_copy_block_pointer_data(const kernel_BlockPointer* bloc return byte_array; } +kernel_BlockHash* kernel_block_get_hash(kernel_Block* block_) +{ + auto block{cast_cblocksharedpointer(block_)}; + auto hash{(*block)->GetHash()}; + auto block_hash = new kernel_BlockHash{}; + std::memcpy(block_hash->hash, hash.begin(), sizeof(hash)); + return block_hash; +} + +kernel_BlockHash* kernel_block_pointer_get_hash(const kernel_BlockPointer* block_) +{ + auto block{cast_const_cblock(block_)}; + auto hash{block->GetHash()}; + auto block_hash = new kernel_BlockHash{}; + std::memcpy(block_hash->hash, hash.begin(), sizeof(hash)); + return block_hash; +} + void kernel_block_destroy(kernel_Block* block) { if (block) { diff --git a/src/kernel/bitcoinkernel.h b/src/kernel/bitcoinkernel.h index dc00b2cfd3eb6..91919c705baee 100644 --- a/src/kernel/bitcoinkernel.h +++ b/src/kernel/bitcoinkernel.h @@ -868,6 +868,16 @@ kernel_Block* BITCOINKERNEL_WARN_UNUSED_RESULT kernel_block_create( const unsigned char* raw_block, size_t raw_block_len ) BITCOINKERNEL_ARG_NONNULL(1); +/** + * @brief Calculate and return the hash of a block. + * + * @param[in] block Non-null. + * @return The block hash. + */ +kernel_BlockHash* BITCOINKERNEL_WARN_UNUSED_RESULT kernel_block_get_hash( + kernel_Block* block +) BITCOINKERNEL_ARG_NONNULL(1); + /** * Destroy the block. */ @@ -893,6 +903,16 @@ kernel_ByteArray* BITCOINKERNEL_WARN_UNUSED_RESULT kernel_copy_block_pointer_dat const kernel_BlockPointer* block ) BITCOINKERNEL_ARG_NONNULL(1); +/** + * @brief Calculate and return the hash of a block. + * + * @param[in] block Non-null. + * @return The block hash. + */ +kernel_BlockHash* BITCOINKERNEL_WARN_UNUSED_RESULT kernel_block_pointer_get_hash( + const kernel_BlockPointer* block +) BITCOINKERNEL_ARG_NONNULL(1); + /** * A helper function for destroying an existing byte array. */ diff --git a/src/kernel/bitcoinkernel_wrapper.h b/src/kernel/bitcoinkernel_wrapper.h index 0544bfd939fcd..5c74c63765687 100644 --- a/src/kernel/bitcoinkernel_wrapper.h +++ b/src/kernel/bitcoinkernel_wrapper.h @@ -219,6 +219,13 @@ class KernelNotifications friend class ContextOptions; }; +struct BlockHashDeleter { + void operator()(kernel_BlockHash* ptr) const + { + kernel_block_hash_destroy(ptr); + } +}; + class UnownedBlock { private: @@ -232,6 +239,11 @@ class UnownedBlock UnownedBlock(UnownedBlock&&) = delete; UnownedBlock& operator=(UnownedBlock&&) = delete; + std::unique_ptr GetHash() const noexcept + { + return std::unique_ptr(kernel_block_pointer_get_hash(m_block)); + } + std::vector GetBlockData() const noexcept { auto serialized_block{kernel_copy_block_pointer_data(m_block)}; @@ -485,6 +497,11 @@ class Block Block(kernel_Block* block) noexcept : m_block{block} {} + std::unique_ptr GetHash() const noexcept + { + return std::unique_ptr(kernel_block_get_hash(m_block.get())); + } + std::vector GetBlockData() const noexcept { auto serialized_block{kernel_copy_block_data(m_block.get())}; @@ -533,13 +550,6 @@ class BlockUndo } }; -struct BlockHashDeleter { - void operator()(kernel_BlockHash* ptr) const - { - kernel_block_hash_destroy(ptr); - } -}; - class BlockIndex { private: diff --git a/src/test/kernel/test_kernel.cpp b/src/test/kernel/test_kernel.cpp index ac885c75fb6b0..022343a5f91e7 100644 --- a/src/test/kernel/test_kernel.cpp +++ b/src/test/kernel/test_kernel.cpp @@ -568,7 +568,8 @@ void chainman_reindex_test(TestDirectory& test_directory) auto tip_index{chainman->GetBlockIndexFromTip()}; auto tip_block_string{chainman->ReadBlock(tip_index).value().GetBlockData()}; auto second_index{chainman->GetBlockIndexByHeight(1).value()}; - auto second_block_string{chainman->ReadBlock(second_index).value().GetBlockData()}; + auto second_block{chainman->ReadBlock(second_index).value()}; + auto second_block_string{second_block.GetBlockData()}; auto second_height{second_index.GetHeight()}; assert(second_height == 1); assert(next_block_string == tip_block_string); @@ -577,6 +578,8 @@ void chainman_reindex_test(TestDirectory& test_directory) auto hash{second_index.GetHash()}; auto another_second_index{chainman->GetBlockIndexByHash(hash.get())}; auto another_second_height{another_second_index.GetHeight()}; + auto block_hash{second_block.GetHash()}; + assert(std::equal(std::begin(block_hash->hash), std::end(block_hash->hash), std::begin(hash->hash))); assert(second_height == another_second_height); }