@ -953,7 +953,18 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
@@ -953,7 +953,18 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
CAmount inChainInputValue ;
double dPriority = view . GetPriority ( tx , chainActive . Height ( ) , inChainInputValue ) ;
CTxMemPoolEntry entry ( tx , nFees , GetTime ( ) , dPriority , chainActive . Height ( ) , pool . HasNoInputsOf ( tx ) , inChainInputValue ) ;
// Keep track of transactions that spend a coinbase, which we re-scan
// during reorgs to ensure COINBASE_MATURITY is still met.
bool fSpendsCoinbase = false ;
BOOST_FOREACH ( const CTxIn & txin , tx . vin ) {
const CCoins * coins = view . AccessCoins ( txin . prevout . hash ) ;
if ( coins - > IsCoinBase ( ) ) {
fSpendsCoinbase = true ;
break ;
}
}
CTxMemPoolEntry entry ( tx , nFees , GetTime ( ) , dPriority , chainActive . Height ( ) , pool . HasNoInputsOf ( tx ) , inChainInputValue , fSpendsCoinbase ) ;
unsigned int nSize = entry . GetTxSize ( ) ;
// Don't accept it if it can't get into a block
@ -2310,12 +2321,11 @@ void static UpdateTip(CBlockIndex *pindexNew) {
@@ -2310,12 +2321,11 @@ void static UpdateTip(CBlockIndex *pindexNew) {
}
}
/** Disconnect chainActive's tip. You want to manually re-limit mempool size after this */
/** Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and manually re-limit mempool size after this, with cs_main held. */
bool static DisconnectTip ( CValidationState & state , const Consensus : : Params & consensusParams )
{
CBlockIndex * pindexDelete = chainActive . Tip ( ) ;
assert ( pindexDelete ) ;
mempool . check ( pcoinsTip ) ;
// Read block from disk.
CBlock block ;
if ( ! ReadBlockFromDisk ( block , pindexDelete , consensusParams ) )
@ -2350,8 +2360,6 @@ bool static DisconnectTip(CValidationState& state, const Consensus::Params& cons
@@ -2350,8 +2360,6 @@ bool static DisconnectTip(CValidationState& state, const Consensus::Params& cons
// UpdateTransactionsFromBlock finds descendants of any transactions in this
// block that were added back and cleans up the mempool state.
mempool . UpdateTransactionsFromBlock ( vHashUpdate ) ;
mempool . removeCoinbaseSpends ( pcoinsTip , pindexDelete - > nHeight ) ;
mempool . check ( pcoinsTip ) ;
// Update chainActive and related variables.
UpdateTip ( pindexDelete - > pprev ) ;
// Let wallets know transactions went from 1-confirmed to
@ -2375,7 +2383,6 @@ static int64_t nTimePostConnect = 0;
@@ -2375,7 +2383,6 @@ static int64_t nTimePostConnect = 0;
bool static ConnectTip ( CValidationState & state , const CChainParams & chainparams , CBlockIndex * pindexNew , const CBlock * pblock )
{
assert ( pindexNew - > pprev = = chainActive . Tip ( ) ) ;
mempool . check ( pcoinsTip ) ;
// Read block from disk.
int64_t nTime1 = GetTimeMicros ( ) ;
CBlock block ;
@ -2412,7 +2419,6 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams,
@@ -2412,7 +2419,6 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams,
// Remove conflicting transactions from the mempool.
list < CTransaction > txConflicted ;
mempool . removeForBlock ( pblock - > vtx , pindexNew - > nHeight , txConflicted , ! IsInitialBlockDownload ( ) ) ;
mempool . check ( pcoinsTip ) ;
// Update chainActive & related variables.
UpdateTip ( pindexNew ) ;
// Tell wallet about transactions that went from mempool
@ -2525,46 +2531,49 @@ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& c
@@ -2525,46 +2531,49 @@ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& c
bool fContinue = true ;
int nHeight = pindexFork ? pindexFork - > nHeight : - 1 ;
while ( fContinue & & nHeight ! = pindexMostWork - > nHeight ) {
// Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
// a few blocks along the way.
int nTargetHeight = std : : min ( nHeight + 32 , pindexMostWork - > nHeight ) ;
vpindexToConnect . clear ( ) ;
vpindexToConnect . reserve ( nTargetHeight - nHeight ) ;
CBlockIndex * pindexIter = pindexMostWork - > GetAncestor ( nTargetHeight ) ;
while ( pindexIter & & pindexIter - > nHeight ! = nHeight ) {
vpindexToConnect . push_back ( pindexIter ) ;
pindexIter = pindexIter - > pprev ;
}
nHeight = nTargetHeight ;
// Connect new blocks.
BOOST_REVERSE_FOREACH ( CBlockIndex * pindexConnect , vpindexToConnect ) {
if ( ! ConnectTip ( state , chainparams , pindexConnect , pindexConnect = = pindexMostWork ? pblock : NULL ) ) {
if ( state . IsInvalid ( ) ) {
// The block violates a consensus rule.
if ( ! state . CorruptionPossible ( ) )
InvalidChainFound ( vpindexToConnect . back ( ) ) ;
state = CValidationState ( ) ;
fInvalidFound = true ;
fContinue = false ;
break ;
// Don't iterate the entire list of potential improvements toward the best tip, as we likely only need
// a few blocks along the way.
int nTargetHeight = std : : min ( nHeight + 32 , pindexMostWork - > nHeight ) ;
vpindexToConnect . clear ( ) ;
vpindexToConnect . reserve ( nTargetHeight - nHeight ) ;
CBlockIndex * pindexIter = pindexMostWork - > GetAncestor ( nTargetHeight ) ;
while ( pindexIter & & pindexIter - > nHeight ! = nHeight ) {
vpindexToConnect . push_back ( pindexIter ) ;
pindexIter = pindexIter - > pprev ;
}
nHeight = nTargetHeight ;
// Connect new blocks.
BOOST_REVERSE_FOREACH ( CBlockIndex * pindexConnect , vpindexToConnect ) {
if ( ! ConnectTip ( state , chainparams , pindexConnect , pindexConnect = = pindexMostWork ? pblock : NULL ) ) {
if ( state . IsInvalid ( ) ) {
// The block violates a consensus rule.
if ( ! state . CorruptionPossible ( ) )
InvalidChainFound ( vpindexToConnect . back ( ) ) ;
state = CValidationState ( ) ;
fInvalidFound = true ;
fContinue = false ;
break ;
} else {
// A system error occurred (disk space, database error, ...).
return false ;
}
} else {
// A system error occurred (disk space, database error, ...).
return false ;
}
} else {
PruneBlockIndexCandidates ( ) ;
if ( ! pindexOldTip | | chainActive . Tip ( ) - > nChainWork > pindexOldTip - > nChainWork ) {
// We're in a better position than we were. Return temporarily to release the lock.
fContinue = false ;
break ;
PruneBlockIndexCandidates ( ) ;
if ( ! pindexOldTip | | chainActive . Tip ( ) - > nChainWork > pindexOldTip - > nChainWork ) {
// We're in a better position than we were. Return temporarily to release the lock.
fContinue = false ;
break ;
}
}
}
}
}
if ( fBlocksDisconnected )
if ( fBlocksDisconnected ) {
mempool . removeForReorg ( pcoinsTip , chainActive . Tip ( ) - > nHeight + 1 , STANDARD_LOCKTIME_VERIFY_FLAGS ) ;
mempool . TrimToSize ( GetArg ( " -maxmempool " , DEFAULT_MAX_MEMPOOL_SIZE ) * 1000000 ) ;
}
mempool . check ( pcoinsTip ) ;
// Callbacks/notifications for a new best chain.
if ( fInvalidFound )
@ -2672,6 +2681,7 @@ bool InvalidateBlock(CValidationState& state, const Consensus::Params& consensus
@@ -2672,6 +2681,7 @@ bool InvalidateBlock(CValidationState& state, const Consensus::Params& consensus
// ActivateBestChain considers blocks already in chainActive
// unconditionally valid already, so force disconnect away from it.
if ( ! DisconnectTip ( state , consensusParams ) ) {
mempool . removeForReorg ( pcoinsTip , chainActive . Tip ( ) - > nHeight + 1 , STANDARD_LOCKTIME_VERIFY_FLAGS ) ;
return false ;
}
}
@ -2689,6 +2699,7 @@ bool InvalidateBlock(CValidationState& state, const Consensus::Params& consensus
@@ -2689,6 +2699,7 @@ bool InvalidateBlock(CValidationState& state, const Consensus::Params& consensus
}
InvalidChainFound ( pindex ) ;
mempool . removeForReorg ( pcoinsTip , chainActive . Tip ( ) - > nHeight + 1 , STANDARD_LOCKTIME_VERIFY_FLAGS ) ;
return true ;
}