Skip to content

Commit d2d5f08

Browse files
committed
[PoS] Lock cs_main when getting chainActive data in miner
1 parent dbc46d8 commit d2d5f08

File tree

2 files changed

+30
-22
lines changed

2 files changed

+30
-22
lines changed

src/miner.cpp

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,17 @@ void UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev)
103103
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock);
104104
}
105105

106+
CBlockIndex* GetChainTip()
107+
{
108+
LOCK(cs_main);
109+
CBlockIndex* p = chainActive.Tip();
110+
if (!p)
111+
return nullptr;
112+
// Do not pass in the chain active tip, because it can change.
113+
// Instead pass the blockindex directly from mapblockindex, which is const
114+
return mapBlockIndex.at(p->GetBlockHash());
115+
}
116+
106117
std::pair<int, std::pair<uint256, uint256> > pCheckpointCache;
107118
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, bool fProofOfStake)
108119
{
@@ -115,16 +126,9 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet,
115126
CBlock* pblock = &pblocktemplate->block; // pointer for convenience
116127

117128
// Tip
118-
CBlockIndex* pindexPrev = nullptr;
119-
{ // Don't keep cs_main locked
120-
LOCK(cs_main);
121-
pindexPrev = chainActive.Tip();
122-
if (!pindexPrev)
123-
return nullptr;
124-
// Do not pass in the chain tip, because it can change.
125-
// Instead pass the blockindex directly from mapblockindex, which is const
126-
pindexPrev = mapBlockIndex.at(pindexPrev->GetBlockHash());
127-
}
129+
CBlockIndex* pindexPrev = GetChainTip();
130+
if (!pindexPrev)
131+
return nullptr;
128132

129133
const int nHeight = pindexPrev->nHeight + 1;
130134

@@ -163,14 +167,14 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet,
163167
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock);
164168
CMutableTransaction txCoinStake;
165169
int64_t nTxNewTime = 0;
166-
if (pwallet->CreateCoinStake(*pwallet, pindexPrev, pblock->nBits, txCoinStake, nTxNewTime)) {
167-
pblock->nTime = nTxNewTime;
168-
pblock->vtx[0].vout[0].SetEmpty();
169-
pblock->vtx.push_back(CTransaction(txCoinStake));
170-
} else {
170+
if (!pwallet->CreateCoinStake(*pwallet, pindexPrev, pblock->nBits, txCoinStake, nTxNewTime)) {
171171
LogPrint("staking", "CreateNewBlock(): stake not found\n");
172172
return nullptr;
173173
}
174+
// Stake found
175+
pblock->nTime = nTxNewTime;
176+
pblock->vtx[0].vout[0].SetEmpty();
177+
pblock->vtx.push_back(CTransaction(txCoinStake));
174178
}
175179

176180
// Largest block you're willing to create:
@@ -664,8 +668,13 @@ void BitcoinMiner(CWallet* pwallet, bool fProofOfStake)
664668
CAmount stakingBalance = 0;
665669

666670
while (fGenerateBitcoins || fProofOfStake) {
671+
CBlockIndex* pindexPrev = GetChainTip();
672+
if (!pindexPrev) {
673+
MilliSleep(Params().TargetSpacing() * 1000); // sleep a block
674+
continue;
675+
}
667676
if (fProofOfStake) {
668-
if (chainActive.Tip()->nHeight < Params().LAST_POW_BLOCK()) {
677+
if (pindexPrev->nHeight < Params().LAST_POW_BLOCK()) {
669678
// The last PoW block hasn't even been mined yet.
670679
MilliSleep(Params().TargetSpacing() * 1000); // sleep a block
671680
continue;
@@ -691,9 +700,9 @@ void BitcoinMiner(CWallet* pwallet, bool fProofOfStake)
691700
}
692701
}
693702

694-
const bool fTimeV2 = Params().IsTimeProtocolV2(chainActive.Height()+1);
703+
const bool fTimeV2 = Params().IsTimeProtocolV2(pindexPrev->nHeight+1);
695704
//search our map of hashed blocks, see if bestblock has been hashed yet
696-
if (pwallet->pStakerStatus->GetLastHash() == chainActive.Tip()->GetBlockHash())
705+
if (pwallet->pStakerStatus->GetLastHash() == pindexPrev->GetBlockHash())
697706
{
698707
uint256 lastHashTime = pwallet->pStakerStatus->GetLastTime();
699708
if ( (!fTimeV2 && GetTime() < lastHashTime + 22) ||
@@ -704,7 +713,7 @@ void BitcoinMiner(CWallet* pwallet, bool fProofOfStake)
704713
}
705714
}
706715
} else { // PoW
707-
if ((chainActive.Tip()->nHeight - 6) > Params().LAST_POW_BLOCK())
716+
if ((pindexPrev->nHeight - 6) > Params().LAST_POW_BLOCK())
708717
{
709718
// Run for a little while longer, just in case there is a rewind on the chain.
710719
LogPrintf("%s: Exiting Proof of Work Mining Thread at height: %d\n",
@@ -717,9 +726,6 @@ void BitcoinMiner(CWallet* pwallet, bool fProofOfStake)
717726
// Create new block
718727
//
719728
unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
720-
CBlockIndex* pindexPrev = chainActive.Tip();
721-
if (!pindexPrev)
722-
continue;
723729

724730
std::unique_ptr<CBlockTemplate> pblocktemplate(
725731
fProofOfStake ? CreateNewBlock(CScript(), pwallet, fProofOfStake) : CreateNewBlockWithKey(reservekey, pwallet)

src/miner.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ class CWallet;
1818

1919
struct CBlockTemplate;
2020

21+
/** Get reliable pointer to current chain tip */
22+
CBlockIndex* GetChainTip();
2123
/** Generate a new block, without valid proof-of-work */
2224
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, bool fProofOfStake);
2325
/** Modify the extranonce in a block */

0 commit comments

Comments
 (0)