Skip to content

Commit cccca83

Browse files
author
MacroFake
committed
Move ::nMinimumChainWork into ChainstateManager
This changes the minimum chain work for the bitcoin-chainstate executable. Previously it was uint256{}, now it is the chain's default minimum chain work.
1 parent fa29d0b commit cccca83

File tree

8 files changed

+53
-33
lines changed

8 files changed

+53
-33
lines changed

src/init.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -937,16 +937,6 @@ bool AppInitParameterInteraction(const ArgsManager& args, bool use_syscall_sandb
937937
fCheckBlockIndex = args.GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks());
938938
fCheckpointsEnabled = args.GetBoolArg("-checkpoints", DEFAULT_CHECKPOINTS_ENABLED);
939939

940-
if (args.IsArgSet("-minimumchainwork")) {
941-
const std::string minChainWorkStr = args.GetArg("-minimumchainwork", "");
942-
if (!IsHexNumber(minChainWorkStr)) {
943-
return InitError(strprintf(Untranslated("Invalid non-hex (%s) minimum chain work value specified"), minChainWorkStr));
944-
}
945-
nMinimumChainWork = UintToArith256(uint256S(minChainWorkStr));
946-
} else {
947-
nMinimumChainWork = UintToArith256(chainparams.GetConsensus().nMinimumChainWork);
948-
}
949-
950940
// block pruning; get the amount of disk space (in MiB) to allot for block & undo files
951941
int64_t nPruneArg = args.GetIntArg("-prune", 0);
952942
if (nPruneArg < 0) {
@@ -1044,6 +1034,16 @@ bool AppInitParameterInteraction(const ArgsManager& args, bool use_syscall_sandb
10441034
}
10451035
#endif // USE_SYSCALL_SANDBOX
10461036

1037+
// Also report errors from parsing before daemonization
1038+
{
1039+
ChainstateManager::Options chainman_opts_dummy{
1040+
.chainparams = chainparams,
1041+
};
1042+
if (const auto error{ApplyArgsManOptions(args, chainman_opts_dummy)}) {
1043+
return InitError(*error);
1044+
}
1045+
}
1046+
10471047
return true;
10481048
}
10491049

@@ -1439,7 +1439,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
14391439
.chainparams = chainparams,
14401440
.adjusted_time_callback = GetAdjustedTime,
14411441
};
1442-
ApplyArgsManOptions(args, chainman_opts);
1442+
Assert(!ApplyArgsManOptions(args, chainman_opts)); // no error can happen, already checked in AppInitParameterInteraction
14431443

14441444
// cache size calculations
14451445
CacheSizes cache_sizes = CalculateCacheSizes(args, g_enabled_filter_types.size());

src/kernel/chainstatemanager_opts.h

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

8+
#include <arith_uint256.h>
89
#include <uint256.h>
910
#include <util/time.h>
1011

@@ -26,6 +27,8 @@ namespace kernel {
2627
struct ChainstateManagerOpts {
2728
const CChainParams& chainparams;
2829
const std::function<NodeClock::time_point()> adjusted_time_callback{nullptr};
30+
//! If set, it will override the minimum work we will assume exists on some valid chain.
31+
std::optional<arith_uint256> minimum_chain_work;
2932
//! If set, it will override the block hash whose ancestors we will assume to have valid scripts without checking them.
3033
std::optional<uint256> assumed_valid_block;
3134
//! If the tip is older than this, the node is considered to be in initial block download.

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
/**
@@ -2702,14 +2702,14 @@ void PeerManagerImpl::UpdatePeerStateForReceivedHeaders(CNode& pfrom,
27022702
if (m_chainman.ActiveChainstate().IsInitialBlockDownload() && !may_have_more_headers) {
27032703
// If the peer has no more headers to give us, then we know we have
27042704
// their tip.
2705-
if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork < nMinimumChainWork) {
2705+
if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork < m_chainman.MinimumChainWork()) {
27062706
// This peer has too little work on their headers chain to help
27072707
// us sync -- disconnect if it is an outbound disconnection
27082708
// candidate.
2709-
// Note: We compare their tip to nMinimumChainWork (rather than
2709+
// Note: We compare their tip to the minumum chain work (rather than
27102710
// m_chainman.ActiveChain().Tip()) because we won't start block download
27112711
// until we have a headers chain that has at least
2712-
// nMinimumChainWork, even if a peer has a chain past our tip,
2712+
// the minimum chain work, even if a peer has a chain past our tip,
27132713
// as an anti-DoS measure.
27142714
if (pfrom.IsOutboundOrBlockRelayConn()) {
27152715
LogPrintf("Disconnecting outbound peer %d -- headers chain has insufficient work\n", pfrom.GetId());
@@ -3893,12 +3893,12 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
38933893
// Note that if we were to be on a chain that forks from the checkpointed
38943894
// chain, then serving those headers to a peer that has seen the
38953895
// checkpointed chain would cause that peer to disconnect us. Requiring
3896-
// that our chainwork exceed nMinimumChainWork is a protection against
3896+
// that our chainwork exceed the mimimum chain work is a protection against
38973897
// being fed a bogus chain when we started up for the first time and
38983898
// getting partitioned off the honest network for serving that chain to
38993899
// others.
39003900
if (m_chainman.ActiveTip() == nullptr ||
3901-
(m_chainman.ActiveTip()->nChainWork < nMinimumChainWork && !pfrom.HasPermission(NetPermissionFlags::Download))) {
3901+
(m_chainman.ActiveTip()->nChainWork < m_chainman.MinimumChainWork() && !pfrom.HasPermission(NetPermissionFlags::Download))) {
39023902
LogPrint(BCLog::NET, "Ignoring getheaders from peer=%d because active chain has too little work; sending empty response\n", pfrom.GetId());
39033903
// Just respond with an empty headers message, to tell the peer to
39043904
// go away but not treat us as unresponsive.
@@ -4362,7 +4362,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
43624362
// (eg disk space). Because we only try to reconstruct blocks when
43634363
// we're close to caught up (via the CanDirectFetch() requirement
43644364
// above, combined with the behavior of not requesting blocks until
4365-
// we have a chain with at least nMinimumChainWork), and we ignore
4365+
// we have a chain with at least the minimum chain work), and we ignore
43664366
// compact blocks with less work than our tip, it is safe to treat
43674367
// reconstructed compact blocks as having been requested.
43684368
ProcessBlock(pfrom, pblock, /*force_processing=*/true, /*min_pow_checked=*/true);
@@ -5228,7 +5228,7 @@ void PeerManagerImpl::MaybeSendSendHeaders(CNode& node, Peer& peer)
52285228
LOCK(cs_main);
52295229
CNodeState &state = *State(node.GetId());
52305230
if (state.pindexBestKnownBlock != nullptr &&
5231-
state.pindexBestKnownBlock->nChainWork > nMinimumChainWork) {
5231+
state.pindexBestKnownBlock->nChainWork > m_chainman.MinimumChainWork()) {
52325232
// Tell our peer we prefer to receive headers rather than inv's
52335233
// We send this to non-NODE NETWORK peers as well, because even
52345234
// non-NODE NETWORK peers can announce blocks (such as pruning

src/node/chainstate.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize
3737
} else {
3838
LogPrintf("Validating signatures for all blocks.\n");
3939
}
40-
LogPrintf("Setting nMinimumChainWork=%s\n", nMinimumChainWork.GetHex());
41-
if (nMinimumChainWork < UintToArith256(chainman.GetConsensus().nMinimumChainWork)) {
40+
LogPrintf("Setting nMinimumChainWork=%s\n", chainman.MinimumChainWork().GetHex());
41+
if (chainman.MinimumChainWork() < UintToArith256(chainman.GetConsensus().nMinimumChainWork)) {
4242
LogPrintf("Warning: nMinimumChainWork set below default value of %s\n", chainman.GetConsensus().nMinimumChainWork.GetHex());
4343
}
4444
if (nPruneTarget == std::numeric_limits<uint64_t>::max()) {

src/node/chainstatemanager_args.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,32 @@
44

55
#include <node/chainstatemanager_args.h>
66

7+
#include <arith_uint256.h>
8+
#include <tinyformat.h>
9+
#include <uint256.h>
10+
#include <util/strencodings.h>
711
#include <util/system.h>
12+
#include <util/translation.h>
13+
#include <validation.h>
814

915
#include <chrono>
1016
#include <optional>
17+
#include <string>
1118

1219
namespace node {
13-
void ApplyArgsManOptions(const ArgsManager& args, ChainstateManager::Options& opts)
20+
std::optional<bilingual_str> ApplyArgsManOptions(const ArgsManager& args, ChainstateManager::Options& opts)
1421
{
22+
if (auto value{args.GetArg("-minimumchainwork")}) {
23+
if (!IsHexNumber(*value)) {
24+
return strprintf(Untranslated("Invalid non-hex (%s) minimum chain work value specified"), *value);
25+
}
26+
opts.minimum_chain_work = UintToArith256(uint256S(*value));
27+
}
28+
1529
if (auto value{args.GetArg("-assumevalid")}) opts.assumed_valid_block = uint256S(*value);
1630

1731
if (auto value{args.GetIntArg("-maxtipage")}) opts.max_tip_age = std::chrono::seconds{*value};
32+
33+
return std::nullopt;
1834
}
1935
} // namespace node

src/node/chainstatemanager_args.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@
77

88
#include <validation.h>
99

10+
#include <optional>
11+
1012
class ArgsManager;
13+
struct bilingual_str;
1114

1215
namespace node {
13-
void ApplyArgsManOptions(const ArgsManager& args, ChainstateManager::Options& opts);
16+
std::optional<bilingual_str> ApplyArgsManOptions(const ArgsManager& args, ChainstateManager::Options& opts);
1417
} // namespace node
1518

1619
#endif // BITCOIN_NODE_CHAINSTATEMANAGER_ARGS_H

src/validation.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,6 @@ bool g_parallel_script_checks{false};
124124
bool fCheckBlockIndex = false;
125125
bool fCheckpointsEnabled = DEFAULT_CHECKPOINTS_ENABLED;
126126

127-
arith_uint256 nMinimumChainWork;
128-
129127
const CBlockIndex* Chainstate::FindForkInGlobalIndex(const CBlockLocator& locator) const
130128
{
131129
AssertLockHeld(cs_main);
@@ -1544,8 +1542,9 @@ bool Chainstate::IsInitialBlockDownload() const
15441542
return true;
15451543
if (m_chain.Tip() == nullptr)
15461544
return true;
1547-
if (m_chain.Tip()->nChainWork < nMinimumChainWork)
1545+
if (m_chain.Tip()->nChainWork < m_chainman.MinimumChainWork()) {
15481546
return true;
1547+
}
15491548
if (m_chain.Tip()->Time() < NodeClock::now() - m_chainman.m_options.max_tip_age) {
15501549
return true;
15511550
}
@@ -2045,7 +2044,7 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
20452044
if (it != m_blockman.m_block_index.end()) {
20462045
if (it->second.GetAncestor(pindex->nHeight) == pindex &&
20472046
m_chainman.m_best_header->GetAncestor(pindex->nHeight) == pindex &&
2048-
m_chainman.m_best_header->nChainWork >= nMinimumChainWork) {
2047+
m_chainman.m_best_header->nChainWork >= m_chainman.MinimumChainWork()) {
20492048
// This block is a member of the assumed verified chain and an ancestor of the best header.
20502049
// Script verification is skipped when connecting blocks under the
20512050
// assumevalid block. Assuming the assumevalid block is valid this
@@ -2058,7 +2057,7 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
20582057
// it hard to hide the implication of the demand. This also avoids having release candidates
20592058
// that are hardly doing any signature verification at all in testing without having to
20602059
// artificially set the default assumed verified block further back.
2061-
// The test against nMinimumChainWork prevents the skipping when denied access to any chain at
2060+
// The test against the minimum chain work prevents the skipping when denied access to any chain at
20622061
// least as good as the expected chain.
20632062
fScriptChecks = (GetBlockProofEquivalentTime(*m_chainman.m_best_header, *pindex, *m_chainman.m_best_header, m_params.GetConsensus()) <= 60 * 60 * 24 * 7 * 2);
20642063
}
@@ -3843,7 +3842,7 @@ bool Chainstate::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockV
38433842
// If our tip is behind, a peer could try to send us
38443843
// low-work blocks on a fake chain that we would never
38453844
// request; don't process these.
3846-
if (pindex->nChainWork < nMinimumChainWork) return true;
3845+
if (pindex->nChainWork < m_chainman.MinimumChainWork()) return true;
38473846
}
38483847

38493848
if (!CheckBlock(block, state, m_params.GetConsensus()) ||
@@ -5250,6 +5249,7 @@ void ChainstateManager::ResetChainstates()
52505249
*/
52515250
static ChainstateManager::Options&& Flatten(ChainstateManager::Options&& opts)
52525251
{
5252+
if (!opts.minimum_chain_work.has_value()) opts.minimum_chain_work = UintToArith256(opts.chainparams.GetConsensus().nMinimumChainWork);
52535253
if (!opts.assumed_valid_block.has_value()) opts.assumed_valid_block = opts.chainparams.GetConsensus().defaultAssumeValid;
52545254
Assert(opts.adjusted_time_callback);
52555255
return std::move(opts);

src/validation.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,6 @@ extern bool g_parallel_script_checks;
9999
extern bool fCheckBlockIndex;
100100
extern bool fCheckpointsEnabled;
101101

102-
/** Minimum work we will assume exists on some valid chain. */
103-
extern arith_uint256 nMinimumChainWork;
104-
105102
/** Documentation for argument 'checklevel'. */
106103
extern const std::vector<std::string> CHECKLEVEL_DOC;
107104

@@ -865,6 +862,7 @@ class ChainstateManager
865862

866863
const CChainParams& GetParams() const { return m_options.chainparams; }
867864
const Consensus::Params& GetConsensus() const { return m_options.chainparams.GetConsensus(); }
865+
const arith_uint256& MinimumChainWork() const { return *Assert(m_options.minimum_chain_work); }
868866
const uint256& AssumedValidBlock() const { return *Assert(m_options.assumed_valid_block); }
869867

870868
/**

0 commit comments

Comments
 (0)