[#ChainstateManager]
= ChainstateManager
:mrdocs:

Interface for managing multiple Chainstate objects, where each chainstate is associated with chainstate&ast; subdirectory in the data directory and contains a database of UTXOs existing at a different point in history&period; (See the Chainstate class for more information&period;)

== Synopsis

Declared in `&lt;validation&period;h&gt;`

[source,cpp,subs="verbatim,replacements,macros,-callouts"]
----
class ChainstateManager;
----

== Description

Normally there is exactly one Chainstate, which contains the UTXO set of chain tip if syncing is completed, or the UTXO set the most recent validated block if the initial sync is still in progress&period;

However, if an assumeutxo snapshot is loaded before syncing is completed, there will be two chainstates&period; The original fully validated chainstate will continue to exist and download new blocks in the background&period; But the new snapshot which is loaded will become a second chainstate&period; The second chainstate will be used as the chain tip for the wallet and RPCs even though it is only assumed to be valid&period; When the initial chainstate catches up to the snapshot height and confirms that the assumeutxo snapshot is actually valid, the second chainstate will be marked validated and become the only chainstate again&period;

== Type Aliases

[cols="1,4"]
|===
| Name| Description
| xref:ChainstateManager/Options.adoc[`Options`] 
| Options controlling the behavior of the chainstate manager&period;
|===


== Member Functions

[cols="1,4"]
|===
| Name| Description
| xref:ChainstateManager/2constructor.adoc[`ChainstateManager`]         [.small]#[constructor]#
| Construct a chainstate manager&period;
| xref:ChainstateManager/2destructor.adoc[`&#126;ChainstateManager`] [.small]#[destructor]#
| Destroy the chainstate manager and its chainstates&period;
| xref:ChainstateManager/AcceptBlock.adoc[`AcceptBlock`] 
| Sufficiently validate a block for disk storage (and store on disk)&period;
| xref:ChainstateManager/ActivateBestChains.adoc[`ActivateBestChains`] 
| Call ActivateBestChain() on every chainstate&period;
| xref:ChainstateManager/ActivateSnapshot.adoc[`ActivateSnapshot`] 
| Construct and activate a Chainstate on the basis of UTXO snapshot data&period;
| xref:ChainstateManager/ActiveChain.adoc[`ActiveChain`] 
| Return the active chain of block headers&period;
| xref:ChainstateManager/ActiveChainstate.adoc[`ActiveChainstate`] 
| Alternatives to CurrentChainstate() used by older code to query latest chainstate information without locking cs&lowbar;main&period; Newer code should avoid querying ChainstateManager and use Chainstate objects directly, or should use CurrentChainstate() instead&period; @&lcub; Return the active chainstate&period;
| xref:ChainstateManager/ActiveHeight.adoc[`ActiveHeight`] 
| Return the height of the active chain tip&period;
| xref:ChainstateManager/ActiveTip.adoc[`ActiveTip`] 
| Return the active chain tip&period;
| xref:ChainstateManager/AddChainstate.adoc[`AddChainstate`] 
| Add new chainstate&period;
| xref:ChainstateManager/AssumedValidBlock.adoc[`AssumedValidBlock`] 
| Access the assumed&hyphen;valid block below which script checks may be skipped&period;
| xref:ChainstateManager/BlockIndex.adoc[`BlockIndex`] 
| Access the map of all known block index entries&period;
| xref:ChainstateManager/BlocksAheadOfTip.adoc[`BlocksAheadOfTip`] 
| Returns how many blocks the best header is ahead of the current tip, or nullopt if the best header does not extend the tip&period;
| xref:ChainstateManager/CheckBlockIndex.adoc[`CheckBlockIndex`] 
| Make various assertions about the state of the block index&period;
| xref:ChainstateManager/CurrentChainstate.adoc[`CurrentChainstate`] 
| Return current chainstate targeting the most&hyphen;work, network tip&period;
| xref:ChainstateManager/DeleteChainstate.adoc[`DeleteChainstate`] 
| Remove the chainstate and all on&hyphen;disk artifacts&period; Used when reindex&lcub;&hyphen;chainstate&rcub; is called during snapshot use&period;
| xref:ChainstateManager/GenerateCoinbaseCommitment.adoc[`GenerateCoinbaseCommitment`] 
| Produce the necessary coinbase commitment for a block (modifies the hash, don&apos;t call for mined blocks)&period;
| xref:ChainstateManager/GetBackgroundVerificationProgress.adoc[`GetBackgroundVerificationProgress`] 
| Guess background verification progress in case assume&hyphen;utxo was used (as a fraction between 0&period;0&equals;genesis and 1&period;0&equals;snapshot blocks)&period;
| xref:ChainstateManager/GetCheckQueue.adoc[`GetCheckQueue`] 
| Access the queue of pending script verifications&period;
| xref:ChainstateManager/GetConsensus.adoc[`GetConsensus`] 
| Access the consensus parameters in use&period;
| xref:ChainstateManager/GetHistoricalBlockRange.adoc[`GetHistoricalBlockRange`] 
| Get range of historical blocks to download&period;
| xref:ChainstateManager/GetMutex.adoc[`GetMutex`] 
| Alias for &colon;&colon;cs&lowbar;main&period; Should be used in new code to make it easier to make &colon;&colon;cs&lowbar;main a member of this class&period; Generally, methods of this class should be annotated to require this mutex&period; This will make calling code more verbose, but also help to&colon; &hyphen; Clarify that the method will acquire a mutex that heavily affects overall performance&period; &hyphen; Force call sites to think how long they need to acquire the mutex to get consistent results&period;
| xref:ChainstateManager/GetNotifications.adoc[`GetNotifications`] 
| Access the notifications sink used to surface validation events&period;
| xref:ChainstateManager/GetParams.adoc[`GetParams`] 
| Access the chain parameters in use&period;
| xref:ChainstateManager/GuessVerificationProgress.adoc[`GuessVerificationProgress`] 
| Guess verification progress (as a fraction between 0&period;0&equals;genesis and 1&period;0&equals;current tip)&period; This is also the case in the assumeutxo context, meaning that the progress reported for the snapshot chainstate may suggest that all historical blocks have already been verified even though that may not actually be the case&period;
| xref:ChainstateManager/HistoricalChainstate.adoc[`HistoricalChainstate`] 
| Return historical chainstate targeting a specific block, if any&period;
| xref:ChainstateManager/InitializeChainstate.adoc[`InitializeChainstate`] 
| Instantiate a new chainstate&period;
| xref:ChainstateManager/IsInitialBlockDownload.adoc[`IsInitialBlockDownload`] 
| Check whether we are doing an initial block download (synchronizing from disk or network)&period;
| xref:ChainstateManager/LoadAssumeutxoChainstate.adoc[`LoadAssumeutxoChainstate`] 
| When starting up, search the datadir for a chainstate based on a UTXO snapshot that is in the process of being validated and load it if found&period; Return pointer to the Chainstate if it is loaded&period;
| xref:ChainstateManager/LoadBlockIndex.adoc[`LoadBlockIndex`] 
| Load the block tree and coins database from disk, initializing state if we&apos;re running with &hyphen;reindex
| xref:ChainstateManager/LoadExternalBlockFile.adoc[`LoadExternalBlockFile`] 
| Import blocks from an external file
| xref:ChainstateManager/LoadGenesisBlock.adoc[`LoadGenesisBlock`] 
| Ensures a genesis block is in the block tree, possibly writing one to disk&period;
| xref:ChainstateManager/MaybeRebalanceCaches.adoc[`MaybeRebalanceCaches`] 
| Check to see if caches are out of balance and if so, call ResizeCoinsCaches() as needed&period;
| xref:ChainstateManager/MaybeValidateSnapshot.adoc[`MaybeValidateSnapshot`] 
| Try to validate an assumeutxo snapshot by using a validated historical chainstate targeted at the snapshot block&period; When the target block is reached, the UTXO hash is computed and saved to `validated&lowbar;cs&period;m&lowbar;target&lowbar;utxohash`, and `unvalidated&lowbar;cs&period;m&lowbar;assumeutxo` will be updated from UNVALIDATED to either VALIDATED or INVALID depending on whether the hash matches&period; The INVALID case should not happen in practice because the software should refuse to load unrecognized snapshots, but if it does happen, it is a fatal error&period;
| xref:ChainstateManager/MinimumChainWork.adoc[`MinimumChainWork`] 
| Access the minimum chain work required to consider syncing complete&period;
| xref:ChainstateManager/ProcessNewBlock.adoc[`ProcessNewBlock`] 
| Process an incoming block&period; This only returns after the best known valid block is made active&period; Note that it does not, however, guarantee that the specific block passed to it has been checked for validity!
| xref:ChainstateManager/ProcessNewBlockHeaders.adoc[`ProcessNewBlockHeaders`] 
| Process incoming block headers&period;
| xref:ChainstateManager/ProcessTransaction.adoc[`ProcessTransaction`] 
| Try to add a transaction to the memory pool&period;
| xref:ChainstateManager/RecalculateBestHeader.adoc[`RecalculateBestHeader`] 
| If, due to invalidation &sol; reconsideration of blocks, the previous best header is no longer valid &sol; guaranteed to be the most&hyphen;work header in our block&hyphen;index not known to be invalid, recalculate it&period;
| xref:ChainstateManager/ReceivedBlockTransactions.adoc[`ReceivedBlockTransactions`] 
| Mark that the transaction data for a block has been received and stored&period;
| xref:ChainstateManager/RemoveChainstate.adoc[`RemoveChainstate`] 
| Remove a chainstate&period;
| xref:ChainstateManager/ReportHeadersPresync.adoc[`ReportHeadersPresync`] 
| This is used by net&lowbar;processing to report pre&hyphen;synchronization progress of headers, as headers are not yet fed to validation during that time, but validation is (for now) responsible for logging and signalling through NotifyHeaderTip, so it needs this information&period;
| xref:ChainstateManager/ResetBlockSequenceCounters.adoc[`ResetBlockSequenceCounters`] 
| Reset the memory&hyphen;only sequence counters used to track block arrival (used by tests)&period;
| xref:ChainstateManager/ResetChainstates.adoc[`ResetChainstates`] 
| Destroy all chainstates managed by this instance&period;
| xref:ChainstateManager/ShouldCheckBlockIndex.adoc[`ShouldCheckBlockIndex`] 
| Whether expensive block&hyphen;index consistency checks should run&period;
| xref:ChainstateManager/UpdateIBDStatus.adoc[`UpdateIBDStatus`] 
| Update and possibly latch the IBD status&period;
| xref:ChainstateManager/UpdateUncommittedBlockStructures.adoc[`UpdateUncommittedBlockStructures`] 
| Update uncommitted block structures (currently&colon; only the witness reserved value)&period; This is safe for submitted blocks as long as they honor default&lowbar;witness&lowbar;commitment from the template&period;
| xref:ChainstateManager/ValidatedChainstate.adoc[`ValidatedChainstate`] 
| Return fully validated chainstate that should be used for indexing, to support indexes that need to index blocks in order and can&apos;t start from the snapshot block&period;
| xref:ChainstateManager/ValidatedSnapshotCleanup.adoc[`ValidatedSnapshotCleanup`] 
| If we have validated a snapshot chain during this runtime, copy its chainstate directory over to the main `chainstate` location, completing validation of the snapshot&period;
|===


== Data Members

[cols="1,4"]
|===
| Name| Description
| xref:ChainstateManager/m_best_header.adoc[`m&lowbar;best&lowbar;header`] 
| Best header we&apos;ve seen so far for which the block is not known to be invalid (used, among others, for getheaders queries&apos; starting points)&period; In case of multiple best headers with the same work, it could point to any because CBlockIndexWorkComparator tiebreaker rules are not applied&period;
| xref:ChainstateManager/m_blockman.adoc[`m&lowbar;blockman`] 
| A single BlockManager instance is shared across each constructed chainstate to avoid duplicating block metadata&period;
| xref:ChainstateManager/m_cached_is_ibd.adoc[`m&lowbar;cached&lowbar;is&lowbar;ibd`] 
| Whether initial block download (IBD) is ongoing&period;
| xref:ChainstateManager/m_chainstates.adoc[`m&lowbar;chainstates`] 
| List of chainstates&period; Note&colon; in general, it is not safe to delete Chainstate objects once they are added to this list because there is no mutex that can be locked to prevent Chainstate pointers from being used while they are deleted&period; (cs&lowbar;main doesn&apos;t work because it is too narrow and is released in the middle of Chainstate&colon;&colon;ActivateBestChain to let notifications be processed&period; m&lowbar;chainstate&lowbar;mutex doesn&apos;t work because it is not locked at other times when the chainstate is in use&period;)
| xref:ChainstateManager/m_interrupt.adoc[`m&lowbar;interrupt`] 
| Signal used to observe shutdown requests during long&hyphen;running operations&period;
| xref:ChainstateManager/m_options.adoc[`m&lowbar;options`] 
| Options controlling the behavior of this chainstate manager&period;
| xref:ChainstateManager/m_total_coinsdb_cache.adoc[`m&lowbar;total&lowbar;coinsdb&lowbar;cache`] 
| The total number of bytes available for us to use across all leveldb coins databases&period; This will be split somehow across chainstates&period;
| xref:ChainstateManager/m_total_coinstip_cache.adoc[`m&lowbar;total&lowbar;coinstip&lowbar;cache`] 
| The total number of bytes available for us to use across all in&hyphen;memory coins caches&period; This will be split somehow across chainstates&period;
| xref:ChainstateManager/m_validation_cache.adoc[`m&lowbar;validation&lowbar;cache`] 
| Caches for script execution and signature verification results&period;
| xref:ChainstateManager/m_versionbitscache.adoc[`m&lowbar;versionbitscache`] 
| Track versionbit status
| xref:ChainstateManager/nBlockReverseSequenceId.adoc[`nBlockReverseSequenceId`] 
| Decreasing counter (used by subsequent preciousblock calls)&period;
| xref:ChainstateManager/nBlockSequenceId.adoc[`nBlockSequenceId`] 
| Every received block is assigned a unique and increasing identifier, so we know which one to give priority in case of a fork&period;
| xref:ChainstateManager/nLastPreciousChainwork.adoc[`nLastPreciousChainwork`] 
| chainwork for the last block that preciousblock has been applied to&period;
| xref:ChainstateManager/snapshot_download_completed.adoc[`snapshot&lowbar;download&lowbar;completed`] 
| Function to restart active indexes&semi; set dynamically to avoid a circular dependency on `base&sol;index&period;cpp`&period;
|===


== Protected Data Members

[cols="1,4"]
|===
| Name| Description
| xref:ChainstateManager/m_best_invalid.adoc[`m&lowbar;best&lowbar;invalid`] 
| Best known invalid block, tracked to detect a longer invalid chain than the valid one&period;
|===


== Friends

[cols="1,4"]
|===
| Name| Description
| `xref:Chainstate.adoc[Chainstate]`
| Chainstate stores and provides an API to update our local knowledge of the current best chain&period;
|===

== Non-Member Functions

[cols="1,4"]
|===
| Name| Description
| xref:DeploymentEnabled-04.adoc[`DeploymentEnabled`]
| Whether a deployment is enabled in the consensus rules, resolved via ChainstateManager&period;
| xref:EnsureAnyChainman.adoc[`EnsureAnyChainman`]
| Get the chainstate manager from an opaque RPC context, asserting it is present&period;
| xref:EnsureChainman.adoc[`EnsureChainman`]
| Get the chainstate manager from a node context, asserting it is present&period;
| xref:node/CooldownIfHeadersAhead.adoc[`node&colon;&colon;CooldownIfHeadersAhead`]
| Wait while the best known header extends the current chain tip AND at least one block is being added to the tip every 3 seconds&period; If the tip is sufficiently far behind, allow up to 20 seconds for the next tip update&period;
| xref:node/GetTip.adoc[`node&colon;&colon;GetTip`]
| Return the hash and height of the active chain tip&period;
| xref:node/ImportBlocks.adoc[`node&colon;&colon;ImportBlocks`]
| Load blocks from the given files and activate the best chain, even if none are imported&period;
| xref:node/LoadChainstate.adoc[`node&colon;&colon;LoadChainstate`]
| This sequence can have 4 types of outcomes&colon;
| xref:node/SubmitBlock.adoc[`node&colon;&colon;SubmitBlock`]
| Submit a block and capture the validation state via the BlockChecked callback&period; Returns whether the block was accepted as a new valid block&period;
| xref:node/VerifyLoadedChainstate.adoc[`node&colon;&colon;VerifyLoadedChainstate`]
| Verify a chainstate that has already been loaded&period;
| xref:node/WaitAndCreateNewBlock.adoc[`node&colon;&colon;WaitAndCreateNewBlock`]
| Return a new block template when fees rise to a certain threshold or after a new tip&semi; return nullopt if timeout is reached&period;
| xref:node/WaitTipChanged.adoc[`node&colon;&colon;WaitTipChanged`]
| Waits for the connected tip to change until timeout has elapsed&period; During node initialization, this will wait until the tip is connected (regardless of `timeout`)&period; Returns the current tip, or nullopt if the node is shutting down or interrupt() is called&period;
|===


[.small]#Created with https://www.mrdocs.com[MrDocs]#
