aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/net_processing.cpp27
-rw-r--r--src/txorphanage.cpp38
-rw-r--r--src/txorphanage.h4
3 files changed, 40 insertions, 29 deletions
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 4ac50dc1f0..89586beba5 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -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;
}
diff --git a/src/txorphanage.cpp b/src/txorphanage.cpp
index 6baea9f69e..1527bdf5ea 100644
--- a/src/txorphanage.cpp
+++ b/src/txorphanage.cpp
@@ -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);
diff --git a/src/txorphanage.h b/src/txorphanage.h
index 1adc6f1d6c..1a72af175c 100644
--- a/src/txorphanage.h
+++ b/src/txorphanage.h
@@ -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 */