Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 2,187 Lines • ▼ Show 20 Lines | LogPrint(BCLog::BENCH, "- Disconnect block: %.2fms\n", | ||||
(GetTimeMicros() - nStart) * MILLI); | (GetTimeMicros() - nStart) * MILLI); | ||||
// Write the chain state to disk, if necessary. | // Write the chain state to disk, if necessary. | ||||
if (!FlushStateToDisk(config.GetChainParams(), state, | if (!FlushStateToDisk(config.GetChainParams(), state, | ||||
FLUSH_STATE_IF_NEEDED)) { | FLUSH_STATE_IF_NEEDED)) { | ||||
return false; | return false; | ||||
} | } | ||||
// If this block was deactivating the replay protection, then we need to | // If this block is deactivating a fork, we move all mempool transactions | ||||
// remove transactions that are replay protected from the mempool. There is | // in front of disconnectpool for reprocessing in a future | ||||
// no easy way to do this so we'll just discard the whole mempool and then | // updateMempoolForReorg call | ||||
// add the transaction of the block we just disconnected back. | if (GetBlockScriptFlags(config, pindexDelete) != | ||||
if (IsReplayProtectionEnabled(config, pindexDelete) && | GetBlockScriptFlags(config, pindexDelete->pprev)) { | ||||
!IsReplayProtectionEnabled(config, pindexDelete->pprev)) { | LogPrint( | ||||
LogPrint(BCLog::MEMPOOL, "Clearing mempool for reorg"); | BCLog::MEMPOOL, | ||||
disconnectpool | |||||
g_mempool.clear(); | ? "Reprocessing mempool for a reorg crossing a fork boundary\n" | ||||
// While not strictly necessary, clearing the disconnect pool is also | : "Clearing mempool for a reorg crossing a fork boundary\n"); | ||||
deadalnix: Thinking about it, I think it's fine to just say the mempool is cleared. That doesn't prevent… | |||||
// beneficial so we don't try to reuse its content at the end of the | |||||
// reorg, which we know will fail. | |||||
if (disconnectpool) { | if (disconnectpool) { | ||||
disconnectpool->clear(); | disconnectpool->importMempool(g_mempool); | ||||
} | } | ||||
g_mempool.clear(); | |||||
} | } | ||||
if (disconnectpool) { | if (disconnectpool) { | ||||
disconnectpool->addForBlock(block.vtx); | disconnectpool->addForBlock(block.vtx); | ||||
} | } | ||||
// If the tip is finalized, then undo it. | // If the tip is finalized, then undo it. | ||||
if (pindexFinalized == pindexDelete) { | if (pindexFinalized == pindexDelete) { | ||||
▲ Show 20 Lines • Show All 250 Lines • ▼ Show 20 Lines | static bool ConnectTip(const Config &config, CValidationState &state, | ||||
int64_t nTime5 = GetTimeMicros(); | int64_t nTime5 = GetTimeMicros(); | ||||
nTimeChainState += nTime5 - nTime4; | nTimeChainState += nTime5 - nTime4; | ||||
LogPrint(BCLog::BENCH, | LogPrint(BCLog::BENCH, | ||||
" - Writing chainstate: %.2fms [%.2fs (%.2fms/blk)]\n", | " - Writing chainstate: %.2fms [%.2fs (%.2fms/blk)]\n", | ||||
(nTime5 - nTime4) * MILLI, nTimeChainState * MICRO, | (nTime5 - nTime4) * MILLI, nTimeChainState * MICRO, | ||||
nTimeChainState * MILLI / nBlocksTotal); | nTimeChainState * MILLI / nBlocksTotal); | ||||
// If we just activated the replay protection with that block, it means | |||||
// transaction in the mempool are now invalid. As a result, we need to clear | |||||
// the mempool. | |||||
if (IsReplayProtectionEnabled(config, pindexNew) && | |||||
!IsReplayProtectionEnabled(config, pindexNew->pprev)) { | |||||
g_mempool.clear(); | |||||
} | |||||
// Remove conflicting transactions from the mempool.; | // Remove conflicting transactions from the mempool.; | ||||
g_mempool.removeForBlock(blockConnecting.vtx, pindexNew->nHeight); | g_mempool.removeForBlock(blockConnecting.vtx, pindexNew->nHeight); | ||||
disconnectpool.removeForBlock(blockConnecting.vtx); | disconnectpool.removeForBlock(blockConnecting.vtx); | ||||
// If this block is activating a fork, we move all mempool transactions | |||||
// in front of disconnectpool for reprocessing in a future | |||||
// updateMempoolForReorg call | |||||
if (pindexNew->pprev != nullptr && | |||||
GetBlockScriptFlags(config, pindexNew) != | |||||
GetBlockScriptFlags(config, pindexNew->pprev)) { | |||||
LogPrint(BCLog::MEMPOOL, "Reprocessing mempool because new validation " | |||||
"rules are in effect\n"); | |||||
disconnectpool.importMempool(g_mempool); | |||||
} | |||||
// Update chainActive & related variables. | // Update chainActive & related variables. | ||||
UpdateTip(config, pindexNew); | UpdateTip(config, pindexNew); | ||||
int64_t nTime6 = GetTimeMicros(); | int64_t nTime6 = GetTimeMicros(); | ||||
nTimePostConnect += nTime6 - nTime5; | nTimePostConnect += nTime6 - nTime5; | ||||
nTimeTotal += nTime6 - nTime1; | nTimeTotal += nTime6 - nTime1; | ||||
LogPrint(BCLog::BENCH, | LogPrint(BCLog::BENCH, | ||||
" - Connect postprocess: %.2fms [%.2fs (%.2fms/blk)]\n", | " - Connect postprocess: %.2fms [%.2fs (%.2fms/blk)]\n", | ||||
▲ Show 20 Lines • Show All 252 Lines • ▼ Show 20 Lines | while (fContinue && nHeight != pindexMostWork->nHeight) { | ||||
// temporarily to release the lock. | // temporarily to release the lock. | ||||
fContinue = false; | fContinue = false; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (fBlocksDisconnected) { | if (fBlocksDisconnected || !disconnectpool.isEmpty()) { | ||||
// If any blocks were disconnected, disconnectpool may be non empty. Add | // If any blocks were disconnected, we need to update the mempool even | ||||
// any disconnected transactions back to the mempool. | // if disconnectpool is empty. The disconnectpool may also be non-empty | ||||
// if the mempool was imported due to new validation rules being in | |||||
// effect. | |||||
disconnectpool.updateMempoolForReorg(config, true); | disconnectpool.updateMempoolForReorg(config, true); | ||||
} | } | ||||
g_mempool.check(pcoinsTip.get()); | g_mempool.check(pcoinsTip.get()); | ||||
// Callbacks/notifications for a new best chain. | // Callbacks/notifications for a new best chain. | ||||
if (fInvalidFound) { | if (fInvalidFound) { | ||||
CheckForkWarningConditionsOnNewFork(pindexMostWork); | CheckForkWarningConditionsOnNewFork(pindexMostWork); | ||||
▲ Show 20 Lines • Show All 2,765 Lines • Show Last 20 Lines |
Thinking about it, I think it's fine to just say the mempool is cleared. That doesn't prevent to reinsert things at a later stage if appropriate :)