5 #include <chainparams.h> 20 #include <validation.h> 31 template <
typename... Args>
50 .cache_bytes = n_cache_size,
51 .memory_only = f_memory,
53 .obfuscate = f_obfuscate,
72 :
m_chain{std::move(chain)}, m_name{std::move(
name)} {}
90 return &
m_chain->context()->chainman->GetChainstateForIndexing());
96 if (!
GetDB().ReadBestBlock(locator)) {
109 if (!locator_index) {
134 return chain.Genesis();
137 const CBlockIndex* pindex = chain.Next(pindex_prev);
142 return chain.Next(chain.FindFork(pindex_prev));
149 std::chrono::steady_clock::time_point last_log_time{0s};
150 std::chrono::steady_clock::time_point last_locator_write_time{0s};
174 FatalErrorf(
"%s: Failed to rewind index %s to a previous chain tip",
178 pindex = pindex_next;
181 auto current_time{std::chrono::steady_clock::now()};
183 LogPrintf(
"Syncing %s with block chain from height %d\n",
185 last_log_time = current_time;
190 last_locator_write_time = current_time;
198 FatalErrorf(
"%s: Failed to read block %s from disk",
202 block_info.
data = █
205 FatalErrorf(
"%s: Failed to write block %s to index database",
233 return error(
"%s: Failed to commit latest %s state", __func__,
GetName());
280 if (!best_block_index) {
282 FatalErrorf(
"%s: First block connected is not the genesis block (height=%d)",
293 LogPrintf(
"%s: WARNING: Block %s does not connect to an ancestor of " 294 "known best chain (tip=%s); not updating index\n",
299 if (best_block_index != pindex->
pprev && !
Rewind(best_block_index, pindex->
pprev)) {
300 FatalErrorf(
"%s: Failed to rewind index %s to a previous chain tip",
313 FatalErrorf(
"%s: Failed to write block %s to index",
331 const uint256& locator_tip_hash = locator.
vHave.front();
338 if (!locator_tip_index) {
339 FatalErrorf(
"%s: First block (hash=%s) in locator was not found",
340 __func__, locator_tip_hash.
ToString());
351 LogPrintf(
"%s: WARNING: Locator contains block (hash=%s) not on known best " 352 "chain (tip=%s); not writing index locator\n",
353 __func__, locator_tip_hash.
ToString(),
364 bool BaseIndex::BlockUntilSyncedToCurrentChain()
const 383 LogPrintf(
"%s: %s is catching up on block notifications\n", __func__,
GetName());
395 if (!
m_init)
throw std::logic_error(
"Error: Cannot start a non-initialized index");
416 summary.best_block_height = pindex->nHeight;
417 summary.best_block_hash = pindex->GetBlockHash();
419 summary.best_block_height = 0;
420 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.
void SyncWithValidationInterfaceQueue()
This is a synonym for the following, which asserts certain locks are not held: std::promise<void> pro...
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.
bool ReadBlockFromDisk(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.
void FatalErrorf(const char *fmt, const Args &... args)
virtual ~BaseIndex()
Destructor interrupts sync thread if running and blocks until it exits.
void AbortNode(std::atomic< int > &exit_status, const std::string &debug_message, const bilingual_str &user_message, bool shutdown)
void WriteBestBlock(CDBBatch &batch, const CBlockLocator &locator)
Write block locator of the chain that the index is in sync with.
virtual bool CustomInit(const std::optional< interfaces::BlockKey > &block)
Initialize internal state from the database and block index.
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.
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)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
bool StartBackgroundSync()
Starts the initial sync process.
void UnregisterValidationInterface(CValidationInterface *callbacks)
Unregister subscriber.
virtual bool CustomRewind(const interfaces::BlockKey ¤t_tip, const interfaces::BlockKey &new_tip)
Rewind index to an earlier chain tip during a chain reorg.
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)
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
bool error(const char *fmt, const Args &... args)
The block chain is a tree shaped structure starting with the genesis block at the root...
Hash/height pair to help track and identify blocks.
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)
void RegisterValidationInterface(CValidationInterface *callbacks)
Register subscriber.
void ThreadSync()
Sync the index with the block index starting from the current best block.
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.
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.