aboutsummaryrefslogtreecommitdiff
path: root/src/validation.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/validation.h')
-rw-r--r--src/validation.h150
1 files changed, 94 insertions, 56 deletions
diff --git a/src/validation.h b/src/validation.h
index af8ceb5dfa..d7ad86a5e8 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -466,17 +466,6 @@ class Chainstate
{
protected:
/**
- * Every received block is assigned a unique and increasing identifier, so we
- * know which one to give priority in case of a fork.
- */
- /** Blocks loaded from disk are assigned id 0, so start the counter at 1. */
- int32_t nBlockSequenceId GUARDED_BY(::cs_main) = 1;
- /** Decreasing counter (used by subsequent preciousblock calls). */
- int32_t nBlockReverseSequenceId = -1;
- /** chainwork for the last block that preciousblock has been applied to. */
- arith_uint256 nLastPreciousChainwork = 0;
-
- /**
* The ChainState Mutex
* A lock that must be held when modifying this ChainState - held in ActivateBestChain() and
* InvalidateBlock()
@@ -511,6 +500,9 @@ protected:
//! is set to true on the snapshot chainstate.
bool m_disabled GUARDED_BY(::cs_main) {false};
+ //! Cached result of LookupBlockIndex(*m_from_snapshot_blockhash)
+ const CBlockIndex* m_cached_snapshot_base GUARDED_BY(::cs_main) {nullptr};
+
public:
//! Reference to a BlockManager instance which itself is shared across all
//! Chainstate instances.
@@ -562,9 +554,12 @@ public:
*/
const std::optional<uint256> m_from_snapshot_blockhash;
- //! Return true if this chainstate relies on blocks that are assumed-valid. In
- //! practice this means it was created based on a UTXO snapshot.
- bool reliesOnAssumedValid() { return m_from_snapshot_blockhash.has_value(); }
+ /**
+ * The base of the snapshot this chainstate was created from.
+ *
+ * nullptr if this chainstate was not created from a snapshot.
+ */
+ const CBlockIndex* SnapshotBase() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
/**
* The set of all CBlockIndex entries with either BLOCK_VALID_TRANSACTIONS (for
@@ -620,37 +615,6 @@ public:
bool ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size)
EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
- /**
- * Import blocks from an external file
- *
- * During reindexing, this function is called for each block file (datadir/blocks/blk?????.dat).
- * It reads all blocks contained in the given file and attempts to process them (add them to the
- * block index). The blocks may be out of order within each file and across files. Often this
- * function reads a block but finds that its parent hasn't been read yet, so the block can't be
- * processed yet. The function will add an entry to the blocks_with_unknown_parent map (which is
- * passed as an argument), so that when the block's parent is later read and processed, this
- * function can re-read the child block from disk and process it.
- *
- * Because a block's parent may be in a later file, not just later in the same file, the
- * blocks_with_unknown_parent map must be passed in and out with each call. It's a multimap,
- * rather than just a map, because multiple blocks may have the same parent (when chain splits
- * or stale blocks exist). It maps from parent-hash to child-disk-position.
- *
- * This function can also be used to read blocks from user-specified block files using the
- * -loadblock= option. There's no unknown-parent tracking, so the last two arguments are omitted.
- *
- *
- * @param[in] fileIn FILE handle to file containing blocks to read
- * @param[in] dbp (optional) Disk block position (only for reindex)
- * @param[in,out] blocks_with_unknown_parent (optional) Map of disk positions for blocks with
- * unknown parent, key is parent block hash
- * (only used for reindex)
- * */
- void LoadExternalBlockFile(
- FILE* fileIn,
- FlatFilePos* dbp = nullptr,
- std::multimap<uint256, FlatFilePos>* blocks_with_unknown_parent = nullptr)
- EXCLUSIVE_LOCKS_REQUIRED(!m_chainstate_mutex);
/**
* Update the on-disk chain state.
@@ -702,8 +666,6 @@ public:
EXCLUSIVE_LOCKS_REQUIRED(!m_chainstate_mutex)
LOCKS_EXCLUDED(::cs_main);
- bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock, bool min_pow_checked) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
-
// Block (dis)connection on a given view:
DisconnectResult DisconnectBlock(const CBlock& block, const CBlockIndex* pindex, CCoinsViewCache& view)
EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
@@ -738,9 +700,11 @@ public:
/** Ensures we have a genesis block in the block tree, possibly writing one to disk. */
bool LoadGenesisBlock();
+ void TryAddBlockIndexCandidate(CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+
void PruneBlockIndexCandidates();
- void UnloadBlockIndex() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
+ void ClearBlockIndexCandidates() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
/** Check whether we are doing an initial block download (synchronizing from disk or network) */
bool IsInitialBlockDownload() const;
@@ -748,13 +712,6 @@ public:
/** Find the last common block of this chain and a locator. */
const CBlockIndex* FindForkInGlobalIndex(const CBlockLocator& locator) const EXCLUSIVE_LOCKS_REQUIRED(cs_main);
- /**
- * Make various assertions about the state of the block index.
- *
- * By default this only executes fully when using the Regtest chain; see: m_options.check_block_index.
- */
- void CheckBlockIndex();
-
/** Load the persisted mempool from disk */
void LoadMempool(const fs::path& load_path, fsbridge::FopenFn mockable_fopen_function = fsbridge::fopen);
@@ -784,7 +741,6 @@ private:
void InvalidBlockFound(CBlockIndex* pindex, const BlockValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
CBlockIndex* FindMostWorkChain() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
- void ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pindexNew, const FlatFilePos& pos) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
bool RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
@@ -971,6 +927,13 @@ public:
kernel::Notifications& GetNotifications() const { return m_options.notifications; };
/**
+ * Make various assertions about the state of the block index.
+ *
+ * By default this only executes fully when using the Regtest chain; see: m_options.check_block_index.
+ */
+ void CheckBlockIndex();
+
+ /**
* Alias for ::cs_main.
* Should be used in new code to make it easier to make ::cs_main a member
* of this class.
@@ -991,6 +954,27 @@ public:
node::BlockManager m_blockman;
/**
+ * Every received block is assigned a unique and increasing identifier, so we
+ * know which one to give priority in case of a fork.
+ */
+ /** Blocks loaded from disk are assigned id 0, so start the counter at 1. */
+ int32_t nBlockSequenceId GUARDED_BY(::cs_main) = 1;
+ /** Decreasing counter (used by subsequent preciousblock calls). */
+ int32_t nBlockReverseSequenceId = -1;
+ /** chainwork for the last block that preciousblock has been applied to. */
+ arith_uint256 nLastPreciousChainwork = 0;
+
+ // Reset the memory-only sequence counters we use to track block arrival
+ // (used by tests to reset state)
+ void ResetBlockSequenceCounters() EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
+ {
+ AssertLockHeld(::cs_main);
+ nBlockSequenceId = 1;
+ nBlockReverseSequenceId = -1;
+ }
+
+
+ /**
* In order to efficiently track invalidity of headers, we keep the set of
* blocks which we tried to connect and found to be invalid here (ie which
* were set to BLOCK_FAILED_VALID since the last restart). We can then
@@ -1086,6 +1070,37 @@ public:
}
/**
+ * Import blocks from an external file
+ *
+ * During reindexing, this function is called for each block file (datadir/blocks/blk?????.dat).
+ * It reads all blocks contained in the given file and attempts to process them (add them to the
+ * block index). The blocks may be out of order within each file and across files. Often this
+ * function reads a block but finds that its parent hasn't been read yet, so the block can't be
+ * processed yet. The function will add an entry to the blocks_with_unknown_parent map (which is
+ * passed as an argument), so that when the block's parent is later read and processed, this
+ * function can re-read the child block from disk and process it.
+ *
+ * Because a block's parent may be in a later file, not just later in the same file, the
+ * blocks_with_unknown_parent map must be passed in and out with each call. It's a multimap,
+ * rather than just a map, because multiple blocks may have the same parent (when chain splits
+ * or stale blocks exist). It maps from parent-hash to child-disk-position.
+ *
+ * This function can also be used to read blocks from user-specified block files using the
+ * -loadblock= option. There's no unknown-parent tracking, so the last two arguments are omitted.
+ *
+ *
+ * @param[in] fileIn FILE handle to file containing blocks to read
+ * @param[in] dbp (optional) Disk block position (only for reindex)
+ * @param[in,out] blocks_with_unknown_parent (optional) Map of disk positions for blocks with
+ * unknown parent, key is parent block hash
+ * (only used for reindex)
+ * */
+ void LoadExternalBlockFile(
+ FILE* fileIn,
+ FlatFilePos* dbp = nullptr,
+ std::multimap<uint256, FlatFilePos>* blocks_with_unknown_parent = nullptr);
+
+ /**
* Process an incoming block. This only returns after the best known valid
* block is made active. Note that it does not, however, guarantee that the
* specific block passed to it has been checked for validity!
@@ -1125,6 +1140,29 @@ public:
bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, bool min_pow_checked, BlockValidationState& state, const CBlockIndex** ppindex = nullptr) LOCKS_EXCLUDED(cs_main);
/**
+ * Sufficiently validate a block for disk storage (and store on disk).
+ *
+ * @param[in] pblock The block we want to process.
+ * @param[in] fRequested Whether we requested this block from a
+ * peer.
+ * @param[in] dbp The location on disk, if we are importing
+ * this block from prior storage.
+ * @param[in] min_pow_checked True if proof-of-work anti-DoS checks have
+ * been done by caller for headers chain
+ *
+ * @param[out] state The state of the block validation.
+ * @param[out] ppindex Optional return parameter to get the
+ * CBlockIndex pointer for this block.
+ * @param[out] fNewBlock Optional return parameter to indicate if the
+ * block is new to our storage.
+ *
+ * @returns False if the block or header is invalid, or if saving to disk fails (likely a fatal error); true otherwise.
+ */
+ bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock, bool min_pow_checked) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+
+ void ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pindexNew, const FlatFilePos& pos) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+
+ /**
* Try to add a transaction to the memory pool.
*
* @param[in] tx The transaction to submit for mempool acceptance.