Skip to content

Commit

Permalink
[PoS] Lock cs_main when getting chainActive data in miner
Browse files Browse the repository at this point in the history
Github-Pull: #1245
Rebased-From: d2d5f08
  • Loading branch information
random-zebra authored and Fuzzbawls committed Jan 11, 2020
1 parent 6fac9b9 commit b63d963
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 22 deletions.
50 changes: 28 additions & 22 deletions src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,17 @@ void UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev)
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock);
}

CBlockIndex* GetChainTip()
{
LOCK(cs_main);
CBlockIndex* p = chainActive.Tip();
if (!p)
return nullptr;
// Do not pass in the chain active tip, because it can change.
// Instead pass the blockindex directly from mapblockindex, which is const
return mapBlockIndex.at(p->GetBlockHash());
}

std::pair<int, std::pair<uint256, uint256> > pCheckpointCache;
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, bool fProofOfStake)
{
Expand All @@ -115,16 +126,9 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet,
CBlock* pblock = &pblocktemplate->block; // pointer for convenience

// Tip
CBlockIndex* pindexPrev = nullptr;
{ // Don't keep cs_main locked
LOCK(cs_main);
pindexPrev = chainActive.Tip();
if (!pindexPrev)
return nullptr;
// Do not pass in the chain tip, because it can change.
// Instead pass the blockindex directly from mapblockindex, which is const
pindexPrev = mapBlockIndex.at(pindexPrev->GetBlockHash());
}
CBlockIndex* pindexPrev = GetChainTip();
if (!pindexPrev)
return nullptr;

const int nHeight = pindexPrev->nHeight + 1;

Expand Down Expand Up @@ -163,14 +167,14 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet,
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock);
CMutableTransaction txCoinStake;
int64_t nTxNewTime = 0;
if (pwallet->CreateCoinStake(*pwallet, pindexPrev, pblock->nBits, txCoinStake, nTxNewTime)) {
pblock->nTime = nTxNewTime;
pblock->vtx[0].vout[0].SetEmpty();
pblock->vtx.push_back(CTransaction(txCoinStake));
} else {
if (!pwallet->CreateCoinStake(*pwallet, pindexPrev, pblock->nBits, txCoinStake, nTxNewTime)) {
LogPrint("staking", "CreateNewBlock(): stake not found\n");
return nullptr;
}
// Stake found
pblock->nTime = nTxNewTime;
pblock->vtx[0].vout[0].SetEmpty();
pblock->vtx.push_back(CTransaction(txCoinStake));
}

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

while (fGenerateBitcoins || fProofOfStake) {
CBlockIndex* pindexPrev = GetChainTip();
if (!pindexPrev) {
MilliSleep(Params().TargetSpacing() * 1000); // sleep a block
continue;
}
if (fProofOfStake) {
if (chainActive.Tip()->nHeight < Params().LAST_POW_BLOCK()) {
if (pindexPrev->nHeight < Params().LAST_POW_BLOCK()) {
// The last PoW block hasn't even been mined yet.
MilliSleep(Params().TargetSpacing() * 1000); // sleep a block
continue;
Expand All @@ -691,9 +700,9 @@ void BitcoinMiner(CWallet* pwallet, bool fProofOfStake)
}
}

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

std::unique_ptr<CBlockTemplate> pblocktemplate(
fProofOfStake ? CreateNewBlock(CScript(), pwallet, fProofOfStake) : CreateNewBlockWithKey(reservekey, pwallet)
Expand Down
2 changes: 2 additions & 0 deletions src/miner.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class CWallet;

struct CBlockTemplate;

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

0 comments on commit b63d963

Please sign in to comment.