44
44
* or from the last difficulty change if 'lookup' is nonpositive.
45
45
* If 'height' is nonnegative, compute the estimate at the time when a given block was found.
46
46
*/
47
- static UniValue GetNetworkHashPS (int lookup, int height) {
48
- CBlockIndex * pb = :: ChainActive () .Tip ();
47
+ static UniValue GetNetworkHashPS (int lookup, int height, const CChain& active_chain ) {
48
+ const CBlockIndex* pb = active_chain .Tip ();
49
49
50
- if (height >= 0 && height < ::ChainActive ().Height ())
51
- pb = ::ChainActive ()[height];
50
+ if (height >= 0 && height < active_chain.Height ()) {
51
+ pb = active_chain[height];
52
+ }
52
53
53
54
if (pb == nullptr || !pb->nHeight )
54
55
return 0 ;
@@ -61,7 +62,7 @@ static UniValue GetNetworkHashPS(int lookup, int height) {
61
62
if (lookup > pb->nHeight )
62
63
lookup = pb->nHeight ;
63
64
64
- CBlockIndex * pb0 = pb;
65
+ const CBlockIndex* pb0 = pb;
65
66
int64_t minTime = pb0->GetBlockTime ();
66
67
int64_t maxTime = minTime;
67
68
for (int i = 0 ; i < lookup; i++) {
@@ -100,7 +101,8 @@ static RPCHelpMan getnetworkhashps()
100
101
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
101
102
{
102
103
LOCK (cs_main);
103
- return GetNetworkHashPS (!request.params [0 ].isNull () ? request.params [0 ].get_int () : 120 , !request.params [1 ].isNull () ? request.params [1 ].get_int () : -1 );
104
+ const CChain& active_chain = EnsureChainman (request.context ).ActiveChain ();
105
+ return GetNetworkHashPS (!request.params [0 ].isNull () ? request.params [0 ].get_int () : 120 , !request.params [1 ].isNull () ? request.params [1 ].get_int () : -1 , active_chain);
104
106
},
105
107
};
106
108
}
@@ -111,7 +113,8 @@ static bool GenerateBlock(ChainstateManager& chainman, CBlock& block, uint64_t&
111
113
112
114
{
113
115
LOCK (cs_main);
114
- IncrementExtraNonce (&block, ::ChainActive ().Tip (), extra_nonce);
116
+ CHECK_NONFATAL (std::addressof (::ChainActive ()) == std::addressof (chainman.ActiveChain ()));
117
+ IncrementExtraNonce (&block, chainman.ActiveChain ().Tip (), extra_nonce);
115
118
}
116
119
117
120
CChainParams chainparams (Params ());
@@ -143,7 +146,8 @@ static UniValue generateBlocks(ChainstateManager& chainman, const CTxMemPool& me
143
146
144
147
{ // Don't keep cs_main locked
145
148
LOCK (cs_main);
146
- nHeight = ::ChainActive ().Height ();
149
+ CHECK_NONFATAL (std::addressof (::ChainActive ()) == std::addressof (chainman.ActiveChain ()));
150
+ nHeight = chainman.ActiveChain ().Height ();
147
151
nHeightEnd = nHeight+nGenerate;
148
152
}
149
153
unsigned int nExtraNonce = 0 ;
@@ -354,11 +358,12 @@ static RPCHelpMan generateblock()
354
358
CChainParams chainparams (Params ());
355
359
CBlock block;
356
360
361
+ ChainstateManager& chainman = EnsureChainman (request.context );
357
362
{
358
363
LOCK (cs_main);
359
364
360
365
CTxMemPool empty_mempool;
361
- std::unique_ptr<CBlockTemplate> blocktemplate (BlockAssembler (:: ChainstateActive (), empty_mempool, chainparams).CreateNewBlock (coinbase_script));
366
+ std::unique_ptr<CBlockTemplate> blocktemplate (BlockAssembler (chainman. ActiveChainstate (), empty_mempool, chainparams).CreateNewBlock (coinbase_script));
362
367
if (!blocktemplate) {
363
368
throw JSONRPCError (RPC_INTERNAL_ERROR, " Couldn't create new block" );
364
369
}
@@ -369,14 +374,14 @@ static RPCHelpMan generateblock()
369
374
370
375
// Add transactions
371
376
block.vtx .insert (block.vtx .end (), txs.begin (), txs.end ());
372
- CBlockIndex* prev_block = WITH_LOCK (::cs_main, return g_chainman .m_blockman .LookupBlockIndex (block.hashPrevBlock ));
377
+ CBlockIndex* prev_block = WITH_LOCK (::cs_main, return chainman .m_blockman .LookupBlockIndex (block.hashPrevBlock ));
373
378
RegenerateCommitments (block, prev_block);
374
379
375
380
{
376
381
LOCK (cs_main);
377
382
378
383
BlockValidationState state;
379
- if (!TestBlockValidity (state, chainparams, :: ChainstateActive (), block, g_chainman .m_blockman .LookupBlockIndex (block.hashPrevBlock ), false , false )) {
384
+ if (!TestBlockValidity (state, chainparams, chainman. ActiveChainstate (), block, chainman .m_blockman .LookupBlockIndex (block.hashPrevBlock ), false , false )) {
380
385
throw JSONRPCError (RPC_VERIFY_ERROR, strprintf (" TestBlockValidity failed: %s" , state.ToString ()));
381
386
}
382
387
}
@@ -385,7 +390,7 @@ static RPCHelpMan generateblock()
385
390
uint64_t max_tries{DEFAULT_MAX_TRIES};
386
391
unsigned int extra_nonce{0 };
387
392
388
- if (!GenerateBlock (EnsureChainman (request. context ) , block, max_tries, extra_nonce, block_hash) || block_hash.IsNull ()) {
393
+ if (!GenerateBlock (chainman , block, max_tries, extra_nonce, block_hash) || block_hash.IsNull ()) {
389
394
throw JSONRPCError (RPC_MISC_ERROR, " Failed to make block." );
390
395
}
391
396
@@ -421,12 +426,13 @@ static RPCHelpMan getmininginfo()
421
426
{
422
427
LOCK (cs_main);
423
428
const CTxMemPool& mempool = EnsureMemPool (request.context );
429
+ const CChain& active_chain = EnsureChainman (request.context ).ActiveChain ();
424
430
425
431
UniValue obj (UniValue::VOBJ);
426
- obj.pushKV (" blocks" , (int ):: ChainActive () .Height ());
432
+ obj.pushKV (" blocks" , (int )active_chain .Height ());
427
433
if (BlockAssembler::m_last_block_weight) obj.pushKV (" currentblockweight" , *BlockAssembler::m_last_block_weight);
428
434
if (BlockAssembler::m_last_block_num_txs) obj.pushKV (" currentblocktx" , *BlockAssembler::m_last_block_num_txs);
429
- obj.pushKV (" difficulty" , (double )GetDifficulty (:: ChainActive () .Tip ()));
435
+ obj.pushKV (" difficulty" , (double )GetDifficulty (active_chain .Tip ()));
430
436
obj.pushKV (" networkhashps" , getnetworkhashps ().HandleRequest (request));
431
437
obj.pushKV (" pooledtx" , (uint64_t )mempool.size ());
432
438
obj.pushKV (" chain" , Params ().NetworkIDString ());
@@ -590,6 +596,7 @@ static RPCHelpMan getblocktemplate()
590
596
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
591
597
{
592
598
LOCK (cs_main);
599
+ ChainstateManager& chainman = EnsureChainman (request.context );
593
600
594
601
std::string strMode = " template" ;
595
602
UniValue lpval = NullUniValue;
@@ -620,7 +627,7 @@ static RPCHelpMan getblocktemplate()
620
627
throw JSONRPCError (RPC_DESERIALIZATION_ERROR, " Block decode failed" );
621
628
622
629
uint256 hash = block.GetHash ();
623
- const CBlockIndex* pindex = g_chainman .m_blockman .LookupBlockIndex (hash);
630
+ const CBlockIndex* pindex = chainman .m_blockman .LookupBlockIndex (hash);
624
631
if (pindex) {
625
632
if (pindex->IsValid (BLOCK_VALID_SCRIPTS))
626
633
return " duplicate" ;
@@ -629,12 +636,12 @@ static RPCHelpMan getblocktemplate()
629
636
return " duplicate-inconclusive" ;
630
637
}
631
638
632
- CBlockIndex* const pindexPrev = :: ChainActive ().Tip ();
639
+ CBlockIndex* const pindexPrev = chainman. ActiveChain ().Tip ();
633
640
// TestBlockValidity only supports blocks built on the current Tip
634
641
if (block.hashPrevBlock != pindexPrev->GetBlockHash ())
635
642
return " inconclusive-not-best-prevblk" ;
636
643
BlockValidationState state;
637
- TestBlockValidity (state, Params (), :: ChainstateActive (), block, pindexPrev, false , true );
644
+ TestBlockValidity (state, Params (), chainman. ActiveChainstate (), block, pindexPrev, false , true );
638
645
return BIP22ValidationResult (state);
639
646
}
640
647
@@ -665,7 +672,7 @@ static RPCHelpMan getblocktemplate()
665
672
throw JSONRPCError (RPC_CLIENT_NOT_CONNECTED, PACKAGE_NAME " is not connected!" );
666
673
}
667
674
668
- if (:: ChainstateActive ().IsInitialBlockDownload ()) {
675
+ if (chainman. ActiveChainstate ().IsInitialBlockDownload ()) {
669
676
throw JSONRPCError (RPC_CLIENT_IN_INITIAL_DOWNLOAD, PACKAGE_NAME " is in initial sync and waiting for blocks..." );
670
677
}
671
678
}
@@ -691,7 +698,7 @@ static RPCHelpMan getblocktemplate()
691
698
else
692
699
{
693
700
// NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier
694
- hashWatchedChain = :: ChainActive ().Tip ()->GetBlockHash ();
701
+ hashWatchedChain = chainman. ActiveChain ().Tip ()->GetBlockHash ();
695
702
nTransactionsUpdatedLastLP = nTransactionsUpdatedLast;
696
703
}
697
704
@@ -736,20 +743,20 @@ static RPCHelpMan getblocktemplate()
736
743
static CBlockIndex* pindexPrev;
737
744
static int64_t nStart;
738
745
static std::unique_ptr<CBlockTemplate> pblocktemplate;
739
- if (pindexPrev != :: ChainActive ().Tip () ||
746
+ if (pindexPrev != chainman. ActiveChain ().Tip () ||
740
747
(mempool.GetTransactionsUpdated () != nTransactionsUpdatedLast && GetTime () - nStart > 5 ))
741
748
{
742
749
// Clear pindexPrev so future calls make a new block, despite any failures from here on
743
750
pindexPrev = nullptr ;
744
751
745
752
// Store the pindexBest used before CreateNewBlock, to avoid races
746
753
nTransactionsUpdatedLast = mempool.GetTransactionsUpdated ();
747
- CBlockIndex* pindexPrevNew = :: ChainActive ().Tip ();
754
+ CBlockIndex* pindexPrevNew = chainman. ActiveChain ().Tip ();
748
755
nStart = GetTime ();
749
756
750
757
// Create new block
751
758
CScript scriptDummy = CScript () << OP_TRUE;
752
- pblocktemplate = BlockAssembler (:: ChainstateActive (), mempool, Params ()).CreateNewBlock (scriptDummy);
759
+ pblocktemplate = BlockAssembler (chainman. ActiveChainstate (), mempool, Params ()).CreateNewBlock (scriptDummy);
753
760
if (!pblocktemplate)
754
761
throw JSONRPCError (RPC_OUT_OF_MEMORY, " Out of memory" );
755
762
@@ -885,7 +892,7 @@ static RPCHelpMan getblocktemplate()
885
892
result.pushKV (" transactions" , transactions);
886
893
result.pushKV (" coinbaseaux" , aux);
887
894
result.pushKV (" coinbasevalue" , (int64_t )pblock->vtx [0 ]->vout [0 ].nValue );
888
- result.pushKV (" longpollid" , :: ChainActive ().Tip ()->GetBlockHash ().GetHex () + ToString (nTransactionsUpdatedLast));
895
+ result.pushKV (" longpollid" , chainman. ActiveChain ().Tip ()->GetBlockHash ().GetHex () + ToString (nTransactionsUpdatedLast));
889
896
result.pushKV (" target" , hashTarget.GetHex ());
890
897
result.pushKV (" mintime" , (int64_t )pindexPrev->GetMedianTimePast ()+1 );
891
898
result.pushKV (" mutable" , aMutable);
@@ -968,10 +975,11 @@ static RPCHelpMan submitblock()
968
975
throw JSONRPCError (RPC_DESERIALIZATION_ERROR, " Block does not start with a coinbase" );
969
976
}
970
977
978
+ ChainstateManager& chainman = EnsureChainman (request.context );
971
979
uint256 hash = block.GetHash ();
972
980
{
973
981
LOCK (cs_main);
974
- const CBlockIndex* pindex = g_chainman .m_blockman .LookupBlockIndex (hash);
982
+ const CBlockIndex* pindex = chainman .m_blockman .LookupBlockIndex (hash);
975
983
if (pindex) {
976
984
if (pindex->IsValid (BLOCK_VALID_SCRIPTS)) {
977
985
return " duplicate" ;
@@ -984,7 +992,7 @@ static RPCHelpMan submitblock()
984
992
985
993
{
986
994
LOCK (cs_main);
987
- const CBlockIndex* pindex = g_chainman .m_blockman .LookupBlockIndex (block.hashPrevBlock );
995
+ const CBlockIndex* pindex = chainman .m_blockman .LookupBlockIndex (block.hashPrevBlock );
988
996
if (pindex) {
989
997
UpdateUncommittedBlockStructures (block, pindex, Params ().GetConsensus ());
990
998
}
@@ -993,7 +1001,7 @@ static RPCHelpMan submitblock()
993
1001
bool new_block;
994
1002
auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash ());
995
1003
RegisterSharedValidationInterface (sc);
996
- bool accepted = EnsureChainman (request. context ) .ProcessNewBlock (Params (), blockptr, /* fForceProcessing */ true , /* fNewBlock */ &new_block);
1004
+ bool accepted = chainman .ProcessNewBlock (Params (), blockptr, /* fForceProcessing */ true , /* fNewBlock */ &new_block);
997
1005
UnregisterSharedValidationInterface (sc);
998
1006
if (!new_block && accepted) {
999
1007
return " duplicate" ;
@@ -1026,15 +1034,16 @@ static RPCHelpMan submitheader()
1026
1034
if (!DecodeHexBlockHeader (h, request.params [0 ].get_str ())) {
1027
1035
throw JSONRPCError (RPC_DESERIALIZATION_ERROR, " Block header decode failed" );
1028
1036
}
1037
+ ChainstateManager& chainman = EnsureChainman (request.context );
1029
1038
{
1030
1039
LOCK (cs_main);
1031
- if (!g_chainman .m_blockman .LookupBlockIndex (h.hashPrevBlock )) {
1040
+ if (!chainman .m_blockman .LookupBlockIndex (h.hashPrevBlock )) {
1032
1041
throw JSONRPCError (RPC_VERIFY_ERROR, " Must submit previous header (" + h.hashPrevBlock .GetHex () + " ) first" );
1033
1042
}
1034
1043
}
1035
1044
1036
1045
BlockValidationState state;
1037
- EnsureChainman (request. context ) .ProcessNewBlockHeaders ({h}, state, Params ());
1046
+ chainman .ProcessNewBlockHeaders ({h}, state, Params ());
1038
1047
if (state.IsValid ()) return NullUniValue;
1039
1048
if (state.IsError ()) {
1040
1049
throw JSONRPCError (RPC_VERIFY_ERROR, state.ToString ());
0 commit comments