From 3a48d2b83250b8ebc946c91571fdbcf7583b0db8 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 23 Nov 2016 16:19:14 -0800 Subject: [PATCH] Merge #8930: Move orphan processing to ActivateBestChain d2b88f9 Move orphan-conflict removal from main logic into a callback (Matt Corallo) 97e2802 Erase orphans per-transaction instead of per-block (Matt Corallo) ec4525c Move orphan processing to ActivateBestChain (Matt Corallo) --- src/net_processing.cpp | 43 +++++++++++++++++++++++++++--------------- src/net_processing.h | 1 + src/validation.cpp | 25 ------------------------ 3 files changed, 29 insertions(+), 40 deletions(-) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 75061f2e8..8e1cc5672 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -525,21 +525,6 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals) // mapOrphanTransactions // -// TODO This is a temporary solution while backporting Bitcoin 0.13 changes into Dash -// See caller of this method -void LoopMapOrphanTransactionsByPrev(const CTransaction &tx, std::vector &vOrphanErase) -{ - for (size_t j = 0; j < tx.vin.size(); j++) { - auto itByPrev = mapOrphanTransactionsByPrev.find(tx.vin[j].prevout); - if (itByPrev == mapOrphanTransactionsByPrev.end()) continue; - for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) { - const CTransaction& orphanTx = (*mi)->second.tx; - const uint256& orphanHash = orphanTx.GetHash(); - vOrphanErase.push_back(orphanHash); - } - } -} - bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { uint256 hash = tx.GetHash(); @@ -678,6 +663,34 @@ PeerLogicValidation::PeerLogicValidation(CConnman* connmanIn) : connman(connmanI recentRejects.reset(new CRollingBloomFilter(120000, 0.000001)); } +void PeerLogicValidation::SyncTransaction(const CTransaction& tx, const CBlockIndex* pindex, int nPosInBlock) { + if (nPosInBlock == CMainSignals::SYNC_TRANSACTION_NOT_IN_BLOCK) + return; + + LOCK(cs_main); + + std::vector vOrphanErase; + // Which orphan pool entries must we evict? + for (size_t j = 0; j < tx.vin.size(); j++) { + auto itByPrev = mapOrphanTransactionsByPrev.find(tx.vin[j].prevout); + if (itByPrev == mapOrphanTransactionsByPrev.end()) continue; + for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) { + const CTransaction& orphanTx = (*mi)->second.tx; + const uint256& orphanHash = orphanTx.GetHash(); + vOrphanErase.push_back(orphanHash); + } + } + + // Erase orphan transactions include or precluded by this block + if (vOrphanErase.size()) { + int nErased = 0; + BOOST_FOREACH(uint256 &orphanHash, vOrphanErase) { + nErased += EraseOrphanTx(orphanHash); + } + LogPrint("mempool", "Erased %d orphan tx included or conflicted by block\n", nErased); + } +} + void PeerLogicValidation::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) { const int nNewHeight = pindexNew->nHeight; connman->SetBestHeight(nNewHeight); diff --git a/src/net_processing.h b/src/net_processing.h index 9ff1ab8da..5cae487c4 100644 --- a/src/net_processing.h +++ b/src/net_processing.h @@ -33,6 +33,7 @@ private: public: PeerLogicValidation(CConnman* connmanIn); + virtual void SyncTransaction(const CTransaction& tx, const CBlockIndex* pindex, int nPosInBlock); virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload); virtual void BlockChecked(const CBlock& block, const CValidationState& state); }; diff --git a/src/validation.cpp b/src/validation.cpp index 4cf0d18af..d9ed9e8f2 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2101,7 +2101,6 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd CCheckQueueControl control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL); - std::vector vOrphanErase; std::vector prevheights; CAmount nFees = 0; int nInputs = 0; @@ -2141,22 +2140,6 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd prevheights[j] = view.AccessCoin(tx.vin[j].prevout).nHeight; } - // Which orphan pool entries must we evict? - //for (size_t j = 0; j < tx.vin.size(); j++) { - // auto itByPrev = mapOrphanTransactionsByPrev.find(tx.vin[j].prevout); - // if (itByPrev == mapOrphanTransactionsByPrev.end()) continue; - // for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) { - // const CTransaction& orphanTx = (*mi)->second.tx; - // const uint256& orphanHash = orphanTx.GetHash(); - // vOrphanErase.push_back(orphanHash); - // } - //} - // TODO This is a temporary solution while backporting Bitcoin 0.13 changes into Dash - // It is needed because the splitting of main.cpp into validation.cpp/net_processing.cpp was done out of order - // When we catch up with backporting, the above loop will be at the correct place in net_processing.cpp - // and this hack can be removed - LoopMapOrphanTransactionsByPrev(tx, vOrphanErase); - if (!SequenceLocks(tx, nLockTimeFlags, &prevheights, *pindex)) { return state.DoS(100, error("%s: contains a non-BIP68-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal"); @@ -2349,14 +2332,6 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase); hashPrevBestCoinBase = block.vtx[0]->GetHash(); - // Erase orphan transactions include or precluded by this block - if (vOrphanErase.size()) { - int nErased = 0; - BOOST_FOREACH(uint256 &orphanHash, vOrphanErase) { - nErased += EraseOrphanTx(orphanHash); - } - LogPrint("mempool", "Erased %d orphan tx included or conflicted by block\n", nErased); - } int64_t nTime6 = GetTimeMicros(); nTimeCallbacks += nTime6 - nTime5; LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime6 - nTime5), nTimeCallbacks * 0.000001);