|
|
@ -2165,7 +2165,7 @@ struct ConnectTrace { |
|
|
|
* Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock |
|
|
|
* Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock |
|
|
|
* corresponding to pindexNew, to bypass loading it again from disk. |
|
|
|
* corresponding to pindexNew, to bypass loading it again from disk. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const CBlock* pblock, ConnectTrace& connectTrace) |
|
|
|
bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace) |
|
|
|
{ |
|
|
|
{ |
|
|
|
assert(pindexNew->pprev == chainActive.Tip()); |
|
|
|
assert(pindexNew->pprev == chainActive.Tip()); |
|
|
|
// Read block from disk.
|
|
|
|
// Read block from disk.
|
|
|
@ -2175,19 +2175,18 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, |
|
|
|
connectTrace.blocksConnected.emplace_back(pindexNew, pblockNew); |
|
|
|
connectTrace.blocksConnected.emplace_back(pindexNew, pblockNew); |
|
|
|
if (!ReadBlockFromDisk(*pblockNew, pindexNew, chainparams.GetConsensus())) |
|
|
|
if (!ReadBlockFromDisk(*pblockNew, pindexNew, chainparams.GetConsensus())) |
|
|
|
return AbortNode(state, "Failed to read block"); |
|
|
|
return AbortNode(state, "Failed to read block"); |
|
|
|
pblock = pblockNew.get(); |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
//TODO: This copy is a major performance regression, but ProcessNewBlock callers need updated to fix this
|
|
|
|
connectTrace.blocksConnected.emplace_back(pindexNew, pblock); |
|
|
|
connectTrace.blocksConnected.emplace_back(pindexNew, std::make_shared<const CBlock>(*pblock)); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const CBlock& blockConnecting = *connectTrace.blocksConnected.back().second; |
|
|
|
// Apply the block atomically to the chain state.
|
|
|
|
// Apply the block atomically to the chain state.
|
|
|
|
int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1; |
|
|
|
int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1; |
|
|
|
int64_t nTime3; |
|
|
|
int64_t nTime3; |
|
|
|
LogPrint("bench", " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001); |
|
|
|
LogPrint("bench", " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * 0.001, nTimeReadFromDisk * 0.000001); |
|
|
|
{ |
|
|
|
{ |
|
|
|
CCoinsViewCache view(pcoinsTip); |
|
|
|
CCoinsViewCache view(pcoinsTip); |
|
|
|
bool rv = ConnectBlock(*pblock, state, pindexNew, view, chainparams); |
|
|
|
bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, chainparams); |
|
|
|
GetMainSignals().BlockChecked(*pblock, state); |
|
|
|
GetMainSignals().BlockChecked(blockConnecting, state); |
|
|
|
if (!rv) { |
|
|
|
if (!rv) { |
|
|
|
if (state.IsInvalid()) |
|
|
|
if (state.IsInvalid()) |
|
|
|
InvalidBlockFound(pindexNew, state); |
|
|
|
InvalidBlockFound(pindexNew, state); |
|
|
@ -2205,7 +2204,7 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, |
|
|
|
int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4; |
|
|
|
int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4; |
|
|
|
LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001); |
|
|
|
LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001); |
|
|
|
// Remove conflicting transactions from the mempool.;
|
|
|
|
// Remove conflicting transactions from the mempool.;
|
|
|
|
mempool.removeForBlock(pblock->vtx, pindexNew->nHeight, &connectTrace.txConflicted, !IsInitialBlockDownload()); |
|
|
|
mempool.removeForBlock(blockConnecting.vtx, pindexNew->nHeight, &connectTrace.txConflicted, !IsInitialBlockDownload()); |
|
|
|
// Update chainActive & related variables.
|
|
|
|
// Update chainActive & related variables.
|
|
|
|
UpdateTip(pindexNew, chainparams); |
|
|
|
UpdateTip(pindexNew, chainparams); |
|
|
|
|
|
|
|
|
|
|
@ -2322,7 +2321,8 @@ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& c |
|
|
|
|
|
|
|
|
|
|
|
// Connect new blocks.
|
|
|
|
// Connect new blocks.
|
|
|
|
BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) { |
|
|
|
BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) { |
|
|
|
if (!ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL, connectTrace)) { |
|
|
|
//TODO: The pblock copy is a major performance regression, but callers need updated to fix this
|
|
|
|
|
|
|
|
if (!ConnectTip(state, chainparams, pindexConnect, (pblock && pindexConnect == pindexMostWork) ? std::make_shared<const CBlock>(*pblock) : std::shared_ptr<const CBlock>(), connectTrace)) { |
|
|
|
if (state.IsInvalid()) { |
|
|
|
if (state.IsInvalid()) { |
|
|
|
// The block violates a consensus rule.
|
|
|
|
// The block violates a consensus rule.
|
|
|
|
if (!state.CorruptionPossible()) |
|
|
|
if (!state.CorruptionPossible()) |
|
|
|