5 #include <chainparams.h> 20 #include <validation.h> 30 template <
typename... Args>
49 .cache_bytes = n_cache_size,
50 .memory_only = f_memory,
52 .obfuscate = f_obfuscate,
71 :
m_chain{std::move(chain)}, m_name{std::move(
name)} {}
89 return &
m_chain->context()->chainman->GetChainstateForIndexing());
92 m_chain->context()->validation_signals->RegisterValidationInterface(
this);
95 if (!
GetDB().ReadBestBlock(locator)) {
108 if (!locator_index) {
133 return chain.Genesis();
136 const CBlockIndex* pindex = chain.Next(pindex_prev);
141 return chain.Next(chain.FindFork(pindex_prev));
148 std::chrono::steady_clock::time_point last_log_time{0
s};
149 std::chrono::steady_clock::time_point last_locator_write_time{0
s};
183 FatalErrorf(
"%s: Failed to rewind index %s to a previous chain tip", __func__,
GetName());
186 pindex = pindex_next;
192 FatalErrorf(
"%s: Failed to read block %s from disk",
196 block_info.
data = █
199 FatalErrorf(
"%s: Failed to write block %s to index database",
204 auto current_time{std::chrono::steady_clock::now()};
206 LogPrintf(
"Syncing %s with block chain from height %d\n",
208 last_log_time = current_time;
213 last_locator_write_time = current_time;
241 LogError(
"%s: Failed to commit latest %s state\n", __func__,
GetName());
284 if (!best_block_index) {
286 FatalErrorf(
"%s: First block connected is not the genesis block (height=%d)",
297 LogPrintf(
"%s: WARNING: Block %s does not connect to an ancestor of " 298 "known best chain (tip=%s); not updating index\n",
303 if (best_block_index != pindex->
pprev && !
Rewind(best_block_index, pindex->
pprev)) {
304 FatalErrorf(
"%s: Failed to rewind index %s to a previous chain tip",
317 FatalErrorf(
"%s: Failed to write block %s to index",
335 const uint256& locator_tip_hash = locator.
vHave.front();
342 if (!locator_tip_index) {
343 FatalErrorf(
"%s: First block (hash=%s) in locator was not found",
344 __func__, locator_tip_hash.
ToString());
355 LogPrintf(
"%s: WARNING: Locator contains block (hash=%s) not on known best " 356 "chain (tip=%s); not writing index locator\n",
357 __func__, locator_tip_hash.
ToString(),
368 bool BaseIndex::BlockUntilSyncedToCurrentChain()
const 387 LogPrintf(
"%s: %s is catching up on block notifications\n", __func__,
GetName());
388 m_chain->context()->validation_signals->SyncWithValidationInterfaceQueue();
399 if (!
m_init)
throw std::logic_error(
"Error: Cannot start a non-initialized index");
407 if (
m_chain->context()->validation_signals) {
408 m_chain->context()->validation_signals->UnregisterValidationInterface(
this);
422 summary.best_block_height = pindex->nHeight;
423 summary.best_block_hash = pindex->GetBlockHash();
425 summary.best_block_height = 0;
426 summary.best_block_hash =
m_chain->getBlockHash(0);
Helper for findBlock to selectively return pieces of block data.
fs::path path
Location in the filesystem where leveldb data will be stored.
bool Commit()
Write the current index state (eg.
bool IsPruneMode() const
Whether running in -prune mode.
bool Init()
Initializes the sync state and registers the instance to the validation interface so that it stays in...
CThreadInterrupt m_interrupt
BaseIndex(std::unique_ptr< interfaces::Chain > chain, std::string name)
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
std::atomic< bool > m_synced
Whether the index is in sync with the main chain.
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Batch of changes queued to be written to a CDBWrapper.
virtual bool CustomAppend(const interfaces::BlockInfo &block)
Write update index entries for a newly connected block.
node::BlockManager & m_blockman
Reference to a BlockManager instance which itself is shared across all Chainstate instances...
void SetBestBlockIndex(const CBlockIndex *block)
Update the internal best block index as well as the prune lock.
An in-memory indexed chain of blocks.
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Hash/height pair to help track and identify blocks.
bool ReadBlock(CBlock &block, const FlatFilePos &pos) const
Functions for disk access for blocks.
bool Rewind(const CBlockIndex *current_tip, const CBlockIndex *new_tip)
Loop over disconnected blocks and call CustomRewind.
CChain m_chain
The current chain of blockheaders we consult and build on.
User-controlled performance and debug options.
void Stop()
Stops the instance from staying in sync with blockchain updates.
std::thread m_thread_sync
uint256 GetBlockHash() const
Block data sent with blockConnected, blockDisconnected notifications.
virtual ~BaseIndex()
Destructor interrupts sync thread if running and blocks until it exits.
void WriteBestBlock(CDBBatch &batch, const CBlockLocator &locator)
Write block locator of the chain that the index is in sync with.
void ChainStateFlushed(ChainstateRole role, const CBlockLocator &locator) override
Notifies listeners of the new active block chain on-disk.
constexpr auto SYNC_LOG_INTERVAL
ChainstateRole
This enum describes the various roles a specific Chainstate instance can take.
const std::string & GetName() const LIFETIMEBOUND
Get the name of the index for display in logs.
CBlockLocator GetLocator(interfaces::Chain &chain, const uint256 &block_hash)
bool InitError(const bilingual_str &str)
Show error message.
std::atomic< bool > m_init
Whether the index has been initialized or not.
void Sync()
Sync the index with the block index starting from the current best block.
virtual bool findBlock(const uint256 &hash, const FoundBlock &block={})=0
Return whether node has the block and optionally return block metadata or contents.
constexpr uint8_t DB_BEST_BLOCK
void Write(const K &key, const V &value)
std::string ToString() const
void ReadDatabaseArgs(const ArgsManager &args, DBOptions &options)
constexpr auto SYNC_LOCATOR_WRITE_INTERVAL
std::vector< uint256 > vHave
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
virtual bool CustomInit(const std::optional< interfaces::BlockRef > &block)
Initialize internal state from the database and block index.
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
bool StartBackgroundSync()
Starts the initial sync process on a background thread.
virtual bool CustomCommit(CDBBatch &batch)
Virtual method called internally by Commit that can be overridden to atomically commit more index sta...
#define EXCLUSIVE_LOCKS_REQUIRED(...)
static const CBlockIndex * NextSyncBlock(const CBlockIndex *pindex_prev, CChain &chain) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
void AbortNode(const std::function< bool()> &shutdown_request, std::atomic< int > &exit_status, const bilingual_str &message, node::Warnings *warnings)
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
The block chain is a tree shaped structure starting with the genesis block at the root...
Chainstate * m_chainstate
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Application-specific storage settings.
#define AssertLockNotHeld(cs)
virtual bool CustomRewind(const interfaces::BlockRef ¤t_tip, const interfaces::BlockRef &new_tip)
Rewind index to an earlier chain tip during a chain reorg.
bool WriteBatch(CDBBatch &batch, bool fSync=false)
void BlockConnected(ChainstateRole role, const std::shared_ptr< const CBlock > &block, const CBlockIndex *pindex) override
Notifies listeners of a block being connected.
interfaces::BlockInfo MakeBlockInfo(const CBlockIndex *index, const CBlock *data)
Return data from block index.
int nHeight
height of the entry in the chain. The genesis block has height 0
DB(const fs::path &path, size_t n_cache_size, bool f_memory=false, bool f_wipe=false, bool f_obfuscate=false)
bool ReadBestBlock(CBlockLocator &locator) const
Read block locator of the chain that the index is in sync with.
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
virtual DB & GetDB() const =0
std::atomic< const CBlockIndex * > m_best_block_index
The last block in the chain that the index is in sync with.
void FatalErrorf(util::ConstevalFormatString< sizeof...(Args)> fmt, const Args &... args)
virtual bool AllowPrune() const =0
std::unique_ptr< interfaces::Chain > m_chain
void TraceThread(std::string_view thread_name, std::function< void()> thread_func)
A wrapper for do-something-once thread functions.
IndexSummary GetSummary() const
Get a summary of the index and its state.