Protect from null ptr on chain tip

This commit is contained in:
Michael Toutonghi
2018-07-14 21:45:38 -07:00
parent 7756dac0c7
commit 37ad688668
4 changed files with 43 additions and 26 deletions

View File

@@ -11,6 +11,7 @@ using namespace std;
* CChain implementation * CChain implementation
*/ */
void CChain::SetTip(CBlockIndex *pindex) { void CChain::SetTip(CBlockIndex *pindex) {
lastTip = pindex;
if (pindex == NULL) { if (pindex == NULL) {
vChain.clear(); vChain.clear();
return; return;

View File

@@ -424,6 +424,7 @@ public:
class CChain { class CChain {
private: private:
std::vector<CBlockIndex*> vChain; std::vector<CBlockIndex*> vChain;
CBlockIndex *lastTip;
public: public:
/** Returns the index entry for the genesis block of this chain, or NULL if none. */ /** Returns the index entry for the genesis block of this chain, or NULL if none. */
@@ -436,6 +437,11 @@ public:
return vChain.size() > 0 ? vChain[vChain.size() - 1] : NULL; return vChain.size() > 0 ? vChain[vChain.size() - 1] : NULL;
} }
/** Returns the last tip of the chain, or NULL if none. */
CBlockIndex *LastTip() const {
return vChain.size() > 0 ? lastTip : NULL;
}
/** Returns the index entry at a particular height in this chain, or NULL if no such height exists. */ /** Returns the index entry at a particular height in this chain, or NULL if no such height exists. */
CBlockIndex *operator[](int nHeight) const { CBlockIndex *operator[](int nHeight) const {
if (nHeight < 0 || nHeight >= (int)vChain.size()) if (nHeight < 0 || nHeight >= (int)vChain.size())

View File

@@ -253,7 +253,16 @@ bool CCoinsViewCache::HaveCoins(const uint256 &txid) const {
uint256 CCoinsViewCache::GetBestBlock() const { uint256 CCoinsViewCache::GetBestBlock() const {
if (hashBlock.IsNull()) if (hashBlock.IsNull())
hashBlock = base->GetBestBlock(); {
if (base)
{
hashBlock = base->GetBestBlock();
}
else
{
hashBlock = uint256();
}
}
return hashBlock; return hashBlock;
} }

View File

@@ -370,7 +370,7 @@ CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, bool isStake)
//fprintf(stderr,"dont have inputs\n"); //fprintf(stderr,"dont have inputs\n");
continue; continue;
} }
CAmount nTxFees = view.GetValueIn(chainActive.Tip()->nHeight,&interest,tx,chainActive.Tip()->nTime)-tx.GetValueOut(); CAmount nTxFees = view.GetValueIn(chainActive.LastTip()->nHeight,&interest,tx,chainActive.LastTip()->nTime)-tx.GetValueOut();
nTxSigOps += GetP2SHSigOpCount(tx, view); nTxSigOps += GetP2SHSigOpCount(tx, view);
if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS-1) if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS-1)
@@ -485,7 +485,7 @@ CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, bool isStake)
pblocktemplate->vTxSigOps.push_back(GetLegacySigOpCount(txStaked)); pblocktemplate->vTxSigOps.push_back(GetLegacySigOpCount(txStaked));
nFees += txfees; nFees += txfees;
pblock->nTime = blocktime; pblock->nTime = blocktime;
//printf("PoS ht.%d t%u\n",(int32_t)chainActive.Tip()->nHeight+1,blocktime); //printf("PoS ht.%d t%u\n",(int32_t)chainActive.LastTip()->nHeight+1,blocktime);
} else return(0); //fprintf(stderr,"no utxos eligible for staking\n"); } else return(0); //fprintf(stderr,"no utxos eligible for staking\n");
} }
@@ -723,11 +723,11 @@ static bool ProcessBlockFound(CBlock* pblock)
#endif // ENABLE_WALLET #endif // ENABLE_WALLET
{ {
LogPrintf("%s\n", pblock->ToString()); LogPrintf("%s\n", pblock->ToString());
LogPrintf("generated %s height.%d\n", FormatMoney(pblock->vtx[0].vout[0].nValue),chainActive.Tip()->nHeight+1);
// Found a solution // Found a solution
{ {
LOCK(cs_main); LOCK(cs_main);
LogPrintf("generated %s height.%d\n", FormatMoney(pblock->vtx[0].vout[0].nValue),chainActive.Tip()->nHeight+1);
if (pblock->hashPrevBlock != chainActive.Tip()->GetBlockHash()) if (pblock->hashPrevBlock != chainActive.Tip()->GetBlockHash())
{ {
uint256 hash; int32_t i; uint256 hash; int32_t i;
@@ -763,7 +763,7 @@ static bool ProcessBlockFound(CBlock* pblock)
// Process this block the same as if we had received it from another node // Process this block the same as if we had received it from another node
CValidationState state; CValidationState state;
if (!ProcessNewBlock(1,chainActive.Tip()->nHeight+1,state, NULL, pblock, true, NULL)) if (!ProcessNewBlock(1,chainActive.LastTip()->nHeight+1,state, NULL, pblock, true, NULL))
return error("KomodoMiner: ProcessNewBlock, block not accepted"); return error("KomodoMiner: ProcessNewBlock, block not accepted");
TrackMinedBlock(pblock->GetHash()); TrackMinedBlock(pblock->GetHash());
@@ -852,9 +852,10 @@ void static VerusStaker(CWallet *pwallet)
sleep(5); sleep(5);
{ {
LOCK(cs_main);
printf("Staking height %d for %s\n", chainActive.Tip()->nHeight + 1, ASSETCHAINS_SYMBOL); printf("Staking height %d for %s\n", chainActive.Tip()->nHeight + 1, ASSETCHAINS_SYMBOL);
//fprintf(stderr,"Staking height %d for %s\n", chainActive.Tip()->nHeight + 1, ASSETCHAINS_SYMBOL);
} }
//fprintf(stderr,"Staking height %d for %s\n", chainActive.Tip()->nHeight + 1, ASSETCHAINS_SYMBOL);
miningTimer.start(); miningTimer.start();
@@ -867,7 +868,7 @@ void static VerusStaker(CWallet *pwallet)
// Create new block // Create new block
unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
CBlockIndex* pindexPrev = chainActive.Tip(); CBlockIndex* pindexPrev = chainActive.LastTip();
if ( Mining_height != pindexPrev->nHeight+1 ) if ( Mining_height != pindexPrev->nHeight+1 )
{ {
Mining_height = pindexPrev->nHeight+1; Mining_height = pindexPrev->nHeight+1;
@@ -885,8 +886,8 @@ void static VerusStaker(CWallet *pwallet)
if ( ptr == 0 ) if ( ptr == 0 )
{ {
// wait to try another staking block until after the tip moves again // wait to try another staking block until after the tip moves again
while ( chainActive.Tip() == pindexPrev ) while ( chainActive.LastTip() == pindexPrev )
sleep(5); sleep(1);
continue; continue;
} }
@@ -932,9 +933,9 @@ void static VerusStaker(CWallet *pwallet)
continue; continue;
} }
if ( pindexPrev != chainActive.Tip() ) if ( pindexPrev != chainActive.LastTip() )
{ {
printf("Block %d added to chain\n", chainActive.Tip()->nHeight); printf("Block %d added to chain\n", chainActive.LastTip()->nHeight);
MilliSleep(250); MilliSleep(250);
continue; continue;
} }
@@ -1024,9 +1025,9 @@ void static BitcoinMiner_noeq()
waitForPeers(chainparams); waitForPeers(chainparams);
CBlockIndex *pindexPrev, *pindexCur; CBlockIndex *pindexPrev, *pindexCur;
do { do {
pindexPrev = chainActive.Tip(); pindexPrev = chainActive.LastTip();
MilliSleep(5000 + rand() % 5000); MilliSleep(5000 + rand() % 5000);
pindexCur = chainActive.Tip(); pindexCur = chainActive.LastTip();
} while (pindexPrev != pindexCur); } while (pindexPrev != pindexCur);
// this will not stop printing more than once in all cases, but it will allow us to print in all cases // this will not stop printing more than once in all cases, but it will allow us to print in all cases
@@ -1042,16 +1043,16 @@ void static BitcoinMiner_noeq()
miningTimer.stop(); miningTimer.stop();
waitForPeers(chainparams); waitForPeers(chainparams);
pindexPrev = chainActive.Tip(); pindexPrev = chainActive.LastTip();
sleep(1); sleep(1);
// prevent forking on startup before the diff algorithm kicks in // prevent forking on startup before the diff algorithm kicks in
if (pindexPrev->nHeight < 50 || pindexPrev != chainActive.Tip()) if (pindexPrev->nHeight < 50 || pindexPrev != chainActive.LastTip())
{ {
do { do {
pindexPrev = chainActive.Tip(); pindexPrev = chainActive.LastTip();
MilliSleep(5000 + rand() % 5000); MilliSleep(5000 + rand() % 5000);
} while (pindexPrev != chainActive.Tip()); } while (pindexPrev != chainActive.LastTip());
} }
// Create new block // Create new block
@@ -1125,11 +1126,11 @@ void static BitcoinMiner_noeq()
Mining_start = 0; Mining_start = 0;
if ( pindexPrev != chainActive.Tip() ) if ( pindexPrev != chainActive.LastTip() )
{ {
if (lastChainTipPrinted != chainActive.Tip()) if (lastChainTipPrinted != chainActive.LastTip())
{ {
lastChainTipPrinted = chainActive.Tip(); lastChainTipPrinted = chainActive.LastTip();
printf("Block %d added to chain\n", lastChainTipPrinted->nHeight); printf("Block %d added to chain\n", lastChainTipPrinted->nHeight);
} }
MilliSleep(250); MilliSleep(250);
@@ -1200,11 +1201,11 @@ void static BitcoinMiner_noeq()
// check periodically if we're stale // check periodically if we're stale
if (!--hashesToGo) if (!--hashesToGo)
{ {
if ( pindexPrev != chainActive.Tip() ) if ( pindexPrev != chainActive.LastTip() )
{ {
if (lastChainTipPrinted != chainActive.Tip()) if (lastChainTipPrinted != chainActive.LastTip())
{ {
lastChainTipPrinted = chainActive.Tip(); lastChainTipPrinted = chainActive.LastTip();
printf("Block %d added to chain\n", lastChainTipPrinted->nHeight); printf("Block %d added to chain\n", lastChainTipPrinted->nHeight);
} }
break; break;
@@ -1236,11 +1237,11 @@ void static BitcoinMiner_noeq()
break; break;
} }
if ( pindexPrev != chainActive.Tip() ) if ( pindexPrev != chainActive.LastTip() )
{ {
if (lastChainTipPrinted != chainActive.Tip()) if (lastChainTipPrinted != chainActive.LastTip())
{ {
lastChainTipPrinted = chainActive.Tip(); lastChainTipPrinted = chainActive.LastTip();
printf("Block %d added to chain\n", lastChainTipPrinted->nHeight); printf("Block %d added to chain\n", lastChainTipPrinted->nHeight);
} }
break; break;