Skip to content

Commit a1fff27

Browse files
author
MacroFake
committed
Merge bitcoin/bitcoin#25704: refactor: Remove almost all validation option globals
aaaa7bd iwyu: Add missing includes (MacroFake) fa9ebec Remove g_parallel_script_checks (MacroFake) fa7c834 Move ::fCheckBlockIndex into ChainstateManager (MacroFake) fa43188 Move ::fCheckpointsEnabled into ChainstateManager (MacroFake) cccca83 Move ::nMinimumChainWork into ChainstateManager (MacroFake) fa29d0b Move ::hashAssumeValid into ChainstateManager (MacroFake) faf4487 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 ACK aaaa7bd ryanofsky: Code review ACK aaaa7bd. No changes since last review, other than rebase aureleoules: reACK aaaa7bd Tree-SHA512: 83ec3ba0fb4f1dad95810d4bd4e578454e0718dc1bdd3a794cc4e48aa819b6f5dad4ac4edab3719bdfd5f89cbe23c2740a50fd56c1ff81c99e521c5f6d4e898d
2 parents cf28837 + aaaa7bd commit a1fff27

13 files changed

+151
-81
lines changed

ci/test/06_script_b.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ if [ "${RUN_TIDY}" = "true" ]; then
4545
" src/init"\
4646
" src/kernel"\
4747
" src/node/chainstate.cpp"\
48+
" src/node/chainstatemanager_args.cpp"\
4849
" src/node/mempool_args.cpp"\
4950
" src/node/validation_cache_args.cpp"\
5051
" src/policy/feerate.cpp"\

src/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ BITCOIN_CORE_H = \
198198
node/blockstorage.h \
199199
node/caches.h \
200200
node/chainstate.h \
201+
node/chainstatemanager_args.h \
201202
node/coin.h \
202203
node/connection_types.h \
203204
node/context.h \
@@ -381,6 +382,7 @@ libbitcoin_node_a_SOURCES = \
381382
node/blockstorage.cpp \
382383
node/caches.cpp \
383384
node/chainstate.cpp \
385+
node/chainstatemanager_args.cpp \
384386
node/coin.cpp \
385387
node/connection_types.cpp \
386388
node/context.cpp \

src/checkqueue.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,11 +199,12 @@ class CCheckQueue
199199
WITH_LOCK(m_mutex, m_request_stop = false);
200200
}
201201

202+
bool HasThreads() const { return !m_worker_threads.empty(); }
203+
202204
~CCheckQueue()
203205
{
204206
assert(m_worker_threads.empty());
205207
}
206-
207208
};
208209

209210
/**

src/init.cpp

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <node/blockstorage.h>
4141
#include <node/caches.h>
4242
#include <node/chainstate.h>
43+
#include <node/chainstatemanager_args.h>
4344
#include <node/context.h>
4445
#include <node/interface_ui.h>
4546
#include <node/mempool_args.h>
@@ -554,7 +555,10 @@ void SetupServerArgs(ArgsManager& argsman)
554555
argsman.AddArg("-capturemessages", "Capture all P2P messages to disk", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
555556
argsman.AddArg("-mocktime=<n>", "Replace actual time with " + UNIX_EPOCH_TIME + " (default: 0)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
556557
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);
557-
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);
558+
argsman.AddArg("-maxtipage=<n>",
559+
strprintf("Maximum tip age in seconds to consider node in initial block download (default: %u)",
560+
Ticks<std::chrono::seconds>(DEFAULT_MAX_TIP_AGE)),
561+
ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
558562
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);
559563
argsman.AddArg("-uacomment=<cmt>", "Append comment to the user agent string", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
560564

@@ -930,21 +934,6 @@ bool AppInitParameterInteraction(const ArgsManager& args, bool use_syscall_sandb
930934
init::SetLoggingCategories(args);
931935
init::SetLoggingLevel(args);
932936

933-
fCheckBlockIndex = args.GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks());
934-
fCheckpointsEnabled = args.GetBoolArg("-checkpoints", DEFAULT_CHECKPOINTS_ENABLED);
935-
936-
hashAssumeValid = uint256S(args.GetArg("-assumevalid", chainparams.GetConsensus().defaultAssumeValid.GetHex()));
937-
938-
if (args.IsArgSet("-minimumchainwork")) {
939-
const std::string minChainWorkStr = args.GetArg("-minimumchainwork", "");
940-
if (!IsHexNumber(minChainWorkStr)) {
941-
return InitError(strprintf(Untranslated("Invalid non-hex (%s) minimum chain work value specified"), minChainWorkStr));
942-
}
943-
nMinimumChainWork = UintToArith256(uint256S(minChainWorkStr));
944-
} else {
945-
nMinimumChainWork = UintToArith256(chainparams.GetConsensus().nMinimumChainWork);
946-
}
947-
948937
// block pruning; get the amount of disk space (in MiB) to allot for block & undo files
949938
int64_t nPruneArg = args.GetIntArg("-prune", 0);
950939
if (nPruneArg < 0) {
@@ -995,8 +984,6 @@ bool AppInitParameterInteraction(const ArgsManager& args, bool use_syscall_sandb
995984
if (args.GetIntArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) > 1)
996985
return InitError(Untranslated("Unknown rpcserialversion requested."));
997986

998-
nMaxTipAge = args.GetIntArg("-maxtipage", DEFAULT_MAX_TIP_AGE);
999-
1000987
if (args.GetBoolArg("-reindex-chainstate", false)) {
1001988
// indexes that must be deactivated to prevent index corruption, see #24630
1002989
if (args.GetBoolArg("-coinstatsindex", DEFAULT_COINSTATSINDEX)) {
@@ -1044,6 +1031,16 @@ bool AppInitParameterInteraction(const ArgsManager& args, bool use_syscall_sandb
10441031
}
10451032
#endif // USE_SYSCALL_SANDBOX
10461033

1034+
// Also report errors from parsing before daemonization
1035+
{
1036+
ChainstateManager::Options chainman_opts_dummy{
1037+
.chainparams = chainparams,
1038+
};
1039+
if (const auto error{ApplyArgsManOptions(args, chainman_opts_dummy)}) {
1040+
return InitError(*error);
1041+
}
1042+
}
1043+
10471044
return true;
10481045
}
10491046

@@ -1146,7 +1143,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
11461143

11471144
LogPrintf("Script verification uses %d additional threads\n", script_threads);
11481145
if (script_threads >= 1) {
1149-
g_parallel_script_checks = true;
11501146
StartScriptCheckWorkerThreads(script_threads);
11511147
}
11521148

@@ -1435,6 +1431,11 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
14351431

14361432
fReindex = args.GetBoolArg("-reindex", false);
14371433
bool fReindexChainState = args.GetBoolArg("-reindex-chainstate", false);
1434+
ChainstateManager::Options chainman_opts{
1435+
.chainparams = chainparams,
1436+
.adjusted_time_callback = GetAdjustedTime,
1437+
};
1438+
Assert(!ApplyArgsManOptions(args, chainman_opts)); // no error can happen, already checked in AppInitParameterInteraction
14381439

14391440
// cache size calculations
14401441
CacheSizes cache_sizes = CalculateCacheSizes(args, g_enabled_filter_types.size());
@@ -1471,10 +1472,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
14711472
for (bool fLoaded = false; !fLoaded && !ShutdownRequested();) {
14721473
node.mempool = std::make_unique<CTxMemPool>(mempool_opts);
14731474

1474-
const ChainstateManager::Options chainman_opts{
1475-
.chainparams = chainparams,
1476-
.adjusted_time_callback = GetAdjustedTime,
1477-
};
14781475
node.chainman = std::make_unique<ChainstateManager>(chainman_opts);
14791476
ChainstateManager& chainman = *node.chainman;
14801477

src/kernel/chainstatemanager_opts.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,19 @@
55
#ifndef BITCOIN_KERNEL_CHAINSTATEMANAGER_OPTS_H
66
#define BITCOIN_KERNEL_CHAINSTATEMANAGER_OPTS_H
77

8+
#include <arith_uint256.h>
9+
#include <uint256.h>
810
#include <util/time.h>
911

1012
#include <cstdint>
1113
#include <functional>
14+
#include <optional>
1215

1316
class CChainParams;
1417

18+
static constexpr bool DEFAULT_CHECKPOINTS_ENABLED{true};
19+
static constexpr auto DEFAULT_MAX_TIP_AGE{24h};
20+
1521
namespace kernel {
1622

1723
/**
@@ -22,6 +28,14 @@ namespace kernel {
2228
struct ChainstateManagerOpts {
2329
const CChainParams& chainparams;
2430
const std::function<NodeClock::time_point()> adjusted_time_callback{nullptr};
31+
std::optional<bool> check_block_index{};
32+
bool checkpoints_enabled{DEFAULT_CHECKPOINTS_ENABLED};
33+
//! If set, it will override the minimum work we will assume exists on some valid chain.
34+
std::optional<arith_uint256> minimum_chain_work;
35+
//! If set, it will override the block hash whose ancestors we will assume to have valid scripts without checking them.
36+
std::optional<uint256> assumed_valid_block;
37+
//! If the tip is older than this, the node is considered to be in initial block download.
38+
std::chrono::seconds max_tip_age{DEFAULT_MAX_TIP_AGE};
2539
};
2640

2741
} // namespace kernel

src/net_processing.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,7 +1291,7 @@ void PeerManagerImpl::FindNextBlocksToDownload(const Peer& peer, unsigned int co
12911291
// Make sure pindexBestKnownBlock is up to date, we'll need it.
12921292
ProcessBlockAvailability(peer.m_id);
12931293

1294-
if (state->pindexBestKnownBlock == nullptr || state->pindexBestKnownBlock->nChainWork < m_chainman.ActiveChain().Tip()->nChainWork || state->pindexBestKnownBlock->nChainWork < nMinimumChainWork) {
1294+
if (state->pindexBestKnownBlock == nullptr || state->pindexBestKnownBlock->nChainWork < m_chainman.ActiveChain().Tip()->nChainWork || state->pindexBestKnownBlock->nChainWork < m_chainman.MinimumChainWork()) {
12951295
// This peer has nothing interesting.
12961296
return;
12971297
}
@@ -2392,7 +2392,7 @@ arith_uint256 PeerManagerImpl::GetAntiDoSWorkThreshold()
23922392
// near our tip.
23932393
near_chaintip_work = tip->nChainWork - std::min<arith_uint256>(144*GetBlockProof(*tip), tip->nChainWork);
23942394
}
2395-
return std::max(near_chaintip_work, arith_uint256(nMinimumChainWork));
2395+
return std::max(near_chaintip_work, m_chainman.MinimumChainWork());
23962396
}
23972397

23982398
/**
@@ -2710,14 +2710,14 @@ void PeerManagerImpl::UpdatePeerStateForReceivedHeaders(CNode& pfrom,
27102710
if (m_chainman.ActiveChainstate().IsInitialBlockDownload() && !may_have_more_headers) {
27112711
// If the peer has no more headers to give us, then we know we have
27122712
// their tip.
2713-
if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork < nMinimumChainWork) {
2713+
if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork < m_chainman.MinimumChainWork()) {
27142714
// This peer has too little work on their headers chain to help
27152715
// us sync -- disconnect if it is an outbound disconnection
27162716
// candidate.
2717-
// Note: We compare their tip to nMinimumChainWork (rather than
2717+
// Note: We compare their tip to the minumum chain work (rather than
27182718
// m_chainman.ActiveChain().Tip()) because we won't start block download
27192719
// until we have a headers chain that has at least
2720-
// nMinimumChainWork, even if a peer has a chain past our tip,
2720+
// the minimum chain work, even if a peer has a chain past our tip,
27212721
// as an anti-DoS measure.
27222722
if (pfrom.IsOutboundOrBlockRelayConn()) {
27232723
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,
39013901
// Note that if we were to be on a chain that forks from the checkpointed
39023902
// chain, then serving those headers to a peer that has seen the
39033903
// checkpointed chain would cause that peer to disconnect us. Requiring
3904-
// that our chainwork exceed nMinimumChainWork is a protection against
3904+
// that our chainwork exceed the mimimum chain work is a protection against
39053905
// being fed a bogus chain when we started up for the first time and
39063906
// getting partitioned off the honest network for serving that chain to
39073907
// others.
39083908
if (m_chainman.ActiveTip() == nullptr ||
3909-
(m_chainman.ActiveTip()->nChainWork < nMinimumChainWork && !pfrom.HasPermission(NetPermissionFlags::Download))) {
3909+
(m_chainman.ActiveTip()->nChainWork < m_chainman.MinimumChainWork() && !pfrom.HasPermission(NetPermissionFlags::Download))) {
39103910
LogPrint(BCLog::NET, "Ignoring getheaders from peer=%d because active chain has too little work; sending empty response\n", pfrom.GetId());
39113911
// Just respond with an empty headers message, to tell the peer to
39123912
// go away but not treat us as unresponsive.
@@ -4370,7 +4370,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
43704370
// (eg disk space). Because we only try to reconstruct blocks when
43714371
// we're close to caught up (via the CanDirectFetch() requirement
43724372
// above, combined with the behavior of not requesting blocks until
4373-
// we have a chain with at least nMinimumChainWork), and we ignore
4373+
// we have a chain with at least the minimum chain work), and we ignore
43744374
// compact blocks with less work than our tip, it is safe to treat
43754375
// reconstructed compact blocks as having been requested.
43764376
ProcessBlock(pfrom, pblock, /*force_processing=*/true, /*min_pow_checked=*/true);
@@ -5236,7 +5236,7 @@ void PeerManagerImpl::MaybeSendSendHeaders(CNode& node, Peer& peer)
52365236
LOCK(cs_main);
52375237
CNodeState &state = *State(node.GetId());
52385238
if (state.pindexBestKnownBlock != nullptr &&
5239-
state.pindexBestKnownBlock->nChainWork > nMinimumChainWork) {
5239+
state.pindexBestKnownBlock->nChainWork > m_chainman.MinimumChainWork()) {
52405240
// Tell our peer we prefer to receive headers rather than inv's
52415241
// We send this to non-NODE NETWORK peers as well, because even
52425242
// non-NODE NETWORK peers can announce blocks (such as pruning

src/node/chainstate.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44

55
#include <node/chainstate.h>
66

7+
#include <arith_uint256.h>
78
#include <chain.h>
89
#include <coins.h>
910
#include <consensus/params.h>
11+
#include <logging.h>
1012
#include <node/blockstorage.h>
1113
#include <node/caches.h>
1214
#include <sync.h>
@@ -21,6 +23,7 @@
2123
#include <algorithm>
2224
#include <atomic>
2325
#include <cassert>
26+
#include <limits>
2427
#include <memory>
2528
#include <vector>
2629

@@ -32,13 +35,13 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize
3235
return options.reindex || options.reindex_chainstate || chainstate->CoinsTip().GetBestBlock().IsNull();
3336
};
3437

35-
if (!hashAssumeValid.IsNull()) {
36-
LogPrintf("Assuming ancestors of block %s have valid signatures.\n", hashAssumeValid.GetHex());
38+
if (!chainman.AssumedValidBlock().IsNull()) {
39+
LogPrintf("Assuming ancestors of block %s have valid signatures.\n", chainman.AssumedValidBlock().GetHex());
3740
} else {
3841
LogPrintf("Validating signatures for all blocks.\n");
3942
}
40-
LogPrintf("Setting nMinimumChainWork=%s\n", nMinimumChainWork.GetHex());
41-
if (nMinimumChainWork < UintToArith256(chainman.GetConsensus().nMinimumChainWork)) {
43+
LogPrintf("Setting nMinimumChainWork=%s\n", chainman.MinimumChainWork().GetHex());
44+
if (chainman.MinimumChainWork() < UintToArith256(chainman.GetConsensus().nMinimumChainWork)) {
4245
LogPrintf("Warning: nMinimumChainWork set below default value of %s\n", chainman.GetConsensus().nMinimumChainWork.GetHex());
4346
}
4447
if (nPruneTarget == std::numeric_limits<uint64_t>::max()) {

src/node/chainstatemanager_args.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright (c) 2022 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <node/chainstatemanager_args.h>
6+
7+
#include <arith_uint256.h>
8+
#include <tinyformat.h>
9+
#include <uint256.h>
10+
#include <util/strencodings.h>
11+
#include <util/system.h>
12+
#include <util/translation.h>
13+
#include <validation.h>
14+
15+
#include <chrono>
16+
#include <optional>
17+
#include <string>
18+
19+
namespace node {
20+
std::optional<bilingual_str> ApplyArgsManOptions(const ArgsManager& args, ChainstateManager::Options& opts)
21+
{
22+
if (auto value{args.GetBoolArg("-checkblockindex")}) opts.check_block_index = *value;
23+
24+
if (auto value{args.GetBoolArg("-checkpoints")}) opts.checkpoints_enabled = *value;
25+
26+
if (auto value{args.GetArg("-minimumchainwork")}) {
27+
if (!IsHexNumber(*value)) {
28+
return strprintf(Untranslated("Invalid non-hex (%s) minimum chain work value specified"), *value);
29+
}
30+
opts.minimum_chain_work = UintToArith256(uint256S(*value));
31+
}
32+
33+
if (auto value{args.GetArg("-assumevalid")}) opts.assumed_valid_block = uint256S(*value);
34+
35+
if (auto value{args.GetIntArg("-maxtipage")}) opts.max_tip_age = std::chrono::seconds{*value};
36+
37+
return std::nullopt;
38+
}
39+
} // namespace node

src/node/chainstatemanager_args.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) 2022 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_NODE_CHAINSTATEMANAGER_ARGS_H
6+
#define BITCOIN_NODE_CHAINSTATEMANAGER_ARGS_H
7+
8+
#include <validation.h>
9+
10+
#include <optional>
11+
12+
class ArgsManager;
13+
struct bilingual_str;
14+
15+
namespace node {
16+
std::optional<bilingual_str> ApplyArgsManOptions(const ArgsManager& args, ChainstateManager::Options& opts);
17+
} // namespace node
18+
19+
#endif // BITCOIN_NODE_CHAINSTATEMANAGER_ARGS_H

src/test/util/setup_common.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve
146146
Assert(InitScriptExecutionCache(validation_cache_sizes.script_execution_cache_bytes));
147147

148148
m_node.chain = interfaces::MakeChain(m_node);
149-
fCheckBlockIndex = true;
150149
static bool noui_connected = false;
151150
if (!noui_connected) {
152151
noui_connect();
@@ -181,14 +180,13 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve
181180
const ChainstateManager::Options chainman_opts{
182181
.chainparams = chainparams,
183182
.adjusted_time_callback = GetAdjustedTime,
183+
.check_block_index = true,
184184
};
185185
m_node.chainman = std::make_unique<ChainstateManager>(chainman_opts);
186186
m_node.chainman->m_blockman.m_block_tree_db = std::make_unique<CBlockTreeDB>(m_cache_sizes.block_tree_db, true);
187187

188-
// Start script-checking threads. Set g_parallel_script_checks to true so they are used.
189188
constexpr int script_check_threads = 2;
190189
StartScriptCheckWorkerThreads(script_check_threads);
191-
g_parallel_script_checks = true;
192190
}
193191

194192
ChainTestingSetup::~ChainTestingSetup()

0 commit comments

Comments
 (0)