aboutsummaryrefslogtreecommitdiff
path: root/src/validation.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/validation.h')
-rw-r--r--src/validation.h140
1 files changed, 79 insertions, 61 deletions
diff --git a/src/validation.h b/src/validation.h
index 9c718b3d63..9a2be3ad97 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -24,7 +24,6 @@
#include <sync.h>
#include <txmempool.h> // For CTxMemPool::cs
#include <txdb.h>
-#include <versionbits.h>
#include <serialize.h>
#include <util/check.h>
#include <util/hasher.h>
@@ -234,11 +233,13 @@ MempoolAcceptResult AcceptToMemoryPool(CChainState& active_chainstate, CTxMemPoo
bool bypass_limits, bool test_accept=false) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/**
-* Atomically test acceptance of a package. If the package only contains one tx, package rules still apply.
+* Atomically test acceptance of a package. If the package only contains one tx, package rules still
+* apply. Package validation does not allow BIP125 replacements, so the transaction(s) cannot spend
+* the same inputs as any transaction in the mempool.
* @param[in] txns Group of transactions which may be independent or contain
-* parent-child dependencies. The transactions must not conflict, i.e.
-* must not spend the same inputs, even if it would be a valid BIP125
-* replace-by-fee. Parents must appear before children.
+* parent-child dependencies. The transactions must not conflict
+* with each other, i.e., must not spend the same inputs. If any
+* dependencies exist, parents must appear before children.
* @returns a PackageMempoolAcceptResult which includes a MempoolAcceptResult for each transaction.
* If a transaction fails, validation will exit early and some results may be missing.
*/
@@ -269,9 +270,13 @@ bool TestLockPointValidity(CChain& active_chain, const LockPoints* lp) EXCLUSIVE
* Check if transaction will be BIP68 final in the next block to be created on top of tip.
* @param[in] tip Chain tip to check tx sequence locks against. For example,
* the tip of the current active chain.
- * @param[in] coins_view Any CCoinsView that provides access to the relevant coins
- * for checking sequence locks. Any CCoinsView can be passed in;
- * it is assumed to be consistent with the tip.
+ * @param[in] coins_view Any CCoinsView that provides access to the relevant coins for
+ * checking sequence locks. For example, it can be a CCoinsViewCache
+ * that isn't connected to anything but contains all the relevant
+ * coins, or a CCoinsViewMemPool that is connected to the
+ * mempool and chainstate UTXO set. In the latter case, the caller is
+ * responsible for holding the appropriate locks to ensure that
+ * calls to GetCoin() return correct coins.
* Simulates calling SequenceLocks() with data from the tip passed in.
* Optionally stores in LockPoints the resulting height and time calculated and the hash
* of the block needed for calculation or skips the calculation and uses the LockPoints
@@ -339,10 +344,6 @@ bool TestBlockValidity(BlockValidationState& state,
bool fCheckPOW = true,
bool fCheckMerkleRoot = true) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
-/** Check whether witness commitments are required for a block, and whether to enforce NULLDUMMY (BIP 147) rules.
- * Note that transaction witness validation rules are always enforced when P2SH is enforced. */
-bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params);
-
/** Update uncommitted block structures (currently: only the witness reserved value). This is safe for submitted blocks. */
void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams);
@@ -555,7 +556,7 @@ enum class CoinsCacheSizeState
*
* Anything that is contingent on the current tip of the chain is stored here,
* whereas block information and metadata independent of the current tip is
- * kept in `BlockMetadataManager`.
+ * kept in `BlockManager`.
*/
class CChainState
{
@@ -586,8 +587,11 @@ protected:
*/
mutable std::atomic<bool> m_cached_finished_ibd{false};
- //! mempool that is kept in sync with the chain
- CTxMemPool& m_mempool;
+ //! Optional mempool that is kept in sync with the chain.
+ //! Only the active chainstate has a mempool.
+ CTxMemPool* m_mempool;
+
+ const CChainParams& m_params;
//! Manages the UTXO set, which is a reflection of the contents of `m_chain`.
std::unique_ptr<CoinsViews> m_coins_views;
@@ -597,7 +601,10 @@ public:
//! CChainState instances.
BlockManager& m_blockman;
- explicit CChainState(CTxMemPool& mempool, BlockManager& blockman, std::optional<uint256> from_snapshot_blockhash = std::nullopt);
+ explicit CChainState(
+ CTxMemPool* mempool,
+ BlockManager& blockman,
+ std::optional<uint256> from_snapshot_blockhash = std::nullopt);
/**
* Initialize the CoinsViews UTXO set database management data structures. The in-memory
@@ -674,7 +681,7 @@ public:
EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
/** Import blocks from an external file */
- void LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, FlatFilePos* dbp = nullptr);
+ void LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp = nullptr);
/**
* Update the on-disk chain state.
@@ -688,8 +695,7 @@ public:
* @returns true unless a system error occurred
*/
bool FlushStateToDisk(
- const CChainParams& chainparams,
- BlockValidationState &state,
+ BlockValidationState& state,
FlushStateMode mode,
int nManualPruneHeight = 0);
@@ -717,37 +723,36 @@ public:
*/
bool ActivateBestChain(
BlockValidationState& state,
- const CChainParams& chainparams,
std::shared_ptr<const CBlock> pblock = nullptr) LOCKS_EXCLUDED(cs_main);
- bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
// Block (dis)connection on a given view:
DisconnectResult DisconnectBlock(const CBlock& block, const CBlockIndex* pindex, CCoinsViewCache& view);
bool ConnectBlock(const CBlock& block, BlockValidationState& state, CBlockIndex* pindex,
- CCoinsViewCache& view, const CChainParams& chainparams, bool fJustCheck = false) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ CCoinsViewCache& view, bool fJustCheck = false) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
// Apply the effects of a block disconnection on the UTXO set.
- bool DisconnectTip(BlockValidationState& state, const CChainParams& chainparams, DisconnectedBlockTransactions* disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_mempool.cs);
+ bool DisconnectTip(BlockValidationState& state, DisconnectedBlockTransactions* disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_mempool->cs);
// Manual block validity manipulation:
/** Mark a block as precious and reorganize.
*
* May not be called in a validationinterface callback.
*/
- bool PreciousBlock(BlockValidationState& state, const CChainParams& params, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main);
+ bool PreciousBlock(BlockValidationState& state, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main);
/** Mark a block as invalid. */
- bool InvalidateBlock(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main);
+ bool InvalidateBlock(BlockValidationState& state, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main);
/** Remove invalidity status from a block and its descendants. */
void ResetBlockFailureFlags(CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/** Replay blocks that aren't fully applied to the database. */
- bool ReplayBlocks(const CChainParams& params);
+ bool ReplayBlocks();
/** Whether the chain state needs to be redownloaded due to lack of witness data */
- [[nodiscard]] bool NeedsRedownload(const CChainParams& params) const EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ [[nodiscard]] bool NeedsRedownload() const EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/** Ensures we have a genesis block in the block tree, possibly writing one to disk. */
- bool LoadGenesisBlock(const CChainParams& chainparams);
+ bool LoadGenesisBlock();
void PruneBlockIndexCandidates();
@@ -761,41 +766,66 @@ public:
*
* By default this only executes fully when using the Regtest chain; see: fCheckBlockIndex.
*/
- void CheckBlockIndex(const Consensus::Params& consensusParams);
+ void CheckBlockIndex();
/** Load the persisted mempool from disk */
void LoadMempool(const ArgsManager& args);
/** Update the chain tip based on database information, i.e. CoinsTip()'s best block. */
- bool LoadChainTip(const CChainParams& chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ bool LoadChainTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
//! Dictates whether we need to flush the cache to disk or not.
//!
//! @return the state of the size of the coins cache.
- CoinsCacheSizeState GetCoinsCacheSizeState(const CTxMemPool* tx_pool)
- EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
+ CoinsCacheSizeState GetCoinsCacheSizeState() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
CoinsCacheSizeState GetCoinsCacheSizeState(
- const CTxMemPool* tx_pool,
size_t max_coins_cache_size_bytes,
size_t max_mempool_size_bytes) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
std::string ToString() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
private:
- bool ActivateBestChainStep(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_mempool.cs);
- bool ConnectTip(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions& disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_mempool.cs);
+ bool ActivateBestChainStep(BlockValidationState& state, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_mempool->cs);
+ bool ConnectTip(BlockValidationState& state, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions& disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_mempool->cs);
- void InvalidBlockFound(CBlockIndex *pindex, const BlockValidationState &state) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ 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, const Consensus::Params& consensusParams) 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, const CChainParams& params) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ bool RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
void CheckForkWarningConditions() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
void InvalidChainFound(CBlockIndex* pindexNew) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
- bool LoadBlockIndexDB(const CChainParams& chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ bool LoadBlockIndexDB() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+
+ //! Indirection necessary to make lock annotations work with an optional mempool.
+ RecursiveMutex* MempoolMutex() const LOCK_RETURNED(m_mempool->cs)
+ {
+ return m_mempool ? &m_mempool->cs : nullptr;
+ }
+
+ /**
+ * Make mempool consistent after a reorg, by re-adding or recursively erasing
+ * disconnected block transactions from the mempool, and also removing any
+ * other transactions from the mempool that are no longer valid given the new
+ * tip/height.
+ *
+ * Note: we assume that disconnectpool only contains transactions that are NOT
+ * confirmed in the current chain nor already in the mempool (otherwise,
+ * in-mempool descendants of such transactions would be removed).
+ *
+ * Passing fAddToMempool=false will skip trying to add the transactions back,
+ * and instead just erase from the mempool as needed.
+ */
+ void MaybeUpdateMempoolForReorg(
+ DisconnectedBlockTransactions& disconnectpool,
+ bool fAddToMempool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_mempool->cs);
+
+ /** Check warning conditions and do some notifications on new chain tip set. */
+ void UpdateTip(const CBlockIndex* pindexNew)
+ EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
friend ChainstateManager;
};
@@ -885,10 +915,6 @@ private:
CAutoFile& coins_file,
const SnapshotMetadata& metadata);
- // For access to m_active_chainstate.
- friend CChainState& ChainstateActive();
- friend CChain& ChainActive();
-
public:
std::thread m_load_block;
//! A single BlockManager instance is shared across each constructed
@@ -910,7 +936,9 @@ public:
// constructor
//! @param[in] snapshot_blockhash If given, signify that this chainstate
//! is based on a snapshot.
- CChainState& InitializeChainstate(CTxMemPool& mempool, const std::optional<uint256>& snapshot_blockhash = std::nullopt)
+ CChainState& InitializeChainstate(
+ CTxMemPool* mempool,
+ const std::optional<uint256>& snapshot_blockhash = std::nullopt)
EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
//! Get all chainstates currently being used.
@@ -1000,7 +1028,7 @@ public:
bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, BlockValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex = nullptr) LOCKS_EXCLUDED(cs_main);
//! Load the block tree and coins database from disk, initializing state if we're running with -reindex
- bool LoadBlockIndex(const CChainParams& chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ bool LoadBlockIndex() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
//! Unload block index and chain data before shutdown.
void Unload() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
@@ -1011,27 +1039,17 @@ public:
//! Check to see if caches are out of balance and if so, call
//! ResizeCoinsCaches() as needed.
void MaybeRebalanceCaches() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
-};
-
-/** DEPRECATED! Please use node.chainman instead. May only be used in validation.cpp internally */
-extern ChainstateManager g_chainman GUARDED_BY(::cs_main);
-
-/** Please prefer the identical ChainstateManager::ActiveChainstate */
-CChainState& ChainstateActive();
-/** Please prefer the identical ChainstateManager::ActiveChain */
-CChain& ChainActive();
+ ~ChainstateManager() {
+ LOCK(::cs_main);
+ UnloadBlockIndex(/* mempool */ nullptr, *this);
+ Reset();
+ }
+};
/** Global variable that points to the active block tree (protected by cs_main) */
extern std::unique_ptr<CBlockTreeDB> pblocktree;
-extern VersionBitsCache versionbitscache;
-
-/**
- * Determine what nVersion a new block should use.
- */
-int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params);
-
using FopenFn = std::function<FILE*(const fs::path&, const char*)>;
/** Dump the mempool to disk. */