18 #include <validation.h> 31 template <
typename... Args>
37 AbortError(
_(
"A fatal internal error occurred, see debug.log for details"));
51 CDBWrapper(path, n_cache_size, f_memory, f_wipe, f_obfuscate)
69 :
m_chain{std::move(chain)}, m_name{std::move(
name)} {}
80 if (!
GetDB().ReadBestBlock(locator)) {
97 bool prune_violation =
false;
107 if (!active_chain.
Contains(block_to_test)) {
110 block_to_test = active_chain.
FindFork(block_to_test);
113 prune_violation =
true;
116 if (block_to_test == block) {
117 prune_violation =
false;
123 block = block->
pprev;
126 if (prune_violation) {
127 return InitError(
strprintf(
Untranslated(
"%s best block of the index goes beyond pruned data. Please disable the index or reindex (which will download the whole blockchain again)"),
GetName()));
138 return chain.Genesis();
141 const CBlockIndex* pindex = chain.Next(pindex_prev);
146 return chain.Next(chain.FindFork(pindex_prev));
156 std::chrono::steady_clock::time_point last_log_time{0s};
157 std::chrono::steady_clock::time_point last_locator_write_time{0s};
179 FatalError(
"%s: Failed to rewind index %s to a previous chain tip",
183 pindex = pindex_next;
186 auto current_time{std::chrono::steady_clock::now()};
188 LogPrintf(
"Syncing %s with block chain from height %d\n",
190 last_log_time = current_time;
195 last_locator_write_time = current_time;
203 FatalError(
"%s: Failed to read block %s from disk",
207 block_info.
data = █
210 FatalError(
"%s: Failed to write block %s to index database",
238 return error(
"%s: Failed to commit latest %s state", __func__,
GetName());
274 if (!best_block_index) {
276 FatalError(
"%s: First block connected is not the genesis block (height=%d)",
287 LogPrintf(
"%s: WARNING: Block %s does not connect to an ancestor of " 288 "known best chain (tip=%s); not updating index\n",
293 if (best_block_index != pindex->
pprev && !
Rewind(best_block_index, pindex->
pprev)) {
294 FatalError(
"%s: Failed to rewind index %s to a previous chain tip",
307 FatalError(
"%s: Failed to write block %s to index",
319 const uint256& locator_tip_hash = locator.
vHave.front();
326 if (!locator_tip_index) {
327 FatalError(
"%s: First block (hash=%s) in locator was not found",
328 __func__, locator_tip_hash.
ToString());
339 LogPrintf(
"%s: WARNING: Locator contains block (hash=%s) not on known best " 340 "chain (tip=%s); not writing index locator\n",
341 __func__, locator_tip_hash.
ToString(),
352 bool BaseIndex::BlockUntilSyncedToCurrentChain()
const 371 LogPrintf(
"%s: %s is catching up on block notifications\n", __func__,
GetName());
389 if (!
Init())
return false;
Helper for findBlock to selectively return pieces of block data.
bool Start()
Start initializes the sync state and registers the instance as a ValidationInterface so that it stays...
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 ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
bool Init()
Read best block locator and check that data needed to sync has not been pruned.
CThreadInterrupt m_interrupt
void ChainStateFlushed(const CBlockLocator &locator) override
Notifies listeners of the new active block chain on-disk.
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.
void SetMiscWarning(const bilingual_str &warning)
constexpr auto AbortError
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
CBlockIndex * Genesis() const
Returns the index entry for the genesis block of this chain, or nullptr if none.
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.
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.
virtual bool CustomInit(const std::optional< interfaces::BlockKey > &block)
Initialize internal state from the database and block index.
constexpr auto SYNC_LOG_INTERVAL
const CBlockIndex * FindForkInGlobalIndex(const CBlockLocator &locator) const EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Find the last common block of this chain and a locator.
void Interrupt(NodeContext &node)
Interrupt threads.
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.
bilingual_str _(const char *psz)
Translation function.
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
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 SetSyscallSandboxPolicy(SyscallSandboxPolicy syscall_policy)
Force the current thread (and threads created from the current thread) into a restricted-service oper...
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 fPruneMode
Pruning-related variables and constants.
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...
The block chain is a tree shaped structure starting with the genesis block at the root...
const CChainParams & Params()
Return the currently selected parameters.
void BlockConnected(const std::shared_ptr< const CBlock > &block, const CBlockIndex *pindex) override
Notifies listeners of a block being connected.
static void FatalError(const char *fmt, const Args &... args)
Hash/height pair to help track and identify blocks.
Chainstate * m_chainstate
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
#define AssertLockNotHeld(cs)
void StartShutdown()
Request shutdown of the application.
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)
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)
const Consensus::Params & GetConsensus() const
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.
full block available in blk*.dat
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
const CBlockIndex * FindFork(const CBlockIndex *pindex) const
Find the last common block between this chain and a block index entry.
virtual DB & GetDB() const =0
bool error(const char *fmt, const Args &... args)
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.