Skip to content

Commit

Permalink
index: add start_height to base index
Browse files Browse the repository at this point in the history
This allows indexing to start from a specified start_height (default 0).
This is particularly useful for blockfilter indexes in that a new filter type could
be defined where the filter is only relevant after a certain block height (e.g.
a filter for only taproot scriptPubKeys).

Although this is currently not possible, start_height would also be needed if we wanted
to enable an index in pruned mode (e.g. having a txindex for recent blocks).

Co-Authored-by: Fabian Jahr <fjahr@protonmail.com>
  • Loading branch information
josibake and fjahr committed Jan 31, 2024
1 parent 0b76874 commit 3b40c19
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 5 deletions.
19 changes: 15 additions & 4 deletions src/index/base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ void BaseIndex::DB::WriteBestBlock(CDBBatch& batch, const CBlockLocator& locator
batch.Write(DB_BEST_BLOCK, locator);
}

BaseIndex::BaseIndex(std::unique_ptr<interfaces::Chain> chain, std::string name)
: m_chain{std::move(chain)}, m_name{std::move(name)} {}
BaseIndex::BaseIndex(std::unique_ptr<interfaces::Chain> chain, std::string name, int start_height)
: m_chain{std::move(chain)}, m_name{std::move(name)}, m_start_height{std::move(start_height)} {}

BaseIndex::~BaseIndex()
{
Expand Down Expand Up @@ -125,11 +125,16 @@ bool BaseIndex::Init()
return true;
}

static const CBlockIndex* NextSyncBlock(const CBlockIndex* pindex_prev, CChain& chain) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
static const CBlockIndex* NextSyncBlock(const CBlockIndex* pindex_prev, CChain& chain, int start_height) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
AssertLockHeld(cs_main);

if (!pindex_prev) {
// pindex_prev is null, we are starting our sync. Return the genesis block
// or start from the specified start_height.
if (start_height > 0) {
return chain[start_height];
}
return chain.Genesis();
}

Expand Down Expand Up @@ -161,14 +166,20 @@ void BaseIndex::ThreadSync()

{
LOCK(cs_main);
const CBlockIndex* pindex_next = NextSyncBlock(pindex, m_chainstate->m_chain);
const CBlockIndex* pindex_next = NextSyncBlock(pindex, m_chainstate->m_chain, m_start_height);
if (!pindex_next) {
SetBestBlockIndex(pindex);
m_synced = true;
// No need to handle errors in Commit. See rationale above.
Commit();
break;
}
// If pindex_next is our first block and we are starting from a custom height,
// set pindex to be the previous block. This ensures we test that we can still rewind
// from our custom start height in the event of a reorg.
if (pindex_next->nHeight == m_start_height && m_start_height > 0) {
pindex = pindex_next->pprev;
}
if (pindex_next->pprev != pindex && !Rewind(pindex, pindex_next->pprev)) {
FatalErrorf("%s: Failed to rewind index %s to a previous chain tip",
__func__, GetName());
Expand Down
3 changes: 2 additions & 1 deletion src/index/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ class BaseIndex : public CValidationInterface
std::unique_ptr<interfaces::Chain> m_chain;
Chainstate* m_chainstate{nullptr};
const std::string m_name;
const int m_start_height{0};

void BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex) override;

Expand All @@ -132,7 +133,7 @@ class BaseIndex : public CValidationInterface
void SetBestBlockIndex(const CBlockIndex* block);

public:
BaseIndex(std::unique_ptr<interfaces::Chain> chain, std::string name);
BaseIndex(std::unique_ptr<interfaces::Chain> chain, std::string name, int start_height = 0);
/// Destructor interrupts sync thread if running and blocks until it exits.
virtual ~BaseIndex();

Expand Down

0 comments on commit 3b40c19

Please sign in to comment.