Resolves #34206
I'm not certain the test is worth keeping, but included it for now to show minimal example that crashes without fix. Can be removed.
Resolves #34206
I'm not certain the test is worth keeping, but included it for now to show minimal example that crashes without fix. Can be removed.
<!--e57a25ab6845829454e8d69fc972939a-->
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
<!--006a51241073e994b41acfe9ec718e94-->
For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/34238.
<!--021abf342d371248e50ceaed478a90ca-->
See the guideline for information on the review process.
| Type | Reviewers |
|---|---|
| ACK | bensig, dergoegge |
| Stale ACK | ismaelsadeeq |
If your review is incorrectly listed, please copy-paste <code><!--meta-tag:bot-skip--></code> into the comment that the bot should ignore.
<!--5faf32d7da4f0f540f40219e4f7537a3-->
Possible places where named args for integral literals may be used (e.g. func(x, /*named_arg=*/0) in C++, and func(x, named_arg=0) in Python):
<sup>2026-01-12</sup>
Code review ACK a591867c4100d349aa4b25328b609f983d7f8741
First commit removed erroneous assume, this is in line with my understanding of the solution here #34206 (comment)
The test also looks good to me. I ran the test with the assumption, and the assume got triggered; the test failed.
Without the assume the test passes.
701 | + # Now try to create a v2 transaction - this triggers AvailableCoins with 702 | + # check_version_trucness=true. The v2 parent has truc_child_in_mempool set 703 | + # because the truc child is in mempool. 704 | + new_v2_outputs = {self.bob.getnewaddress(): 0.1} 705 | + raw_tx = self.alice.createrawtransaction(inputs=[], outputs=new_v2_outputs, version=2) 706 | + self.alice.fundrawtransaction(raw_tx, {'include_unsafe': True})
Might be worth testing that you can also create + broadcast this transaction. But this doesn't mean all TRUC rules are out the window:
diff --git a/test/functional/wallet_v3_txs.py b/test/functional/wallet_v3_txs.py
index 85865c3e54f..4728416099b 100755
--- a/test/functional/wallet_v3_txs.py
+++ b/test/functional/wallet_v3_txs.py
@@ -676,8 +676,15 @@ class WalletV3Test(BitcoinTestFramework):
self.generate(self.nodes[0], 1)
# Verify both transactions are confirmed
- assert_equal(self.alice.gettransaction(v2_txid)["confirmations"], 2)
- assert_equal(self.alice.gettransaction(truc_txid)["confirmations"], 1)
+ wallet_tx_v2 = self.alice.gettransaction(v2_txid)
+ wallet_tx_truc = self.alice.gettransaction(truc_txid)
+
+ assert_equal(wallet_tx_v2["confirmations"], 2)
+ assert_equal(wallet_tx_truc["confirmations"], 1)
+
+ # Check that their versions are correct
+ assert_equal(self.alice.decoderawtransaction(wallet_tx_v2["hex"])["version"], 2)
+ assert_equal(self.alice.decoderawtransaction(wallet_tx_truc["hex"])["version"], 3)
# Check listunspent before reorg - should have the truc output
unspent_before = self.alice.listunspent()
@@ -686,6 +693,8 @@ class WalletV3Test(BitcoinTestFramework):
# Trigger the reorg
self.trigger_reorg(fork_blocks)
+ # The TRUC transaction is now in a cluster of size 3, which is only permitted in a reorg.
+ assert_equal(self.nodes[0].getmempoolcluster(truc_txid)["txcount"], 3)
# After reorg, both transactions should be back in mempool
mempool = self.nodes[0].getrawmempool()
@@ -698,12 +707,34 @@ class WalletV3Test(BitcoinTestFramework):
unspent_txids_after = [u["txid"] for u in unspent_after]
assert truc_txid in unspent_txids_after
+ total_unconfirmed_amount = sum([u["amount"] for u in self.alice.listunspent(minconf=0)])
+ # We cannot create a transaction spending both outputs, regardless of version.
+ output_too_high = {self.bob.getnewaddress(): total_unconfirmed_amount - Decimal("0.001")}
+ for version in [2, 3]:
+ raw_output_too_high = self.alice.createrawtransaction(inputs=[], outputs=output_too_high, version=version)
+ assert_raises_rpc_error(
+ -4,
+ "Insufficient funds",
+ self.alice.fundrawtransaction,
+ raw_output_too_high,
+ {'include_unsafe' : True}
+ )
+
# Now try to create a v2 transaction - this triggers AvailableCoins with
# check_version_trucness=true. The v2 parent has truc_child_in_mempool set
# because the truc child is in mempool.
new_v2_outputs = {self.bob.getnewaddress(): 0.1}
- raw_tx = self.alice.createrawtransaction(inputs=[], outputs=new_v2_outputs, version=2)
- self.alice.fundrawtransaction(raw_tx, {'include_unsafe': True})
+ raw_v2_child = self.alice.createrawtransaction(inputs=[], outputs=new_v2_outputs, version=2)
+ raw_v2_with_v3_sibling = self.alice.fundrawtransaction(raw_v2_child, {'include_unsafe': True})
+
+ # See that this transaction can be added to mempool
+ signed_raw_v2_with_v3_sibling = self.alice.signrawtransactionwithwallet(raw_v2_with_v3_sibling["hex"])
+ self.alice.sendrawtransaction(signed_raw_v2_with_v3_sibling["hex"])
+
+ # This TRUC transaction is in a cluster of size 4
+ assert_equal(self.nodes[0].getmempoolcluster(truc_txid)["txcount"], 4)
+
+
if __name__ == '__main__':
WalletV3Test(__file__).main()
took, just made the insufficient funds case a little more "obvious" by subtracting a larger number
a591867c410 lgtm, can add more to the test
ACK d09a19fd41cb71a5d1c10297763e72bc551a7d3a
utACK d09a19fd41cb71a5d1c10297763e72bc551a7d3a