Skip to content

Commit fd9d890

Browse files
committed
Keep blocks as shared_ptrs, instead of copying txn in ConnectTip
1 parent 6fdd43b commit fd9d890

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

src/validation.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2158,7 +2158,7 @@ static int64_t nTimePostConnect = 0;
21582158
*/
21592159
struct ConnectTrace {
21602160
std::vector<CTransactionRef> txConflicted;
2161-
std::vector<std::tuple<CTransactionRef,CBlockIndex*,int>> txChanged;
2161+
std::vector<std::pair<CBlockIndex*, std::shared_ptr<const CBlock> > > blocksConnected;
21622162
};
21632163

21642164
/**
@@ -2170,11 +2170,15 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams,
21702170
assert(pindexNew->pprev == chainActive.Tip());
21712171
// Read block from disk.
21722172
int64_t nTime1 = GetTimeMicros();
2173-
CBlock block;
21742173
if (!pblock) {
2175-
if (!ReadBlockFromDisk(block, pindexNew, chainparams.GetConsensus()))
2174+
std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>();
2175+
connectTrace.blocksConnected.emplace_back(pindexNew, pblockNew);
2176+
if (!ReadBlockFromDisk(*pblockNew, pindexNew, chainparams.GetConsensus()))
21762177
return AbortNode(state, "Failed to read block");
2177-
pblock = &block;
2178+
pblock = pblockNew.get();
2179+
} else {
2180+
//TODO: This copy is a major performance regression, but ProcessNewBlock callers need updated to fix this
2181+
connectTrace.blocksConnected.emplace_back(pindexNew, std::make_shared<const CBlock>(*pblock));
21782182
}
21792183
// Apply the block atomically to the chain state.
21802184
int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1;
@@ -2205,9 +2209,6 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams,
22052209
// Update chainActive & related variables.
22062210
UpdateTip(pindexNew, chainparams);
22072211

2208-
for (unsigned int i=0; i < pblock->vtx.size(); i++)
2209-
connectTrace.txChanged.emplace_back(pblock->vtx[i], pindexNew, i);
2210-
22112212
int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
22122213
LogPrint("bench", " - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001);
22132214
LogPrint("bench", "- Connect block: %.2fms [%.2fs]\n", (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001);
@@ -2329,6 +2330,8 @@ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& c
23292330
state = CValidationState();
23302331
fInvalidFound = true;
23312332
fContinue = false;
2333+
// If we didn't actually connect the block, don't notify listeners about it
2334+
connectTrace.blocksConnected.pop_back();
23322335
break;
23332336
} else {
23342337
// A system error occurred (disk space, database error, ...).
@@ -2431,8 +2434,12 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
24312434
GetMainSignals().SyncTransaction(*tx, pindexNewTip, CMainSignals::SYNC_TRANSACTION_NOT_IN_BLOCK);
24322435
}
24332436
// ... and about transactions that got confirmed:
2434-
for (unsigned int i = 0; i < connectTrace.txChanged.size(); i++)
2435-
GetMainSignals().SyncTransaction(*std::get<0>(connectTrace.txChanged[i]), std::get<1>(connectTrace.txChanged[i]), std::get<2>(connectTrace.txChanged[i]));
2437+
for (const auto& pair : connectTrace.blocksConnected) {
2438+
assert(pair.second);
2439+
const CBlock& block = *(pair.second);
2440+
for (unsigned int i = 0; i < block.vtx.size(); i++)
2441+
GetMainSignals().SyncTransaction(*block.vtx[i], pair.first, i);
2442+
}
24362443

24372444
// Notify external listeners about the new tip.
24382445
GetMainSignals().UpdatedBlockTip(pindexNewTip, pindexFork, fInitialDownload);

0 commit comments

Comments
 (0)