mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-25 10:43:19 -03:00
Merge bitcoin/bitcoin#25704: refactor: Remove almost all validation option globals
aaaa7bd0ba
iwyu: Add missing includes (MacroFake)fa9ebec096
Remove g_parallel_script_checks (MacroFake)fa7c834b9f
Move ::fCheckBlockIndex into ChainstateManager (MacroFake)fa43188d86
Move ::fCheckpointsEnabled into ChainstateManager (MacroFake)cccca83099
Move ::nMinimumChainWork into ChainstateManager (MacroFake)fa29d0b57c
Move ::hashAssumeValid into ChainstateManager (MacroFake)faf44876db
Move ::nMaxTipAge into ChainstateManager (MacroFake) Pull request description: It seems preferable to assign globals to a class (in this case `ChainstateManager`), than to leave them dangling. This should clarify scope for code-readers, as well as clarifying unit test behaviour. ACKs for top commit: dergoegge: Code review ACKaaaa7bd0ba
ryanofsky: Code review ACKaaaa7bd0ba
. No changes since last review, other than rebase aureleoules: reACKaaaa7bd0ba
Tree-SHA512: 83ec3ba0fb4f1dad95810d4bd4e578454e0718dc1bdd3a794cc4e48aa819b6f5dad4ac4edab3719bdfd5f89cbe23c2740a50fd56c1ff81c99e521c5f6d4e898d
This commit is contained in:
commit
a1fff275e7
13 changed files with 151 additions and 81 deletions
|
@ -45,6 +45,7 @@ if [ "${RUN_TIDY}" = "true" ]; then
|
||||||
" src/init"\
|
" src/init"\
|
||||||
" src/kernel"\
|
" src/kernel"\
|
||||||
" src/node/chainstate.cpp"\
|
" src/node/chainstate.cpp"\
|
||||||
|
" src/node/chainstatemanager_args.cpp"\
|
||||||
" src/node/mempool_args.cpp"\
|
" src/node/mempool_args.cpp"\
|
||||||
" src/node/validation_cache_args.cpp"\
|
" src/node/validation_cache_args.cpp"\
|
||||||
" src/policy/feerate.cpp"\
|
" src/policy/feerate.cpp"\
|
||||||
|
|
|
@ -198,6 +198,7 @@ BITCOIN_CORE_H = \
|
||||||
node/blockstorage.h \
|
node/blockstorage.h \
|
||||||
node/caches.h \
|
node/caches.h \
|
||||||
node/chainstate.h \
|
node/chainstate.h \
|
||||||
|
node/chainstatemanager_args.h \
|
||||||
node/coin.h \
|
node/coin.h \
|
||||||
node/connection_types.h \
|
node/connection_types.h \
|
||||||
node/context.h \
|
node/context.h \
|
||||||
|
@ -381,6 +382,7 @@ libbitcoin_node_a_SOURCES = \
|
||||||
node/blockstorage.cpp \
|
node/blockstorage.cpp \
|
||||||
node/caches.cpp \
|
node/caches.cpp \
|
||||||
node/chainstate.cpp \
|
node/chainstate.cpp \
|
||||||
|
node/chainstatemanager_args.cpp \
|
||||||
node/coin.cpp \
|
node/coin.cpp \
|
||||||
node/connection_types.cpp \
|
node/connection_types.cpp \
|
||||||
node/context.cpp \
|
node/context.cpp \
|
||||||
|
|
|
@ -199,11 +199,12 @@ public:
|
||||||
WITH_LOCK(m_mutex, m_request_stop = false);
|
WITH_LOCK(m_mutex, m_request_stop = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HasThreads() const { return !m_worker_threads.empty(); }
|
||||||
|
|
||||||
~CCheckQueue()
|
~CCheckQueue()
|
||||||
{
|
{
|
||||||
assert(m_worker_threads.empty());
|
assert(m_worker_threads.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
43
src/init.cpp
43
src/init.cpp
|
@ -40,6 +40,7 @@
|
||||||
#include <node/blockstorage.h>
|
#include <node/blockstorage.h>
|
||||||
#include <node/caches.h>
|
#include <node/caches.h>
|
||||||
#include <node/chainstate.h>
|
#include <node/chainstate.h>
|
||||||
|
#include <node/chainstatemanager_args.h>
|
||||||
#include <node/context.h>
|
#include <node/context.h>
|
||||||
#include <node/interface_ui.h>
|
#include <node/interface_ui.h>
|
||||||
#include <node/mempool_args.h>
|
#include <node/mempool_args.h>
|
||||||
|
@ -554,7 +555,10 @@ void SetupServerArgs(ArgsManager& argsman)
|
||||||
argsman.AddArg("-capturemessages", "Capture all P2P messages to disk", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
|
argsman.AddArg("-capturemessages", "Capture all P2P messages to disk", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
|
||||||
argsman.AddArg("-mocktime=<n>", "Replace actual time with " + UNIX_EPOCH_TIME + " (default: 0)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
|
argsman.AddArg("-mocktime=<n>", "Replace actual time with " + UNIX_EPOCH_TIME + " (default: 0)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
|
||||||
argsman.AddArg("-maxsigcachesize=<n>", strprintf("Limit sum of signature cache and script execution cache sizes to <n> MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_BYTES >> 20), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
|
argsman.AddArg("-maxsigcachesize=<n>", strprintf("Limit sum of signature cache and script execution cache sizes to <n> MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_BYTES >> 20), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
|
||||||
argsman.AddArg("-maxtipage=<n>", strprintf("Maximum tip age in seconds to consider node in initial block download (default: %u)", DEFAULT_MAX_TIP_AGE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
|
argsman.AddArg("-maxtipage=<n>",
|
||||||
|
strprintf("Maximum tip age in seconds to consider node in initial block download (default: %u)",
|
||||||
|
Ticks<std::chrono::seconds>(DEFAULT_MAX_TIP_AGE)),
|
||||||
|
ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
|
||||||
argsman.AddArg("-printpriority", strprintf("Log transaction fee rate in " + CURRENCY_UNIT + "/kvB when mining blocks (default: %u)", DEFAULT_PRINTPRIORITY), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
|
argsman.AddArg("-printpriority", strprintf("Log transaction fee rate in " + CURRENCY_UNIT + "/kvB when mining blocks (default: %u)", DEFAULT_PRINTPRIORITY), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
|
||||||
argsman.AddArg("-uacomment=<cmt>", "Append comment to the user agent string", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
|
argsman.AddArg("-uacomment=<cmt>", "Append comment to the user agent string", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
|
||||||
|
|
||||||
|
@ -930,21 +934,6 @@ bool AppInitParameterInteraction(const ArgsManager& args, bool use_syscall_sandb
|
||||||
init::SetLoggingCategories(args);
|
init::SetLoggingCategories(args);
|
||||||
init::SetLoggingLevel(args);
|
init::SetLoggingLevel(args);
|
||||||
|
|
||||||
fCheckBlockIndex = args.GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks());
|
|
||||||
fCheckpointsEnabled = args.GetBoolArg("-checkpoints", DEFAULT_CHECKPOINTS_ENABLED);
|
|
||||||
|
|
||||||
hashAssumeValid = uint256S(args.GetArg("-assumevalid", chainparams.GetConsensus().defaultAssumeValid.GetHex()));
|
|
||||||
|
|
||||||
if (args.IsArgSet("-minimumchainwork")) {
|
|
||||||
const std::string minChainWorkStr = args.GetArg("-minimumchainwork", "");
|
|
||||||
if (!IsHexNumber(minChainWorkStr)) {
|
|
||||||
return InitError(strprintf(Untranslated("Invalid non-hex (%s) minimum chain work value specified"), minChainWorkStr));
|
|
||||||
}
|
|
||||||
nMinimumChainWork = UintToArith256(uint256S(minChainWorkStr));
|
|
||||||
} else {
|
|
||||||
nMinimumChainWork = UintToArith256(chainparams.GetConsensus().nMinimumChainWork);
|
|
||||||
}
|
|
||||||
|
|
||||||
// block pruning; get the amount of disk space (in MiB) to allot for block & undo files
|
// block pruning; get the amount of disk space (in MiB) to allot for block & undo files
|
||||||
int64_t nPruneArg = args.GetIntArg("-prune", 0);
|
int64_t nPruneArg = args.GetIntArg("-prune", 0);
|
||||||
if (nPruneArg < 0) {
|
if (nPruneArg < 0) {
|
||||||
|
@ -995,8 +984,6 @@ bool AppInitParameterInteraction(const ArgsManager& args, bool use_syscall_sandb
|
||||||
if (args.GetIntArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) > 1)
|
if (args.GetIntArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) > 1)
|
||||||
return InitError(Untranslated("Unknown rpcserialversion requested."));
|
return InitError(Untranslated("Unknown rpcserialversion requested."));
|
||||||
|
|
||||||
nMaxTipAge = args.GetIntArg("-maxtipage", DEFAULT_MAX_TIP_AGE);
|
|
||||||
|
|
||||||
if (args.GetBoolArg("-reindex-chainstate", false)) {
|
if (args.GetBoolArg("-reindex-chainstate", false)) {
|
||||||
// indexes that must be deactivated to prevent index corruption, see #24630
|
// indexes that must be deactivated to prevent index corruption, see #24630
|
||||||
if (args.GetBoolArg("-coinstatsindex", DEFAULT_COINSTATSINDEX)) {
|
if (args.GetBoolArg("-coinstatsindex", DEFAULT_COINSTATSINDEX)) {
|
||||||
|
@ -1044,6 +1031,16 @@ bool AppInitParameterInteraction(const ArgsManager& args, bool use_syscall_sandb
|
||||||
}
|
}
|
||||||
#endif // USE_SYSCALL_SANDBOX
|
#endif // USE_SYSCALL_SANDBOX
|
||||||
|
|
||||||
|
// Also report errors from parsing before daemonization
|
||||||
|
{
|
||||||
|
ChainstateManager::Options chainman_opts_dummy{
|
||||||
|
.chainparams = chainparams,
|
||||||
|
};
|
||||||
|
if (const auto error{ApplyArgsManOptions(args, chainman_opts_dummy)}) {
|
||||||
|
return InitError(*error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1146,7 +1143,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||||
|
|
||||||
LogPrintf("Script verification uses %d additional threads\n", script_threads);
|
LogPrintf("Script verification uses %d additional threads\n", script_threads);
|
||||||
if (script_threads >= 1) {
|
if (script_threads >= 1) {
|
||||||
g_parallel_script_checks = true;
|
|
||||||
StartScriptCheckWorkerThreads(script_threads);
|
StartScriptCheckWorkerThreads(script_threads);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1435,6 +1431,11 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||||
|
|
||||||
fReindex = args.GetBoolArg("-reindex", false);
|
fReindex = args.GetBoolArg("-reindex", false);
|
||||||
bool fReindexChainState = args.GetBoolArg("-reindex-chainstate", false);
|
bool fReindexChainState = args.GetBoolArg("-reindex-chainstate", false);
|
||||||
|
ChainstateManager::Options chainman_opts{
|
||||||
|
.chainparams = chainparams,
|
||||||
|
.adjusted_time_callback = GetAdjustedTime,
|
||||||
|
};
|
||||||
|
Assert(!ApplyArgsManOptions(args, chainman_opts)); // no error can happen, already checked in AppInitParameterInteraction
|
||||||
|
|
||||||
// cache size calculations
|
// cache size calculations
|
||||||
CacheSizes cache_sizes = CalculateCacheSizes(args, g_enabled_filter_types.size());
|
CacheSizes cache_sizes = CalculateCacheSizes(args, g_enabled_filter_types.size());
|
||||||
|
@ -1471,10 +1472,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||||
for (bool fLoaded = false; !fLoaded && !ShutdownRequested();) {
|
for (bool fLoaded = false; !fLoaded && !ShutdownRequested();) {
|
||||||
node.mempool = std::make_unique<CTxMemPool>(mempool_opts);
|
node.mempool = std::make_unique<CTxMemPool>(mempool_opts);
|
||||||
|
|
||||||
const ChainstateManager::Options chainman_opts{
|
|
||||||
.chainparams = chainparams,
|
|
||||||
.adjusted_time_callback = GetAdjustedTime,
|
|
||||||
};
|
|
||||||
node.chainman = std::make_unique<ChainstateManager>(chainman_opts);
|
node.chainman = std::make_unique<ChainstateManager>(chainman_opts);
|
||||||
ChainstateManager& chainman = *node.chainman;
|
ChainstateManager& chainman = *node.chainman;
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,19 @@
|
||||||
#ifndef BITCOIN_KERNEL_CHAINSTATEMANAGER_OPTS_H
|
#ifndef BITCOIN_KERNEL_CHAINSTATEMANAGER_OPTS_H
|
||||||
#define BITCOIN_KERNEL_CHAINSTATEMANAGER_OPTS_H
|
#define BITCOIN_KERNEL_CHAINSTATEMANAGER_OPTS_H
|
||||||
|
|
||||||
|
#include <arith_uint256.h>
|
||||||
|
#include <uint256.h>
|
||||||
#include <util/time.h>
|
#include <util/time.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
class CChainParams;
|
class CChainParams;
|
||||||
|
|
||||||
|
static constexpr bool DEFAULT_CHECKPOINTS_ENABLED{true};
|
||||||
|
static constexpr auto DEFAULT_MAX_TIP_AGE{24h};
|
||||||
|
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,6 +28,14 @@ namespace kernel {
|
||||||
struct ChainstateManagerOpts {
|
struct ChainstateManagerOpts {
|
||||||
const CChainParams& chainparams;
|
const CChainParams& chainparams;
|
||||||
const std::function<NodeClock::time_point()> adjusted_time_callback{nullptr};
|
const std::function<NodeClock::time_point()> adjusted_time_callback{nullptr};
|
||||||
|
std::optional<bool> check_block_index{};
|
||||||
|
bool checkpoints_enabled{DEFAULT_CHECKPOINTS_ENABLED};
|
||||||
|
//! If set, it will override the minimum work we will assume exists on some valid chain.
|
||||||
|
std::optional<arith_uint256> minimum_chain_work;
|
||||||
|
//! If set, it will override the block hash whose ancestors we will assume to have valid scripts without checking them.
|
||||||
|
std::optional<uint256> assumed_valid_block;
|
||||||
|
//! If the tip is older than this, the node is considered to be in initial block download.
|
||||||
|
std::chrono::seconds max_tip_age{DEFAULT_MAX_TIP_AGE};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
|
|
|
@ -1291,7 +1291,7 @@ void PeerManagerImpl::FindNextBlocksToDownload(const Peer& peer, unsigned int co
|
||||||
// Make sure pindexBestKnownBlock is up to date, we'll need it.
|
// Make sure pindexBestKnownBlock is up to date, we'll need it.
|
||||||
ProcessBlockAvailability(peer.m_id);
|
ProcessBlockAvailability(peer.m_id);
|
||||||
|
|
||||||
if (state->pindexBestKnownBlock == nullptr || state->pindexBestKnownBlock->nChainWork < m_chainman.ActiveChain().Tip()->nChainWork || state->pindexBestKnownBlock->nChainWork < nMinimumChainWork) {
|
if (state->pindexBestKnownBlock == nullptr || state->pindexBestKnownBlock->nChainWork < m_chainman.ActiveChain().Tip()->nChainWork || state->pindexBestKnownBlock->nChainWork < m_chainman.MinimumChainWork()) {
|
||||||
// This peer has nothing interesting.
|
// This peer has nothing interesting.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2392,7 +2392,7 @@ arith_uint256 PeerManagerImpl::GetAntiDoSWorkThreshold()
|
||||||
// near our tip.
|
// near our tip.
|
||||||
near_chaintip_work = tip->nChainWork - std::min<arith_uint256>(144*GetBlockProof(*tip), tip->nChainWork);
|
near_chaintip_work = tip->nChainWork - std::min<arith_uint256>(144*GetBlockProof(*tip), tip->nChainWork);
|
||||||
}
|
}
|
||||||
return std::max(near_chaintip_work, arith_uint256(nMinimumChainWork));
|
return std::max(near_chaintip_work, m_chainman.MinimumChainWork());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2710,14 +2710,14 @@ void PeerManagerImpl::UpdatePeerStateForReceivedHeaders(CNode& pfrom,
|
||||||
if (m_chainman.ActiveChainstate().IsInitialBlockDownload() && !may_have_more_headers) {
|
if (m_chainman.ActiveChainstate().IsInitialBlockDownload() && !may_have_more_headers) {
|
||||||
// If the peer has no more headers to give us, then we know we have
|
// If the peer has no more headers to give us, then we know we have
|
||||||
// their tip.
|
// their tip.
|
||||||
if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork < nMinimumChainWork) {
|
if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork < m_chainman.MinimumChainWork()) {
|
||||||
// This peer has too little work on their headers chain to help
|
// This peer has too little work on their headers chain to help
|
||||||
// us sync -- disconnect if it is an outbound disconnection
|
// us sync -- disconnect if it is an outbound disconnection
|
||||||
// candidate.
|
// candidate.
|
||||||
// Note: We compare their tip to nMinimumChainWork (rather than
|
// Note: We compare their tip to the minumum chain work (rather than
|
||||||
// m_chainman.ActiveChain().Tip()) because we won't start block download
|
// m_chainman.ActiveChain().Tip()) because we won't start block download
|
||||||
// until we have a headers chain that has at least
|
// until we have a headers chain that has at least
|
||||||
// nMinimumChainWork, even if a peer has a chain past our tip,
|
// the minimum chain work, even if a peer has a chain past our tip,
|
||||||
// as an anti-DoS measure.
|
// as an anti-DoS measure.
|
||||||
if (pfrom.IsOutboundOrBlockRelayConn()) {
|
if (pfrom.IsOutboundOrBlockRelayConn()) {
|
||||||
LogPrintf("Disconnecting outbound peer %d -- headers chain has insufficient work\n", pfrom.GetId());
|
LogPrintf("Disconnecting outbound peer %d -- headers chain has insufficient work\n", pfrom.GetId());
|
||||||
|
@ -3901,12 +3901,12 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
// Note that if we were to be on a chain that forks from the checkpointed
|
// Note that if we were to be on a chain that forks from the checkpointed
|
||||||
// chain, then serving those headers to a peer that has seen the
|
// chain, then serving those headers to a peer that has seen the
|
||||||
// checkpointed chain would cause that peer to disconnect us. Requiring
|
// checkpointed chain would cause that peer to disconnect us. Requiring
|
||||||
// that our chainwork exceed nMinimumChainWork is a protection against
|
// that our chainwork exceed the mimimum chain work is a protection against
|
||||||
// being fed a bogus chain when we started up for the first time and
|
// being fed a bogus chain when we started up for the first time and
|
||||||
// getting partitioned off the honest network for serving that chain to
|
// getting partitioned off the honest network for serving that chain to
|
||||||
// others.
|
// others.
|
||||||
if (m_chainman.ActiveTip() == nullptr ||
|
if (m_chainman.ActiveTip() == nullptr ||
|
||||||
(m_chainman.ActiveTip()->nChainWork < nMinimumChainWork && !pfrom.HasPermission(NetPermissionFlags::Download))) {
|
(m_chainman.ActiveTip()->nChainWork < m_chainman.MinimumChainWork() && !pfrom.HasPermission(NetPermissionFlags::Download))) {
|
||||||
LogPrint(BCLog::NET, "Ignoring getheaders from peer=%d because active chain has too little work; sending empty response\n", pfrom.GetId());
|
LogPrint(BCLog::NET, "Ignoring getheaders from peer=%d because active chain has too little work; sending empty response\n", pfrom.GetId());
|
||||||
// Just respond with an empty headers message, to tell the peer to
|
// Just respond with an empty headers message, to tell the peer to
|
||||||
// go away but not treat us as unresponsive.
|
// go away but not treat us as unresponsive.
|
||||||
|
@ -4370,7 +4370,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
|
||||||
// (eg disk space). Because we only try to reconstruct blocks when
|
// (eg disk space). Because we only try to reconstruct blocks when
|
||||||
// we're close to caught up (via the CanDirectFetch() requirement
|
// we're close to caught up (via the CanDirectFetch() requirement
|
||||||
// above, combined with the behavior of not requesting blocks until
|
// above, combined with the behavior of not requesting blocks until
|
||||||
// we have a chain with at least nMinimumChainWork), and we ignore
|
// we have a chain with at least the minimum chain work), and we ignore
|
||||||
// compact blocks with less work than our tip, it is safe to treat
|
// compact blocks with less work than our tip, it is safe to treat
|
||||||
// reconstructed compact blocks as having been requested.
|
// reconstructed compact blocks as having been requested.
|
||||||
ProcessBlock(pfrom, pblock, /*force_processing=*/true, /*min_pow_checked=*/true);
|
ProcessBlock(pfrom, pblock, /*force_processing=*/true, /*min_pow_checked=*/true);
|
||||||
|
@ -5236,7 +5236,7 @@ void PeerManagerImpl::MaybeSendSendHeaders(CNode& node, Peer& peer)
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
CNodeState &state = *State(node.GetId());
|
CNodeState &state = *State(node.GetId());
|
||||||
if (state.pindexBestKnownBlock != nullptr &&
|
if (state.pindexBestKnownBlock != nullptr &&
|
||||||
state.pindexBestKnownBlock->nChainWork > nMinimumChainWork) {
|
state.pindexBestKnownBlock->nChainWork > m_chainman.MinimumChainWork()) {
|
||||||
// Tell our peer we prefer to receive headers rather than inv's
|
// Tell our peer we prefer to receive headers rather than inv's
|
||||||
// We send this to non-NODE NETWORK peers as well, because even
|
// We send this to non-NODE NETWORK peers as well, because even
|
||||||
// non-NODE NETWORK peers can announce blocks (such as pruning
|
// non-NODE NETWORK peers can announce blocks (such as pruning
|
||||||
|
|
|
@ -4,9 +4,11 @@
|
||||||
|
|
||||||
#include <node/chainstate.h>
|
#include <node/chainstate.h>
|
||||||
|
|
||||||
|
#include <arith_uint256.h>
|
||||||
#include <chain.h>
|
#include <chain.h>
|
||||||
#include <coins.h>
|
#include <coins.h>
|
||||||
#include <consensus/params.h>
|
#include <consensus/params.h>
|
||||||
|
#include <logging.h>
|
||||||
#include <node/blockstorage.h>
|
#include <node/blockstorage.h>
|
||||||
#include <node/caches.h>
|
#include <node/caches.h>
|
||||||
#include <sync.h>
|
#include <sync.h>
|
||||||
|
@ -21,6 +23,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -32,13 +35,13 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize
|
||||||
return options.reindex || options.reindex_chainstate || chainstate->CoinsTip().GetBestBlock().IsNull();
|
return options.reindex || options.reindex_chainstate || chainstate->CoinsTip().GetBestBlock().IsNull();
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!hashAssumeValid.IsNull()) {
|
if (!chainman.AssumedValidBlock().IsNull()) {
|
||||||
LogPrintf("Assuming ancestors of block %s have valid signatures.\n", hashAssumeValid.GetHex());
|
LogPrintf("Assuming ancestors of block %s have valid signatures.\n", chainman.AssumedValidBlock().GetHex());
|
||||||
} else {
|
} else {
|
||||||
LogPrintf("Validating signatures for all blocks.\n");
|
LogPrintf("Validating signatures for all blocks.\n");
|
||||||
}
|
}
|
||||||
LogPrintf("Setting nMinimumChainWork=%s\n", nMinimumChainWork.GetHex());
|
LogPrintf("Setting nMinimumChainWork=%s\n", chainman.MinimumChainWork().GetHex());
|
||||||
if (nMinimumChainWork < UintToArith256(chainman.GetConsensus().nMinimumChainWork)) {
|
if (chainman.MinimumChainWork() < UintToArith256(chainman.GetConsensus().nMinimumChainWork)) {
|
||||||
LogPrintf("Warning: nMinimumChainWork set below default value of %s\n", chainman.GetConsensus().nMinimumChainWork.GetHex());
|
LogPrintf("Warning: nMinimumChainWork set below default value of %s\n", chainman.GetConsensus().nMinimumChainWork.GetHex());
|
||||||
}
|
}
|
||||||
if (nPruneTarget == std::numeric_limits<uint64_t>::max()) {
|
if (nPruneTarget == std::numeric_limits<uint64_t>::max()) {
|
||||||
|
|
39
src/node/chainstatemanager_args.cpp
Normal file
39
src/node/chainstatemanager_args.cpp
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
// Copyright (c) 2022 The Bitcoin Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include <node/chainstatemanager_args.h>
|
||||||
|
|
||||||
|
#include <arith_uint256.h>
|
||||||
|
#include <tinyformat.h>
|
||||||
|
#include <uint256.h>
|
||||||
|
#include <util/strencodings.h>
|
||||||
|
#include <util/system.h>
|
||||||
|
#include <util/translation.h>
|
||||||
|
#include <validation.h>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace node {
|
||||||
|
std::optional<bilingual_str> ApplyArgsManOptions(const ArgsManager& args, ChainstateManager::Options& opts)
|
||||||
|
{
|
||||||
|
if (auto value{args.GetBoolArg("-checkblockindex")}) opts.check_block_index = *value;
|
||||||
|
|
||||||
|
if (auto value{args.GetBoolArg("-checkpoints")}) opts.checkpoints_enabled = *value;
|
||||||
|
|
||||||
|
if (auto value{args.GetArg("-minimumchainwork")}) {
|
||||||
|
if (!IsHexNumber(*value)) {
|
||||||
|
return strprintf(Untranslated("Invalid non-hex (%s) minimum chain work value specified"), *value);
|
||||||
|
}
|
||||||
|
opts.minimum_chain_work = UintToArith256(uint256S(*value));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto value{args.GetArg("-assumevalid")}) opts.assumed_valid_block = uint256S(*value);
|
||||||
|
|
||||||
|
if (auto value{args.GetIntArg("-maxtipage")}) opts.max_tip_age = std::chrono::seconds{*value};
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
} // namespace node
|
19
src/node/chainstatemanager_args.h
Normal file
19
src/node/chainstatemanager_args.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright (c) 2022 The Bitcoin Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#ifndef BITCOIN_NODE_CHAINSTATEMANAGER_ARGS_H
|
||||||
|
#define BITCOIN_NODE_CHAINSTATEMANAGER_ARGS_H
|
||||||
|
|
||||||
|
#include <validation.h>
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
class ArgsManager;
|
||||||
|
struct bilingual_str;
|
||||||
|
|
||||||
|
namespace node {
|
||||||
|
std::optional<bilingual_str> ApplyArgsManOptions(const ArgsManager& args, ChainstateManager::Options& opts);
|
||||||
|
} // namespace node
|
||||||
|
|
||||||
|
#endif // BITCOIN_NODE_CHAINSTATEMANAGER_ARGS_H
|
|
@ -146,7 +146,6 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve
|
||||||
Assert(InitScriptExecutionCache(validation_cache_sizes.script_execution_cache_bytes));
|
Assert(InitScriptExecutionCache(validation_cache_sizes.script_execution_cache_bytes));
|
||||||
|
|
||||||
m_node.chain = interfaces::MakeChain(m_node);
|
m_node.chain = interfaces::MakeChain(m_node);
|
||||||
fCheckBlockIndex = true;
|
|
||||||
static bool noui_connected = false;
|
static bool noui_connected = false;
|
||||||
if (!noui_connected) {
|
if (!noui_connected) {
|
||||||
noui_connect();
|
noui_connect();
|
||||||
|
@ -181,14 +180,13 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve
|
||||||
const ChainstateManager::Options chainman_opts{
|
const ChainstateManager::Options chainman_opts{
|
||||||
.chainparams = chainparams,
|
.chainparams = chainparams,
|
||||||
.adjusted_time_callback = GetAdjustedTime,
|
.adjusted_time_callback = GetAdjustedTime,
|
||||||
|
.check_block_index = true,
|
||||||
};
|
};
|
||||||
m_node.chainman = std::make_unique<ChainstateManager>(chainman_opts);
|
m_node.chainman = std::make_unique<ChainstateManager>(chainman_opts);
|
||||||
m_node.chainman->m_blockman.m_block_tree_db = std::make_unique<CBlockTreeDB>(m_cache_sizes.block_tree_db, true);
|
m_node.chainman->m_blockman.m_block_tree_db = std::make_unique<CBlockTreeDB>(m_cache_sizes.block_tree_db, true);
|
||||||
|
|
||||||
// Start script-checking threads. Set g_parallel_script_checks to true so they are used.
|
|
||||||
constexpr int script_check_threads = 2;
|
constexpr int script_check_threads = 2;
|
||||||
StartScriptCheckWorkerThreads(script_check_threads);
|
StartScriptCheckWorkerThreads(script_check_threads);
|
||||||
g_parallel_script_checks = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ChainTestingSetup::~ChainTestingSetup()
|
ChainTestingSetup::~ChainTestingSetup()
|
||||||
|
|
|
@ -120,13 +120,6 @@ RecursiveMutex cs_main;
|
||||||
GlobalMutex g_best_block_mutex;
|
GlobalMutex g_best_block_mutex;
|
||||||
std::condition_variable g_best_block_cv;
|
std::condition_variable g_best_block_cv;
|
||||||
uint256 g_best_block;
|
uint256 g_best_block;
|
||||||
bool g_parallel_script_checks{false};
|
|
||||||
bool fCheckBlockIndex = false;
|
|
||||||
bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED;
|
|
||||||
int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
|
|
||||||
|
|
||||||
uint256 hashAssumeValid;
|
|
||||||
arith_uint256 nMinimumChainWork;
|
|
||||||
|
|
||||||
const CBlockIndex* Chainstate::FindForkInGlobalIndex(const CBlockLocator& locator) const
|
const CBlockIndex* Chainstate::FindForkInGlobalIndex(const CBlockLocator& locator) const
|
||||||
{
|
{
|
||||||
|
@ -1545,10 +1538,12 @@ bool Chainstate::IsInitialBlockDownload() const
|
||||||
return true;
|
return true;
|
||||||
if (m_chain.Tip() == nullptr)
|
if (m_chain.Tip() == nullptr)
|
||||||
return true;
|
return true;
|
||||||
if (m_chain.Tip()->nChainWork < nMinimumChainWork)
|
if (m_chain.Tip()->nChainWork < m_chainman.MinimumChainWork()) {
|
||||||
return true;
|
return true;
|
||||||
if (m_chain.Tip()->GetBlockTime() < (GetTime() - nMaxTipAge))
|
}
|
||||||
|
if (m_chain.Tip()->Time() < NodeClock::now() - m_chainman.m_options.max_tip_age) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
LogPrintf("Leaving InitialBlockDownload (latching to false)\n");
|
LogPrintf("Leaving InitialBlockDownload (latching to false)\n");
|
||||||
m_cached_finished_ibd.store(true, std::memory_order_relaxed);
|
m_cached_finished_ibd.store(true, std::memory_order_relaxed);
|
||||||
return false;
|
return false;
|
||||||
|
@ -1994,6 +1989,7 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
|
||||||
|
|
||||||
uint256 block_hash{block.GetHash()};
|
uint256 block_hash{block.GetHash()};
|
||||||
assert(*pindex->phashBlock == block_hash);
|
assert(*pindex->phashBlock == block_hash);
|
||||||
|
const bool parallel_script_checks{scriptcheckqueue.HasThreads()};
|
||||||
|
|
||||||
const auto time_start{SteadyClock::now()};
|
const auto time_start{SteadyClock::now()};
|
||||||
const CChainParams& params{m_chainman.GetParams()};
|
const CChainParams& params{m_chainman.GetParams()};
|
||||||
|
@ -2036,17 +2032,17 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fScriptChecks = true;
|
bool fScriptChecks = true;
|
||||||
if (!hashAssumeValid.IsNull()) {
|
if (!m_chainman.AssumedValidBlock().IsNull()) {
|
||||||
// We've been configured with the hash of a block which has been externally verified to have a valid history.
|
// We've been configured with the hash of a block which has been externally verified to have a valid history.
|
||||||
// A suitable default value is included with the software and updated from time to time. Because validity
|
// A suitable default value is included with the software and updated from time to time. Because validity
|
||||||
// relative to a piece of software is an objective fact these defaults can be easily reviewed.
|
// relative to a piece of software is an objective fact these defaults can be easily reviewed.
|
||||||
// This setting doesn't force the selection of any particular chain but makes validating some faster by
|
// This setting doesn't force the selection of any particular chain but makes validating some faster by
|
||||||
// effectively caching the result of part of the verification.
|
// effectively caching the result of part of the verification.
|
||||||
BlockMap::const_iterator it = m_blockman.m_block_index.find(hashAssumeValid);
|
BlockMap::const_iterator it{m_blockman.m_block_index.find(m_chainman.AssumedValidBlock())};
|
||||||
if (it != m_blockman.m_block_index.end()) {
|
if (it != m_blockman.m_block_index.end()) {
|
||||||
if (it->second.GetAncestor(pindex->nHeight) == pindex &&
|
if (it->second.GetAncestor(pindex->nHeight) == pindex &&
|
||||||
m_chainman.m_best_header->GetAncestor(pindex->nHeight) == pindex &&
|
m_chainman.m_best_header->GetAncestor(pindex->nHeight) == pindex &&
|
||||||
m_chainman.m_best_header->nChainWork >= nMinimumChainWork) {
|
m_chainman.m_best_header->nChainWork >= m_chainman.MinimumChainWork()) {
|
||||||
// This block is a member of the assumed verified chain and an ancestor of the best header.
|
// This block is a member of the assumed verified chain and an ancestor of the best header.
|
||||||
// Script verification is skipped when connecting blocks under the
|
// Script verification is skipped when connecting blocks under the
|
||||||
// assumevalid block. Assuming the assumevalid block is valid this
|
// assumevalid block. Assuming the assumevalid block is valid this
|
||||||
|
@ -2059,7 +2055,7 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
|
||||||
// it hard to hide the implication of the demand. This also avoids having release candidates
|
// it hard to hide the implication of the demand. This also avoids having release candidates
|
||||||
// that are hardly doing any signature verification at all in testing without having to
|
// that are hardly doing any signature verification at all in testing without having to
|
||||||
// artificially set the default assumed verified block further back.
|
// artificially set the default assumed verified block further back.
|
||||||
// The test against nMinimumChainWork prevents the skipping when denied access to any chain at
|
// The test against the minimum chain work prevents the skipping when denied access to any chain at
|
||||||
// least as good as the expected chain.
|
// least as good as the expected chain.
|
||||||
fScriptChecks = (GetBlockProofEquivalentTime(*m_chainman.m_best_header, *pindex, *m_chainman.m_best_header, params.GetConsensus()) <= 60 * 60 * 24 * 7 * 2);
|
fScriptChecks = (GetBlockProofEquivalentTime(*m_chainman.m_best_header, *pindex, *m_chainman.m_best_header, params.GetConsensus()) <= 60 * 60 * 24 * 7 * 2);
|
||||||
}
|
}
|
||||||
|
@ -2183,7 +2179,7 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
|
||||||
// in multiple threads). Preallocate the vector size so a new allocation
|
// in multiple threads). Preallocate the vector size so a new allocation
|
||||||
// doesn't invalidate pointers into the vector, and keep txsdata in scope
|
// doesn't invalidate pointers into the vector, and keep txsdata in scope
|
||||||
// for as long as `control`.
|
// for as long as `control`.
|
||||||
CCheckQueueControl<CScriptCheck> control(fScriptChecks && g_parallel_script_checks ? &scriptcheckqueue : nullptr);
|
CCheckQueueControl<CScriptCheck> control(fScriptChecks && parallel_script_checks ? &scriptcheckqueue : nullptr);
|
||||||
std::vector<PrecomputedTransactionData> txsdata(block.vtx.size());
|
std::vector<PrecomputedTransactionData> txsdata(block.vtx.size());
|
||||||
|
|
||||||
std::vector<int> prevheights;
|
std::vector<int> prevheights;
|
||||||
|
@ -2242,7 +2238,7 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
|
||||||
std::vector<CScriptCheck> vChecks;
|
std::vector<CScriptCheck> vChecks;
|
||||||
bool fCacheResults = fJustCheck; /* Don't cache results if we're actually connecting blocks (still consult the cache, though) */
|
bool fCacheResults = fJustCheck; /* Don't cache results if we're actually connecting blocks (still consult the cache, though) */
|
||||||
TxValidationState tx_state;
|
TxValidationState tx_state;
|
||||||
if (fScriptChecks && !CheckInputScripts(tx, tx_state, view, flags, fCacheResults, fCacheResults, txsdata[i], g_parallel_script_checks ? &vChecks : nullptr)) {
|
if (fScriptChecks && !CheckInputScripts(tx, tx_state, view, flags, fCacheResults, fCacheResults, txsdata[i], parallel_script_checks ? &vChecks : nullptr)) {
|
||||||
// Any transaction validation failure in ConnectBlock is a block consensus failure
|
// Any transaction validation failure in ConnectBlock is a block consensus failure
|
||||||
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS,
|
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS,
|
||||||
tx_state.GetRejectReason(), tx_state.GetDebugMessage());
|
tx_state.GetRejectReason(), tx_state.GetDebugMessage());
|
||||||
|
@ -3532,7 +3528,7 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
|
||||||
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "bad-diffbits", "incorrect proof of work");
|
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "bad-diffbits", "incorrect proof of work");
|
||||||
|
|
||||||
// Check against checkpoints
|
// Check against checkpoints
|
||||||
if (fCheckpointsEnabled) {
|
if (chainman.m_options.checkpoints_enabled) {
|
||||||
// Don't accept any forks from the main chain prior to last checkpoint.
|
// Don't accept any forks from the main chain prior to last checkpoint.
|
||||||
// GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in our
|
// GetLastCheckpoint finds the last checkpoint in MapCheckpoints that's in our
|
||||||
// BlockIndex().
|
// BlockIndex().
|
||||||
|
@ -3846,7 +3842,7 @@ bool Chainstate::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockV
|
||||||
// If our tip is behind, a peer could try to send us
|
// If our tip is behind, a peer could try to send us
|
||||||
// low-work blocks on a fake chain that we would never
|
// low-work blocks on a fake chain that we would never
|
||||||
// request; don't process these.
|
// request; don't process these.
|
||||||
if (pindex->nChainWork < nMinimumChainWork) return true;
|
if (pindex->nChainWork < m_chainman.MinimumChainWork()) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CChainParams& params{m_chainman.GetParams()};
|
const CChainParams& params{m_chainman.GetParams()};
|
||||||
|
@ -4517,7 +4513,7 @@ void Chainstate::LoadExternalBlockFile(
|
||||||
|
|
||||||
void Chainstate::CheckBlockIndex()
|
void Chainstate::CheckBlockIndex()
|
||||||
{
|
{
|
||||||
if (!fCheckBlockIndex) {
|
if (!m_chainman.ShouldCheckBlockIndex()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5251,6 +5247,22 @@ void ChainstateManager::ResetChainstates()
|
||||||
m_active_chainstate = nullptr;
|
m_active_chainstate = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply default chain params to nullopt members.
|
||||||
|
* This helps to avoid coding errors around the accidental use of the compare
|
||||||
|
* operators that accept nullopt, thus ignoring the intended default value.
|
||||||
|
*/
|
||||||
|
static ChainstateManager::Options&& Flatten(ChainstateManager::Options&& opts)
|
||||||
|
{
|
||||||
|
if (!opts.check_block_index.has_value()) opts.check_block_index = opts.chainparams.DefaultConsistencyChecks();
|
||||||
|
if (!opts.minimum_chain_work.has_value()) opts.minimum_chain_work = UintToArith256(opts.chainparams.GetConsensus().nMinimumChainWork);
|
||||||
|
if (!opts.assumed_valid_block.has_value()) opts.assumed_valid_block = opts.chainparams.GetConsensus().defaultAssumeValid;
|
||||||
|
Assert(opts.adjusted_time_callback);
|
||||||
|
return std::move(opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChainstateManager::ChainstateManager(Options options) : m_options{Flatten(std::move(options))} {}
|
||||||
|
|
||||||
ChainstateManager::~ChainstateManager()
|
ChainstateManager::~ChainstateManager()
|
||||||
{
|
{
|
||||||
LOCK(::cs_main);
|
LOCK(::cs_main);
|
||||||
|
|
|
@ -63,8 +63,6 @@ struct Params;
|
||||||
static const int MAX_SCRIPTCHECK_THREADS = 15;
|
static const int MAX_SCRIPTCHECK_THREADS = 15;
|
||||||
/** -par default (number of script-checking threads, 0 = auto) */
|
/** -par default (number of script-checking threads, 0 = auto) */
|
||||||
static const int DEFAULT_SCRIPTCHECK_THREADS = 0;
|
static const int DEFAULT_SCRIPTCHECK_THREADS = 0;
|
||||||
static const int64_t DEFAULT_MAX_TIP_AGE = 24 * 60 * 60;
|
|
||||||
static const bool DEFAULT_CHECKPOINTS_ENABLED = true;
|
|
||||||
/** Default for -stopatheight */
|
/** Default for -stopatheight */
|
||||||
static const int DEFAULT_STOPATHEIGHT = 0;
|
static const int DEFAULT_STOPATHEIGHT = 0;
|
||||||
/** Block files containing a block-height within MIN_BLOCKS_TO_KEEP of ActiveChain().Tip() will not be pruned. */
|
/** Block files containing a block-height within MIN_BLOCKS_TO_KEEP of ActiveChain().Tip() will not be pruned. */
|
||||||
|
@ -93,20 +91,6 @@ extern GlobalMutex g_best_block_mutex;
|
||||||
extern std::condition_variable g_best_block_cv;
|
extern std::condition_variable g_best_block_cv;
|
||||||
/** Used to notify getblocktemplate RPC of new tips. */
|
/** Used to notify getblocktemplate RPC of new tips. */
|
||||||
extern uint256 g_best_block;
|
extern uint256 g_best_block;
|
||||||
/** Whether there are dedicated script-checking threads running.
|
|
||||||
* False indicates all script checking is done on the main threadMessageHandler thread.
|
|
||||||
*/
|
|
||||||
extern bool g_parallel_script_checks;
|
|
||||||
extern bool fCheckBlockIndex;
|
|
||||||
extern bool fCheckpointsEnabled;
|
|
||||||
/** If the tip is older than this (in seconds), the node is considered to be in initial block download. */
|
|
||||||
extern int64_t nMaxTipAge;
|
|
||||||
|
|
||||||
/** Block hash whose ancestors we will assume to have valid scripts without checking them. */
|
|
||||||
extern uint256 hashAssumeValid;
|
|
||||||
|
|
||||||
/** Minimum work we will assume exists on some valid chain. */
|
|
||||||
extern arith_uint256 nMinimumChainWork;
|
|
||||||
|
|
||||||
/** Documentation for argument 'checklevel'. */
|
/** Documentation for argument 'checklevel'. */
|
||||||
extern const std::vector<std::string> CHECKLEVEL_DOC;
|
extern const std::vector<std::string> CHECKLEVEL_DOC;
|
||||||
|
@ -698,7 +682,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Make various assertions about the state of the block index.
|
* Make various assertions about the state of the block index.
|
||||||
*
|
*
|
||||||
* By default this only executes fully when using the Regtest chain; see: fCheckBlockIndex.
|
* By default this only executes fully when using the Regtest chain; see: m_options.check_block_index.
|
||||||
*/
|
*/
|
||||||
void CheckBlockIndex();
|
void CheckBlockIndex();
|
||||||
|
|
||||||
|
@ -863,13 +847,13 @@ private:
|
||||||
public:
|
public:
|
||||||
using Options = kernel::ChainstateManagerOpts;
|
using Options = kernel::ChainstateManagerOpts;
|
||||||
|
|
||||||
explicit ChainstateManager(Options options) : m_options{std::move(options)}
|
explicit ChainstateManager(Options options);
|
||||||
{
|
|
||||||
Assert(m_options.adjusted_time_callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
const CChainParams& GetParams() const { return m_options.chainparams; }
|
const CChainParams& GetParams() const { return m_options.chainparams; }
|
||||||
const Consensus::Params& GetConsensus() const { return m_options.chainparams.GetConsensus(); }
|
const Consensus::Params& GetConsensus() const { return m_options.chainparams.GetConsensus(); }
|
||||||
|
bool ShouldCheckBlockIndex() const { return *Assert(m_options.check_block_index); }
|
||||||
|
const arith_uint256& MinimumChainWork() const { return *Assert(m_options.minimum_chain_work); }
|
||||||
|
const uint256& AssumedValidBlock() const { return *Assert(m_options.assumed_valid_block); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alias for ::cs_main.
|
* Alias for ::cs_main.
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
# Copyright (c) 2022 The Bitcoin Core developers
|
# Copyright (c) 2022 The Bitcoin Core developers
|
||||||
# Distributed under the MIT software license, see the accompanying
|
# Distributed under the MIT software license, see the accompanying
|
||||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
"""Test logic for setting nMaxTipAge on command line.
|
"""Test logic for setting -maxtipage on command line.
|
||||||
|
|
||||||
Nodes don't consider themselves out of "initial block download" as long as
|
Nodes don't consider themselves out of "initial block download" as long as
|
||||||
their best known block header time is more than nMaxTipAge in the past.
|
their best known block header time is more than -maxtipage in the past.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
Loading…
Add table
Reference in a new issue