@ -2310,12 +2310,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 )
bool static DisconnectTip ( CValidationState & state , const Consensus : : Params & consensusParams )
{
{
CBlockIndex * pindexDelete = chainActive . Tip ( ) ;
CBlockIndex * pindexDelete = chainActive . Tip ( ) ;
assert ( pindexDelete ) ;
assert ( pindexDelete ) ;
mempool . check ( pcoinsTip ) ;
// Read block from disk.
// Read block from disk.
CBlock block ;
CBlock block ;
if ( ! ReadBlockFromDisk ( block , pindexDelete , consensusParams ) )
if ( ! ReadBlockFromDisk ( block , pindexDelete , consensusParams ) )
@ -2350,8 +2349,6 @@ bool static DisconnectTip(CValidationState& state, const Consensus::Params& cons
// UpdateTransactionsFromBlock finds descendants of any transactions in this
// UpdateTransactionsFromBlock finds descendants of any transactions in this
// block that were added back and cleans up the mempool state.
// block that were added back and cleans up the mempool state.
mempool . UpdateTransactionsFromBlock ( vHashUpdate ) ;
mempool . UpdateTransactionsFromBlock ( vHashUpdate ) ;
mempool . removeForReorg ( pcoinsTip , pindexDelete - > nHeight ) ;
mempool . check ( pcoinsTip ) ;
// Update chainActive and related variables.
// Update chainActive and related variables.
UpdateTip ( pindexDelete - > pprev ) ;
UpdateTip ( pindexDelete - > pprev ) ;
// Let wallets know transactions went from 1-confirmed to
// Let wallets know transactions went from 1-confirmed to
@ -2375,7 +2372,6 @@ static int64_t nTimePostConnect = 0;
bool static ConnectTip ( CValidationState & state , const CChainParams & chainparams , CBlockIndex * pindexNew , const CBlock * pblock )
bool static ConnectTip ( CValidationState & state , const CChainParams & chainparams , CBlockIndex * pindexNew , const CBlock * pblock )
{
{
assert ( pindexNew - > pprev = = chainActive . Tip ( ) ) ;
assert ( pindexNew - > pprev = = chainActive . Tip ( ) ) ;
mempool . check ( pcoinsTip ) ;
// Read block from disk.
// Read block from disk.
int64_t nTime1 = GetTimeMicros ( ) ;
int64_t nTime1 = GetTimeMicros ( ) ;
CBlock block ;
CBlock block ;
@ -2412,7 +2408,6 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams,
// Remove conflicting transactions from the mempool.
// Remove conflicting transactions from the mempool.
list < CTransaction > txConflicted ;
list < CTransaction > txConflicted ;
mempool . removeForBlock ( pblock - > vtx , pindexNew - > nHeight , txConflicted , ! IsInitialBlockDownload ( ) ) ;
mempool . removeForBlock ( pblock - > vtx , pindexNew - > nHeight , txConflicted , ! IsInitialBlockDownload ( ) ) ;
mempool . check ( pcoinsTip ) ;
// Update chainActive & related variables.
// Update chainActive & related variables.
UpdateTip ( pindexNew ) ;
UpdateTip ( pindexNew ) ;
// Tell wallet about transactions that went from mempool
// Tell wallet about transactions that went from mempool
@ -2515,8 +2510,11 @@ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& c
// Disconnect active blocks which are no longer in the best chain.
// Disconnect active blocks which are no longer in the best chain.
bool fBlocksDisconnected = false ;
bool fBlocksDisconnected = false ;
while ( chainActive . Tip ( ) & & chainActive . Tip ( ) ! = pindexFork ) {
while ( chainActive . Tip ( ) & & chainActive . Tip ( ) ! = pindexFork ) {
if ( ! DisconnectTip ( state , chainparams . GetConsensus ( ) ) )
if ( ! DisconnectTip ( state , chainparams . GetConsensus ( ) ) ) {
// Probably an AbortNode() error, but try to keep mempool consistent anyway
mempool . removeForReorg ( pcoinsTip , chainActive . Tip ( ) - > nHeight + 1 ) ;
return false ;
return false ;
}
fBlocksDisconnected = true ;
fBlocksDisconnected = true ;
}
}
@ -2550,6 +2548,9 @@ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& c
break ;
break ;
} else {
} else {
// A system error occurred (disk space, database error, ...).
// A system error occurred (disk space, database error, ...).
// Probably gonna shut down ASAP, but try to keep mempool consistent anyway
if ( fBlocksDisconnected )
mempool . removeForReorg ( pcoinsTip , chainActive . Tip ( ) - > nHeight + 1 ) ;
return false ;
return false ;
}
}
} else {
} else {
@ -2563,8 +2564,11 @@ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& c
}
}
}
}
if ( fBlocksDisconnected )
if ( fBlocksDisconnected ) {
mempool . removeForReorg ( pcoinsTip , chainActive . Tip ( ) - > nHeight + 1 ) ;
mempool . TrimToSize ( GetArg ( " -maxmempool " , DEFAULT_MAX_MEMPOOL_SIZE ) * 1000000 ) ;
mempool . TrimToSize ( GetArg ( " -maxmempool " , DEFAULT_MAX_MEMPOOL_SIZE ) * 1000000 ) ;
}
mempool . check ( pcoinsTip ) ;
// Callbacks/notifications for a new best chain.
// Callbacks/notifications for a new best chain.
if ( fInvalidFound )
if ( fInvalidFound )
@ -2672,6 +2676,7 @@ bool InvalidateBlock(CValidationState& state, const Consensus::Params& consensus
// ActivateBestChain considers blocks already in chainActive
// ActivateBestChain considers blocks already in chainActive
// unconditionally valid already, so force disconnect away from it.
// unconditionally valid already, so force disconnect away from it.
if ( ! DisconnectTip ( state , consensusParams ) ) {
if ( ! DisconnectTip ( state , consensusParams ) ) {
mempool . removeForReorg ( pcoinsTip , chainActive . Tip ( ) - > nHeight + 1 ) ;
return false ;
return false ;
}
}
}
}
@ -2689,6 +2694,7 @@ bool InvalidateBlock(CValidationState& state, const Consensus::Params& consensus
}
}
InvalidChainFound ( pindex ) ;
InvalidChainFound ( pindex ) ;
mempool . removeForReorg ( pcoinsTip , chainActive . Tip ( ) - > nHeight + 1 ) ;
return true ;
return true ;
}
}