Changeset View
Changeset View
Standalone View
Standalone View
src/net_processing.cpp
Show First 20 Lines • Show All 1,181 Lines • ▼ Show 20 Lines | switch (inv.type) { | ||||
} | } | ||||
} | } | ||||
// Use pcoinsTip->HaveCoinInCache as a quick approximation to | // Use pcoinsTip->HaveCoinInCache as a quick approximation to | ||||
// exclude requesting or processing some txs which have already been | // exclude requesting or processing some txs which have already been | ||||
// included in a block. As this is best effort, we only check for | // included in a block. As this is best effort, we only check for | ||||
// output 0 and 1. This works well enough in practice and we get | // output 0 and 1. This works well enough in practice and we get | ||||
// diminishing returns with 2 onward. | // diminishing returns with 2 onward. | ||||
const TxId txid(inv.hash); | |||||
return recentRejects->contains(inv.hash) || | return recentRejects->contains(inv.hash) || | ||||
g_mempool.exists(inv.hash) || | g_mempool.exists(inv.hash) || | ||||
pcoinsTip->HaveCoinInCache(COutPoint(inv.hash, 0)) || | pcoinsTip->HaveCoinInCache(COutPoint(txid, 0)) || | ||||
pcoinsTip->HaveCoinInCache(COutPoint(inv.hash, 1)); | pcoinsTip->HaveCoinInCache(COutPoint(txid, 1)); | ||||
} | } | ||||
case MSG_BLOCK: | case MSG_BLOCK: | ||||
return LookupBlockIndex(inv.hash) != nullptr; | return LookupBlockIndex(inv.hash) != nullptr; | ||||
} | } | ||||
// Don't know what it is, just say we already got one | // Don't know what it is, just say we already got one | ||||
return true; | return true; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,270 Lines • ▼ Show 20 Lines | else if (strCommand == NetMsgType::TX) { | ||||
CInv inv(MSG_TX, tx.GetId()); | CInv inv(MSG_TX, tx.GetId()); | ||||
pfrom->AddInventoryKnown(inv); | pfrom->AddInventoryKnown(inv); | ||||
LOCK2(cs_main, g_cs_orphans); | LOCK2(cs_main, g_cs_orphans); | ||||
bool fMissingInputs = false; | bool fMissingInputs = false; | ||||
CValidationState state; | CValidationState state; | ||||
pfrom->setAskFor.erase(inv.hash); | const TxId txid(inv.hash); | ||||
mapAlreadyAskedFor.erase(inv.hash); | pfrom->setAskFor.erase(txid); | ||||
mapAlreadyAskedFor.erase(txid); | |||||
if (!AlreadyHave(inv) && | if (!AlreadyHave(inv) && | ||||
AcceptToMemoryPool(config, g_mempool, state, ptx, true, | AcceptToMemoryPool(config, g_mempool, state, ptx, true, | ||||
&fMissingInputs)) { | &fMissingInputs)) { | ||||
g_mempool.check(pcoinsTip.get()); | g_mempool.check(pcoinsTip.get()); | ||||
RelayTransaction(tx, connman); | RelayTransaction(tx, connman); | ||||
for (size_t i = 0; i < tx.vout.size(); i++) { | for (size_t i = 0; i < tx.vout.size(); i++) { | ||||
vWorkQueue.emplace_back(inv.hash, i); | vWorkQueue.emplace_back(txid, i); | ||||
} | } | ||||
pfrom->nLastTXTime = GetTime(); | pfrom->nLastTXTime = GetTime(); | ||||
LogPrint(BCLog::MEMPOOL, | LogPrint(BCLog::MEMPOOL, | ||||
"AcceptToMemoryPool: peer=%d: accepted %s " | "AcceptToMemoryPool: peer=%d: accepted %s " | ||||
"(poolsz %u txn, %u kB)\n", | "(poolsz %u txn, %u kB)\n", | ||||
pfrom->GetId(), tx.GetId().ToString(), g_mempool.size(), | pfrom->GetId(), tx.GetId().ToString(), g_mempool.size(), | ||||
g_mempool.DynamicMemoryUsage() / 1000); | g_mempool.DynamicMemoryUsage() / 1000); | ||||
// Recursively process any orphan transactions that depended on this | // Recursively process any orphan transactions that depended on this | ||||
// one | // one | ||||
std::unordered_map<NodeId, uint32_t> rejectCountPerNode; | std::unordered_map<NodeId, uint32_t> rejectCountPerNode; | ||||
while (!vWorkQueue.empty()) { | while (!vWorkQueue.empty()) { | ||||
auto itByPrev = | auto itByPrev = | ||||
mapOrphanTransactionsByPrev.find(vWorkQueue.front()); | mapOrphanTransactionsByPrev.find(vWorkQueue.front()); | ||||
vWorkQueue.pop_front(); | vWorkQueue.pop_front(); | ||||
if (itByPrev == mapOrphanTransactionsByPrev.end()) { | if (itByPrev == mapOrphanTransactionsByPrev.end()) { | ||||
continue; | continue; | ||||
} | } | ||||
for (auto mi = itByPrev->second.begin(); | for (auto mi = itByPrev->second.begin(); | ||||
mi != itByPrev->second.end(); ++mi) { | mi != itByPrev->second.end(); ++mi) { | ||||
const CTransactionRef &porphanTx = (*mi)->second.tx; | const CTransactionRef &porphanTx = (*mi)->second.tx; | ||||
const CTransaction &orphanTx = *porphanTx; | const CTransaction &orphanTx = *porphanTx; | ||||
const uint256 &orphanId = orphanTx.GetId(); | const TxId &orphanId = orphanTx.GetId(); | ||||
NodeId fromPeer = (*mi)->second.fromPeer; | NodeId fromPeer = (*mi)->second.fromPeer; | ||||
bool fMissingInputs2 = false; | bool fMissingInputs2 = false; | ||||
// Use a dummy CValidationState so someone can't setup nodes | // Use a dummy CValidationState so someone can't setup nodes | ||||
// to counter-DoS based on orphan resolution (that is, | // to counter-DoS based on orphan resolution (that is, | ||||
// feeding people an invalid transaction based on LegitTxX | // feeding people an invalid transaction based on LegitTxX | ||||
// in order to get anyone relaying LegitTxX banned) | // in order to get anyone relaying LegitTxX banned) | ||||
CValidationState stateDummy; | CValidationState stateDummy; | ||||
▲ Show 20 Lines • Show All 1,833 Lines • Show Last 20 Lines |