Skip to content

Commit bd16f59

Browse files
committed
index: enable block filter index parallel sync
It also adds coverage for initial sync from a particular block. Mimicking a node restart.
1 parent 06a21d2 commit bd16f59

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed

src/index/blockfilterindex.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,23 @@ bool BlockFilterIndex::Write(const BlockFilter& filter, uint32_t block_height, c
299299
return true;
300300
}
301301

302+
std::any BlockFilterIndex::CustomProcessBlock(const interfaces::BlockInfo& block_info)
303+
{
304+
return std::make_pair(BlockFilter(BlockFilterType::BASIC, *block_info.data, *block_info.undo_data), block_info.height);
305+
}
306+
307+
bool BlockFilterIndex::CustomPostProcessBlocks(const std::any& obj)
308+
{
309+
const auto& [filter, height] = std::any_cast<std::pair<BlockFilter, int>>(obj);
310+
const uint256& header = filter.ComputeHeader(m_last_header);
311+
if (!Write(filter, height, header)) {
312+
LogError("Error writing filters, shutting down block filters index\n");
313+
return false;
314+
}
315+
m_last_header = header;
316+
return true;
317+
}
318+
302319
[[nodiscard]] static bool CopyHeightIndexToHashIndex(CDBIterator& db_it, CDBBatch& batch,
303320
const std::string& index_name, int height)
304321
{

src/index/blockfilterindex.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,18 @@ class BlockFilterIndex final : public BaseIndex
6464

6565
BaseIndex::DB& GetDB() const LIFETIMEBOUND override { return *m_db; }
6666

67+
std::any CustomProcessBlock(const interfaces::BlockInfo& block) override;
68+
bool CustomPostProcessBlocks(const std::any& obj) override;
69+
6770
public:
6871
/** Constructs the index, which becomes available to be queried. */
6972
explicit BlockFilterIndex(std::unique_ptr<interfaces::Chain> chain, BlockFilterType filter_type,
7073
size_t n_cache_size, bool f_memory = false, bool f_wipe = false);
7174

7275
BlockFilterType GetFilterType() const { return m_filter_type; }
7376

77+
bool AllowParallelSync() override { return true; }
78+
7479
/** Get a single filter by block. */
7580
bool LookupFilter(const CBlockIndex* block_index, BlockFilter& filter_out) const;
7681

src/test/blockfilter_index_tests.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <pow.h>
1414
#include <test/util/blockfilter.h>
1515
#include <test/util/setup_common.h>
16+
#include <util/threadpool.h>
1617
#include <validation.h>
1718

1819
#include <boost/test/unit_test.hpp>
@@ -268,6 +269,50 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
268269
filter_index.Stop();
269270
}
270271

272+
BOOST_FIXTURE_TEST_CASE(blockfilter_index_parallel_initial_sync, BuildChainTestingSetup)
273+
{
274+
int tip_height = 100; // pre-mined blocks
275+
const uint16_t MINE_BLOCKS = 650;
276+
for (int round = 0; round < 2; round++) { // two rounds to test sync from genesis and from a higher block
277+
// Generate blocks
278+
mineBlocks(MINE_BLOCKS);
279+
const CBlockIndex* tip = WITH_LOCK(::cs_main, return m_node.chainman->ActiveChain().Tip());
280+
BOOST_REQUIRE(tip->nHeight == MINE_BLOCKS + tip_height);
281+
tip_height = tip->nHeight;
282+
283+
// Init index
284+
BlockFilterIndex filter_index(interfaces::MakeChain(m_node), BlockFilterType::BASIC, 1 << 20, /*f_memory=*/false);
285+
BOOST_REQUIRE(filter_index.Init());
286+
287+
ThreadPool thread_pool;
288+
thread_pool.Start(2);
289+
filter_index.SetThreadPool(thread_pool);
290+
filter_index.SetBlocksPerWorker(200);
291+
292+
// Start sync
293+
BOOST_CHECK(!filter_index.BlockUntilSyncedToCurrentChain());
294+
filter_index.Sync();
295+
const auto& summary{filter_index.GetSummary()};
296+
BOOST_CHECK(summary.synced);
297+
BOOST_CHECK_EQUAL(summary.best_block_height, tip_height);
298+
299+
// Check that filter index has all blocks that were in the chain before it started.
300+
{
301+
uint256 last_header;
302+
LOCK(cs_main);
303+
const CBlockIndex* block_index;
304+
for (block_index = m_node.chainman->ActiveChain().Genesis();
305+
block_index != nullptr;
306+
block_index = m_node.chainman->ActiveChain().Next(block_index)) {
307+
CheckFilterLookups(filter_index, block_index, last_header, m_node.chainman->m_blockman);
308+
}
309+
}
310+
311+
filter_index.Interrupt();
312+
filter_index.Stop();
313+
}
314+
}
315+
271316
BOOST_FIXTURE_TEST_CASE(blockfilter_index_init_destroy, BasicTestingSetup)
272317
{
273318
BlockFilterIndex* filter_index;

0 commit comments

Comments
 (0)