|
6 | 6 |
|
7 | 7 | from test_framework.messages import (
|
8 | 8 | MAX_BIP125_RBF_SEQUENCE,
|
| 9 | + WITNESS_SCALE_FACTOR, |
9 | 10 | )
|
10 | 11 | from test_framework.test_framework import BitcoinTestFramework
|
11 | 12 | from test_framework.util import (
|
|
21 | 22 | )
|
22 | 23 |
|
23 | 24 | MAX_REPLACEMENT_CANDIDATES = 100
|
| 25 | +V3_MAX_VSIZE = 10000 |
24 | 26 |
|
25 | 27 | def cleanup(extra_args=None):
|
26 | 28 | def decorator(func):
|
@@ -49,6 +51,20 @@ def check_mempool(self, txids):
|
49 | 51 | assert_equal(len(txids), len(mempool_contents))
|
50 | 52 | assert all([txid in txids for txid in mempool_contents])
|
51 | 53 |
|
| 54 | + @cleanup(extra_args=["-datacarriersize=20000", "-acceptnonstdtxn=1"]) |
| 55 | + def test_v3_max_vsize(self): |
| 56 | + node = self.nodes[0] |
| 57 | + self.log.info("Test v3-specific maximum transaction vsize") |
| 58 | + tx_v3_heavy = self.wallet.create_self_transfer(target_weight=(V3_MAX_VSIZE + 1) * WITNESS_SCALE_FACTOR, version=3) |
| 59 | + assert_greater_than_or_equal(tx_v3_heavy["tx"].get_vsize(), V3_MAX_VSIZE) |
| 60 | + expected_error_heavy = f"v3-rule-violation, v3 tx {tx_v3_heavy['txid']} (wtxid={tx_v3_heavy['wtxid']}) is too big" |
| 61 | + assert_raises_rpc_error(-26, expected_error_heavy, node.sendrawtransaction, tx_v3_heavy["hex"]) |
| 62 | + self.check_mempool([]) |
| 63 | + |
| 64 | + # Ensure we are hitting the v3-specific limit and not something else |
| 65 | + tx_v2_heavy = self.wallet.send_self_transfer(from_node=node, target_weight=(V3_MAX_VSIZE + 1) * WITNESS_SCALE_FACTOR, version=2) |
| 66 | + self.check_mempool([tx_v2_heavy["txid"]]) |
| 67 | + |
52 | 68 | @cleanup(extra_args=["-datacarriersize=1000", "-acceptnonstdtxn=1"])
|
53 | 69 | def test_v3_acceptance(self):
|
54 | 70 | node = self.nodes[0]
|
@@ -201,21 +217,47 @@ def test_nondefault_package_limits(self):
|
201 | 217 | """
|
202 | 218 | node = self.nodes[0]
|
203 | 219 | self.log.info("Test that a decreased limitdescendantsize also applies to v3 child")
|
204 |
| - tx_v3_parent_large1 = self.wallet.send_self_transfer(from_node=node, target_weight=99900, version=3) |
205 |
| - tx_v3_child_large1 = self.wallet.create_self_transfer(utxo_to_spend=tx_v3_parent_large1["new_utxo"], version=3) |
206 |
| - # Child is within v3 limits, but parent's descendant limit is exceeded |
207 |
| - assert_greater_than(1000, tx_v3_child_large1["tx"].get_vsize()) |
| 220 | + parent_target_weight = 9990 * WITNESS_SCALE_FACTOR |
| 221 | + child_target_weight = 500 * WITNESS_SCALE_FACTOR |
| 222 | + tx_v3_parent_large1 = self.wallet.send_self_transfer( |
| 223 | + from_node=node, |
| 224 | + target_weight=parent_target_weight, |
| 225 | + version=3 |
| 226 | + ) |
| 227 | + tx_v3_child_large1 = self.wallet.create_self_transfer( |
| 228 | + utxo_to_spend=tx_v3_parent_large1["new_utxo"], |
| 229 | + target_weight=child_target_weight, |
| 230 | + version=3 |
| 231 | + ) |
| 232 | + |
| 233 | + # Parent and child are within v3 limits, but parent's 10kvB descendant limit is exceeded |
| 234 | + assert_greater_than_or_equal(V3_MAX_VSIZE, tx_v3_parent_large1["tx"].get_vsize()) |
| 235 | + assert_greater_than_or_equal(1000, tx_v3_child_large1["tx"].get_vsize()) |
| 236 | + assert_greater_than(tx_v3_parent_large1["tx"].get_vsize() + tx_v3_child_large1["tx"].get_vsize(), 10000) |
| 237 | + |
208 | 238 | assert_raises_rpc_error(-26, f"too-long-mempool-chain, exceeds descendant size limit for tx {tx_v3_parent_large1['txid']}", node.sendrawtransaction, tx_v3_child_large1["hex"])
|
209 | 239 | self.check_mempool([tx_v3_parent_large1["txid"]])
|
210 | 240 | assert_equal(node.getmempoolentry(tx_v3_parent_large1["txid"])["descendantcount"], 1)
|
211 | 241 | self.generate(node, 1)
|
212 | 242 |
|
213 | 243 | self.log.info("Test that a decreased limitancestorsize also applies to v3 parent")
|
214 | 244 | self.restart_node(0, extra_args=["-limitancestorsize=10", "-datacarriersize=40000", "-acceptnonstdtxn=1"])
|
215 |
| - tx_v3_parent_large2 = self.wallet.send_self_transfer(from_node=node, target_weight=99900, version=3) |
216 |
| - tx_v3_child_large2 = self.wallet.create_self_transfer(utxo_to_spend=tx_v3_parent_large2["new_utxo"], version=3) |
217 |
| - # Child is within v3 limits |
| 245 | + tx_v3_parent_large2 = self.wallet.send_self_transfer( |
| 246 | + from_node=node, |
| 247 | + target_weight=parent_target_weight, |
| 248 | + version=3 |
| 249 | + ) |
| 250 | + tx_v3_child_large2 = self.wallet.create_self_transfer( |
| 251 | + utxo_to_spend=tx_v3_parent_large2["new_utxo"], |
| 252 | + target_weight=child_target_weight, |
| 253 | + version=3 |
| 254 | + ) |
| 255 | + |
| 256 | + # Parent and child are within v3 limits |
| 257 | + assert_greater_than_or_equal(V3_MAX_VSIZE, tx_v3_parent_large2["tx"].get_vsize()) |
218 | 258 | assert_greater_than_or_equal(1000, tx_v3_child_large2["tx"].get_vsize())
|
| 259 | + assert_greater_than(tx_v3_parent_large2["tx"].get_vsize() + tx_v3_child_large2["tx"].get_vsize(), 10000) |
| 260 | + |
219 | 261 | assert_raises_rpc_error(-26, f"too-long-mempool-chain, exceeds ancestor size limit", node.sendrawtransaction, tx_v3_child_large2["hex"])
|
220 | 262 | self.check_mempool([tx_v3_parent_large2["txid"]])
|
221 | 263 |
|
@@ -585,6 +627,7 @@ def run_test(self):
|
585 | 627 | node = self.nodes[0]
|
586 | 628 | self.wallet = MiniWallet(node)
|
587 | 629 | self.generate(self.wallet, 120)
|
| 630 | + self.test_v3_max_vsize() |
588 | 631 | self.test_v3_acceptance()
|
589 | 632 | self.test_v3_replacement()
|
590 | 633 | self.test_v3_bip125()
|
|
0 commit comments