mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-08 10:31:50 -05:00
txorphanage: Extract OrphanageAddTx
Extract code from AddOrphanTx into OrphanageAddTx.
This commit is contained in:
parent
f294da7274
commit
1041616d7e
3 changed files with 40 additions and 29 deletions
|
@ -1098,37 +1098,12 @@ static void AddToCompactExtraTransactions(const CTransactionRef& tx) EXCLUSIVE_L
|
|||
|
||||
bool AddOrphanTx(const CTransactionRef& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans)
|
||||
{
|
||||
const uint256& hash = tx->GetHash();
|
||||
if (mapOrphanTransactions.count(hash))
|
||||
if (!OrphanageAddTx(tx, peer)) {
|
||||
return false;
|
||||
|
||||
// Ignore big transactions, to avoid a
|
||||
// send-big-orphans memory exhaustion attack. If a peer has a legitimate
|
||||
// large transaction with a missing parent then we assume
|
||||
// it will rebroadcast it later, after the parent transaction(s)
|
||||
// have been mined or received.
|
||||
// 100 orphans, each of which is at most 100,000 bytes big is
|
||||
// at most 10 megabytes of orphans and somewhat more byprev index (in the worst case):
|
||||
unsigned int sz = GetTransactionWeight(*tx);
|
||||
if (sz > MAX_STANDARD_TX_WEIGHT)
|
||||
{
|
||||
LogPrint(BCLog::MEMPOOL, "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ret = mapOrphanTransactions.emplace(hash, COrphanTx{tx, peer, GetTime() + ORPHAN_TX_EXPIRE_TIME, g_orphan_list.size()});
|
||||
assert(ret.second);
|
||||
g_orphan_list.push_back(ret.first);
|
||||
// Allow for lookups in the orphan pool by wtxid, as well as txid
|
||||
g_orphans_by_wtxid.emplace(tx->GetWitnessHash(), ret.first);
|
||||
for (const CTxIn& txin : tx->vin) {
|
||||
mapOrphanTransactionsByPrev[txin.prevout].insert(ret.first);
|
||||
}
|
||||
|
||||
AddToCompactExtraTransactions(tx);
|
||||
|
||||
LogPrint(BCLog::MEMPOOL, "stored orphan tx %s (mapsz %u outsz %u)\n", hash.ToString(),
|
||||
mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#include <cassert>
|
||||
|
||||
/** Expiration time for orphan transactions in seconds */
|
||||
static constexpr int64_t ORPHAN_TX_EXPIRE_TIME = 20 * 60;
|
||||
/** Minimum time between orphan transactions expire time checks in seconds */
|
||||
static constexpr int64_t ORPHAN_TX_EXPIRE_INTERVAL = 5 * 60;
|
||||
|
||||
|
@ -22,6 +24,42 @@ std::map<uint256, std::map<uint256, COrphanTx>::iterator> g_orphans_by_wtxid GUA
|
|||
|
||||
std::vector<std::map<uint256, COrphanTx>::iterator> g_orphan_list GUARDED_BY(g_cs_orphans);
|
||||
|
||||
bool OrphanageAddTx(const CTransactionRef& tx, NodeId peer)
|
||||
{
|
||||
AssertLockHeld(g_cs_orphans);
|
||||
|
||||
const uint256& hash = tx->GetHash();
|
||||
if (mapOrphanTransactions.count(hash))
|
||||
return false;
|
||||
|
||||
// Ignore big transactions, to avoid a
|
||||
// send-big-orphans memory exhaustion attack. If a peer has a legitimate
|
||||
// large transaction with a missing parent then we assume
|
||||
// it will rebroadcast it later, after the parent transaction(s)
|
||||
// have been mined or received.
|
||||
// 100 orphans, each of which is at most 100,000 bytes big is
|
||||
// at most 10 megabytes of orphans and somewhat more byprev index (in the worst case):
|
||||
unsigned int sz = GetTransactionWeight(*tx);
|
||||
if (sz > MAX_STANDARD_TX_WEIGHT)
|
||||
{
|
||||
LogPrint(BCLog::MEMPOOL, "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ret = mapOrphanTransactions.emplace(hash, COrphanTx{tx, peer, GetTime() + ORPHAN_TX_EXPIRE_TIME, g_orphan_list.size()});
|
||||
assert(ret.second);
|
||||
g_orphan_list.push_back(ret.first);
|
||||
// Allow for lookups in the orphan pool by wtxid, as well as txid
|
||||
g_orphans_by_wtxid.emplace(tx->GetWitnessHash(), ret.first);
|
||||
for (const CTxIn& txin : tx->vin) {
|
||||
mapOrphanTransactionsByPrev[txin.prevout].insert(ret.first);
|
||||
}
|
||||
|
||||
LogPrint(BCLog::MEMPOOL, "stored orphan tx %s (mapsz %u outsz %u)\n", hash.ToString(),
|
||||
mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
int EraseOrphanTx(const uint256& txid)
|
||||
{
|
||||
std::map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(txid);
|
||||
|
|
|
@ -9,9 +9,6 @@
|
|||
#include <primitives/transaction.h>
|
||||
#include <sync.h>
|
||||
|
||||
/** Expiration time for orphan transactions in seconds */
|
||||
static constexpr int64_t ORPHAN_TX_EXPIRE_TIME = 20 * 60;
|
||||
|
||||
/** Guards orphan transactions and extra txs for compact blocks */
|
||||
extern RecursiveMutex g_cs_orphans;
|
||||
|
||||
|
@ -29,6 +26,7 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRE
|
|||
void AddChildrenToWorkSet(const CTransaction& tx, std::set<uint256>& orphan_work_set) EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans);
|
||||
bool HaveOrphanTx(const GenTxid& gtxid) EXCLUSIVE_LOCKS_REQUIRED(!g_cs_orphans);
|
||||
std::pair<CTransactionRef, NodeId> GetOrphanTx(const uint256& txid) EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans);
|
||||
bool OrphanageAddTx(const CTransactionRef& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans);
|
||||
|
||||
/** Map from txid to orphan transaction record. Limited by
|
||||
* -maxorphantx/DEFAULT_MAX_ORPHAN_TRANSACTIONS */
|
||||
|
|
Loading…
Add table
Reference in a new issue