Skip to content

Commit 33303b2

Browse files
committed
Merge bitcoin#30000: p2p: index TxOrphanage by wtxid, allow entries with same txid
0fb17bf [log] updates in TxOrphanage (glozow) b16da7e [functional test] attackers sending mutated orphans (glozow) 6675f64 [unit test] TxOrphanage handling of same-txid-different-witness txns (glozow) 8923edf [p2p] allow entries with the same txid in TxOrphanage (glozow) c31f148 [refactor] TxOrphanage::EraseTx by wtxid (glozow) efcc593 [refactor] TxOrphanage::HaveTx only by wtxid (glozow) 7e475b9 [p2p] don't query orphanage by txid (glozow) Pull request description: Part of bitcoin#27463 in the "make orphan handling more robust" section. Currently the main map in `TxOrphanage` is indexed by txid; we do not allow 2 transactions with the same txid into TxOrphanage. This means that if we receive a transaction and want to store it in orphanage, we'll fail to do so if a same-txid-different-witness version of the tx already exists in the orphanage. The existing orphanage entry can stay until it expires 20 minutes later, or until we find that it is invalid. This means an attacker can try to block/delay us accepting an orphan transaction by sending a mutated version of the child ahead of time. See included test. Prior to bitcoin#28970, we don't rely on the orphanage for anything and it would be relatively difficult to guess what transaction will go to a node's orphanage. After the parent(s) are accepted, if anybody sends us the correct transaction, we'll end up accepting it. However, this is a bit more painful for 1p1c: it's easier for an attacker to tell when a tx is going to hit a node's orphanage, and we need to store the correct orphan + receive the parent before we'll consider the package. If we start out with a bad orphan, we can't evict it until we receive the parent + try the 1p1c, and then we'll need to download the real child, put it in orphanage, download the parent again, and then retry 1p1c. ACKs for top commit: AngusP: ACK 0fb17bf itornaza: trACK 0fb17bf instagibbs: ACK 0fb17bf theStack: ACK 0fb17bf sr-gi: crACK [0fb17bf](bitcoin@0fb17bf) stickies-v: ACK 0fb17bf Tree-SHA512: edcbac7287c628bc27036920c2d4e4f63ec65087fbac1de9319c4f541515d669fc4e5fdc30c8b9a248b720da42b89153d388e91c7bf5caf4bc5b3b931ded1f59
2 parents 42d5a1f + 0fb17bf commit 33303b2

7 files changed

+296
-65
lines changed

src/net_processing.cpp

+19-3
Original file line numberDiff line numberDiff line change
@@ -2293,7 +2293,23 @@ bool PeerManagerImpl::AlreadyHaveTx(const GenTxid& gtxid, bool include_reconside
22932293

22942294
const uint256& hash = gtxid.GetHash();
22952295

2296-
if (m_orphanage.HaveTx(gtxid)) return true;
2296+
if (gtxid.IsWtxid()) {
2297+
// Normal query by wtxid.
2298+
if (m_orphanage.HaveTx(Wtxid::FromUint256(hash))) return true;
2299+
} else {
2300+
// Never query by txid: it is possible that the transaction in the orphanage has the same
2301+
// txid but a different witness, which would give us a false positive result. If we decided
2302+
// not to request the transaction based on this result, an attacker could prevent us from
2303+
// downloading a transaction by intentionally creating a malleated version of it. While
2304+
// only one (or none!) of these transactions can ultimately be confirmed, we have no way of
2305+
// discerning which one that is, so the orphanage can store multiple transactions with the
2306+
// same txid.
2307+
//
2308+
// While we won't query by txid, we can try to "guess" what the wtxid is based on the txid.
2309+
// A non-segwit transaction's txid == wtxid. Query this txid "casted" to a wtxid. This will
2310+
// help us find non-segwit transactions, saving bandwidth, and should have no false positives.
2311+
if (m_orphanage.HaveTx(Wtxid::FromUint256(hash))) return true;
2312+
}
22972313

22982314
if (include_reconsiderable && m_recent_rejects_reconsiderable.contains(hash)) return true;
22992315

@@ -3239,7 +3255,7 @@ void PeerManagerImpl::ProcessInvalidTx(NodeId nodeid, const CTransactionRef& ptx
32393255

32403256
// If the tx failed in ProcessOrphanTx, it should be removed from the orphanage unless the
32413257
// tx was still missing inputs. If the tx was not in the orphanage, EraseTx does nothing and returns 0.
3242-
if (Assume(state.GetResult() != TxValidationResult::TX_MISSING_INPUTS) && m_orphanage.EraseTx(ptx->GetHash()) > 0) {
3258+
if (Assume(state.GetResult() != TxValidationResult::TX_MISSING_INPUTS) && m_orphanage.EraseTx(ptx->GetWitnessHash()) > 0) {
32433259
LogDebug(BCLog::TXPACKAGES, " removed orphan tx %s (wtxid=%s)\n", ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString());
32443260
}
32453261
}
@@ -3257,7 +3273,7 @@ void PeerManagerImpl::ProcessValidTx(NodeId nodeid, const CTransactionRef& tx, c
32573273

32583274
m_orphanage.AddChildrenToWorkSet(*tx);
32593275
// If it came from the orphanage, remove it. No-op if the tx is not in txorphanage.
3260-
m_orphanage.EraseTx(tx->GetHash());
3276+
m_orphanage.EraseTx(tx->GetWitnessHash());
32613277

32623278
LogDebug(BCLog::MEMPOOL, "AcceptToMemoryPool: peer=%d: accepted %s (wtxid=%s) (poolsz %u txn, %u kB)\n",
32633279
nodeid,

src/test/fuzz/txorphan.cpp

+7-8
Original file line numberDiff line numberDiff line change
@@ -104,21 +104,20 @@ FUZZ_TARGET(txorphan, .init = initialize_orphanage)
104104
{
105105
CTransactionRef ref = orphanage.GetTxToReconsider(peer_id);
106106
if (ref) {
107-
bool have_tx = orphanage.HaveTx(GenTxid::Txid(ref->GetHash())) || orphanage.HaveTx(GenTxid::Wtxid(ref->GetWitnessHash()));
108-
Assert(have_tx);
107+
Assert(orphanage.HaveTx(ref->GetWitnessHash()));
109108
}
110109
}
111110
},
112111
[&] {
113-
bool have_tx = orphanage.HaveTx(GenTxid::Txid(tx->GetHash())) || orphanage.HaveTx(GenTxid::Wtxid(tx->GetWitnessHash()));
112+
bool have_tx = orphanage.HaveTx(tx->GetWitnessHash());
114113
// AddTx should return false if tx is too big or already have it
115114
// tx weight is unknown, we only check when tx is already in orphanage
116115
{
117116
bool add_tx = orphanage.AddTx(tx, peer_id);
118117
// have_tx == true -> add_tx == false
119118
Assert(!have_tx || !add_tx);
120119
}
121-
have_tx = orphanage.HaveTx(GenTxid::Txid(tx->GetHash())) || orphanage.HaveTx(GenTxid::Wtxid(tx->GetWitnessHash()));
120+
have_tx = orphanage.HaveTx(tx->GetWitnessHash());
122121
{
123122
bool add_tx = orphanage.AddTx(tx, peer_id);
124123
// if have_tx is still false, it must be too big
@@ -127,15 +126,15 @@ FUZZ_TARGET(txorphan, .init = initialize_orphanage)
127126
}
128127
},
129128
[&] {
130-
bool have_tx = orphanage.HaveTx(GenTxid::Txid(tx->GetHash())) || orphanage.HaveTx(GenTxid::Wtxid(tx->GetWitnessHash()));
129+
bool have_tx = orphanage.HaveTx(tx->GetWitnessHash());
131130
// EraseTx should return 0 if m_orphans doesn't have the tx
132131
{
133-
Assert(have_tx == orphanage.EraseTx(tx->GetHash()));
132+
Assert(have_tx == orphanage.EraseTx(tx->GetWitnessHash()));
134133
}
135-
have_tx = orphanage.HaveTx(GenTxid::Txid(tx->GetHash())) || orphanage.HaveTx(GenTxid::Wtxid(tx->GetWitnessHash()));
134+
have_tx = orphanage.HaveTx(tx->GetWitnessHash());
136135
// have_tx should be false and EraseTx should fail
137136
{
138-
Assert(!have_tx && !orphanage.EraseTx(tx->GetHash()));
137+
Assert(!have_tx && !orphanage.EraseTx(tx->GetWitnessHash()));
139138
}
140139
},
141140
[&] {

src/test/orphanage_tests.cpp

+55-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ class TxOrphanageTest : public TxOrphanage
3030
CTransactionRef RandomOrphan() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
3131
{
3232
LOCK(m_mutex);
33-
std::map<Txid, OrphanTx>::iterator it;
34-
it = m_orphans.lower_bound(Txid::FromUint256(InsecureRand256()));
33+
std::map<Wtxid, OrphanTx>::iterator it;
34+
it = m_orphans.lower_bound(Wtxid::FromUint256(InsecureRand256()));
3535
if (it == m_orphans.end())
3636
it = m_orphans.begin();
3737
return it->second.tx;
@@ -70,6 +70,16 @@ static CTransactionRef MakeTransactionSpending(const std::vector<COutPoint>& out
7070
return MakeTransactionRef(tx);
7171
}
7272

73+
// Make another (not necessarily valid) tx with the same txid but different wtxid.
74+
static CTransactionRef MakeMutation(const CTransactionRef& ptx)
75+
{
76+
CMutableTransaction tx(*ptx);
77+
tx.vin[0].scriptWitness.stack.push_back({5});
78+
auto mutated_tx = MakeTransactionRef(tx);
79+
assert(ptx->GetHash() == mutated_tx->GetHash());
80+
return mutated_tx;
81+
}
82+
7383
static bool EqualTxns(const std::set<CTransactionRef>& set_txns, const std::vector<CTransactionRef>& vec_txns)
7484
{
7585
if (vec_txns.size() != set_txns.size()) return false;
@@ -180,6 +190,49 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
180190
BOOST_CHECK(orphanage.CountOrphans() == 0);
181191
}
182192

193+
BOOST_AUTO_TEST_CASE(same_txid_diff_witness)
194+
{
195+
FastRandomContext det_rand{true};
196+
TxOrphanage orphanage;
197+
NodeId peer{0};
198+
199+
std::vector<COutPoint> empty_outpoints;
200+
auto parent = MakeTransactionSpending(empty_outpoints, det_rand);
201+
202+
// Create children to go into orphanage.
203+
auto child_normal = MakeTransactionSpending({{parent->GetHash(), 0}}, det_rand);
204+
auto child_mutated = MakeMutation(child_normal);
205+
206+
const auto& normal_wtxid = child_normal->GetWitnessHash();
207+
const auto& mutated_wtxid = child_mutated->GetWitnessHash();
208+
BOOST_CHECK(normal_wtxid != mutated_wtxid);
209+
210+
BOOST_CHECK(orphanage.AddTx(child_normal, peer));
211+
// EraseTx fails as transaction by this wtxid doesn't exist.
212+
BOOST_CHECK_EQUAL(orphanage.EraseTx(mutated_wtxid), 0);
213+
BOOST_CHECK(orphanage.HaveTx(normal_wtxid));
214+
BOOST_CHECK(!orphanage.HaveTx(mutated_wtxid));
215+
216+
// Must succeed. Both transactions should be present in orphanage.
217+
BOOST_CHECK(orphanage.AddTx(child_mutated, peer));
218+
BOOST_CHECK(orphanage.HaveTx(normal_wtxid));
219+
BOOST_CHECK(orphanage.HaveTx(mutated_wtxid));
220+
221+
// Outpoints map should track all entries: check that both are returned as children of the parent.
222+
std::set<CTransactionRef> expected_children{child_normal, child_mutated};
223+
BOOST_CHECK(EqualTxns(expected_children, orphanage.GetChildrenFromSamePeer(parent, peer)));
224+
225+
// Erase by wtxid: mutated first
226+
BOOST_CHECK_EQUAL(orphanage.EraseTx(mutated_wtxid), 1);
227+
BOOST_CHECK(orphanage.HaveTx(normal_wtxid));
228+
BOOST_CHECK(!orphanage.HaveTx(mutated_wtxid));
229+
230+
BOOST_CHECK_EQUAL(orphanage.EraseTx(normal_wtxid), 1);
231+
BOOST_CHECK(!orphanage.HaveTx(normal_wtxid));
232+
BOOST_CHECK(!orphanage.HaveTx(mutated_wtxid));
233+
}
234+
235+
183236
BOOST_AUTO_TEST_CASE(get_children)
184237
{
185238
FastRandomContext det_rand{true};

src/txorphanage.cpp

+30-35
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ bool TxOrphanage::AddTx(const CTransactionRef& tx, NodeId peer)
2323

2424
const Txid& hash = tx->GetHash();
2525
const Wtxid& wtxid = tx->GetWitnessHash();
26-
if (m_orphans.count(hash))
26+
if (m_orphans.count(wtxid))
2727
return false;
2828

2929
// Ignore big transactions, to avoid a
@@ -40,30 +40,28 @@ bool TxOrphanage::AddTx(const CTransactionRef& tx, NodeId peer)
4040
return false;
4141
}
4242

43-
auto ret = m_orphans.emplace(hash, OrphanTx{tx, peer, GetTime() + ORPHAN_TX_EXPIRE_TIME, m_orphan_list.size()});
43+
auto ret = m_orphans.emplace(wtxid, OrphanTx{tx, peer, GetTime() + ORPHAN_TX_EXPIRE_TIME, m_orphan_list.size()});
4444
assert(ret.second);
4545
m_orphan_list.push_back(ret.first);
46-
// Allow for lookups in the orphan pool by wtxid, as well as txid
47-
m_wtxid_to_orphan_it.emplace(tx->GetWitnessHash(), ret.first);
4846
for (const CTxIn& txin : tx->vin) {
4947
m_outpoint_to_orphan_it[txin.prevout].insert(ret.first);
5048
}
5149

52-
LogPrint(BCLog::TXPACKAGES, "stored orphan tx %s (wtxid=%s) (mapsz %u outsz %u)\n", hash.ToString(), wtxid.ToString(),
50+
LogPrint(BCLog::TXPACKAGES, "stored orphan tx %s (wtxid=%s), weight: %u (mapsz %u outsz %u)\n", hash.ToString(), wtxid.ToString(), sz,
5351
m_orphans.size(), m_outpoint_to_orphan_it.size());
5452
return true;
5553
}
5654

57-
int TxOrphanage::EraseTx(const Txid& txid)
55+
int TxOrphanage::EraseTx(const Wtxid& wtxid)
5856
{
5957
LOCK(m_mutex);
60-
return EraseTxNoLock(txid);
58+
return EraseTxNoLock(wtxid);
6159
}
6260

63-
int TxOrphanage::EraseTxNoLock(const Txid& txid)
61+
int TxOrphanage::EraseTxNoLock(const Wtxid& wtxid)
6462
{
6563
AssertLockHeld(m_mutex);
66-
std::map<Txid, OrphanTx>::iterator it = m_orphans.find(txid);
64+
std::map<Wtxid, OrphanTx>::iterator it = m_orphans.find(wtxid);
6765
if (it == m_orphans.end())
6866
return 0;
6967
for (const CTxIn& txin : it->second.tx->vin)
@@ -85,10 +83,12 @@ int TxOrphanage::EraseTxNoLock(const Txid& txid)
8583
m_orphan_list[old_pos] = it_last;
8684
it_last->second.list_pos = old_pos;
8785
}
88-
const auto& wtxid = it->second.tx->GetWitnessHash();
89-
LogPrint(BCLog::TXPACKAGES, " removed orphan tx %s (wtxid=%s)\n", txid.ToString(), wtxid.ToString());
86+
const auto& txid = it->second.tx->GetHash();
87+
// Time spent in orphanage = difference between current and entry time.
88+
// Entry time is equal to ORPHAN_TX_EXPIRE_TIME earlier than entry's expiry.
89+
LogPrint(BCLog::TXPACKAGES, " removed orphan tx %s (wtxid=%s) after %ds\n", txid.ToString(), wtxid.ToString(),
90+
GetTime() + ORPHAN_TX_EXPIRE_TIME - it->second.nTimeExpire);
9091
m_orphan_list.pop_back();
91-
m_wtxid_to_orphan_it.erase(it->second.tx->GetWitnessHash());
9292

9393
m_orphans.erase(it);
9494
return 1;
@@ -101,16 +101,16 @@ void TxOrphanage::EraseForPeer(NodeId peer)
101101
m_peer_work_set.erase(peer);
102102

103103
int nErased = 0;
104-
std::map<Txid, OrphanTx>::iterator iter = m_orphans.begin();
104+
std::map<Wtxid, OrphanTx>::iterator iter = m_orphans.begin();
105105
while (iter != m_orphans.end())
106106
{
107-
std::map<Txid, OrphanTx>::iterator maybeErase = iter++; // increment to avoid iterator becoming invalid
108-
if (maybeErase->second.fromPeer == peer)
109-
{
110-
nErased += EraseTxNoLock(maybeErase->second.tx->GetHash());
107+
// increment to avoid iterator becoming invalid after erasure
108+
const auto& [wtxid, orphan] = *iter++;
109+
if (orphan.fromPeer == peer) {
110+
nErased += EraseTxNoLock(wtxid);
111111
}
112112
}
113-
if (nErased > 0) LogPrint(BCLog::TXPACKAGES, "Erased %d orphan tx from peer=%d\n", nErased, peer);
113+
if (nErased > 0) LogPrint(BCLog::TXPACKAGES, "Erased %d orphan transaction(s) from peer=%d\n", nErased, peer);
114114
}
115115

116116
void TxOrphanage::LimitOrphans(unsigned int max_orphans, FastRandomContext& rng)
@@ -124,12 +124,12 @@ void TxOrphanage::LimitOrphans(unsigned int max_orphans, FastRandomContext& rng)
124124
// Sweep out expired orphan pool entries:
125125
int nErased = 0;
126126
int64_t nMinExpTime = nNow + ORPHAN_TX_EXPIRE_TIME - ORPHAN_TX_EXPIRE_INTERVAL;
127-
std::map<Txid, OrphanTx>::iterator iter = m_orphans.begin();
127+
std::map<Wtxid, OrphanTx>::iterator iter = m_orphans.begin();
128128
while (iter != m_orphans.end())
129129
{
130-
std::map<Txid, OrphanTx>::iterator maybeErase = iter++;
130+
std::map<Wtxid, OrphanTx>::iterator maybeErase = iter++;
131131
if (maybeErase->second.nTimeExpire <= nNow) {
132-
nErased += EraseTxNoLock(maybeErase->second.tx->GetHash());
132+
nErased += EraseTxNoLock(maybeErase->second.tx->GetWitnessHash());
133133
} else {
134134
nMinExpTime = std::min(maybeErase->second.nTimeExpire, nMinExpTime);
135135
}
@@ -142,7 +142,7 @@ void TxOrphanage::LimitOrphans(unsigned int max_orphans, FastRandomContext& rng)
142142
{
143143
// Evict a random orphan:
144144
size_t randompos = rng.randrange(m_orphan_list.size());
145-
EraseTxNoLock(m_orphan_list[randompos]->first);
145+
EraseTxNoLock(m_orphan_list[randompos]->second.tx->GetWitnessHash());
146146
++nEvicted;
147147
}
148148
if (nEvicted > 0) LogPrint(BCLog::TXPACKAGES, "orphanage overflow, removed %u tx\n", nEvicted);
@@ -159,7 +159,7 @@ void TxOrphanage::AddChildrenToWorkSet(const CTransaction& tx)
159159
for (const auto& elem : it_by_prev->second) {
160160
// Get this source peer's work set, emplacing an empty set if it didn't exist
161161
// (note: if this peer wasn't still connected, we would have removed the orphan tx already)
162-
std::set<Txid>& orphan_work_set = m_peer_work_set.try_emplace(elem->second.fromPeer).first->second;
162+
std::set<Wtxid>& orphan_work_set = m_peer_work_set.try_emplace(elem->second.fromPeer).first->second;
163163
// Add this tx to the work set
164164
orphan_work_set.insert(elem->first);
165165
LogPrint(BCLog::TXPACKAGES, "added %s (wtxid=%s) to peer %d workset\n",
@@ -169,14 +169,10 @@ void TxOrphanage::AddChildrenToWorkSet(const CTransaction& tx)
169169
}
170170
}
171171

172-
bool TxOrphanage::HaveTx(const GenTxid& gtxid) const
172+
bool TxOrphanage::HaveTx(const Wtxid& wtxid) const
173173
{
174174
LOCK(m_mutex);
175-
if (gtxid.IsWtxid()) {
176-
return m_wtxid_to_orphan_it.count(Wtxid::FromUint256(gtxid.GetHash()));
177-
} else {
178-
return m_orphans.count(Txid::FromUint256(gtxid.GetHash()));
179-
}
175+
return m_orphans.count(wtxid);
180176
}
181177

182178
CTransactionRef TxOrphanage::GetTxToReconsider(NodeId peer)
@@ -187,10 +183,10 @@ CTransactionRef TxOrphanage::GetTxToReconsider(NodeId peer)
187183
if (work_set_it != m_peer_work_set.end()) {
188184
auto& work_set = work_set_it->second;
189185
while (!work_set.empty()) {
190-
Txid txid = *work_set.begin();
186+
Wtxid wtxid = *work_set.begin();
191187
work_set.erase(work_set.begin());
192188

193-
const auto orphan_it = m_orphans.find(txid);
189+
const auto orphan_it = m_orphans.find(wtxid);
194190
if (orphan_it != m_orphans.end()) {
195191
return orphan_it->second.tx;
196192
}
@@ -215,7 +211,7 @@ void TxOrphanage::EraseForBlock(const CBlock& block)
215211
{
216212
LOCK(m_mutex);
217213

218-
std::vector<Txid> vOrphanErase;
214+
std::vector<Wtxid> vOrphanErase;
219215

220216
for (const CTransactionRef& ptx : block.vtx) {
221217
const CTransaction& tx = *ptx;
@@ -226,8 +222,7 @@ void TxOrphanage::EraseForBlock(const CBlock& block)
226222
if (itByPrev == m_outpoint_to_orphan_it.end()) continue;
227223
for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) {
228224
const CTransaction& orphanTx = *(*mi)->second.tx;
229-
const auto& orphanHash = orphanTx.GetHash();
230-
vOrphanErase.push_back(orphanHash);
225+
vOrphanErase.push_back(orphanTx.GetWitnessHash());
231226
}
232227
}
233228
}
@@ -238,7 +233,7 @@ void TxOrphanage::EraseForBlock(const CBlock& block)
238233
for (const auto& orphanHash : vOrphanErase) {
239234
nErased += EraseTxNoLock(orphanHash);
240235
}
241-
LogPrint(BCLog::TXPACKAGES, "Erased %d orphan tx included or conflicted by block\n", nErased);
236+
LogPrint(BCLog::TXPACKAGES, "Erased %d orphan transaction(s) included or conflicted by block\n", nErased);
242237
}
243238
}
244239

src/txorphanage.h

+9-13
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ class TxOrphanage {
2323
/** Add a new orphan transaction */
2424
bool AddTx(const CTransactionRef& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
2525

26-
/** Check if we already have an orphan transaction (by txid or wtxid) */
27-
bool HaveTx(const GenTxid& gtxid) const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
26+
/** Check if we already have an orphan transaction (by wtxid only) */
27+
bool HaveTx(const Wtxid& wtxid) const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
2828

2929
/** Extract a transaction from a peer's work set
3030
* Returns nullptr if there are no transactions to work on.
@@ -33,8 +33,8 @@ class TxOrphanage {
3333
*/
3434
CTransactionRef GetTxToReconsider(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
3535

36-
/** Erase an orphan by txid */
37-
int EraseTx(const Txid& txid) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
36+
/** Erase an orphan by wtxid */
37+
int EraseTx(const Wtxid& wtxid) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
3838

3939
/** Erase all orphans announced by a peer (eg, after that peer disconnects) */
4040
void EraseForPeer(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
@@ -77,12 +77,12 @@ class TxOrphanage {
7777
size_t list_pos;
7878
};
7979

80-
/** Map from txid to orphan transaction record. Limited by
80+
/** Map from wtxid to orphan transaction record. Limited by
8181
* -maxorphantx/DEFAULT_MAX_ORPHAN_TRANSACTIONS */
82-
std::map<Txid, OrphanTx> m_orphans GUARDED_BY(m_mutex);
82+
std::map<Wtxid, OrphanTx> m_orphans GUARDED_BY(m_mutex);
8383

8484
/** Which peer provided the orphans that need to be reconsidered */
85-
std::map<NodeId, std::set<Txid>> m_peer_work_set GUARDED_BY(m_mutex);
85+
std::map<NodeId, std::set<Wtxid>> m_peer_work_set GUARDED_BY(m_mutex);
8686

8787
using OrphanMap = decltype(m_orphans);
8888

@@ -102,12 +102,8 @@ class TxOrphanage {
102102
/** Orphan transactions in vector for quick random eviction */
103103
std::vector<OrphanMap::iterator> m_orphan_list GUARDED_BY(m_mutex);
104104

105-
/** Index from wtxid into the m_orphans to lookup orphan
106-
* transactions using their witness ids. */
107-
std::map<Wtxid, OrphanMap::iterator> m_wtxid_to_orphan_it GUARDED_BY(m_mutex);
108-
109-
/** Erase an orphan by txid */
110-
int EraseTxNoLock(const Txid& txid) EXCLUSIVE_LOCKS_REQUIRED(m_mutex);
105+
/** Erase an orphan by wtxid */
106+
int EraseTxNoLock(const Wtxid& wtxid) EXCLUSIVE_LOCKS_REQUIRED(m_mutex);
111107
};
112108

113109
#endif // BITCOIN_TXORPHANAGE_H

0 commit comments

Comments
 (0)