aboutsummaryrefslogtreecommitdiff
path: root/src/rpc/blockchain.cpp
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2021-04-17 17:37:26 +0200
committerMarcoFalke <falke.marco@gmail.com>2021-04-17 17:37:37 +0200
commit0dd7b234895b02bfc512ae83bd77b581c861d6e9 (patch)
treeb9ddbf86936e1db3f84a4346ab3234e6c83b2266 /src/rpc/blockchain.cpp
parent4a1751a929cc5727d4941543baf2238f041b4b70 (diff)
parent586190f0b4740457cb86cba632e3d64e6dfe9b0c (diff)
downloadbitcoin-0dd7b234895b02bfc512ae83bd77b581c861d6e9.tar.xz
Merge #21391: [Bundle 5/n] Prune g_chainman usage in RPC modules
586190f0b4740457cb86cba632e3d64e6dfe9b0c rpc/rest: Take and reuse local Chain/ChainState obj (Carl Dong) bc3bd369027273278a0541f3b991eb71de831aa2 rpc: style: Improve BuriedForkDescPushBack signature (Carl Dong) f99913969f92b8b9cef1b83f5ee8e6a9267b4af0 rpc: Remove unnecessary casting of block height (Carl Dong) 6a3d1920209cded0dae52fb9070a3530d9a4e5fd rpc: Tidy up local references (see commit message) (Carl Dong) 038854f31e3511e8bb6e163305cab0a96783d25b rest/rpc: Remove now-unused old Ensure functions (Carl Dong) 6fb65b49f4d393b091479be5a5df5a0a160cf986 scripted-diff: rest/rpc: Use renamed EnsureAny*() (Carl Dong) 1570c7ee98612366df031bebef9e0468fb57b8a2 rpc: Add renamed EnsureAny*() functions (Carl Dong) 306b1cd3eeb2502904ed4698646d2c86d028aad2 rpc: Add alt Ensure* functions acepting NodeContext (Carl Dong) d7824acdb9b18fe8f151771a83ccae1681f16c66 rest: Use existing NodeContext (Carl Dong) 3f0893479908ca28d6127c8d0ada30737cb830be rest: Pass in NodeContext to rest_block (Carl Dong) 7be0671b950842fc3a17641a4a21501de0a800b5 rpc/rawtx: Use existing NodeContext (Carl Dong) 60dc05afc6f6388c6f86729a0edd7cb69f1748e0 rpc/mining: Use existing NodeContext (Carl Dong) d485e815e2b62dc74a485569d08130dc3ef9ff63 rpc/blockchain: Use existing NodeContext (Carl Dong) d0abf0bf429586e3a5b4c3231fe430dc29695481 rpc/*,rest: Add review-only assertion to EnsureChainman (Carl Dong) cced0f46c9133e0fc6211e987421ad1d9be1a399 miner: Pass in previous CBlockIndex to RegenerateCommitments (Carl Dong) Pull request description: Overall PR: #20158 (tree-wide: De-globalize ChainstateManager) Based on: - [x] #21270 | [Bundle 4/n] Prune g_chainman usage in validation-adjacent modules - [x] #21525 | [Bundle 4.5/n] Followup fixups to bundle 4 Note to reviewers: 1. This bundle may _apparently_ introduce usage of `g_chainman` or `::Chain(state|)Active()` globals, but these are resolved later on in the overall PR. [Commits of overall PR](https://github.com/bitcoin/bitcoin/pull/20158/commits) 2. There may be seemingly obvious local references to `ChainstateManager` or other validation objects which are not being used in callers of the current function in question, this is done intentionally to **_keep each commit centered around one function/method_** to ease review and to make the overall change systematic. We don't assume anything about our callers. Rest assured that once we are considering that particular caller in later commits, we will use the obvious local references. [Commits of overall PR](https://github.com/bitcoin/bitcoin/pull/20158/commits) 3. When changing a function/method that has many callers (e.g. `LookupBlockIndex` with 55 callers), it is sometimes easier (and less error-prone) to use a scripted-diff. When doing so, there will be 3 commits in sequence so that every commit compiles like so: 1. Add `new_function`, make `old_function` a wrapper of `new_function`, divert all calls to `old_function` to `new_function` **in the local module only** 2. Scripted-diff to divert all calls to `old_function` to `new_function` **in the rest of the codebase** 3. Remove `old_function` ACKs for top commit: ryanofsky: Code review ACK 586190f0b4740457cb86cba632e3d64e6dfe9b0c. Since last review, no changes to existing commits, just some simple new commits added: three new commits renaming std::any Ensure functions (scripted diff commit and manual pre/post commits), and one new commit factoring out a repeated `ActiveChain()` call made in a loop. Thanks for the updates! jnewbery: utACK 586190f0b4740457cb86cba632e3d64e6dfe9b0c MarcoFalke: review ACK 586190f0b4740457cb86cba632e3d64e6dfe9b0c 🍯 Tree-SHA512: 64b677fb50141805b55c3f1afe68fcd298f9a071a359bdcd63256d52e334f83e462f31fb3ebee9b630da8f1d912a03a128cfc38179e7aaec29a055744a98478c
Diffstat (limited to 'src/rpc/blockchain.cpp')
-rw-r--r--src/rpc/blockchain.cpp208
1 files changed, 129 insertions, 79 deletions
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index f27e9af0d9..7cf6a413e1 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -56,7 +56,7 @@ static Mutex cs_blockchange;
static std::condition_variable cond_blockchange;
static CUpdatedBlock latestblock GUARDED_BY(cs_blockchange);
-NodeContext& EnsureNodeContext(const std::any& context)
+NodeContext& EnsureAnyNodeContext(const std::any& context)
{
auto node_context = util::AnyPtr<NodeContext>(context);
if (!node_context) {
@@ -65,33 +65,46 @@ NodeContext& EnsureNodeContext(const std::any& context)
return *node_context;
}
-CTxMemPool& EnsureMemPool(const std::any& context)
+CTxMemPool& EnsureMemPool(const NodeContext& node)
{
- const NodeContext& node = EnsureNodeContext(context);
if (!node.mempool) {
throw JSONRPCError(RPC_CLIENT_MEMPOOL_DISABLED, "Mempool disabled or instance not found");
}
return *node.mempool;
}
-ChainstateManager& EnsureChainman(const std::any& context)
+CTxMemPool& EnsureAnyMemPool(const std::any& context)
+{
+ return EnsureMemPool(EnsureAnyNodeContext(context));
+}
+
+ChainstateManager& EnsureChainman(const NodeContext& node)
{
- const NodeContext& node = EnsureNodeContext(context);
if (!node.chainman) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Node chainman not found");
}
+ WITH_LOCK(::cs_main, CHECK_NONFATAL(std::addressof(g_chainman) == std::addressof(*node.chainman)));
return *node.chainman;
}
-CBlockPolicyEstimator& EnsureFeeEstimator(const std::any& context)
+ChainstateManager& EnsureAnyChainman(const std::any& context)
+{
+ return EnsureChainman(EnsureAnyNodeContext(context));
+}
+
+CBlockPolicyEstimator& EnsureFeeEstimator(const NodeContext& node)
{
- NodeContext& node = EnsureNodeContext(context);
if (!node.fee_estimator) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Fee estimation disabled");
}
return *node.fee_estimator;
}
+CBlockPolicyEstimator& EnsureAnyFeeEstimator(const std::any& context)
+{
+ return EnsureFeeEstimator(EnsureAnyNodeContext(context));
+}
+
/* Calculate the difficulty for a given block index.
*/
double GetDifficulty(const CBlockIndex* blockindex)
@@ -198,8 +211,9 @@ static RPCHelpMan getblockcount()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
+ ChainstateManager& chainman = EnsureAnyChainman(request.context);
LOCK(cs_main);
- return ::ChainActive().Height();
+ return chainman.ActiveChain().Height();
},
};
}
@@ -217,8 +231,9 @@ static RPCHelpMan getbestblockhash()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
+ ChainstateManager& chainman = EnsureAnyChainman(request.context);
LOCK(cs_main);
- return ::ChainActive().Tip()->GetBlockHash().GetHex();
+ return chainman.ActiveChain().Tip()->GetBlockHash().GetHex();
},
};
}
@@ -398,8 +413,9 @@ static RPCHelpMan getdifficulty()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
+ ChainstateManager& chainman = EnsureAnyChainman(request.context);
LOCK(cs_main);
- return GetDifficulty(::ChainActive().Tip());
+ return GetDifficulty(chainman.ActiveChain().Tip());
},
};
}
@@ -581,7 +597,7 @@ static RPCHelpMan getrawmempool()
include_mempool_sequence = request.params[1].get_bool();
}
- return MempoolToJSON(EnsureMemPool(request.context), fVerbose, include_mempool_sequence);
+ return MempoolToJSON(EnsureAnyMemPool(request.context), fVerbose, include_mempool_sequence);
},
};
}
@@ -616,7 +632,7 @@ static RPCHelpMan getmempoolancestors()
uint256 hash = ParseHashV(request.params[0], "parameter 1");
- const CTxMemPool& mempool = EnsureMemPool(request.context);
+ const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
LOCK(mempool.cs);
CTxMemPool::txiter it = mempool.mapTx.find(hash);
@@ -680,7 +696,7 @@ static RPCHelpMan getmempooldescendants()
uint256 hash = ParseHashV(request.params[0], "parameter 1");
- const CTxMemPool& mempool = EnsureMemPool(request.context);
+ const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
LOCK(mempool.cs);
CTxMemPool::txiter it = mempool.mapTx.find(hash);
@@ -732,7 +748,7 @@ static RPCHelpMan getmempoolentry()
{
uint256 hash = ParseHashV(request.params[0], "parameter 1");
- const CTxMemPool& mempool = EnsureMemPool(request.context);
+ const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
LOCK(mempool.cs);
CTxMemPool::txiter it = mempool.mapTx.find(hash);
@@ -763,13 +779,15 @@ static RPCHelpMan getblockhash()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
+ ChainstateManager& chainman = EnsureAnyChainman(request.context);
LOCK(cs_main);
+ const CChain& active_chain = chainman.ActiveChain();
int nHeight = request.params[0].get_int();
- if (nHeight < 0 || nHeight > ::ChainActive().Height())
+ if (nHeight < 0 || nHeight > active_chain.Height())
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
- CBlockIndex* pblockindex = ::ChainActive()[nHeight];
+ CBlockIndex* pblockindex = active_chain[nHeight];
return pblockindex->GetBlockHash().GetHex();
},
};
@@ -822,9 +840,10 @@ static RPCHelpMan getblockheader()
const CBlockIndex* pblockindex;
const CBlockIndex* tip;
{
+ ChainstateManager& chainman = EnsureAnyChainman(request.context);
LOCK(cs_main);
- pblockindex = g_chainman.m_blockman.LookupBlockIndex(hash);
- tip = ::ChainActive().Tip();
+ pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
+ tip = chainman.ActiveChain().Tip();
}
if (!pblockindex) {
@@ -946,9 +965,10 @@ static RPCHelpMan getblock()
const CBlockIndex* pblockindex;
const CBlockIndex* tip;
{
+ ChainstateManager& chainman = EnsureAnyChainman(request.context);
LOCK(cs_main);
- pblockindex = g_chainman.m_blockman.LookupBlockIndex(hash);
- tip = ::ChainActive().Tip();
+ pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
+ tip = chainman.ActiveChain().Tip();
if (!pblockindex) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
@@ -988,7 +1008,10 @@ static RPCHelpMan pruneblockchain()
if (!fPruneMode)
throw JSONRPCError(RPC_MISC_ERROR, "Cannot prune blocks because node is not in prune mode.");
+ ChainstateManager& chainman = EnsureAnyChainman(request.context);
LOCK(cs_main);
+ CChainState& active_chainstate = chainman.ActiveChainstate();
+ CChain& active_chain = active_chainstate.m_chain;
int heightParam = request.params[0].get_int();
if (heightParam < 0)
@@ -998,7 +1021,7 @@ static RPCHelpMan pruneblockchain()
// too low to be a block time (corresponds to timestamp from Sep 2001).
if (heightParam > 1000000000) {
// Add a 2 hour buffer to include blocks which might have had old timestamps
- CBlockIndex* pindex = ::ChainActive().FindEarliestAtLeast(heightParam - TIMESTAMP_WINDOW, 0);
+ CBlockIndex* pindex = active_chain.FindEarliestAtLeast(heightParam - TIMESTAMP_WINDOW, 0);
if (!pindex) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Could not find block with at least the specified timestamp.");
}
@@ -1006,7 +1029,7 @@ static RPCHelpMan pruneblockchain()
}
unsigned int height = (unsigned int) heightParam;
- unsigned int chainHeight = (unsigned int) ::ChainActive().Height();
+ unsigned int chainHeight = (unsigned int) active_chain.Height();
if (chainHeight < Params().PruneAfterHeight())
throw JSONRPCError(RPC_MISC_ERROR, "Blockchain is too short for pruning.");
else if (height > chainHeight)
@@ -1016,8 +1039,8 @@ static RPCHelpMan pruneblockchain()
height = chainHeight - MIN_BLOCKS_TO_KEEP;
}
- PruneBlockFilesManual(::ChainstateActive(), height);
- const CBlockIndex* block = ::ChainActive().Tip();
+ PruneBlockFilesManual(active_chainstate, height);
+ const CBlockIndex* block = active_chain.Tip();
CHECK_NONFATAL(block);
while (block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) {
block = block->pprev;
@@ -1070,13 +1093,21 @@ static RPCHelpMan gettxoutsetinfo()
UniValue ret(UniValue::VOBJ);
CCoinsStats stats;
- ::ChainstateActive().ForceFlushStateToDisk();
+ NodeContext& node = EnsureAnyNodeContext(request.context);
+ ChainstateManager& chainman = EnsureChainman(node);
+ CChainState& active_chainstate = chainman.ActiveChainstate();
+ active_chainstate.ForceFlushStateToDisk();
const CoinStatsHashType hash_type{request.params[0].isNull() ? CoinStatsHashType::HASH_SERIALIZED : ParseHashType(request.params[0].get_str())};
- CCoinsView* coins_view = WITH_LOCK(::cs_main, return &::ChainstateActive().CoinsDB());
- NodeContext& node = EnsureNodeContext(request.context);
- if (GetUTXOStats(coins_view, WITH_LOCK(::cs_main, return std::ref(g_chainman.m_blockman)), stats, hash_type, node.rpc_interruption_point)) {
+ CCoinsView* coins_view;
+ BlockManager* blockman;
+ {
+ LOCK(::cs_main);
+ coins_view = &active_chainstate.CoinsDB();
+ blockman = &active_chainstate.m_blockman;
+ }
+ if (GetUTXOStats(coins_view, *blockman, stats, hash_type, node.rpc_interruption_point)) {
ret.pushKV("height", (int64_t)stats.nHeight);
ret.pushKV("bestblock", stats.hashBlock.GetHex());
ret.pushKV("transactions", (int64_t)stats.nTransactions);
@@ -1135,6 +1166,8 @@ static RPCHelpMan gettxout()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
+ NodeContext& node = EnsureAnyNodeContext(request.context);
+ ChainstateManager& chainman = EnsureChainman(node);
LOCK(cs_main);
UniValue ret(UniValue::VOBJ);
@@ -1147,10 +1180,11 @@ static RPCHelpMan gettxout()
fMempool = request.params[2].get_bool();
Coin coin;
- CCoinsViewCache* coins_view = &::ChainstateActive().CoinsTip();
+ CChainState& active_chainstate = chainman.ActiveChainstate();
+ CCoinsViewCache* coins_view = &active_chainstate.CoinsTip();
if (fMempool) {
- const CTxMemPool& mempool = EnsureMemPool(request.context);
+ const CTxMemPool& mempool = EnsureMemPool(node);
LOCK(mempool.cs);
CCoinsViewMemPool view(coins_view, mempool);
if (!view.GetCoin(out, coin) || mempool.isSpent(out)) {
@@ -1162,7 +1196,7 @@ static RPCHelpMan gettxout()
}
}
- const CBlockIndex* pindex = g_chainman.m_blockman.LookupBlockIndex(coins_view->GetBestBlock());
+ const CBlockIndex* pindex = active_chainstate.m_blockman.LookupBlockIndex(coins_view->GetBestBlock());
ret.pushKV("bestblock", pindex->GetBlockHash().GetHex());
if (coin.nHeight == MEMPOOL_HEIGHT) {
ret.pushKV("confirmations", 0);
@@ -1200,39 +1234,41 @@ static RPCHelpMan verifychain()
const int check_level(request.params[0].isNull() ? DEFAULT_CHECKLEVEL : request.params[0].get_int());
const int check_depth{request.params[1].isNull() ? DEFAULT_CHECKBLOCKS : request.params[1].get_int()};
+ ChainstateManager& chainman = EnsureAnyChainman(request.context);
LOCK(cs_main);
- return CVerifyDB().VerifyDB(Params(), ::ChainstateActive(), &::ChainstateActive().CoinsTip(), check_level, check_depth);
+ CChainState& active_chainstate = chainman.ActiveChainstate();
+ return CVerifyDB().VerifyDB(Params(), active_chainstate, &active_chainstate.CoinsTip(), check_level, check_depth);
},
};
}
-static void BuriedForkDescPushBack(UniValue& softforks, const std::string &name, int height) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
+static void BuriedForkDescPushBack(UniValue& softforks, const std::string &name, int softfork_height, int tip_height) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
// For buried deployments.
// A buried deployment is one where the height of the activation has been hardcoded into
// the client implementation long after the consensus change has activated. See BIP 90.
// Buried deployments with activation height value of
// std::numeric_limits<int>::max() are disabled and thus hidden.
- if (height == std::numeric_limits<int>::max()) return;
+ if (softfork_height == std::numeric_limits<int>::max()) return;
UniValue rv(UniValue::VOBJ);
rv.pushKV("type", "buried");
// getblockchaininfo reports the softfork as active from when the chain height is
// one below the activation height
- rv.pushKV("active", ::ChainActive().Tip()->nHeight + 1 >= height);
- rv.pushKV("height", height);
+ rv.pushKV("active", tip_height + 1 >= softfork_height);
+ rv.pushKV("height", softfork_height);
softforks.pushKV(name, rv);
}
-static void BIP9SoftForkDescPushBack(UniValue& softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
+static void BIP9SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniValue& softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
// For BIP9 deployments.
// Deployments that are never active are hidden.
if (consensusParams.vDeployments[id].nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE) return;
UniValue bip9(UniValue::VOBJ);
- const ThresholdState thresholdState = VersionBitsState(::ChainActive().Tip(), consensusParams, id, versionbitscache);
+ const ThresholdState thresholdState = VersionBitsState(active_chain_tip, consensusParams, id, versionbitscache);
switch (thresholdState) {
case ThresholdState::DEFINED: bip9.pushKV("status", "defined"); break;
case ThresholdState::STARTED: bip9.pushKV("status", "started"); break;
@@ -1246,12 +1282,12 @@ static void BIP9SoftForkDescPushBack(UniValue& softforks, const std::string &nam
}
bip9.pushKV("start_time", consensusParams.vDeployments[id].nStartTime);
bip9.pushKV("timeout", consensusParams.vDeployments[id].nTimeout);
- int64_t since_height = VersionBitsStateSinceHeight(::ChainActive().Tip(), consensusParams, id, versionbitscache);
+ int64_t since_height = VersionBitsStateSinceHeight(active_chain_tip, consensusParams, id, versionbitscache);
bip9.pushKV("since", since_height);
if (ThresholdState::STARTED == thresholdState)
{
UniValue statsUV(UniValue::VOBJ);
- BIP9Stats statsStruct = VersionBitsStatistics(::ChainActive().Tip(), consensusParams, id);
+ BIP9Stats statsStruct = VersionBitsStatistics(active_chain_tip, consensusParams, id);
statsUV.pushKV("period", statsStruct.period);
statsUV.pushKV("threshold", statsStruct.threshold);
statsUV.pushKV("elapsed", statsStruct.elapsed);
@@ -1328,18 +1364,22 @@ RPCHelpMan getblockchaininfo()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
+ ChainstateManager& chainman = EnsureAnyChainman(request.context);
LOCK(cs_main);
+ CChainState& active_chainstate = chainman.ActiveChainstate();
- const CBlockIndex* tip = ::ChainActive().Tip();
+ const CBlockIndex* tip = active_chainstate.m_chain.Tip();
+ CHECK_NONFATAL(tip);
+ const int height = tip->nHeight;
UniValue obj(UniValue::VOBJ);
obj.pushKV("chain", Params().NetworkIDString());
- obj.pushKV("blocks", (int)::ChainActive().Height());
+ obj.pushKV("blocks", height);
obj.pushKV("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1);
obj.pushKV("bestblockhash", tip->GetBlockHash().GetHex());
obj.pushKV("difficulty", (double)GetDifficulty(tip));
obj.pushKV("mediantime", (int64_t)tip->GetMedianTimePast());
obj.pushKV("verificationprogress", GuessVerificationProgress(Params().TxData(), tip));
- obj.pushKV("initialblockdownload", ::ChainstateActive().IsInitialBlockDownload());
+ obj.pushKV("initialblockdownload", active_chainstate.IsInitialBlockDownload());
obj.pushKV("chainwork", tip->nChainWork.GetHex());
obj.pushKV("size_on_disk", CalculateCurrentUsage());
obj.pushKV("pruned", fPruneMode);
@@ -1362,13 +1402,13 @@ RPCHelpMan getblockchaininfo()
const Consensus::Params& consensusParams = Params().GetConsensus();
UniValue softforks(UniValue::VOBJ);
- BuriedForkDescPushBack(softforks, "bip34", consensusParams.BIP34Height);
- BuriedForkDescPushBack(softforks, "bip66", consensusParams.BIP66Height);
- BuriedForkDescPushBack(softforks, "bip65", consensusParams.BIP65Height);
- BuriedForkDescPushBack(softforks, "csv", consensusParams.CSVHeight);
- BuriedForkDescPushBack(softforks, "segwit", consensusParams.SegwitHeight);
- BIP9SoftForkDescPushBack(softforks, "testdummy", consensusParams, Consensus::DEPLOYMENT_TESTDUMMY);
- BIP9SoftForkDescPushBack(softforks, "taproot", consensusParams, Consensus::DEPLOYMENT_TAPROOT);
+ BuriedForkDescPushBack(softforks, "bip34", consensusParams.BIP34Height, height);
+ BuriedForkDescPushBack(softforks, "bip66", consensusParams.BIP66Height, height);
+ BuriedForkDescPushBack(softforks, "bip65", consensusParams.BIP65Height, height);
+ BuriedForkDescPushBack(softforks, "csv", consensusParams.CSVHeight, height);
+ BuriedForkDescPushBack(softforks, "segwit", consensusParams.SegwitHeight, height);
+ BIP9SoftForkDescPushBack(tip, softforks, "testdummy", consensusParams, Consensus::DEPLOYMENT_TESTDUMMY);
+ BIP9SoftForkDescPushBack(tip, softforks, "taproot", consensusParams, Consensus::DEPLOYMENT_TAPROOT);
obj.pushKV("softforks", softforks);
obj.pushKV("warnings", GetWarnings(false).original);
@@ -1419,8 +1459,9 @@ static RPCHelpMan getchaintips()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- ChainstateManager& chainman = EnsureChainman(request.context);
+ ChainstateManager& chainman = EnsureAnyChainman(request.context);
LOCK(cs_main);
+ CChain& active_chain = chainman.ActiveChain();
/*
* Idea: The set of chain tips is the active chain tip, plus orphan blocks which do not have another orphan building off of them.
@@ -1434,7 +1475,7 @@ static RPCHelpMan getchaintips()
std::set<const CBlockIndex*> setPrevs;
for (const std::pair<const uint256, CBlockIndex*>& item : chainman.BlockIndex()) {
- if (!chainman.ActiveChain().Contains(item.second)) {
+ if (!active_chain.Contains(item.second)) {
setOrphans.insert(item.second);
setPrevs.insert(item.second->pprev);
}
@@ -1447,7 +1488,7 @@ static RPCHelpMan getchaintips()
}
// Always report the currently active tip.
- setTips.insert(chainman.ActiveChain().Tip());
+ setTips.insert(active_chain.Tip());
/* Construct the output array. */
UniValue res(UniValue::VARR);
@@ -1456,11 +1497,11 @@ static RPCHelpMan getchaintips()
obj.pushKV("height", block->nHeight);
obj.pushKV("hash", block->phashBlock->GetHex());
- const int branchLen = block->nHeight - chainman.ActiveChain().FindFork(block)->nHeight;
+ const int branchLen = block->nHeight - active_chain.FindFork(block)->nHeight;
obj.pushKV("branchlen", branchLen);
std::string status;
- if (chainman.ActiveChain().Contains(block)) {
+ if (active_chain.Contains(block)) {
// This block is part of the currently active chain.
status = "active";
} else if (block->nStatus & BLOCK_FAILED_MASK) {
@@ -1531,7 +1572,7 @@ static RPCHelpMan getmempoolinfo()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- return MempoolInfoToJSON(EnsureMemPool(request.context));
+ return MempoolInfoToJSON(EnsureAnyMemPool(request.context));
},
};
}
@@ -1555,16 +1596,17 @@ static RPCHelpMan preciousblock()
uint256 hash(ParseHashV(request.params[0], "blockhash"));
CBlockIndex* pblockindex;
+ ChainstateManager& chainman = EnsureAnyChainman(request.context);
{
LOCK(cs_main);
- pblockindex = g_chainman.m_blockman.LookupBlockIndex(hash);
+ pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
if (!pblockindex) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
}
}
BlockValidationState state;
- ::ChainstateActive().PreciousBlock(state, Params(), pblockindex);
+ chainman.ActiveChainstate().PreciousBlock(state, Params(), pblockindex);
if (!state.IsValid()) {
throw JSONRPCError(RPC_DATABASE_ERROR, state.ToString());
@@ -1592,18 +1634,19 @@ static RPCHelpMan invalidateblock()
uint256 hash(ParseHashV(request.params[0], "blockhash"));
BlockValidationState state;
+ ChainstateManager& chainman = EnsureAnyChainman(request.context);
CBlockIndex* pblockindex;
{
LOCK(cs_main);
- pblockindex = g_chainman.m_blockman.LookupBlockIndex(hash);
+ pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
if (!pblockindex) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
}
}
- ::ChainstateActive().InvalidateBlock(state, Params(), pblockindex);
+ chainman.ActiveChainstate().InvalidateBlock(state, Params(), pblockindex);
if (state.IsValid()) {
- ::ChainstateActive().ActivateBestChain(state, Params());
+ chainman.ActiveChainstate().ActivateBestChain(state, Params());
}
if (!state.IsValid()) {
@@ -1630,20 +1673,21 @@ static RPCHelpMan reconsiderblock()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
+ ChainstateManager& chainman = EnsureAnyChainman(request.context);
uint256 hash(ParseHashV(request.params[0], "blockhash"));
{
LOCK(cs_main);
- CBlockIndex* pblockindex = g_chainman.m_blockman.LookupBlockIndex(hash);
+ CBlockIndex* pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
if (!pblockindex) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
}
- ::ChainstateActive().ResetBlockFailureFlags(pblockindex);
+ chainman.ActiveChainstate().ResetBlockFailureFlags(pblockindex);
}
BlockValidationState state;
- ::ChainstateActive().ActivateBestChain(state, Params());
+ chainman.ActiveChainstate().ActivateBestChain(state, Params());
if (!state.IsValid()) {
throw JSONRPCError(RPC_DATABASE_ERROR, state.ToString());
@@ -1680,20 +1724,21 @@ static RPCHelpMan getchaintxstats()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
+ ChainstateManager& chainman = EnsureAnyChainman(request.context);
const CBlockIndex* pindex;
int blockcount = 30 * 24 * 60 * 60 / Params().GetConsensus().nPowTargetSpacing; // By default: 1 month
if (request.params[1].isNull()) {
LOCK(cs_main);
- pindex = ::ChainActive().Tip();
+ pindex = chainman.ActiveChain().Tip();
} else {
uint256 hash(ParseHashV(request.params[1], "blockhash"));
LOCK(cs_main);
- pindex = g_chainman.m_blockman.LookupBlockIndex(hash);
+ pindex = chainman.m_blockman.LookupBlockIndex(hash);
if (!pindex) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
}
- if (!::ChainActive().Contains(pindex)) {
+ if (!chainman.ActiveChain().Contains(pindex)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block is not in main chain");
}
}
@@ -1861,12 +1906,14 @@ static RPCHelpMan getblockstats()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
+ ChainstateManager& chainman = EnsureAnyChainman(request.context);
LOCK(cs_main);
+ CChain& active_chain = chainman.ActiveChain();
CBlockIndex* pindex;
if (request.params[0].isNum()) {
const int height = request.params[0].get_int();
- const int current_tip = ::ChainActive().Height();
+ const int current_tip = active_chain.Height();
if (height < 0) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Target block height %d is negative", height));
}
@@ -1874,14 +1921,14 @@ static RPCHelpMan getblockstats()
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Target block height %d after current tip %d", height, current_tip));
}
- pindex = ::ChainActive()[height];
+ pindex = active_chain[height];
} else {
const uint256 hash(ParseHashV(request.params[0], "hash_or_height"));
- pindex = g_chainman.m_blockman.LookupBlockIndex(hash);
+ pindex = chainman.m_blockman.LookupBlockIndex(hash);
if (!pindex) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
}
- if (!::ChainActive().Contains(pindex)) {
+ if (!active_chain.Contains(pindex)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Block is not in chain %s", Params().NetworkIDString()));
}
}
@@ -2072,7 +2119,7 @@ static RPCHelpMan savemempool()
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
- const CTxMemPool& mempool = EnsureMemPool(request.context);
+ const CTxMemPool& mempool = EnsureAnyMemPool(request.context);
if (!mempool.IsLoaded()) {
throw JSONRPCError(RPC_MISC_ERROR, "The mempool was not loaded yet");
@@ -2262,15 +2309,17 @@ static RPCHelpMan scantxoutset()
int64_t count = 0;
std::unique_ptr<CCoinsViewCursor> pcursor;
CBlockIndex* tip;
+ NodeContext& node = EnsureAnyNodeContext(request.context);
{
+ ChainstateManager& chainman = EnsureChainman(node);
LOCK(cs_main);
- ::ChainstateActive().ForceFlushStateToDisk();
- pcursor = std::unique_ptr<CCoinsViewCursor>(::ChainstateActive().CoinsDB().Cursor());
+ CChainState& active_chainstate = chainman.ActiveChainstate();
+ active_chainstate.ForceFlushStateToDisk();
+ pcursor = std::unique_ptr<CCoinsViewCursor>(active_chainstate.CoinsDB().Cursor());
CHECK_NONFATAL(pcursor);
- tip = ::ChainActive().Tip();
+ tip = active_chainstate.m_chain.Tip();
CHECK_NONFATAL(tip);
}
- NodeContext& node = EnsureNodeContext(request.context);
bool res = FindScriptPubKey(g_scan_progress, g_should_abort_scan, count, pcursor.get(), needles, coins, node.rpc_interruption_point);
result.pushKV("success", res);
result.pushKV("txouts", count);
@@ -2343,8 +2392,9 @@ static RPCHelpMan getblockfilter()
const CBlockIndex* block_index;
bool block_was_connected;
{
+ ChainstateManager& chainman = EnsureAnyChainman(request.context);
LOCK(cs_main);
- block_index = g_chainman.m_blockman.LookupBlockIndex(block_hash);
+ block_index = chainman.m_blockman.LookupBlockIndex(block_hash);
if (!block_index) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
}
@@ -2427,7 +2477,7 @@ static RPCHelpMan dumptxoutset()
FILE* file{fsbridge::fopen(temppath, "wb")};
CAutoFile afile{file, SER_DISK, CLIENT_VERSION};
- NodeContext& node = EnsureNodeContext(request.context);
+ NodeContext& node = EnsureAnyNodeContext(request.context);
UniValue result = CreateUTXOSnapshot(node, node.chainman->ActiveChainstate(), afile);
fs::rename(temppath, path);
@@ -2465,7 +2515,7 @@ UniValue CreateUTXOSnapshot(NodeContext& node, CChainState& chainstate, CAutoFil
}
pcursor = std::unique_ptr<CCoinsViewCursor>(chainstate.CoinsDB().Cursor());
- tip = g_chainman.m_blockman.LookupBlockIndex(stats.hashBlock);
+ tip = chainstate.m_blockman.LookupBlockIndex(stats.hashBlock);
CHECK_NONFATAL(tip);
}