Skip to content

Commit ec4525c

Browse files
committed
Move orphan processing to ActivateBestChain
This further decouples "main" and "net" processing logic by moving orphan processing out of the chain-connecting cs_main lock and into its own cs_main lock, beside all of the other chain callbacks. Once further decoupling of net and main processing logic occurs, orphan handing should move to its own lock, out of cs_main. Note that this will introduce a race if there are any cases where we assume the orphan map to be consistent with the current chain tip, however I am confident there is no such case (ATMP will fail without DoS score in all such cases).
1 parent 9346f84 commit ec4525c

File tree

1 file changed

+27
-20
lines changed

1 file changed

+27
-20
lines changed

src/main.cpp

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2461,7 +2461,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
24612461

24622462
CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL);
24632463

2464-
std::vector<uint256> vOrphanErase;
24652464
std::vector<int> prevheights;
24662465
CAmount nFees = 0;
24672466
int nInputs = 0;
@@ -2492,17 +2491,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
24922491
prevheights[j] = view.AccessCoins(tx.vin[j].prevout.hash)->nHeight;
24932492
}
24942493

2495-
// Which orphan pool entries must we evict?
2496-
for (size_t j = 0; j < tx.vin.size(); j++) {
2497-
auto itByPrev = mapOrphanTransactionsByPrev.find(tx.vin[j].prevout);
2498-
if (itByPrev == mapOrphanTransactionsByPrev.end()) continue;
2499-
for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) {
2500-
const CTransaction& orphanTx = (*mi)->second.tx;
2501-
const uint256& orphanHash = orphanTx.GetHash();
2502-
vOrphanErase.push_back(orphanHash);
2503-
}
2504-
}
2505-
25062494
if (!SequenceLocks(tx, nLockTimeFlags, &prevheights, *pindex)) {
25072495
return state.DoS(100, error("%s: contains a non-BIP68-final transaction", __func__),
25082496
REJECT_INVALID, "bad-txns-nonfinal");
@@ -2592,14 +2580,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
25922580
GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase);
25932581
hashPrevBestCoinBase = block.vtx[0].GetHash();
25942582

2595-
// Erase orphan transactions include or precluded by this block
2596-
if (vOrphanErase.size()) {
2597-
int nErased = 0;
2598-
BOOST_FOREACH(uint256 &orphanHash, vOrphanErase) {
2599-
nErased += EraseOrphanTx(orphanHash);
2600-
}
2601-
LogPrint("mempool", "Erased %d orphan tx included or conflicted by block\n", nErased);
2602-
}
26032583

26042584
int64_t nTime6 = GetTimeMicros(); nTimeCallbacks += nTime6 - nTime5;
26052585
LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime6 - nTime5), nTimeCallbacks * 0.000001);
@@ -3105,6 +3085,33 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
31053085
}
31063086
// When we reach this point, we switched to a new tip (stored in pindexNewTip).
31073087

3088+
// Remove orphan transactions with cs_main
3089+
{
3090+
LOCK(cs_main);
3091+
std::vector<uint256> vOrphanErase;
3092+
for(unsigned int i = 0; i < txChanged.size(); i++) {
3093+
const CTransaction& tx = std::get<0>(txChanged[i]);
3094+
// Which orphan pool entries must we evict?
3095+
for (size_t j = 0; j < tx.vin.size(); j++) {
3096+
auto itByPrev = mapOrphanTransactionsByPrev.find(tx.vin[j].prevout);
3097+
if (itByPrev == mapOrphanTransactionsByPrev.end()) continue;
3098+
for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) {
3099+
const CTransaction& orphanTx = (*mi)->second.tx;
3100+
const uint256& orphanHash = orphanTx.GetHash();
3101+
vOrphanErase.push_back(orphanHash);
3102+
}
3103+
}
3104+
}
3105+
// Erase orphan transactions include or precluded by this block
3106+
if (vOrphanErase.size()) {
3107+
int nErased = 0;
3108+
BOOST_FOREACH(uint256 &orphanHash, vOrphanErase) {
3109+
nErased += EraseOrphanTx(orphanHash);
3110+
}
3111+
LogPrint("mempool", "Erased %d orphan tx included or conflicted by block\n", nErased);
3112+
}
3113+
}
3114+
31083115
// Notifications/callbacks that can run without cs_main
31093116

31103117
// throw all transactions though the signal-interface

0 commit comments

Comments
 (0)