aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/init.cpp36
-rw-r--r--src/net_processing.cpp25
-rw-r--r--src/net_processing.h4
-rw-r--r--src/node/context.h9
-rw-r--r--src/rpc/blockchain.cpp6
-rw-r--r--src/rpc/blockchain.h2
-rw-r--r--src/rpc/mining.cpp21
-rw-r--r--src/test/blockfilter_index_tests.cpp8
-rw-r--r--src/test/denialofservice_tests.cpp10
-rw-r--r--src/test/fuzz/process_message.cpp4
-rw-r--r--src/test/miner_tests.cpp2
-rw-r--r--src/test/util/mining.cpp2
-rw-r--r--src/test/util/setup_common.cpp10
-rw-r--r--src/test/validation_block_tests.cpp14
-rw-r--r--src/validation.cpp47
-rw-r--r--src/validation.h89
-rw-r--r--src/wallet/test/wallet_tests.cpp6
17 files changed, 161 insertions, 134 deletions
diff --git a/src/init.cpp b/src/init.cpp
index 025ae06520..37e6251295 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -244,9 +244,9 @@ void Shutdown(NodeContext& node)
}
// FlushStateToDisk generates a ChainStateFlushed callback, which we should avoid missing
- {
+ if (node.chainman) {
LOCK(cs_main);
- for (CChainState* chainstate : g_chainman.GetAll()) {
+ for (CChainState* chainstate : node.chainman->GetAll()) {
if (chainstate->CanFlushToDisk()) {
chainstate->ForceFlushStateToDisk();
}
@@ -271,9 +271,9 @@ void Shutdown(NodeContext& node)
// up with our current chain to avoid any strange pruning edge cases and make
// next startup faster by avoiding rescan.
- {
+ if (node.chainman) {
LOCK(cs_main);
- for (CChainState* chainstate : g_chainman.GetAll()) {
+ for (CChainState* chainstate : node.chainman->GetAll()) {
if (chainstate->CanFlushToDisk()) {
chainstate->ForceFlushStateToDisk();
chainstate->ResetCoinsViews();
@@ -299,7 +299,8 @@ void Shutdown(NodeContext& node)
globalVerifyHandle.reset();
ECC_Stop();
node.args = nullptr;
- if (node.mempool) node.mempool = nullptr;
+ node.mempool = nullptr;
+ node.chainman = nullptr;
node.scheduler.reset();
try {
@@ -689,7 +690,7 @@ static void CleanupBlockRevFiles()
}
}
-static void ThreadImport(std::vector<fs::path> vImportFiles)
+static void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles)
{
const CChainParams& chainparams = Params();
util::ThreadRename("loadblk");
@@ -741,9 +742,9 @@ static void ThreadImport(std::vector<fs::path> vImportFiles)
// scan for better chains in the block chain database, that are not yet connected in the active best chain
// We can't hold cs_main during ActivateBestChain even though we're accessing
- // the g_chainman unique_ptrs since ABC requires us not to be holding cs_main, so retrieve
+ // the chainman unique_ptrs since ABC requires us not to be holding cs_main, so retrieve
// the relevant pointers before the ABC call.
- for (CChainState* chainstate : WITH_LOCK(::cs_main, return g_chainman.GetAll())) {
+ for (CChainState* chainstate : WITH_LOCK(::cs_main, return chainman.GetAll())) {
BlockValidationState state;
if (!chainstate->ActivateBestChain(state, chainparams, nullptr)) {
LogPrintf("Failed to connect best block (%s)\n", state.ToString());
@@ -1377,8 +1378,11 @@ bool AppInitMain(const util::Ref& context, NodeContext& node)
// which are all started after this, may use it from the node context.
assert(!node.mempool);
node.mempool = &::mempool;
+ assert(!node.chainman);
+ node.chainman = &g_chainman;
+ ChainstateManager& chainman = EnsureChainman(node);
- node.peer_logic.reset(new PeerLogicValidation(node.connman.get(), node.banman.get(), *node.scheduler, *node.mempool));
+ node.peer_logic.reset(new PeerLogicValidation(node.connman.get(), node.banman.get(), *node.scheduler, *node.chainman, *node.mempool));
RegisterValidationInterface(node.peer_logic.get());
// sanitize comments per BIP-0014, format user agent and check total size
@@ -1557,7 +1561,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node)
const int64_t load_block_index_start_time = GetTimeMillis();
try {
LOCK(cs_main);
- g_chainman.InitializeChainstate();
+ chainman.InitializeChainstate();
UnloadBlockIndex();
// new CBlockTreeDB tries to delete the existing file, which
@@ -1578,7 +1582,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node)
// block file from disk.
// Note that it also sets fReindex based on the disk flag!
// From here on out fReindex and fReset mean something different!
- if (!LoadBlockIndex(chainparams)) {
+ if (!chainman.LoadBlockIndex(chainparams)) {
if (ShutdownRequested()) break;
strLoadError = _("Error loading block database");
break;
@@ -1612,7 +1616,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node)
bool failed_chainstate_init = false;
- for (CChainState* chainstate : g_chainman.GetAll()) {
+ for (CChainState* chainstate : chainman.GetAll()) {
LogPrintf("Initializing chainstate %s\n", chainstate->ToString());
chainstate->InitCoinsDB(
/* cache_size_bytes */ nCoinDBCache,
@@ -1667,7 +1671,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node)
bool failed_rewind{false};
// Can't hold cs_main while calling RewindBlockIndex, so retrieve the relevant
// chainstates beforehand.
- for (CChainState* chainstate : WITH_LOCK(::cs_main, return g_chainman.GetAll())) {
+ for (CChainState* chainstate : WITH_LOCK(::cs_main, return chainman.GetAll())) {
if (!fReset) {
// Note that RewindBlockIndex MUST run even if we're about to -reindex-chainstate.
// It both disconnects blocks based on the chainstate, and drops block data in
@@ -1692,7 +1696,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node)
try {
LOCK(cs_main);
- for (CChainState* chainstate : g_chainman.GetAll()) {
+ for (CChainState* chainstate : chainman.GetAll()) {
if (!is_coinsview_empty(chainstate)) {
uiInterface.InitMessage(_("Verifying blocks...").translated);
if (fHavePruned && gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS) > MIN_BLOCKS_TO_KEEP) {
@@ -1798,7 +1802,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node)
nLocalServices = ServiceFlags(nLocalServices & ~NODE_NETWORK);
if (!fReindex) {
LOCK(cs_main);
- for (CChainState* chainstate : g_chainman.GetAll()) {
+ for (CChainState* chainstate : chainman.GetAll()) {
uiInterface.InitMessage(_("Pruning blockstore...").translated);
chainstate->PruneAndFlush();
}
@@ -1841,7 +1845,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node)
vImportFiles.push_back(strFile);
}
- threadGroup.create_thread(std::bind(&ThreadImport, vImportFiles));
+ threadGroup.create_thread([=, &chainman] { ThreadImport(chainman, vImportFiles); });
// Wait for genesis block to be processed
{
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index ac5300990f..d0e345c30e 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -1153,9 +1153,10 @@ static bool BlockRequestAllowed(const CBlockIndex* pindex, const Consensus::Para
(GetBlockProofEquivalentTime(*pindexBestHeader, *pindex, *pindexBestHeader, consensusParams) < STALE_RELAY_AGE_LIMIT);
}
-PeerLogicValidation::PeerLogicValidation(CConnman* connmanIn, BanMan* banman, CScheduler& scheduler, CTxMemPool& pool)
+PeerLogicValidation::PeerLogicValidation(CConnman* connmanIn, BanMan* banman, CScheduler& scheduler, ChainstateManager& chainman, CTxMemPool& pool)
: connman(connmanIn),
m_banman(banman),
+ m_chainman(chainman),
m_mempool(pool),
m_stale_tip_check_time(0)
{
@@ -1738,7 +1739,7 @@ inline void static SendBlockTransactions(const CBlock& block, const BlockTransac
connman->PushMessage(pfrom, msgMaker.Make(nSendFlags, NetMsgType::BLOCKTXN, resp));
}
-bool static ProcessHeadersMessage(CNode* pfrom, CConnman* connman, CTxMemPool& mempool, const std::vector<CBlockHeader>& headers, const CChainParams& chainparams, bool via_compact_block)
+bool static ProcessHeadersMessage(CNode* pfrom, CConnman* connman, ChainstateManager& chainman, CTxMemPool& mempool, const std::vector<CBlockHeader>& headers, const CChainParams& chainparams, bool via_compact_block)
{
const CNetMsgMaker msgMaker(pfrom->GetSendVersion());
size_t nCount = headers.size();
@@ -1798,7 +1799,7 @@ bool static ProcessHeadersMessage(CNode* pfrom, CConnman* connman, CTxMemPool& m
}
BlockValidationState state;
- if (!ProcessNewBlockHeaders(headers, state, chainparams, &pindexLast)) {
+ if (!chainman.ProcessNewBlockHeaders(headers, state, chainparams, &pindexLast)) {
if (state.IsInvalid()) {
MaybePunishNodeForBlock(pfrom->GetId(), state, via_compact_block, "invalid header received");
return false;
@@ -2081,7 +2082,7 @@ static void ProcessGetCFCheckPt(CNode* pfrom, CDataStream& vRecv, const CChainPa
connman->PushMessage(pfrom, std::move(msg));
}
-bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, CTxMemPool& mempool, CConnman* connman, BanMan* banman, const std::atomic<bool>& interruptMsgProc)
+bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, ChainstateManager& chainman, CTxMemPool& mempool, CConnman* connman, BanMan* banman, const std::atomic<bool>& interruptMsgProc)
{
LogPrint(BCLog::NET, "received: %s (%u bytes) peer=%d\n", SanitizeString(msg_type), vRecv.size(), pfrom->GetId());
if (gArgs.IsArgSet("-dropmessagestest") && GetRand(gArgs.GetArg("-dropmessagestest", 0)) == 0)
@@ -2848,7 +2849,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
const CBlockIndex *pindex = nullptr;
BlockValidationState state;
- if (!ProcessNewBlockHeaders({cmpctblock.header}, state, chainparams, &pindex)) {
+ if (!chainman.ProcessNewBlockHeaders({cmpctblock.header}, state, chainparams, &pindex)) {
if (state.IsInvalid()) {
MaybePunishNodeForBlock(pfrom->GetId(), state, /*via_compact_block*/ true, "invalid header via cmpctblock");
return true;
@@ -2992,7 +2993,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
} // cs_main
if (fProcessBLOCKTXN)
- return ProcessMessage(pfrom, NetMsgType::BLOCKTXN, blockTxnMsg, nTimeReceived, chainparams, mempool, connman, banman, interruptMsgProc);
+ return ProcessMessage(pfrom, NetMsgType::BLOCKTXN, blockTxnMsg, nTimeReceived, chainparams, chainman, mempool, connman, banman, interruptMsgProc);
if (fRevertToHeaderProcessing) {
// Headers received from HB compact block peers are permitted to be
@@ -3000,7 +3001,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
// the peer if the header turns out to be for an invalid block.
// Note that if a peer tries to build on an invalid chain, that
// will be detected and the peer will be banned.
- return ProcessHeadersMessage(pfrom, connman, mempool, {cmpctblock.header}, chainparams, /*via_compact_block=*/true);
+ return ProcessHeadersMessage(pfrom, connman, chainman, mempool, {cmpctblock.header}, chainparams, /*via_compact_block=*/true);
}
if (fBlockReconstructed) {
@@ -3020,7 +3021,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
// we have a chain with at least nMinimumChainWork), and we ignore
// compact blocks with less work than our tip, it is safe to treat
// reconstructed compact blocks as having been requested.
- ProcessNewBlock(chainparams, pblock, /*fForceProcessing=*/true, &fNewBlock);
+ chainman.ProcessNewBlock(chainparams, pblock, /*fForceProcessing=*/true, &fNewBlock);
if (fNewBlock) {
pfrom->nLastBlockTime = GetTime();
} else {
@@ -3110,7 +3111,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
// disk-space attacks), but this should be safe due to the
// protections in the compact block handler -- see related comment
// in compact block optimistic reconstruction handling.
- ProcessNewBlock(chainparams, pblock, /*fForceProcessing=*/true, &fNewBlock);
+ chainman.ProcessNewBlock(chainparams, pblock, /*fForceProcessing=*/true, &fNewBlock);
if (fNewBlock) {
pfrom->nLastBlockTime = GetTime();
} else {
@@ -3144,7 +3145,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
}
- return ProcessHeadersMessage(pfrom, connman, mempool, headers, chainparams, /*via_compact_block=*/false);
+ return ProcessHeadersMessage(pfrom, connman, chainman, mempool, headers, chainparams, /*via_compact_block=*/false);
}
if (msg_type == NetMsgType::BLOCK)
@@ -3173,7 +3174,7 @@ bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRec
mapBlockSource.emplace(hash, std::make_pair(pfrom->GetId(), true));
}
bool fNewBlock = false;
- ProcessNewBlock(chainparams, pblock, forceProcessing, &fNewBlock);
+ chainman.ProcessNewBlock(chainparams, pblock, forceProcessing, &fNewBlock);
if (fNewBlock) {
pfrom->nLastBlockTime = GetTime();
} else {
@@ -3534,7 +3535,7 @@ bool PeerLogicValidation::ProcessMessages(CNode* pfrom, std::atomic<bool>& inter
bool fRet = false;
try
{
- fRet = ProcessMessage(pfrom, msg_type, vRecv, msg.m_time, chainparams, m_mempool, connman, m_banman, interruptMsgProc);
+ fRet = ProcessMessage(pfrom, msg_type, vRecv, msg.m_time, chainparams, m_chainman, m_mempool, connman, m_banman, interruptMsgProc);
if (interruptMsgProc)
return false;
if (!pfrom->vRecvGetData.empty())
diff --git a/src/net_processing.h b/src/net_processing.h
index 4033c85d07..ec758c7537 100644
--- a/src/net_processing.h
+++ b/src/net_processing.h
@@ -12,6 +12,7 @@
#include <validationinterface.h>
class CTxMemPool;
+class ChainstateManager;
extern RecursiveMutex cs_main;
extern RecursiveMutex g_cs_orphans;
@@ -27,12 +28,13 @@ class PeerLogicValidation final : public CValidationInterface, public NetEventsI
private:
CConnman* const connman;
BanMan* const m_banman;
+ ChainstateManager& m_chainman;
CTxMemPool& m_mempool;
bool CheckIfBanned(CNode* pnode) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
public:
- PeerLogicValidation(CConnman* connman, BanMan* banman, CScheduler& scheduler, CTxMemPool& pool);
+ PeerLogicValidation(CConnman* connman, BanMan* banman, CScheduler& scheduler, ChainstateManager& chainman, CTxMemPool& pool);
/**
* Overridden from CValidationInterface.
diff --git a/src/node/context.h b/src/node/context.h
index 566ff170be..c45d9e6689 100644
--- a/src/node/context.h
+++ b/src/node/context.h
@@ -5,6 +5,7 @@
#ifndef BITCOIN_NODE_CONTEXT_H
#define BITCOIN_NODE_CONTEXT_H
+#include <cassert>
#include <memory>
#include <vector>
@@ -13,6 +14,7 @@ class BanMan;
class CConnman;
class CScheduler;
class CTxMemPool;
+class ChainstateManager;
class PeerLogicValidation;
namespace interfaces {
class Chain;
@@ -33,6 +35,7 @@ struct NodeContext {
std::unique_ptr<CConnman> connman;
CTxMemPool* mempool{nullptr}; // Currently a raw pointer because the memory is not managed by this struct
std::unique_ptr<PeerLogicValidation> peer_logic;
+ ChainstateManager* chainman{nullptr}; // Currently a raw pointer because the memory is not managed by this struct
std::unique_ptr<BanMan> banman;
ArgsManager* args{nullptr}; // Currently a raw pointer because the memory is not managed by this struct
std::unique_ptr<interfaces::Chain> chain;
@@ -46,4 +49,10 @@ struct NodeContext {
~NodeContext();
};
+inline ChainstateManager& EnsureChainman(const NodeContext& node)
+{
+ assert(node.chainman);
+ return *node.chainman;
+}
+
#endif // BITCOIN_NODE_CONTEXT_H
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index ac567e16ce..717ca308ac 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -71,6 +71,12 @@ CTxMemPool& EnsureMemPool(const util::Ref& context)
return *node.mempool;
}
+ChainstateManager& EnsureChainman(const util::Ref& context)
+{
+ NodeContext& node = EnsureNodeContext(context);
+ return EnsureChainman(node);
+}
+
/* Calculate the difficulty for a given block index.
*/
double GetDifficulty(const CBlockIndex* blockindex)
diff --git a/src/rpc/blockchain.h b/src/rpc/blockchain.h
index 453d0bc650..5c9a43b13e 100644
--- a/src/rpc/blockchain.h
+++ b/src/rpc/blockchain.h
@@ -16,6 +16,7 @@ extern RecursiveMutex cs_main;
class CBlock;
class CBlockIndex;
class CTxMemPool;
+class ChainstateManager;
class UniValue;
struct NodeContext;
namespace util {
@@ -52,5 +53,6 @@ void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES],
NodeContext& EnsureNodeContext(const util::Ref& context);
CTxMemPool& EnsureMemPool(const util::Ref& context);
+ChainstateManager& EnsureChainman(const util::Ref& context);
#endif
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index bcaed1ef88..3612f14bbf 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -101,7 +101,7 @@ static UniValue getnetworkhashps(const JSONRPCRequest& request)
return GetNetworkHashPS(!request.params[0].isNull() ? request.params[0].get_int() : 120, !request.params[1].isNull() ? request.params[1].get_int() : -1);
}
-static bool GenerateBlock(CBlock& block, uint64_t& max_tries, unsigned int& extra_nonce, uint256& block_hash)
+static bool GenerateBlock(ChainstateManager& chainman, CBlock& block, uint64_t& max_tries, unsigned int& extra_nonce, uint256& block_hash)
{
block_hash.SetNull();
@@ -124,14 +124,15 @@ static bool GenerateBlock(CBlock& block, uint64_t& max_tries, unsigned int& extr
}
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
- if (!ProcessNewBlock(chainparams, shared_pblock, true, nullptr))
+ if (!chainman.ProcessNewBlock(chainparams, shared_pblock, true, nullptr)) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
+ }
block_hash = block.GetHash();
return true;
}
-static UniValue generateBlocks(const CTxMemPool& mempool, const CScript& coinbase_script, int nGenerate, uint64_t nMaxTries)
+static UniValue generateBlocks(ChainstateManager& chainman, const CTxMemPool& mempool, const CScript& coinbase_script, int nGenerate, uint64_t nMaxTries)
{
int nHeightEnd = 0;
int nHeight = 0;
@@ -151,7 +152,7 @@ static UniValue generateBlocks(const CTxMemPool& mempool, const CScript& coinbas
CBlock *pblock = &pblocktemplate->block;
uint256 block_hash;
- if (!GenerateBlock(*pblock, nMaxTries, nExtraNonce, block_hash)) {
+ if (!GenerateBlock(chainman, *pblock, nMaxTries, nExtraNonce, block_hash)) {
break;
}
@@ -228,8 +229,9 @@ static UniValue generatetodescriptor(const JSONRPCRequest& request)
}
const CTxMemPool& mempool = EnsureMemPool(request.context);
+ ChainstateManager& chainman = EnsureChainman(request.context);
- return generateBlocks(mempool, coinbase_script, num_blocks, max_tries);
+ return generateBlocks(chainman, mempool, coinbase_script, num_blocks, max_tries);
}
static UniValue generatetoaddress(const JSONRPCRequest& request)
@@ -266,10 +268,11 @@ static UniValue generatetoaddress(const JSONRPCRequest& request)
}
const CTxMemPool& mempool = EnsureMemPool(request.context);
+ ChainstateManager& chainman = EnsureChainman(request.context);
CScript coinbase_script = GetScriptForDestination(destination);
- return generateBlocks(mempool, coinbase_script, nGenerate, nMaxTries);
+ return generateBlocks(chainman, mempool, coinbase_script, nGenerate, nMaxTries);
}
static UniValue generateblock(const JSONRPCRequest& request)
@@ -370,7 +373,7 @@ static UniValue generateblock(const JSONRPCRequest& request)
uint64_t max_tries{1000000};
unsigned int extra_nonce{0};
- if (!GenerateBlock(block, max_tries, extra_nonce, block_hash) || block_hash.IsNull()) {
+ if (!GenerateBlock(EnsureChainman(request.context), block, max_tries, extra_nonce, block_hash) || block_hash.IsNull()) {
throw JSONRPCError(RPC_MISC_ERROR, "Failed to make block.");
}
@@ -947,7 +950,7 @@ static UniValue submitblock(const JSONRPCRequest& request)
bool new_block;
auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
RegisterSharedValidationInterface(sc);
- bool accepted = ProcessNewBlock(Params(), blockptr, /* fForceProcessing */ true, /* fNewBlock */ &new_block);
+ bool accepted = EnsureChainman(request.context).ProcessNewBlock(Params(), blockptr, /* fForceProcessing */ true, /* fNewBlock */ &new_block);
UnregisterSharedValidationInterface(sc);
if (!new_block && accepted) {
return "duplicate";
@@ -986,7 +989,7 @@ static UniValue submitheader(const JSONRPCRequest& request)
}
BlockValidationState state;
- ProcessNewBlockHeaders({h}, state, Params());
+ EnsureChainman(request.context).ProcessNewBlockHeaders({h}, state, Params());
if (state.IsValid()) return NullUniValue;
if (state.IsError()) {
throw JSONRPCError(RPC_VERIFY_ERROR, state.ToString());
diff --git a/src/test/blockfilter_index_tests.cpp b/src/test/blockfilter_index_tests.cpp
index e5043f6816..7dff2e6e86 100644
--- a/src/test/blockfilter_index_tests.cpp
+++ b/src/test/blockfilter_index_tests.cpp
@@ -94,7 +94,7 @@ bool BuildChainTestingSetup::BuildChain(const CBlockIndex* pindex,
CBlockHeader header = block->GetBlockHeader();
BlockValidationState state;
- if (!ProcessNewBlockHeaders({header}, state, Params(), &pindex)) {
+ if (!EnsureChainman(m_node).ProcessNewBlockHeaders({header}, state, Params(), &pindex)) {
return false;
}
}
@@ -171,7 +171,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
uint256 chainA_last_header = last_header;
for (size_t i = 0; i < 2; i++) {
const auto& block = chainA[i];
- BOOST_REQUIRE(ProcessNewBlock(Params(), block, true, nullptr));
+ BOOST_REQUIRE(EnsureChainman(m_node).ProcessNewBlock(Params(), block, true, nullptr));
}
for (size_t i = 0; i < 2; i++) {
const auto& block = chainA[i];
@@ -189,7 +189,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
uint256 chainB_last_header = last_header;
for (size_t i = 0; i < 3; i++) {
const auto& block = chainB[i];
- BOOST_REQUIRE(ProcessNewBlock(Params(), block, true, nullptr));
+ BOOST_REQUIRE(EnsureChainman(m_node).ProcessNewBlock(Params(), block, true, nullptr));
}
for (size_t i = 0; i < 3; i++) {
const auto& block = chainB[i];
@@ -220,7 +220,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
// Reorg back to chain A.
for (size_t i = 2; i < 4; i++) {
const auto& block = chainA[i];
- BOOST_REQUIRE(ProcessNewBlock(Params(), block, true, nullptr));
+ BOOST_REQUIRE(EnsureChainman(m_node).ProcessNewBlock(Params(), block, true, nullptr));
}
// Check that chain A and B blocks can be retrieved.
diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp
index 75b38670c9..348b170536 100644
--- a/src/test/denialofservice_tests.cpp
+++ b/src/test/denialofservice_tests.cpp
@@ -78,7 +78,7 @@ BOOST_FIXTURE_TEST_SUITE(denialofservice_tests, TestingSetup)
BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
{
auto connman = MakeUnique<CConnman>(0x1337, 0x1337);
- auto peerLogic = MakeUnique<PeerLogicValidation>(connman.get(), nullptr, *m_node.scheduler, *m_node.mempool);
+ auto peerLogic = MakeUnique<PeerLogicValidation>(connman.get(), nullptr, *m_node.scheduler, *m_node.chainman, *m_node.mempool);
// Mock an outbound peer
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
@@ -148,7 +148,7 @@ static void AddRandomOutboundPeer(std::vector<CNode *> &vNodes, PeerLogicValidat
BOOST_AUTO_TEST_CASE(stale_tip_peer_management)
{
auto connman = MakeUnique<CConnmanTest>(0x1337, 0x1337);
- auto peerLogic = MakeUnique<PeerLogicValidation>(connman.get(), nullptr, *m_node.scheduler, *m_node.mempool);
+ auto peerLogic = MakeUnique<PeerLogicValidation>(connman.get(), nullptr, *m_node.scheduler, *m_node.chainman, *m_node.mempool);
const Consensus::Params& consensusParams = Params().GetConsensus();
constexpr int max_outbound_full_relay = MAX_OUTBOUND_FULL_RELAY_CONNECTIONS;
@@ -221,7 +221,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
{
auto banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
auto connman = MakeUnique<CConnman>(0x1337, 0x1337);
- auto peerLogic = MakeUnique<PeerLogicValidation>(connman.get(), banman.get(), *m_node.scheduler, *m_node.mempool);
+ auto peerLogic = MakeUnique<PeerLogicValidation>(connman.get(), banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool);
banman->ClearBanned();
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
@@ -276,7 +276,7 @@ BOOST_AUTO_TEST_CASE(DoS_banscore)
{
auto banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
auto connman = MakeUnique<CConnman>(0x1337, 0x1337);
- auto peerLogic = MakeUnique<PeerLogicValidation>(connman.get(), banman.get(), *m_node.scheduler, *m_node.mempool);
+ auto peerLogic = MakeUnique<PeerLogicValidation>(connman.get(), banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool);
banman->ClearBanned();
gArgs.ForceSetArg("-banscore", "111"); // because 11 is my favorite number
@@ -323,7 +323,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
{
auto banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
auto connman = MakeUnique<CConnman>(0x1337, 0x1337);
- auto peerLogic = MakeUnique<PeerLogicValidation>(connman.get(), banman.get(), *m_node.scheduler, *m_node.mempool);
+ auto peerLogic = MakeUnique<PeerLogicValidation>(connman.get(), banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool);
banman->ClearBanned();
int64_t nStartTime = GetTime();
diff --git a/src/test/fuzz/process_message.cpp b/src/test/fuzz/process_message.cpp
index c03365199a..665a6224b4 100644
--- a/src/test/fuzz/process_message.cpp
+++ b/src/test/fuzz/process_message.cpp
@@ -29,7 +29,7 @@
#include <string>
#include <vector>
-bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, CTxMemPool& mempool, CConnman* connman, BanMan* banman, const std::atomic<bool>& interruptMsgProc);
+bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, ChainstateManager& chainman, CTxMemPool& mempool, CConnman* connman, BanMan* banman, const std::atomic<bool>& interruptMsgProc);
namespace {
@@ -74,7 +74,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
p2p_node.SetSendVersion(PROTOCOL_VERSION);
g_setup->m_node.peer_logic->InitializeNode(&p2p_node);
try {
- (void)ProcessMessage(&p2p_node, random_message_type, random_bytes_data_stream, GetTimeMillis(), Params(), *g_setup->m_node.mempool, g_setup->m_node.connman.get(), g_setup->m_node.banman.get(), std::atomic<bool>{false});
+ (void)ProcessMessage(&p2p_node, random_message_type, random_bytes_data_stream, GetTimeMillis(), Params(), *g_setup->m_node.chainman, *g_setup->m_node.mempool, g_setup->m_node.connman.get(), g_setup->m_node.banman.get(), std::atomic<bool>{false});
} catch (const std::ios_base::failure&) {
}
SyncWithValidationInterfaceQueue();
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index 9f3ca87206..57eee94330 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -253,7 +253,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
pblock->nNonce = blockinfo[i].nonce;
}
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock);
- BOOST_CHECK(ProcessNewBlock(chainparams, shared_pblock, true, nullptr));
+ BOOST_CHECK(EnsureChainman(m_node).ProcessNewBlock(chainparams, shared_pblock, true, nullptr));
pblock->hashPrevBlock = pblock->GetHash();
}
diff --git a/src/test/util/mining.cpp b/src/test/util/mining.cpp
index 1df6844062..dac7f1a07b 100644
--- a/src/test/util/mining.cpp
+++ b/src/test/util/mining.cpp
@@ -31,7 +31,7 @@ CTxIn MineBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
assert(block->nNonce);
}
- bool processed{ProcessNewBlock(Params(), block, true, nullptr)};
+ bool processed{EnsureChainman(node).ProcessNewBlock(Params(), block, true, nullptr)};
assert(processed);
return CTxIn{block->vtx[0]->GetHash(), 0};
diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp
index 86dac55b2b..3b7a7c8d12 100644
--- a/src/test/util/setup_common.cpp
+++ b/src/test/util/setup_common.cpp
@@ -134,7 +134,8 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
pblocktree.reset(new CBlockTreeDB(1 << 20, true));
- g_chainman.InitializeChainstate();
+ m_node.chainman = &::g_chainman;
+ m_node.chainman->InitializeChainstate();
::ChainstateActive().InitCoinsDB(
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
assert(!::ChainstateActive().CanFlushToDisk());
@@ -160,7 +161,7 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
m_node.mempool->setSanityCheck(1.0);
m_node.banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
m_node.connman = MakeUnique<CConnman>(0x1337, 0x1337); // Deterministic randomness for tests.
- m_node.peer_logic = MakeUnique<PeerLogicValidation>(m_node.connman.get(), m_node.banman.get(), *m_node.scheduler, *m_node.mempool);
+ m_node.peer_logic = MakeUnique<PeerLogicValidation>(m_node.connman.get(), m_node.banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool);
{
CConnman::Options options;
options.m_msgproc = m_node.peer_logic.get();
@@ -181,7 +182,8 @@ TestingSetup::~TestingSetup()
m_node.mempool = nullptr;
m_node.scheduler.reset();
UnloadBlockIndex();
- g_chainman.Reset();
+ m_node.chainman->Reset();
+ m_node.chainman = nullptr;
pblocktree.reset();
}
@@ -226,7 +228,7 @@ CBlock TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransa
while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce;
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
- ProcessNewBlock(chainparams, shared_pblock, true, nullptr);
+ EnsureChainman(m_node).ProcessNewBlock(chainparams, shared_pblock, true, nullptr);
CBlock result = block;
return result;
diff --git a/src/test/validation_block_tests.cpp b/src/test/validation_block_tests.cpp
index 899f054b83..45e0c5484e 100644
--- a/src/test/validation_block_tests.cpp
+++ b/src/test/validation_block_tests.cpp
@@ -163,10 +163,10 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
std::transform(blocks.begin(), blocks.end(), std::back_inserter(headers), [](std::shared_ptr<const CBlock> b) { return b->GetBlockHeader(); });
// Process all the headers so we understand the toplogy of the chain
- BOOST_CHECK(ProcessNewBlockHeaders(headers, state, Params()));
+ BOOST_CHECK(EnsureChainman(m_node).ProcessNewBlockHeaders(headers, state, Params()));
// Connect the genesis block and drain any outstanding events
- BOOST_CHECK(ProcessNewBlock(Params(), std::make_shared<CBlock>(Params().GenesisBlock()), true, &ignored));
+ BOOST_CHECK(EnsureChainman(m_node).ProcessNewBlock(Params(), std::make_shared<CBlock>(Params().GenesisBlock()), true, &ignored));
SyncWithValidationInterfaceQueue();
// subscribe to events (this subscriber will validate event ordering)
@@ -183,18 +183,18 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
// will subscribe to events generated during block validation and assert on ordering invariance
std::vector<std::thread> threads;
for (int i = 0; i < 10; i++) {
- threads.emplace_back([&blocks]() {
+ threads.emplace_back([&]() {
bool ignored;
FastRandomContext insecure;
for (int i = 0; i < 1000; i++) {
auto block = blocks[insecure.randrange(blocks.size() - 1)];
- ProcessNewBlock(Params(), block, true, &ignored);
+ EnsureChainman(m_node).ProcessNewBlock(Params(), block, true, &ignored);
}
// to make sure that eventually we process the full chain - do it here
for (auto block : blocks) {
if (block->vtx.size() == 1) {
- bool processed = ProcessNewBlock(Params(), block, true, &ignored);
+ bool processed = EnsureChainman(m_node).ProcessNewBlock(Params(), block, true, &ignored);
assert(processed);
}
}
@@ -232,8 +232,8 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
BOOST_AUTO_TEST_CASE(mempool_locks_reorg)
{
bool ignored;
- auto ProcessBlock = [&ignored](std::shared_ptr<const CBlock> block) -> bool {
- return ProcessNewBlock(Params(), block, /* fForceProcessing */ true, /* fNewBlock */ &ignored);
+ auto ProcessBlock = [&](std::shared_ptr<const CBlock> block) -> bool {
+ return EnsureChainman(m_node).ProcessNewBlock(Params(), block, /* fForceProcessing */ true, /* fNewBlock */ &ignored);
};
// Process all mined blocks
diff --git a/src/validation.cpp b/src/validation.cpp
index a9dfa5c171..dbdf5028fd 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -196,8 +196,8 @@ CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& loc
std::unique_ptr<CBlockTreeDB> pblocktree;
// See definition for documentation
-static void FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nManualPruneHeight);
-static void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight);
+static void FindFilesToPruneManual(ChainstateManager& chainman, std::set<int>& setFilesToPrune, int nManualPruneHeight);
+static void FindFilesToPrune(ChainstateManager& chainman, std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight);
bool CheckInputScripts(const CTransaction& tx, TxValidationState &state, const CCoinsViewCache &inputs, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks = nullptr);
static FILE* OpenUndoFile(const FlatFilePos &pos, bool fReadOnly = false);
static FlatFileSeq BlockFileSeq();
@@ -2282,11 +2282,11 @@ bool CChainState::FlushStateToDisk(
if (nManualPruneHeight > 0) {
LOG_TIME_MILLIS_WITH_CATEGORY("find files to prune (manual)", BCLog::BENCH);
- FindFilesToPruneManual(setFilesToPrune, nManualPruneHeight);
+ FindFilesToPruneManual(g_chainman, setFilesToPrune, nManualPruneHeight);
} else {
LOG_TIME_MILLIS_WITH_CATEGORY("find files to prune", BCLog::BENCH);
- FindFilesToPrune(setFilesToPrune, chainparams.PruneAfterHeight());
+ FindFilesToPrune(g_chainman, setFilesToPrune, chainparams.PruneAfterHeight());
fCheckForPruning = false;
}
if (!setFilesToPrune.empty()) {
@@ -3691,13 +3691,14 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationS
}
// Exposed wrapper for AcceptBlockHeader
-bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, BlockValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex)
+bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>& headers, BlockValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex)
{
+ AssertLockNotHeld(cs_main);
{
LOCK(cs_main);
for (const CBlockHeader& header : headers) {
CBlockIndex *pindex = nullptr; // Use a temp pindex instead of ppindex to avoid a const_cast
- bool accepted = g_chainman.m_blockman.AcceptBlockHeader(
+ bool accepted = m_blockman.AcceptBlockHeader(
header, state, chainparams, &pindex);
::ChainstateActive().CheckBlockIndex(chainparams.GetConsensus());
@@ -3819,7 +3820,7 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
return true;
}
-bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock> pblock, bool fForceProcessing, bool *fNewBlock)
+bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock> pblock, bool fForceProcessing, bool* fNewBlock)
{
AssertLockNotHeld(cs_main);
@@ -3895,12 +3896,12 @@ uint64_t CalculateCurrentUsage()
return retval;
}
-/* Prune a block file (modify associated database entries)*/
-void PruneOneBlockFile(const int fileNumber)
+void ChainstateManager::PruneOneBlockFile(const int fileNumber)
{
+ AssertLockHeld(cs_main);
LOCK(cs_LastBlockFile);
- for (const auto& entry : g_chainman.BlockIndex()) {
+ for (const auto& entry : m_blockman.m_block_index) {
CBlockIndex* pindex = entry.second;
if (pindex->nFile == fileNumber) {
pindex->nStatus &= ~BLOCK_HAVE_DATA;
@@ -3914,12 +3915,12 @@ void PruneOneBlockFile(const int fileNumber)
// to be downloaded again in order to consider its chain, at which
// point it would be considered as a candidate for
// m_blocks_unlinked or setBlockIndexCandidates.
- auto range = g_chainman.m_blockman.m_blocks_unlinked.equal_range(pindex->pprev);
+ auto range = m_blockman.m_blocks_unlinked.equal_range(pindex->pprev);
while (range.first != range.second) {
std::multimap<CBlockIndex *, CBlockIndex *>::iterator _it = range.first;
range.first++;
if (_it->second == pindex) {
- g_chainman.m_blockman.m_blocks_unlinked.erase(_it);
+ m_blockman.m_blocks_unlinked.erase(_it);
}
}
}
@@ -3941,7 +3942,7 @@ void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune)
}
/* Calculate the block/rev files to delete based on height specified by user with RPC command pruneblockchain */
-static void FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nManualPruneHeight)
+static void FindFilesToPruneManual(ChainstateManager& chainman, std::set<int>& setFilesToPrune, int nManualPruneHeight)
{
assert(fPruneMode && nManualPruneHeight > 0);
@@ -3955,7 +3956,7 @@ static void FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nManualPr
for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) {
if (vinfoBlockFile[fileNumber].nSize == 0 || vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune)
continue;
- PruneOneBlockFile(fileNumber);
+ chainman.PruneOneBlockFile(fileNumber);
setFilesToPrune.insert(fileNumber);
count++;
}
@@ -3988,7 +3989,7 @@ void PruneBlockFilesManual(int nManualPruneHeight)
*
* @param[out] setFilesToPrune The set of file indices that can be unlinked will be returned
*/
-static void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight)
+static void FindFilesToPrune(ChainstateManager& chainman, std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight)
{
LOCK2(cs_main, cs_LastBlockFile);
if (::ChainActive().Tip() == nullptr || nPruneTarget == 0) {
@@ -4030,7 +4031,7 @@ static void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfte
if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune)
continue;
- PruneOneBlockFile(fileNumber);
+ chainman.PruneOneBlockFile(fileNumber);
// Queue up the files for removal
setFilesToPrune.insert(fileNumber);
nCurrentUsage -= nBytesToPrune;
@@ -4154,9 +4155,9 @@ void BlockManager::Unload() {
m_block_index.clear();
}
-bool static LoadBlockIndexDB(const CChainParams& chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
+bool static LoadBlockIndexDB(ChainstateManager& chainman, const CChainParams& chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
- if (!g_chainman.m_blockman.LoadBlockIndex(
+ if (!chainman.m_blockman.LoadBlockIndex(
chainparams.GetConsensus(), *pblocktree,
::ChainstateActive().setBlockIndexCandidates)) {
return false;
@@ -4182,8 +4183,7 @@ bool static LoadBlockIndexDB(const CChainParams& chainparams) EXCLUSIVE_LOCKS_RE
// Check presence of blk files
LogPrintf("Checking all blk files are present...\n");
std::set<int> setBlkDataFiles;
- for (const std::pair<const uint256, CBlockIndex*>& item : g_chainman.BlockIndex())
- {
+ for (const std::pair<const uint256, CBlockIndex*>& item : chainman.BlockIndex()) {
CBlockIndex* pindex = item.second;
if (pindex->nStatus & BLOCK_HAVE_DATA) {
setBlkDataFiles.insert(pindex->nFile);
@@ -4600,14 +4600,15 @@ void UnloadBlockIndex()
fHavePruned = false;
}
-bool LoadBlockIndex(const CChainParams& chainparams)
+bool ChainstateManager::LoadBlockIndex(const CChainParams& chainparams)
{
+ AssertLockHeld(cs_main);
// Load block index from databases
bool needs_init = fReindex;
if (!fReindex) {
- bool ret = LoadBlockIndexDB(chainparams);
+ bool ret = LoadBlockIndexDB(*this, chainparams);
if (!ret) return false;
- needs_init = g_chainman.m_blockman.m_block_index.empty();
+ needs_init = m_blockman.m_block_index.empty();
}
if (needs_init) {
diff --git a/src/validation.h b/src/validation.h
index cbab65e79e..8112e38704 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -43,6 +43,7 @@ class CConnman;
class CScriptCheck;
class CBlockPolicyEstimator;
class CTxMemPool;
+class ChainstateManager;
class TxValidationState;
struct ChainTxData;
@@ -149,41 +150,6 @@ extern bool fPruneMode;
/** Number of MiB of block files that we're trying to stay below. */
extern uint64_t nPruneTarget;
-/**
- * Process an incoming block. This only returns after the best known valid
- * block is made active. Note that it does not, however, guarantee that the
- * specific block passed to it has been checked for validity!
- *
- * If you want to *possibly* get feedback on whether pblock is valid, you must
- * install a CValidationInterface (see validationinterface.h) - this will have
- * its BlockChecked method called whenever *any* block completes validation.
- *
- * Note that we guarantee that either the proof-of-work is valid on pblock, or
- * (and possibly also) BlockChecked will have been called.
- *
- * May not be called in a
- * validationinterface callback.
- *
- * @param[in] pblock The block we want to process.
- * @param[in] fForceProcessing Process this block even if unrequested; used for non-network block sources and whitelisted peers.
- * @param[out] fNewBlock A boolean which is set to indicate if the block was first received via this call
- * @returns If the block was processed, independently of block validity
- */
-bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock> pblock, bool fForceProcessing, bool* fNewBlock) LOCKS_EXCLUDED(cs_main);
-
-/**
- * Process incoming block headers.
- *
- * May not be called in a
- * validationinterface callback.
- *
- * @param[in] block The block headers themselves
- * @param[out] state This may be set to an Error state if any error occurred processing them
- * @param[in] chainparams The params for the chain we want to connect to
- * @param[out] ppindex If set, the pointer will be set to point to the last new block index object for the given headers
- */
-bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, BlockValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex = nullptr) LOCKS_EXCLUDED(cs_main);
-
/** Open a block file (blk?????.dat) */
FILE* OpenBlockFile(const FlatFilePos &pos, bool fReadOnly = false);
/** Translation to a filesystem path */
@@ -192,9 +158,6 @@ fs::path GetBlockPosFilename(const FlatFilePos &pos);
void LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, FlatFilePos* dbp = nullptr);
/** Ensures we have a genesis block in the block tree, possibly writing one to disk. */
bool LoadGenesisBlock(const CChainParams& chainparams);
-/** Load the block tree and coins database from disk,
- * initializing state if we're running with -reindex. */
-bool LoadBlockIndex(const CChainParams& chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/** Unload database information */
void UnloadBlockIndex();
/** Run an instance of the script checking thread */
@@ -217,11 +180,6 @@ double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex* pin
uint64_t CalculateCurrentUsage();
/**
- * Mark one block file as pruned.
- */
-void PruneOneBlockFile(const int fileNumber) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
-
-/**
* Actually unlink the specified files
*/
void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune);
@@ -493,9 +451,6 @@ enum class CoinsCacheSizeState
OK = 0
};
-// Defined below, but needed for `friend` usage in CChainState.
-class ChainstateManager;
-
/**
* CChainState stores and provides an API to update our local knowledge of the
* current best chain.
@@ -870,6 +825,47 @@ public:
CChain& ValidatedChain() const { return ValidatedChainstate().m_chain; }
CBlockIndex* ValidatedTip() const { return ValidatedChain().Tip(); }
+ /**
+ * Process an incoming block. This only returns after the best known valid
+ * block is made active. Note that it does not, however, guarantee that the
+ * specific block passed to it has been checked for validity!
+ *
+ * If you want to *possibly* get feedback on whether pblock is valid, you must
+ * install a CValidationInterface (see validationinterface.h) - this will have
+ * its BlockChecked method called whenever *any* block completes validation.
+ *
+ * Note that we guarantee that either the proof-of-work is valid on pblock, or
+ * (and possibly also) BlockChecked will have been called.
+ *
+ * May not be called in a
+ * validationinterface callback.
+ *
+ * @param[in] pblock The block we want to process.
+ * @param[in] fForceProcessing Process this block even if unrequested; used for non-network block sources and whitelisted peers.
+ * @param[out] fNewBlock A boolean which is set to indicate if the block was first received via this call
+ * @returns If the block was processed, independently of block validity
+ */
+ bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock> pblock, bool fForceProcessing, bool* fNewBlock) LOCKS_EXCLUDED(cs_main);
+
+ /**
+ * Process incoming block headers.
+ *
+ * May not be called in a
+ * validationinterface callback.
+ *
+ * @param[in] block The block headers themselves
+ * @param[out] state This may be set to an Error state if any error occurred processing them
+ * @param[in] chainparams The params for the chain we want to connect to
+ * @param[out] ppindex If set, the pointer will be set to point to the last new block index object for the given headers
+ */
+ bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, BlockValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex = nullptr) LOCKS_EXCLUDED(cs_main);
+
+ //! Mark one block file as pruned (modify associated database entries)
+ void PruneOneBlockFile(const int fileNumber) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+
+ //! Load the block tree and coins database from disk, initializing state if we're running with -reindex
+ bool LoadBlockIndex(const CChainParams& chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+
//! Unload block index and chain data before shutdown.
void Unload() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
@@ -877,6 +873,7 @@ public:
void Reset();
};
+/** DEPRECATED! Please use node.chainman instead. May only be used in validation.cpp internally */
extern ChainstateManager g_chainman GUARDED_BY(::cs_main);
/** @returns the most-work valid chainstate. */
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index eff24025f4..3654420eb2 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -118,7 +118,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
// Prune the older block file.
{
LOCK(cs_main);
- PruneOneBlockFile(oldTip->GetBlockPos().nFile);
+ EnsureChainman(m_node).PruneOneBlockFile(oldTip->GetBlockPos().nFile);
}
UnlinkPrunedFiles({oldTip->GetBlockPos().nFile});
@@ -144,7 +144,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
// Prune the remaining block file.
{
LOCK(cs_main);
- PruneOneBlockFile(newTip->GetBlockPos().nFile);
+ EnsureChainman(m_node).PruneOneBlockFile(newTip->GetBlockPos().nFile);
}
UnlinkPrunedFiles({newTip->GetBlockPos().nFile});
@@ -181,7 +181,7 @@ BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup)
// Prune the older block file.
{
LOCK(cs_main);
- PruneOneBlockFile(oldTip->GetBlockPos().nFile);
+ EnsureChainman(m_node).PruneOneBlockFile(oldTip->GetBlockPos().nFile);
}
UnlinkPrunedFiles({oldTip->GetBlockPos().nFile});