Changeset View
Changeset View
Standalone View
Standalone View
src/validation.h
Show All 25 Lines | |||||
#include <txdb.h> | #include <txdb.h> | ||||
#include <txmempool.h> // For CTxMemPool::cs | #include <txmempool.h> // For CTxMemPool::cs | ||||
#include <versionbits.h> | #include <versionbits.h> | ||||
#include <atomic> | #include <atomic> | ||||
#include <cstdint> | #include <cstdint> | ||||
#include <map> | #include <map> | ||||
#include <memory> | #include <memory> | ||||
#include <optional> | |||||
#include <set> | #include <set> | ||||
#include <utility> | #include <utility> | ||||
#include <vector> | #include <vector> | ||||
class BlockValidationState; | class BlockValidationState; | ||||
class CBlockIndex; | class CBlockIndex; | ||||
class CBlockTreeDB; | class CBlockTreeDB; | ||||
class CBlockUndo; | class CBlockUndo; | ||||
▲ Show 20 Lines • Show All 733 Lines • ▼ Show 20 Lines | public: | ||||
//! All arguments forwarded onto CCoinsViewDB. | //! All arguments forwarded onto CCoinsViewDB. | ||||
CoinsViews(std::string ldb_name, size_t cache_size_bytes, bool in_memory, | CoinsViews(std::string ldb_name, size_t cache_size_bytes, bool in_memory, | ||||
bool should_wipe); | bool should_wipe); | ||||
//! Initialize the CCoinsViewCache member. | //! Initialize the CCoinsViewCache member. | ||||
void InitCache() EXCLUSIVE_LOCKS_REQUIRED(::cs_main); | void InitCache() EXCLUSIVE_LOCKS_REQUIRED(::cs_main); | ||||
}; | }; | ||||
// Defined below, but needed for `friend` usage in CChainState. | |||||
class ChainstateManager; | |||||
/** | /** | ||||
* CChainState stores and provides an API to update our local knowledge of the | * CChainState stores and provides an API to update our local knowledge of the | ||||
* current best chain. | * current best chain. | ||||
* | * | ||||
* Eventually, the API here is targeted at being exposed externally as a | * Eventually, the API here is targeted at being exposed externally as a | ||||
* consumable libconsensus library, so any functions added must only call | * consumable libconsensus library, so any functions added must only call | ||||
* other class member functions, pure functions in other parts of the consensus | * other class member functions, pure functions in other parts of the consensus | ||||
* library, callbacks via the validation interface, or read/write-to-disk | * library, callbacks via the validation interface, or read/write-to-disk | ||||
▲ Show 20 Lines • Show All 234 Lines • ▼ Show 20 Lines | public: | ||||
*/ | */ | ||||
void CheckBlockIndex(const Consensus::Params &consensusParams); | void CheckBlockIndex(const Consensus::Params &consensusParams); | ||||
/** Update the chain tip based on database information, i.e. CoinsTip()'s | /** Update the chain tip based on database information, i.e. CoinsTip()'s | ||||
* best block. */ | * best block. */ | ||||
bool LoadChainTip(const CChainParams &chainparams) | bool LoadChainTip(const CChainParams &chainparams) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main); | EXCLUSIVE_LOCKS_REQUIRED(cs_main); | ||||
std::string ToString() EXCLUSIVE_LOCKS_REQUIRED(::cs_main); | |||||
private: | private: | ||||
bool ActivateBestChainStep(const Config &config, | bool ActivateBestChainStep(const Config &config, | ||||
BlockValidationState &state, | BlockValidationState &state, | ||||
CBlockIndex *pindexMostWork, | CBlockIndex *pindexMostWork, | ||||
const std::shared_ptr<const CBlock> &pblock, | const std::shared_ptr<const CBlock> &pblock, | ||||
bool &fInvalidFound, ConnectTrace &connectTrace) | bool &fInvalidFound, ConnectTrace &connectTrace) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main, ::g_mempool.cs); | EXCLUSIVE_LOCKS_REQUIRED(cs_main, ::g_mempool.cs); | ||||
bool ConnectTip(const Config &config, BlockValidationState &state, | bool ConnectTip(const Config &config, BlockValidationState &state, | ||||
Show All 16 Lines | void ReceivedBlockTransactions(const CBlock &block, CBlockIndex *pindexNew, | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main); | EXCLUSIVE_LOCKS_REQUIRED(cs_main); | ||||
bool RollforwardBlock(const CBlockIndex *pindex, CCoinsViewCache &inputs, | bool RollforwardBlock(const CBlockIndex *pindex, CCoinsViewCache &inputs, | ||||
const Consensus::Params ¶ms) | const Consensus::Params ¶ms) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main); | EXCLUSIVE_LOCKS_REQUIRED(cs_main); | ||||
bool UnwindBlock(const Config &config, BlockValidationState &state, | bool UnwindBlock(const Config &config, BlockValidationState &state, | ||||
CBlockIndex *pindex, bool invalidate) | CBlockIndex *pindex, bool invalidate) | ||||
EXCLUSIVE_LOCKS_REQUIRED(m_cs_chainstate); | EXCLUSIVE_LOCKS_REQUIRED(m_cs_chainstate); | ||||
friend ChainstateManager; | |||||
}; | }; | ||||
/** | /** | ||||
* Mark a block as precious and reorganize. | * Mark a block as precious and reorganize. | ||||
* | * | ||||
* May not be called in a validationinterface callback. | * May not be called in a validationinterface callback. | ||||
*/ | */ | ||||
bool PreciousBlock(const Config &config, BlockValidationState &state, | bool PreciousBlock(const Config &config, BlockValidationState &state, | ||||
CBlockIndex *pindex) LOCKS_EXCLUDED(cs_main); | CBlockIndex *pindex) LOCKS_EXCLUDED(cs_main); | ||||
/** Remove invalidity status from a block and its descendants. */ | /** Remove invalidity status from a block and its descendants. */ | ||||
void ResetBlockFailureFlags(CBlockIndex *pindex) | void ResetBlockFailureFlags(CBlockIndex *pindex) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main); | EXCLUSIVE_LOCKS_REQUIRED(cs_main); | ||||
/** Remove parked status from a block and its descendants. */ | /** Remove parked status from a block and its descendants. */ | ||||
void UnparkBlockAndChildren(CBlockIndex *pindex) | void UnparkBlockAndChildren(CBlockIndex *pindex) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main); | EXCLUSIVE_LOCKS_REQUIRED(cs_main); | ||||
/** Remove parked status from a block. */ | /** Remove parked status from a block. */ | ||||
void UnparkBlock(CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main); | void UnparkBlock(CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main); | ||||
/** | |||||
* Provides an interface for creating and interacting with one or two | |||||
* chainstates: an IBD chainstate generated by downloading blocks, and | |||||
* an optional snapshot chainstate loaded from a UTXO snapshot. Managed | |||||
* chainstates can be maintained at different heights simultaneously. | |||||
* | |||||
* This class provides abstractions that allow the retrieval of the current | |||||
* most-work chainstate ("Active") as well as chainstates which may be in | |||||
* background use to validate UTXO snapshots. | |||||
* | |||||
* Definitions: | |||||
* | |||||
* *IBD chainstate*: a chainstate whose current state has been "fully" | |||||
* validated by the initial block download process. | |||||
* | |||||
* *Snapshot chainstate*: a chainstate populated by loading in an | |||||
* assumeutxo UTXO snapshot. | |||||
* | |||||
* *Active chainstate*: the chainstate containing the current most-work | |||||
* chain. Consulted by most parts of the system (net_processing, | |||||
* wallet) as a reflection of the current chain and UTXO set. | |||||
* This may either be an IBD chainstate or a snapshot chainstate. | |||||
* | |||||
* *Background IBD chainstate*: an IBD chainstate for which the | |||||
* IBD process is happening in the background while use of the | |||||
* active (snapshot) chainstate allows the rest of the system to function. | |||||
* | |||||
* *Validated chainstate*: the most-work chainstate which has been validated | |||||
* locally via initial block download. This will be the snapshot chainstate | |||||
* if a snapshot was loaded and all blocks up to the snapshot starting point | |||||
* have been downloaded and validated (via background validation), otherwise | |||||
* it will be the IBD chainstate. | |||||
*/ | |||||
class ChainstateManager { | |||||
private: | |||||
//! The chainstate used under normal operation (i.e. "regular" IBD) or, if | |||||
//! a snapshot is in use, for background validation. | |||||
//! | |||||
//! Its contents (including on-disk data) will be deleted *upon shutdown* | |||||
//! after background validation of the snapshot has completed. We do not | |||||
//! free the chainstate contents immediately after it finishes validation | |||||
//! to cautiously avoid a case where some other part of the system is still | |||||
//! using this pointer (e.g. net_processing). | |||||
std::unique_ptr<CChainState> m_ibd_chainstate; | |||||
//! A chainstate initialized on the basis of a UTXO snapshot. If this is | |||||
//! non-null, it is always our active chainstate. | |||||
std::unique_ptr<CChainState> m_snapshot_chainstate; | |||||
//! Points to either the ibd or snapshot chainstate; indicates our | |||||
//! most-work chain. | |||||
CChainState *m_active_chainstate{nullptr}; | |||||
//! If true, the assumed-valid chainstate has been fully validated | |||||
//! by the background validation chainstate. | |||||
bool m_snapshot_validated{false}; | |||||
// For access to m_active_chainstate. | |||||
friend CChain &ChainActive(); | |||||
public: | |||||
//! Instantiate a new chainstate and assign it based upon whether it is | |||||
//! from a snapshot. | |||||
//! | |||||
//! @param[in] snapshot_blockhash If given, signify that this chainstate | |||||
//! is based on a snapshot. | |||||
CChainState & | |||||
InitializeChainstate(const BlockHash &snapshot_blockhash = BlockHash()) | |||||
EXCLUSIVE_LOCKS_REQUIRED(::cs_main); | |||||
//! Get all chainstates currently being used. | |||||
std::vector<CChainState *> GetAll(); | |||||
//! The most-work chain. | |||||
CChain &ActiveChain() const; | |||||
int ActiveHeight() const { return ActiveChain().Height(); } | |||||
CBlockIndex *ActiveTip() const { return ActiveChain().Tip(); } | |||||
bool IsSnapshotActive() const; | |||||
std::optional<BlockHash> SnapshotBlockhash() const; | |||||
//! Is there a snapshot in use and has it been fully validated? | |||||
bool IsSnapshotValidated() const { return m_snapshot_validated; } | |||||
//! @returns true if this chainstate is being used to validate an active | |||||
//! snapshot in the background. | |||||
bool IsBackgroundIBD(CChainState *chainstate) const; | |||||
//! Return the most-work chainstate that has been fully validated. | |||||
//! | |||||
//! During background validation of a snapshot, this is the IBD chain. After | |||||
//! background validation has completed, this is the snapshot chain. | |||||
CChainState &ValidatedChainstate() const; | |||||
CChain &ValidatedChain() const { return ValidatedChainstate().m_chain; } | |||||
CBlockIndex *ValidatedTip() const { return ValidatedChain().Tip(); } | |||||
//! Unload block index and chain data before shutdown. | |||||
void Unload() EXCLUSIVE_LOCKS_REQUIRED(::cs_main); | |||||
//! Clear (deconstruct) chainstate data. | |||||
void Reset(); | |||||
}; | |||||
/** @returns the most-work valid chainstate. */ | /** @returns the most-work valid chainstate. */ | ||||
CChainState &ChainstateActive(); | CChainState &ChainstateActive(); | ||||
/** @returns the most-work chain. */ | /** @returns the most-work chain. */ | ||||
CChain &ChainActive(); | CChain &ChainActive(); | ||||
/** @returns the global block index map. */ | /** @returns the global block index map. */ | ||||
BlockMap &BlockIndex(); | BlockMap &BlockIndex(); | ||||
Show All 38 Lines |