Skip to content

Commit a3baead

Browse files
committed
validation: use wtxid instead of txid in CheckEphemeralSpends
1 parent 4571939 commit a3baead

File tree

6 files changed

+68
-67
lines changed

6 files changed

+68
-67
lines changed

src/bench/mempool_ephemeral_spends.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ static void MempoolCheckEphemeralSpends(benchmark::Bench& bench)
7575
uint32_t iteration{0};
7676

7777
TxValidationState dummy_state;
78-
Txid dummy_txid;
78+
Wtxid dummy_wtxid;
7979

8080
bench.run([&]() NO_THREAD_SAFETY_ANALYSIS {
8181

82-
CheckEphemeralSpends({tx2_r}, /*dust_relay_rate=*/CFeeRate(iteration * COIN / 10), pool, dummy_state, dummy_txid);
82+
CheckEphemeralSpends({tx2_r}, /*dust_relay_rate=*/CFeeRate(iteration * COIN / 10), pool, dummy_state, dummy_wtxid);
8383
iteration++;
8484
});
8585
}

src/policy/ephemeral_policy.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ bool PreCheckEphemeralTx(const CTransaction& tx, CFeeRate dust_relay_rate, CAmou
3030
return true;
3131
}
3232

33-
bool CheckEphemeralSpends(const Package& package, CFeeRate dust_relay_rate, const CTxMemPool& tx_pool, TxValidationState& out_child_state, Txid& out_child_txid)
33+
bool CheckEphemeralSpends(const Package& package, CFeeRate dust_relay_rate, const CTxMemPool& tx_pool, TxValidationState& out_child_state, Wtxid& out_child_wtxid)
3434
{
3535
if (!Assume(std::ranges::all_of(package, [](const auto& tx){return tx != nullptr;}))) {
3636
// Bail out of spend checks if caller gave us an invalid package
@@ -83,9 +83,10 @@ bool CheckEphemeralSpends(const Package& package, CFeeRate dust_relay_rate, cons
8383
}
8484

8585
if (!unspent_parent_dust.empty()) {
86-
out_child_txid = tx->GetHash();
86+
const Txid& out_child_txid = tx->GetHash();
87+
out_child_wtxid = tx->GetWitnessHash();
8788
out_child_state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "missing-ephemeral-spends",
88-
strprintf("tx %s did not spend parent's ephemeral dust", out_child_txid.ToString()));
89+
strprintf("tx %s (wtxid=%s) did not spend parent's ephemeral dust", out_child_txid.ToString(), out_child_wtxid.ToString()));
8990
return false;
9091
}
9192
}

src/policy/ephemeral_policy.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ bool PreCheckEphemeralTx(const CTransaction& tx, CFeeRate dust_relay_rate, CAmou
5050
/** Must be called for each transaction(package) if any dust is in the package.
5151
* Checks that each transaction's parents have their dust spent by the child,
5252
* where parents are either in the mempool or in the package itself.
53-
* Sets out_child_state and out_child_txid on failure.
53+
* Sets out_child_state and out_child_wtxid on failure.
5454
* @returns true if all dust is properly spent.
5555
*/
56-
bool CheckEphemeralSpends(const Package& package, CFeeRate dust_relay_rate, const CTxMemPool& tx_pool, TxValidationState& out_child_state, Txid& out_child_txid);
56+
bool CheckEphemeralSpends(const Package& package, CFeeRate dust_relay_rate, const CTxMemPool& tx_pool, TxValidationState& out_child_state, Wtxid& out_child_wtxid);
5757

5858
#endif // BITCOIN_POLICY_EPHEMERAL_POLICY_H

src/test/txvalidation_tests.cpp

Lines changed: 51 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ BOOST_FIXTURE_TEST_CASE(ephemeral_tests, RegTestingSetup)
118118
CTxMemPool::setEntries empty_ancestors;
119119

120120
TxValidationState child_state;
121-
Txid child_txid;
121+
Wtxid child_wtxid;
122122

123123
// Arbitrary non-0 feerate for these tests
124124
CFeeRate dustrelay(DUST_RELAY_TX_FEE);
@@ -133,143 +133,143 @@ BOOST_FIXTURE_TEST_CASE(ephemeral_tests, RegTestingSetup)
133133
// We first start with nothing "in the mempool", using package checks
134134

135135
// Trivial single transaction with no dust
136-
BOOST_CHECK(CheckEphemeralSpends({dust_spend}, dustrelay, pool, child_state, child_txid));
136+
BOOST_CHECK(CheckEphemeralSpends({dust_spend}, dustrelay, pool, child_state, child_wtxid));
137137
BOOST_CHECK(child_state.IsValid());
138-
BOOST_CHECK_EQUAL(child_txid, Txid());
138+
BOOST_CHECK_EQUAL(child_wtxid, Wtxid());
139139

140140
// Now with dust, ok because the tx has no dusty parents
141-
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_1}, dustrelay, pool, child_state, child_txid));
141+
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_1}, dustrelay, pool, child_state, child_wtxid));
142142
BOOST_CHECK(child_state.IsValid());
143-
BOOST_CHECK_EQUAL(child_txid, Txid());
143+
BOOST_CHECK_EQUAL(child_wtxid, Wtxid());
144144

145145
// Dust checks pass
146-
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_1, dust_spend}, CFeeRate(0), pool, child_state, child_txid));
146+
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_1, dust_spend}, CFeeRate(0), pool, child_state, child_wtxid));
147147
BOOST_CHECK(child_state.IsValid());
148-
BOOST_CHECK_EQUAL(child_txid, Txid());
149-
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_1, dust_spend}, dustrelay, pool, child_state, child_txid));
148+
BOOST_CHECK_EQUAL(child_wtxid, Wtxid());
149+
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_1, dust_spend}, dustrelay, pool, child_state, child_wtxid));
150150
BOOST_CHECK(child_state.IsValid());
151-
BOOST_CHECK_EQUAL(child_txid, Txid());
151+
BOOST_CHECK_EQUAL(child_wtxid, Wtxid());
152152

153153
auto dust_non_spend = make_tx({COutPoint{dust_txid, EPHEMERAL_DUST_INDEX - 1}}, /*version=*/2);
154154

155155
// Child spending non-dust only from parent should be disallowed even if dust otherwise spent
156-
const auto dust_non_spend_txid{dust_non_spend->GetHash()};
157-
BOOST_CHECK(!CheckEphemeralSpends({grandparent_tx_1, dust_non_spend, dust_spend}, dustrelay, pool, child_state, child_txid));
156+
const auto dust_non_spend_wtxid{dust_non_spend->GetWitnessHash()};
157+
BOOST_CHECK(!CheckEphemeralSpends({grandparent_tx_1, dust_non_spend, dust_spend}, dustrelay, pool, child_state, child_wtxid));
158158
BOOST_CHECK(!child_state.IsValid());
159-
BOOST_CHECK_EQUAL(child_txid, dust_non_spend_txid);
159+
BOOST_CHECK_EQUAL(child_wtxid, dust_non_spend_wtxid);
160160
child_state = TxValidationState();
161-
child_txid = Txid();
161+
child_wtxid = Wtxid();
162162

163-
BOOST_CHECK(!CheckEphemeralSpends({grandparent_tx_1, dust_spend, dust_non_spend}, dustrelay, pool, child_state, child_txid));
163+
BOOST_CHECK(!CheckEphemeralSpends({grandparent_tx_1, dust_spend, dust_non_spend}, dustrelay, pool, child_state, child_wtxid));
164164
BOOST_CHECK(!child_state.IsValid());
165-
BOOST_CHECK_EQUAL(child_txid, dust_non_spend_txid);
165+
BOOST_CHECK_EQUAL(child_wtxid, dust_non_spend_wtxid);
166166
child_state = TxValidationState();
167-
child_txid = Txid();
167+
child_wtxid = Wtxid();
168168

169-
BOOST_CHECK(!CheckEphemeralSpends({grandparent_tx_1, dust_non_spend}, dustrelay, pool, child_state, child_txid));
169+
BOOST_CHECK(!CheckEphemeralSpends({grandparent_tx_1, dust_non_spend}, dustrelay, pool, child_state, child_wtxid));
170170
BOOST_CHECK(!child_state.IsValid());
171-
BOOST_CHECK_EQUAL(child_txid, dust_non_spend_txid);
171+
BOOST_CHECK_EQUAL(child_wtxid, dust_non_spend_wtxid);
172172
child_state = TxValidationState();
173-
child_txid = Txid();
173+
child_wtxid = Wtxid();
174174

175175
auto grandparent_tx_2 = make_ephemeral_tx(random_outpoints(1), /*version=*/2);
176176
const auto dust_txid_2 = grandparent_tx_2->GetHash();
177177

178178
// Spend dust from one but not another is ok, as long as second grandparent has no child
179-
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_1, grandparent_tx_2, dust_spend}, dustrelay, pool, child_state, child_txid));
179+
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_1, grandparent_tx_2, dust_spend}, dustrelay, pool, child_state, child_wtxid));
180180
BOOST_CHECK(child_state.IsValid());
181-
BOOST_CHECK_EQUAL(child_txid, Txid());
181+
BOOST_CHECK_EQUAL(child_wtxid, Wtxid());
182182

183183
auto dust_non_spend_both_parents = make_tx({COutPoint{dust_txid, EPHEMERAL_DUST_INDEX}, COutPoint{dust_txid_2, EPHEMERAL_DUST_INDEX - 1}}, /*version=*/2);
184184
// But if we spend from the parent, it must spend dust
185-
BOOST_CHECK(!CheckEphemeralSpends({grandparent_tx_1, grandparent_tx_2, dust_non_spend_both_parents}, dustrelay, pool, child_state, child_txid));
185+
BOOST_CHECK(!CheckEphemeralSpends({grandparent_tx_1, grandparent_tx_2, dust_non_spend_both_parents}, dustrelay, pool, child_state, child_wtxid));
186186
BOOST_CHECK(!child_state.IsValid());
187-
BOOST_CHECK_EQUAL(child_txid, dust_non_spend_both_parents->GetHash());
187+
BOOST_CHECK_EQUAL(child_wtxid, dust_non_spend_both_parents->GetWitnessHash());
188188
child_state = TxValidationState();
189-
child_txid = Txid();
189+
child_wtxid = Wtxid();
190190

191191
auto dust_spend_both_parents = make_tx({COutPoint{dust_txid, EPHEMERAL_DUST_INDEX}, COutPoint{dust_txid_2, EPHEMERAL_DUST_INDEX}}, /*version=*/2);
192-
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_1, grandparent_tx_2, dust_spend_both_parents}, dustrelay, pool, child_state, child_txid));
192+
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_1, grandparent_tx_2, dust_spend_both_parents}, dustrelay, pool, child_state, child_wtxid));
193193
BOOST_CHECK(child_state.IsValid());
194-
BOOST_CHECK_EQUAL(child_txid, Txid());
194+
BOOST_CHECK_EQUAL(child_wtxid, Wtxid());
195195

196196
// Spending other outputs is also correct, as long as the dusty one is spent
197197
const std::vector<COutPoint> all_outpoints{COutPoint(dust_txid, 0), COutPoint(dust_txid, 1), COutPoint(dust_txid, 2),
198198
COutPoint(dust_txid_2, 0), COutPoint(dust_txid_2, 1), COutPoint(dust_txid_2, 2)};
199199
auto dust_spend_all_outpoints = make_tx(all_outpoints, /*version=*/2);
200-
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_1, grandparent_tx_2, dust_spend_all_outpoints}, dustrelay, pool, child_state, child_txid));
200+
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_1, grandparent_tx_2, dust_spend_all_outpoints}, dustrelay, pool, child_state, child_wtxid));
201201
BOOST_CHECK(child_state.IsValid());
202-
BOOST_CHECK_EQUAL(child_txid, Txid());
202+
BOOST_CHECK_EQUAL(child_wtxid, Wtxid());
203203

204204
// 2 grandparents with dust <- 1 dust-spending parent with dust <- child with no dust
205205
auto parent_with_dust = make_ephemeral_tx({COutPoint{dust_txid, EPHEMERAL_DUST_INDEX}, COutPoint{dust_txid_2, EPHEMERAL_DUST_INDEX}}, /*version=*/2);
206206
// Ok for parent to have dust
207-
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_1, grandparent_tx_2, parent_with_dust}, dustrelay, pool, child_state, child_txid));
207+
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_1, grandparent_tx_2, parent_with_dust}, dustrelay, pool, child_state, child_wtxid));
208208
BOOST_CHECK(child_state.IsValid());
209-
BOOST_CHECK_EQUAL(child_txid, Txid());
209+
BOOST_CHECK_EQUAL(child_wtxid, Wtxid());
210210
auto child_no_dust = make_tx({COutPoint{parent_with_dust->GetHash(), EPHEMERAL_DUST_INDEX}}, /*version=*/2);
211-
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_1, grandparent_tx_2, parent_with_dust, child_no_dust}, dustrelay, pool, child_state, child_txid));
211+
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_1, grandparent_tx_2, parent_with_dust, child_no_dust}, dustrelay, pool, child_state, child_wtxid));
212212
BOOST_CHECK(child_state.IsValid());
213-
BOOST_CHECK_EQUAL(child_txid, Txid());
213+
BOOST_CHECK_EQUAL(child_wtxid, Wtxid());
214214

215215
// 2 grandparents with dust <- 1 dust-spending parent with dust <- child with dust
216216
auto child_with_dust = make_ephemeral_tx({COutPoint{parent_with_dust->GetHash(), EPHEMERAL_DUST_INDEX}}, /*version=*/2);
217-
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_1, grandparent_tx_2, parent_with_dust, child_with_dust}, dustrelay, pool, child_state, child_txid));
217+
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_1, grandparent_tx_2, parent_with_dust, child_with_dust}, dustrelay, pool, child_state, child_wtxid));
218218
BOOST_CHECK(child_state.IsValid());
219-
BOOST_CHECK_EQUAL(child_txid, Txid());
219+
BOOST_CHECK_EQUAL(child_wtxid, Wtxid());
220220

221221
// Tests with parents in mempool
222222

223223
// Nothing in mempool, this should pass for any transaction
224-
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_1}, dustrelay, pool, child_state, child_txid));
224+
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_1}, dustrelay, pool, child_state, child_wtxid));
225225
BOOST_CHECK(child_state.IsValid());
226-
BOOST_CHECK_EQUAL(child_txid, Txid());
226+
BOOST_CHECK_EQUAL(child_wtxid, Wtxid());
227227

228228
// Add first grandparent to mempool and fetch entry
229229
AddToMempool(pool, entry.FromTx(grandparent_tx_1));
230230

231231
// Ignores ancestors that aren't direct parents
232-
BOOST_CHECK(CheckEphemeralSpends({child_no_dust}, dustrelay, pool, child_state, child_txid));
232+
BOOST_CHECK(CheckEphemeralSpends({child_no_dust}, dustrelay, pool, child_state, child_wtxid));
233233
BOOST_CHECK(child_state.IsValid());
234-
BOOST_CHECK_EQUAL(child_txid, Txid());
234+
BOOST_CHECK_EQUAL(child_wtxid, Wtxid());
235235

236236
// Valid spend of dust with grandparent in mempool
237-
BOOST_CHECK(CheckEphemeralSpends({parent_with_dust}, dustrelay, pool, child_state, child_txid));
237+
BOOST_CHECK(CheckEphemeralSpends({parent_with_dust}, dustrelay, pool, child_state, child_wtxid));
238238
BOOST_CHECK(child_state.IsValid());
239-
BOOST_CHECK_EQUAL(child_txid, Txid());
239+
BOOST_CHECK_EQUAL(child_wtxid, Wtxid());
240240

241241
// Second grandparent in same package
242-
BOOST_CHECK(CheckEphemeralSpends({parent_with_dust, grandparent_tx_2}, dustrelay, pool, child_state, child_txid));
242+
BOOST_CHECK(CheckEphemeralSpends({parent_with_dust, grandparent_tx_2}, dustrelay, pool, child_state, child_wtxid));
243243
BOOST_CHECK(child_state.IsValid());
244-
BOOST_CHECK_EQUAL(child_txid, Txid());
244+
BOOST_CHECK_EQUAL(child_wtxid, Wtxid());
245245

246246
// Order in package doesn't matter
247-
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_2, parent_with_dust}, dustrelay, pool, child_state, child_txid));
247+
BOOST_CHECK(CheckEphemeralSpends({grandparent_tx_2, parent_with_dust}, dustrelay, pool, child_state, child_wtxid));
248248
BOOST_CHECK(child_state.IsValid());
249-
BOOST_CHECK_EQUAL(child_txid, Txid());
249+
BOOST_CHECK_EQUAL(child_wtxid, Wtxid());
250250

251251
// Add second grandparent to mempool
252252
AddToMempool(pool, entry.FromTx(grandparent_tx_2));
253253

254254
// Only spends single dust out of two direct parents
255-
BOOST_CHECK(!CheckEphemeralSpends({dust_non_spend_both_parents}, dustrelay, pool, child_state, child_txid));
255+
BOOST_CHECK(!CheckEphemeralSpends({dust_non_spend_both_parents}, dustrelay, pool, child_state, child_wtxid));
256256
BOOST_CHECK(!child_state.IsValid());
257-
BOOST_CHECK_EQUAL(child_txid, dust_non_spend_both_parents->GetHash());
257+
BOOST_CHECK_EQUAL(child_wtxid, dust_non_spend_both_parents->GetWitnessHash());
258258
child_state = TxValidationState();
259-
child_txid = Txid();
259+
child_wtxid = Wtxid();
260260

261261
// Spends both parents' dust
262-
BOOST_CHECK(CheckEphemeralSpends({parent_with_dust}, dustrelay, pool, child_state, child_txid));
262+
BOOST_CHECK(CheckEphemeralSpends({parent_with_dust}, dustrelay, pool, child_state, child_wtxid));
263263
BOOST_CHECK(child_state.IsValid());
264-
BOOST_CHECK_EQUAL(child_txid, Txid());
264+
BOOST_CHECK_EQUAL(child_wtxid, Wtxid());
265265

266266
// Now add dusty parent to mempool
267267
AddToMempool(pool, entry.FromTx(parent_with_dust));
268268

269269
// Passes dust checks even with non-parent ancestors
270-
BOOST_CHECK(CheckEphemeralSpends({child_no_dust}, dustrelay, pool, child_state, child_txid));
270+
BOOST_CHECK(CheckEphemeralSpends({child_no_dust}, dustrelay, pool, child_state, child_wtxid));
271271
BOOST_CHECK(child_state.IsValid());
272-
BOOST_CHECK_EQUAL(child_txid, Txid());
272+
BOOST_CHECK_EQUAL(child_wtxid, Wtxid());
273273
}
274274

275275
BOOST_FIXTURE_TEST_CASE(version3_tests, RegTestingSetup)

src/validation.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,8 +1438,8 @@ MempoolAcceptResult MemPoolAccept::AcceptSingleTransaction(const CTransactionRef
14381438
}
14391439

14401440
if (m_pool.m_opts.require_standard) {
1441-
Txid dummy_txid;
1442-
if (!CheckEphemeralSpends(/*package=*/{ptx}, m_pool.m_opts.dust_relay_feerate, m_pool, ws.m_state, dummy_txid)) {
1441+
Wtxid dummy_wtxid;
1442+
if (!CheckEphemeralSpends(/*package=*/{ptx}, m_pool.m_opts.dust_relay_feerate, m_pool, ws.m_state, dummy_wtxid)) {
14431443
return MempoolAcceptResult::Failure(ws.m_state);
14441444
}
14451445
}
@@ -1592,10 +1592,10 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std::
15921592
// Now that we've bounded the resulting possible ancestry count, check package for dust spends
15931593
if (m_pool.m_opts.require_standard) {
15941594
TxValidationState child_state;
1595-
Txid child_txid;
1596-
if (!CheckEphemeralSpends(txns, m_pool.m_opts.dust_relay_feerate, m_pool, child_state, child_txid)) {
1595+
Wtxid child_wtxid;
1596+
if (!CheckEphemeralSpends(txns, m_pool.m_opts.dust_relay_feerate, m_pool, child_state, child_wtxid)) {
15971597
package_state.Invalid(PackageValidationResult::PCKG_TX, "unspent-dust");
1598-
results.emplace(child_txid, MempoolAcceptResult::Failure(child_state));
1598+
results.emplace(child_wtxid, MempoolAcceptResult::Failure(child_state));
15991599
return PackageMempoolAcceptResult(package_state, std::move(results));
16001600
}
16011601
}

test/functional/mempool_ephemeral_dust.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,8 +233,8 @@ def test_unspent_ephemeral(self):
233233
unspent_sweep_tx = self.wallet.create_self_transfer_multi(fee_per_output=2000, utxos_to_spend=[dusty_tx["new_utxos"][0]], version=3)
234234
assert_greater_than(unspent_sweep_tx["fee"], sweep_tx["fee"])
235235
res = self.nodes[0].submitpackage([dusty_tx["hex"], unspent_sweep_tx["hex"]])
236-
assert_equal(res["tx-results"][unspent_sweep_tx["wtxid"]]["error"], f"missing-ephemeral-spends, tx {unspent_sweep_tx['txid']} did not spend parent's ephemeral dust")
237-
assert_raises_rpc_error(-26, f"missing-ephemeral-spends, tx {unspent_sweep_tx['txid']} did not spend parent's ephemeral dust", self.nodes[0].sendrawtransaction, unspent_sweep_tx["hex"])
236+
assert_equal(res["tx-results"][unspent_sweep_tx["wtxid"]]["error"], f"missing-ephemeral-spends, tx {unspent_sweep_tx['txid']} (wtxid={unspent_sweep_tx['wtxid']}) did not spend parent's ephemeral dust")
237+
assert_raises_rpc_error(-26, f"missing-ephemeral-spends, tx {unspent_sweep_tx['txid']} (wtxid={unspent_sweep_tx['wtxid']}) did not spend parent's ephemeral dust", self.nodes[0].sendrawtransaction, unspent_sweep_tx["hex"])
238238
assert_mempool_contents(self, self.nodes[0], expected=[dusty_tx["tx"], sweep_tx["tx"]])
239239

240240
# Spend works with dust spent
@@ -405,7 +405,7 @@ def test_no_minrelay_fee(self):
405405

406406
res = self.nodes[0].submitpackage([dusty_tx["hex"] for dusty_tx in dusty_txs] + [insufficient_sweep_tx["hex"]])
407407
assert_equal(res['package_msg'], "transaction failed")
408-
assert_equal(res['tx-results'][insufficient_sweep_tx['wtxid']]['error'], f"missing-ephemeral-spends, tx {insufficient_sweep_tx['txid']} did not spend parent's ephemeral dust")
408+
assert_equal(res['tx-results'][insufficient_sweep_tx['wtxid']]['error'], f"missing-ephemeral-spends, tx {insufficient_sweep_tx['txid']} (wtxid={insufficient_sweep_tx['wtxid']}) did not spend parent's ephemeral dust")
409409
# Everything got in except for insufficient spend
410410
assert_mempool_contents(self, self.nodes[0], expected=[dusty_tx["tx"] for dusty_tx in dusty_txs])
411411

@@ -418,7 +418,7 @@ def test_no_minrelay_fee(self):
418418

419419
res = self.nodes[0].submitpackage([dusty_tx["hex"] for dusty_tx in dusty_txs] + [insufficient_sweep_tx["hex"]])
420420
assert_equal(res['package_msg'], "transaction failed")
421-
assert_equal(res['tx-results'][insufficient_sweep_tx["wtxid"]]["error"], f"missing-ephemeral-spends, tx {insufficient_sweep_tx['txid']} did not spend parent's ephemeral dust")
421+
assert_equal(res['tx-results'][insufficient_sweep_tx["wtxid"]]["error"], f"missing-ephemeral-spends, tx {insufficient_sweep_tx['txid']} (wtxid={insufficient_sweep_tx['wtxid']}) did not spend parent's ephemeral dust")
422422
assert_mempool_contents(self, self.nodes[0], expected=[dusty_tx["tx"] for dusty_tx in dusty_txs] + [sweep_all_but_one_tx["tx"]])
423423

424424
# Cycle out the partial sweep to avoid triggering package RBF behavior which limits package to no in-mempool ancestors

0 commit comments

Comments
 (0)