Merge bitcoin/bitcoin#34885: kernel: expose btck_block_tree_entry_get_ancestor

df44afdc98 kernel: expose btck_block_tree_entry_get_ancestor (Peter Zafonte)

Pull request description:

  Callers building a block locator from a stale tip currently have to walk back one entry at a time using btck_block_tree_entry_get_previous. For large step sizes this means hundreds of C API calls per locator entry.

  This exposes GetAncestor via btck_block_tree_entry_get_ancestor, which uses the existing CBlockIndex skiplist to reach any ancestor height in O(log N) and works on any chain, not just the active chain.

  Includes a C++ convenience wrapper and tests ~~covering same-height, genesis, and out-of-range cases~~ in btck_block_tree_entry_tests.

  See previous discussion here #34843

ACKs for top commit:
  alexanderwiederin:
    ACK df44afdc98
  sedited:
    ACK df44afdc98

Tree-SHA512: e953b634235129fa972e7f148016e8aee7bad61e16d50191d6724d11c71fe0f7623152ff61aa4c4ec5c8a5b500aaeb36613b5b2ff1e404d01ed7b65aa861f7aa
This commit is contained in:
merge-script
2026-04-23 15:17:01 -04:00
4 changed files with 29 additions and 0 deletions

View File

@@ -905,6 +905,13 @@ const btck_BlockTreeEntry* btck_block_tree_entry_get_previous(const btck_BlockTr
return btck_BlockTreeEntry::ref(btck_BlockTreeEntry::get(entry).pprev);
}
const btck_BlockTreeEntry* btck_block_tree_entry_get_ancestor(const btck_BlockTreeEntry* block_tree_entry, int32_t height)
{
const auto* ancestor{btck_BlockTreeEntry::get(block_tree_entry).GetAncestor(height)};
assert(ancestor);
return btck_BlockTreeEntry::ref(ancestor);
}
btck_BlockValidationState* btck_block_validation_state_create()
{
return btck_BlockValidationState::create();

View File

@@ -1039,6 +1039,17 @@ BITCOINKERNEL_API const btck_BlockHash* BITCOINKERNEL_WARN_UNUSED_RESULT btck_bl
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);
/**
* @brief Return the ancestor of a btck_BlockTreeEntry at the given height.
*
* @param[in] block_tree_entry Non-null.
* @param[in] height The height of the requested ancestor.
* @return The ancestor at the given height.
*/
BITCOINKERNEL_API const btck_BlockTreeEntry* BITCOINKERNEL_WARN_UNUSED_RESULT btck_block_tree_entry_get_ancestor(
const btck_BlockTreeEntry* block_tree_entry,
int32_t height) BITCOINKERNEL_ARG_NONNULL(1);
///@}
/** @name ChainstateManagerOptions

View File

@@ -924,6 +924,12 @@ public:
{
return BlockHeader{btck_block_tree_entry_get_block_header(get())};
}
BlockTreeEntry GetAncestor(int32_t height) const
{
return BlockTreeEntry{btck_block_tree_entry_get_ancestor(get(), height)};
}
};
class KernelNotifications

View File

@@ -1047,6 +1047,11 @@ BOOST_AUTO_TEST_CASE(btck_block_tree_entry_tests)
auto prev{entry_1.GetPrevious()};
BOOST_CHECK(prev.has_value());
BOOST_CHECK(prev.value() == entry_0);
// Test GetAncestor
BOOST_CHECK(entry_2.GetAncestor(2) == entry_2);
BOOST_CHECK(entry_2.GetAncestor(1) == entry_1);
BOOST_CHECK(entry_2.GetAncestor(0) == entry_0);
}
BOOST_AUTO_TEST_CASE(btck_chainman_in_memory_tests)