mirror of https://github.com/bitcoin/bitcoin.git
tests: add unit tests for CBlockIndex::GetAncestor and LastCommonAncestor
This commit is contained in:
parent
1ed00a0d39
commit
2e09d66fbb
|
@ -26,6 +26,7 @@ add_executable(test_bitcoin
|
|||
bloom_tests.cpp
|
||||
bswap_tests.cpp
|
||||
caches_tests.cpp
|
||||
chain_tests.cpp
|
||||
chainstate_write_tests.cpp
|
||||
checkqueue_tests.cpp
|
||||
cluster_linearize_tests.cpp
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
// Copyright (c) The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <chain.h>
|
||||
#include <test/util/setup_common.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(chain_tests, BasicTestingSetup)
|
||||
|
||||
namespace {
|
||||
|
||||
const CBlockIndex* NaiveGetAncestor(const CBlockIndex* a, int height)
|
||||
{
|
||||
while (a->nHeight > height) {
|
||||
a = a->pprev;
|
||||
}
|
||||
BOOST_REQUIRE_EQUAL(a->nHeight, height);
|
||||
return a;
|
||||
}
|
||||
|
||||
const CBlockIndex* NaiveLastCommonAncestor(const CBlockIndex* a, const CBlockIndex* b)
|
||||
{
|
||||
while (a->nHeight > b->nHeight) {
|
||||
a = a->pprev;
|
||||
}
|
||||
while (b->nHeight > a->nHeight) {
|
||||
b = b->pprev;
|
||||
}
|
||||
while (a != b) {
|
||||
BOOST_REQUIRE_EQUAL(a->nHeight, b->nHeight);
|
||||
a = a->pprev;
|
||||
b = b->pprev;
|
||||
}
|
||||
BOOST_REQUIRE_EQUAL(a, b);
|
||||
return a;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
BOOST_AUTO_TEST_CASE(chain_test)
|
||||
{
|
||||
FastRandomContext ctx;
|
||||
std::vector<std::unique_ptr<CBlockIndex>> block_index;
|
||||
// Run 10 iterations of the whole test.
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
block_index.clear();
|
||||
// Create genesis block.
|
||||
auto genesis = std::make_unique<CBlockIndex>();
|
||||
genesis->nHeight = 0;
|
||||
block_index.push_back(std::move(genesis));
|
||||
// Create 10000 more blocks.
|
||||
for (int b = 0; b < 10000; ++b) {
|
||||
auto new_index = std::make_unique<CBlockIndex>();
|
||||
// 95% of blocks build on top of the last block; the others fork off randomly.
|
||||
if (ctx.randrange(20) != 0) {
|
||||
new_index->pprev = block_index.back().get();
|
||||
} else {
|
||||
new_index->pprev = block_index[ctx.randrange(block_index.size())].get();
|
||||
}
|
||||
new_index->nHeight = new_index->pprev->nHeight + 1;
|
||||
new_index->BuildSkip();
|
||||
block_index.push_back(std::move(new_index));
|
||||
}
|
||||
// Run 10000 random GetAncestor queries.
|
||||
for (int q = 0; q < 10000; ++q) {
|
||||
const CBlockIndex* block = block_index[ctx.randrange(block_index.size())].get();
|
||||
unsigned height = ctx.randrange<unsigned>(block->nHeight + 1);
|
||||
const CBlockIndex* result = block->GetAncestor(height);
|
||||
BOOST_CHECK(result == NaiveGetAncestor(block, height));
|
||||
}
|
||||
// Run 10000 random LastCommonAncestor queries.
|
||||
for (int q = 0; q < 10000; ++q) {
|
||||
const CBlockIndex* block1 = block_index[ctx.randrange(block_index.size())].get();
|
||||
const CBlockIndex* block2 = block_index[ctx.randrange(block_index.size())].get();
|
||||
const CBlockIndex* result = LastCommonAncestor(block1, block2);
|
||||
BOOST_CHECK(result == NaiveLastCommonAncestor(block1, block2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
Loading…
Reference in New Issue