Merge bitcoin/bitcoin#33855: kernel: add btck_block_tree_entry_equals

096924d39d kernel: add btck_block_tree_entry_equals (stickies-v)

Pull request description:

  `BlockTreeEntry` objects are often compared. This happens frequently in our own codebase and seems likely to be the case for clients, too. Users can already work around this by comparing based on block hash (and optionally height as belt-and-suspenders), but I think this should be part of the interface for performance and consistency reasons.

  Note: perhaps this is too ad-hoc, and we should extend this PR to add the operator for more types? `BlockTreeEntry` is the main one I've needed this for in developing `py-bitcoinkernel`, though.

ACKs for top commit:
  maflcko:
    review ACK 096924d39d 📓
  TheCharlatan:
    ACK 096924d39d
  yuvicc:
    Code Review ACK 096924d39d

Tree-SHA512: a0c08c01ab6c855aec4e2b2b898e9550493cd4cf8c6e1fe9e4fe5039d0d9ef3bffb2f2ab0454c7cc449b9deedd7889f5fd7b5f100fa706a855023af4adb803c6
This commit is contained in:
merge-script
2025-11-25 12:31:17 +00:00
4 changed files with 63 additions and 0 deletions

View File

@@ -1117,6 +1117,11 @@ const btck_BlockHash* btck_block_tree_entry_get_block_hash(const btck_BlockTreeE
return btck_BlockHash::ref(btck_BlockTreeEntry::get(entry).phashBlock);
}
int btck_block_tree_entry_equals(const btck_BlockTreeEntry* entry1, const btck_BlockTreeEntry* entry2)
{
return &btck_BlockTreeEntry::get(entry1) == &btck_BlockTreeEntry::get(entry2);
}
btck_BlockHash* btck_block_hash_create(const unsigned char block_hash[32])
{
return btck_BlockHash::create(std::span<const unsigned char>{block_hash, 32});

View File

@@ -933,6 +933,17 @@ BITCOINKERNEL_API int32_t BITCOINKERNEL_WARN_UNUSED_RESULT btck_block_tree_entry
BITCOINKERNEL_API const btck_BlockHash* BITCOINKERNEL_WARN_UNUSED_RESULT btck_block_tree_entry_get_block_hash(
const btck_BlockTreeEntry* block_tree_entry) BITCOINKERNEL_ARG_NONNULL(1);
/**
* @brief Check if two block tree entries are equal. Two block tree entries are equal when they
* point to the same block.
*
* @param[in] entry1 Non-null.
* @param[in] entry2 Non-null.
* @return 1 if the block tree entries are equal, 0 otherwise.
*/
BITCOINKERNEL_API int BITCOINKERNEL_WARN_UNUSED_RESULT btck_block_tree_entry_equals(
const btck_BlockTreeEntry* entry1, const btck_BlockTreeEntry* entry2) BITCOINKERNEL_ARG_NONNULL(1, 2);
///@}
/** @name ChainstateManagerOptions

View File

@@ -786,6 +786,11 @@ public:
{
}
bool operator==(const BlockTreeEntry& other) const
{
return btck_block_tree_entry_equals(get(), other.get()) != 0;
}
std::optional<BlockTreeEntry> GetPrevious() const
{
auto entry{btck_block_tree_entry_get_previous(get())};

View File

@@ -812,6 +812,48 @@ BOOST_AUTO_TEST_CASE(btck_block_hash_tests)
CheckHandle(block_hash, block_hash_2);
}
BOOST_AUTO_TEST_CASE(btck_block_tree_entry_tests)
{
auto test_directory{TestDirectory{"block_tree_entry_test_bitcoin_kernel"}};
auto notifications{std::make_shared<TestKernelNotifications>()};
auto context{create_context(notifications, ChainType::REGTEST)};
auto chainman{create_chainman(
test_directory,
/*reindex=*/false,
/*wipe_chainstate=*/false,
/*block_tree_db_in_memory=*/true,
/*chainstate_db_in_memory=*/true,
context)};
// Process a couple of blocks
for (size_t i{0}; i < 3; i++) {
Block block{hex_string_to_byte_vec(REGTEST_BLOCK_DATA[i])};
bool new_block{false};
chainman->ProcessBlock(block, &new_block);
BOOST_CHECK(new_block);
}
auto chain{chainman->GetChain()};
auto entry_0{chain.GetByHeight(0)};
auto entry_1{chain.GetByHeight(1)};
auto entry_2{chain.GetByHeight(2)};
// Test inequality
BOOST_CHECK(entry_0 != entry_1);
BOOST_CHECK(entry_1 != entry_2);
BOOST_CHECK(entry_0 != entry_2);
// Test equality with same entry
BOOST_CHECK(entry_0 == chain.GetByHeight(0));
BOOST_CHECK(entry_0 == BlockTreeEntry{entry_0});
BOOST_CHECK(entry_1 == entry_1);
// Test GetPrevious
auto prev{entry_1.GetPrevious()};
BOOST_CHECK(prev.has_value());
BOOST_CHECK(prev.value() == entry_0);
}
BOOST_AUTO_TEST_CASE(btck_chainman_in_memory_tests)
{
auto in_memory_test_directory{TestDirectory{"in-memory_test_bitcoin_kernel"}};