Skip to content

Commit 6675f64

Browse files
committed
[unit test] TxOrphanage handling of same-txid-different-witness txns
1 parent 8923edf commit 6675f64

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

src/test/orphanage_tests.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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};

0 commit comments

Comments
 (0)