mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-04-09 23:27:23 +02:00
kernel: Add functions to read block from disk to C header
This adds functions for reading a block from disk with a retrieved block tree entry. External services that wish to build their own index, or analyze blocks can use this to retrieve block data. The block tree can now be traversed from the tip backwards. This is guaranteed to work, since the chainstate maintains an internal block tree index in memory and every block (besides the genesis) has an ancestor. The user can use this function to iterate through all blocks in the chain (starting from the tip). The tip is retrieved from a separate `Chain` object, which allows distinguishing whether entries are currently in the best chain. Once the block tree entry for the genesis block is reached a nullptr is returned if the user attempts to get the previous entry.
This commit is contained in:
@@ -693,6 +693,20 @@ void chainman_mainnet_validation_test(TestDirectory& test_directory)
|
||||
BOOST_CHECK(!chainman->ProcessBlock(invalid_block, &new_block));
|
||||
BOOST_CHECK(!new_block);
|
||||
|
||||
auto chain{chainman->GetChain()};
|
||||
BOOST_CHECK_EQUAL(chain.Height(), 1);
|
||||
auto tip{chain.Tip()};
|
||||
auto read_block{chainman->ReadBlock(tip)};
|
||||
BOOST_REQUIRE(read_block);
|
||||
check_equal(read_block.value().ToBytes(), raw_block);
|
||||
|
||||
// Check that we can read the previous block
|
||||
auto tip_2{tip.GetPrevious()};
|
||||
auto read_block_2{chainman->ReadBlock(tip_2.value())};
|
||||
|
||||
// It should be an error if we go another block back, since the genesis has no ancestor
|
||||
BOOST_CHECK(!tip_2.value().GetPrevious());
|
||||
|
||||
// If we try to validate it again, it should be a duplicate
|
||||
BOOST_CHECK(chainman->ProcessBlock(block, &new_block));
|
||||
BOOST_CHECK(!new_block);
|
||||
@@ -758,4 +772,16 @@ BOOST_AUTO_TEST_CASE(btck_chainman_regtest_tests)
|
||||
BOOST_CHECK(chainman->ProcessBlock(block, &new_block));
|
||||
BOOST_CHECK(new_block);
|
||||
}
|
||||
|
||||
auto chain = chainman->GetChain();
|
||||
auto tip = chain.Tip();
|
||||
auto read_block = chainman->ReadBlock(tip).value();
|
||||
check_equal(read_block.ToBytes(), hex_string_to_byte_vec(REGTEST_BLOCK_DATA[REGTEST_BLOCK_DATA.size() - 1]));
|
||||
|
||||
auto tip_2 = tip.GetPrevious().value();
|
||||
auto read_block_2 = chainman->ReadBlock(tip_2).value();
|
||||
check_equal(read_block_2.ToBytes(), hex_string_to_byte_vec(REGTEST_BLOCK_DATA[REGTEST_BLOCK_DATA.size() - 2]));
|
||||
|
||||
std::filesystem::remove_all(test_directory.m_directory / "blocks" / "blk00000.dat");
|
||||
BOOST_CHECK(!chainman->ReadBlock(tip_2));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user