Skip to content

Commit a263a4c

Browse files
committed
kernel: Add function for copying block data to C header
This adds a function for streaming bytes into a user-owned data structure. Use it in the tests for verifying the implementation of the validation interface's `BlockChecked` method.
1 parent b30e15f commit a263a4c

File tree

4 files changed

+55
-8
lines changed

4 files changed

+55
-8
lines changed

src/kernel/bitcoinkernel.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,17 @@ const btck_Transaction* btck_block_get_transaction_at(const btck_Block* block, s
967967
return btck_Transaction::ref(&btck_Block::get(block)->vtx[index]);
968968
}
969969

970+
int btck_block_to_bytes(const btck_Block* block, btck_WriteBytes writer, void* user_data)
971+
{
972+
try {
973+
WriterStream ws{writer, user_data};
974+
ws << TX_WITH_WITNESS(*btck_Block::get(block));
975+
return 0;
976+
} catch (...) {
977+
return -1;
978+
}
979+
}
980+
970981
void btck_block_destroy(btck_Block* block)
971982
{
972983
delete block;

src/kernel/bitcoinkernel.h

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,11 @@ typedef void (*btck_ValidationInterfacePoWValidBlock)(void* user_data, btck_Bloc
249249
typedef void (*btck_ValidationInterfaceBlockConnected)(void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry);
250250
typedef void (*btck_ValidationInterfaceBlockDisconnected)(void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry);
251251

252+
/**
253+
* Function signature for serializing data.
254+
*/
255+
typedef int (*btck_WriteBytes)(const void* bytes, size_t size, void* userdata);
256+
252257
/**
253258
* Whether a validated data structure is valid, invalid, or an error was
254259
* encountered during processing.
@@ -389,11 +394,6 @@ typedef uint8_t btck_ChainType;
389394
#define btck_ChainType_SIGNET ((btck_ChainType)(3))
390395
#define btck_ChainType_REGTEST ((btck_ChainType)(4))
391396

392-
/**
393-
* Function signature for serializing data.
394-
*/
395-
typedef int (*btck_WriteBytes)(const void* bytes, size_t size, void* userdata);
396-
397397
/** @name Transaction
398398
* Functions for working with transactions.
399399
*/
@@ -983,6 +983,21 @@ BITCOINKERNEL_API size_t BITCOINKERNEL_WARN_UNUSED_RESULT btck_block_count_trans
983983
BITCOINKERNEL_API const btck_Transaction* BITCOINKERNEL_WARN_UNUSED_RESULT btck_block_get_transaction_at(
984984
const btck_Block* block, size_t transaction_index) BITCOINKERNEL_ARG_NONNULL(1);
985985

986+
/**
987+
* @brief Serializes the block through the passed in callback to bytes.
988+
* This is consensus serialization that is also used for the P2P network.
989+
*
990+
* @param[in] block Non-null.
991+
* @param[in] writer Non-null, callback to a write bytes function.
992+
* @param[in] user_data Holds a user-defined opaque structure that will be
993+
* passed back through the writer callback.
994+
* @return 0 on success.
995+
*/
996+
BITCOINKERNEL_API int btck_block_to_bytes(
997+
const btck_Block* block,
998+
btck_WriteBytes writer,
999+
void* user_data) BITCOINKERNEL_ARG_NONNULL(1, 2);
1000+
9861001
/**
9871002
* Destroy the block.
9881003
*/

src/kernel/bitcoinkernel_wrapper.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,11 @@ class Block : public Handle<btck_Block, btck_block_copy, btck_block_destroy>
548548
}
549549

550550
MAKE_RANGE_METHOD(Transactions, Block, &Block::CountTransactions, &Block::GetTransaction, *this)
551+
552+
std::vector<std::byte> ToBytes() const
553+
{
554+
return write_bytes(get(), btck_block_to_bytes);
555+
}
551556
};
552557

553558
inline void logging_disable()

src/test/kernel/test_kernel.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <filesystem>
1717
#include <iostream>
1818
#include <memory>
19+
#include <optional>
1920
#include <random>
2021
#include <ranges>
2122
#include <span>
@@ -129,9 +130,14 @@ class TestKernelNotifications : public KernelNotifications
129130
class TestValidationInterface : public ValidationInterface
130131
{
131132
public:
133+
std::optional<std::vector<std::byte>> m_expected_valid_block = std::nullopt;
134+
132135
void BlockChecked(Block block, const BlockValidationState state) override
133136
{
134-
std::cout << "Block checked: ";
137+
if (m_expected_valid_block.has_value()) {
138+
auto ser_block{block.ToBytes()};
139+
check_equal(m_expected_valid_block.value(), ser_block);
140+
}
135141

136142
auto mode{state.GetValidationMode()};
137143
switch (mode) {
@@ -545,8 +551,8 @@ BOOST_AUTO_TEST_CASE(btck_context_tests)
545551
BOOST_AUTO_TEST_CASE(btck_block)
546552
{
547553
Block block{hex_string_to_byte_vec(REGTEST_BLOCK_DATA[0])};
548-
Block block_1{hex_string_to_byte_vec(REGTEST_BLOCK_DATA[1])};
549-
CheckHandle(block, block_1);
554+
Block block_100{hex_string_to_byte_vec(REGTEST_BLOCK_DATA[100])};
555+
CheckHandle(block, block_100);
550556
Block block_tx{hex_string_to_byte_vec(REGTEST_BLOCK_DATA[205])};
551557
CheckRange(block_tx.Transactions(), block_tx.CountTransactions());
552558
}
@@ -673,10 +679,20 @@ void chainman_mainnet_validation_test(TestDirectory& test_directory)
673679
return tx.CountOutputs();
674680
})).begin();
675681
BOOST_CHECK_EQUAL(output_counts, 1);
682+
683+
validation_interface->m_expected_valid_block.emplace(raw_block);
684+
auto ser_block{block.ToBytes()};
685+
check_equal(ser_block, raw_block);
676686
bool new_block = false;
677687
BOOST_CHECK(chainman->ProcessBlock(block, &new_block));
678688
BOOST_CHECK(new_block);
679689

690+
validation_interface->m_expected_valid_block = std::nullopt;
691+
new_block = false;
692+
Block invalid_block{hex_string_to_byte_vec(REGTEST_BLOCK_DATA[REGTEST_BLOCK_DATA.size() - 1])};
693+
BOOST_CHECK(!chainman->ProcessBlock(invalid_block, &new_block));
694+
BOOST_CHECK(!new_block);
695+
680696
// If we try to validate it again, it should be a duplicate
681697
BOOST_CHECK(chainman->ProcessBlock(block, &new_block));
682698
BOOST_CHECK(!new_block);

0 commit comments

Comments
 (0)