@@ -244,9 +244,9 @@ void Shutdown(NodeContext& node)
244
244
}
245
245
246
246
// FlushStateToDisk generates a ChainStateFlushed callback, which we should avoid missing
247
- {
247
+ if (node. chainman ) {
248
248
LOCK (cs_main);
249
- for (CChainState* chainstate : g_chainman. GetAll ()) {
249
+ for (CChainState* chainstate : node. chainman -> GetAll ()) {
250
250
if (chainstate->CanFlushToDisk ()) {
251
251
chainstate->ForceFlushStateToDisk ();
252
252
}
@@ -271,9 +271,9 @@ void Shutdown(NodeContext& node)
271
271
// up with our current chain to avoid any strange pruning edge cases and make
272
272
// next startup faster by avoiding rescan.
273
273
274
- {
274
+ if (node. chainman ) {
275
275
LOCK (cs_main);
276
- for (CChainState* chainstate : g_chainman. GetAll ()) {
276
+ for (CChainState* chainstate : node. chainman -> GetAll ()) {
277
277
if (chainstate->CanFlushToDisk ()) {
278
278
chainstate->ForceFlushStateToDisk ();
279
279
chainstate->ResetCoinsViews ();
@@ -299,7 +299,8 @@ void Shutdown(NodeContext& node)
299
299
globalVerifyHandle.reset ();
300
300
ECC_Stop ();
301
301
node.args = nullptr ;
302
- if (node.mempool ) node.mempool = nullptr ;
302
+ node.mempool = nullptr ;
303
+ node.chainman = nullptr ;
303
304
node.scheduler .reset ();
304
305
305
306
try {
@@ -689,7 +690,7 @@ static void CleanupBlockRevFiles()
689
690
}
690
691
}
691
692
692
- static void ThreadImport (std::vector<fs::path> vImportFiles)
693
+ static void ThreadImport (ChainstateManager& chainman, std::vector<fs::path> vImportFiles)
693
694
{
694
695
const CChainParams& chainparams = Params ();
695
696
util::ThreadRename (" loadblk" );
@@ -741,9 +742,9 @@ static void ThreadImport(std::vector<fs::path> vImportFiles)
741
742
// scan for better chains in the block chain database, that are not yet connected in the active best chain
742
743
743
744
// We can't hold cs_main during ActivateBestChain even though we're accessing
744
- // the g_chainman unique_ptrs since ABC requires us not to be holding cs_main, so retrieve
745
+ // the chainman unique_ptrs since ABC requires us not to be holding cs_main, so retrieve
745
746
// the relevant pointers before the ABC call.
746
- for (CChainState* chainstate : WITH_LOCK (::cs_main, return g_chainman .GetAll ())) {
747
+ for (CChainState* chainstate : WITH_LOCK (::cs_main, return chainman .GetAll ())) {
747
748
BlockValidationState state;
748
749
if (!chainstate->ActivateBestChain (state, chainparams, nullptr )) {
749
750
LogPrintf (" Failed to connect best block (%s)\n " , state.ToString ());
@@ -1377,6 +1378,9 @@ bool AppInitMain(const util::Ref& context, NodeContext& node)
1377
1378
// which are all started after this, may use it from the node context.
1378
1379
assert (!node.mempool );
1379
1380
node.mempool = &::mempool;
1381
+ assert (!node.chainman );
1382
+ node.chainman = &g_chainman;
1383
+ ChainstateManager& chainman = EnsureChainman (node);
1380
1384
1381
1385
node.peer_logic .reset (new PeerLogicValidation (node.connman .get (), node.banman .get (), *node.scheduler , *node.mempool ));
1382
1386
RegisterValidationInterface (node.peer_logic .get ());
@@ -1557,7 +1561,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node)
1557
1561
const int64_t load_block_index_start_time = GetTimeMillis ();
1558
1562
try {
1559
1563
LOCK (cs_main);
1560
- g_chainman .InitializeChainstate ();
1564
+ chainman .InitializeChainstate ();
1561
1565
UnloadBlockIndex ();
1562
1566
1563
1567
// new CBlockTreeDB tries to delete the existing file, which
@@ -1612,7 +1616,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node)
1612
1616
1613
1617
bool failed_chainstate_init = false ;
1614
1618
1615
- for (CChainState* chainstate : g_chainman .GetAll ()) {
1619
+ for (CChainState* chainstate : chainman .GetAll ()) {
1616
1620
LogPrintf (" Initializing chainstate %s\n " , chainstate->ToString ());
1617
1621
chainstate->InitCoinsDB (
1618
1622
/* cache_size_bytes */ nCoinDBCache,
@@ -1667,7 +1671,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node)
1667
1671
bool failed_rewind{false };
1668
1672
// Can't hold cs_main while calling RewindBlockIndex, so retrieve the relevant
1669
1673
// chainstates beforehand.
1670
- for (CChainState* chainstate : WITH_LOCK (::cs_main, return g_chainman .GetAll ())) {
1674
+ for (CChainState* chainstate : WITH_LOCK (::cs_main, return chainman .GetAll ())) {
1671
1675
if (!fReset ) {
1672
1676
// Note that RewindBlockIndex MUST run even if we're about to -reindex-chainstate.
1673
1677
// 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)
1692
1696
try {
1693
1697
LOCK (cs_main);
1694
1698
1695
- for (CChainState* chainstate : g_chainman .GetAll ()) {
1699
+ for (CChainState* chainstate : chainman .GetAll ()) {
1696
1700
if (!is_coinsview_empty (chainstate)) {
1697
1701
uiInterface.InitMessage (_ (" Verifying blocks..." ).translated );
1698
1702
if (fHavePruned && gArgs .GetArg (" -checkblocks" , DEFAULT_CHECKBLOCKS) > MIN_BLOCKS_TO_KEEP) {
@@ -1798,7 +1802,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node)
1798
1802
nLocalServices = ServiceFlags (nLocalServices & ~NODE_NETWORK);
1799
1803
if (!fReindex ) {
1800
1804
LOCK (cs_main);
1801
- for (CChainState* chainstate : g_chainman .GetAll ()) {
1805
+ for (CChainState* chainstate : chainman .GetAll ()) {
1802
1806
uiInterface.InitMessage (_ (" Pruning blockstore..." ).translated );
1803
1807
chainstate->PruneAndFlush ();
1804
1808
}
@@ -1841,7 +1845,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node)
1841
1845
vImportFiles.push_back (strFile);
1842
1846
}
1843
1847
1844
- threadGroup.create_thread (std::bind (& ThreadImport, vImportFiles));
1848
+ threadGroup.create_thread ([=, &chainman] { ThreadImport (chainman , vImportFiles); } );
1845
1849
1846
1850
// Wait for genesis block to be processed
1847
1851
{
0 commit comments