11
11
12
12
from test_framework .blocktools import COINBASE_MATURITY
13
13
from test_framework .test_framework import BitcoinTestFramework
14
- from test_framework .util import assert_equal , assert_raises_rpc_error , satoshi_round
14
+ from test_framework .util import (
15
+ assert_equal ,
16
+ assert_raises_rpc_error ,
17
+ chain_transaction ,
18
+ )
15
19
16
20
MAX_ANCESTORS = 25
17
21
MAX_DESCENDANTS = 25
@@ -24,23 +28,6 @@ def set_test_params(self):
24
28
def skip_test_if_missing_module (self ):
25
29
self .skip_if_no_wallet ()
26
30
27
- # Build a transaction that spends parent_txid:vout
28
- # Return amount sent
29
- def chain_transaction (self , node , parent_txids , vouts , value , fee , num_outputs ):
30
- send_value = satoshi_round ((value - fee )/ num_outputs )
31
- inputs = []
32
- for (txid , vout ) in zip (parent_txids , vouts ):
33
- inputs .append ({'txid' : txid , 'vout' : vout })
34
- outputs = {}
35
- for _ in range (num_outputs ):
36
- outputs [node .getnewaddress ()] = send_value
37
- rawtx = node .createrawtransaction (inputs , outputs , 0 , True )
38
- signedtx = node .signrawtransactionwithwallet (rawtx )
39
- txid = node .sendrawtransaction (signedtx ['hex' ])
40
- fulltx = node .getrawtransaction (txid , 1 )
41
- assert len (fulltx ['vout' ]) == num_outputs # make sure we didn't generate a change output
42
- return (txid , send_value )
43
-
44
31
def run_test (self ):
45
32
# Mine some blocks and have them mature.
46
33
self .nodes [0 ].generate (COINBASE_MATURITY + 1 )
@@ -53,32 +40,32 @@ def run_test(self):
53
40
# MAX_ANCESTORS transactions off a confirmed tx should be fine
54
41
chain = []
55
42
for _ in range (4 ):
56
- (txid , sent_value ) = self . chain_transaction (self .nodes [0 ], [txid ], [vout ], value , fee , 2 )
43
+ (txid , sent_value ) = chain_transaction (self .nodes [0 ], [txid ], [vout ], value , fee , 2 )
57
44
vout = 0
58
45
value = sent_value
59
46
chain .append ([txid , value ])
60
47
for _ in range (MAX_ANCESTORS - 4 ):
61
- (txid , sent_value ) = self . chain_transaction (self .nodes [0 ], [txid ], [0 ], value , fee , 1 )
48
+ (txid , sent_value ) = chain_transaction (self .nodes [0 ], [txid ], [0 ], value , fee , 1 )
62
49
value = sent_value
63
50
chain .append ([txid , value ])
64
- (second_chain , second_chain_value ) = self . chain_transaction (self .nodes [0 ], [utxo [1 ]['txid' ]], [utxo [1 ]['vout' ]], utxo [1 ]['amount' ], fee , 1 )
51
+ (second_chain , second_chain_value ) = chain_transaction (self .nodes [0 ], [utxo [1 ]['txid' ]], [utxo [1 ]['vout' ]], utxo [1 ]['amount' ], fee , 1 )
65
52
66
53
# Check mempool has MAX_ANCESTORS + 1 transactions in it
67
54
assert_equal (len (self .nodes [0 ].getrawmempool (True )), MAX_ANCESTORS + 1 )
68
55
69
56
# Adding one more transaction on to the chain should fail.
70
- assert_raises_rpc_error (- 26 , "too-long-mempool-chain, too many unconfirmed ancestors [limit: 25]" , self . chain_transaction , self .nodes [0 ], [txid ], [0 ], value , fee , 1 )
57
+ assert_raises_rpc_error (- 26 , "too-long-mempool-chain, too many unconfirmed ancestors [limit: 25]" , chain_transaction , self .nodes [0 ], [txid ], [0 ], value , fee , 1 )
71
58
# ...even if it chains on from some point in the middle of the chain.
72
- assert_raises_rpc_error (- 26 , "too-long-mempool-chain, too many descendants" , self . chain_transaction , self .nodes [0 ], [chain [2 ][0 ]], [1 ], chain [2 ][1 ], fee , 1 )
73
- assert_raises_rpc_error (- 26 , "too-long-mempool-chain, too many descendants" , self . chain_transaction , self .nodes [0 ], [chain [1 ][0 ]], [1 ], chain [1 ][1 ], fee , 1 )
59
+ assert_raises_rpc_error (- 26 , "too-long-mempool-chain, too many descendants" , chain_transaction , self .nodes [0 ], [chain [2 ][0 ]], [1 ], chain [2 ][1 ], fee , 1 )
60
+ assert_raises_rpc_error (- 26 , "too-long-mempool-chain, too many descendants" , chain_transaction , self .nodes [0 ], [chain [1 ][0 ]], [1 ], chain [1 ][1 ], fee , 1 )
74
61
# ...even if it chains on to two parent transactions with one in the chain.
75
- assert_raises_rpc_error (- 26 , "too-long-mempool-chain, too many descendants" , self . chain_transaction , self .nodes [0 ], [chain [0 ][0 ], second_chain ], [1 , 0 ], chain [0 ][1 ] + second_chain_value , fee , 1 )
62
+ assert_raises_rpc_error (- 26 , "too-long-mempool-chain, too many descendants" , chain_transaction , self .nodes [0 ], [chain [0 ][0 ], second_chain ], [1 , 0 ], chain [0 ][1 ] + second_chain_value , fee , 1 )
76
63
# ...especially if its > 40k weight
77
- assert_raises_rpc_error (- 26 , "too-long-mempool-chain, too many descendants" , self . chain_transaction , self .nodes [0 ], [chain [0 ][0 ]], [1 ], chain [0 ][1 ], fee , 350 )
64
+ assert_raises_rpc_error (- 26 , "too-long-mempool-chain, too many descendants" , chain_transaction , self .nodes [0 ], [chain [0 ][0 ]], [1 ], chain [0 ][1 ], fee , 350 )
78
65
# But not if it chains directly off the first transaction
79
- (replacable_txid , replacable_orig_value ) = self . chain_transaction (self .nodes [0 ], [chain [0 ][0 ]], [1 ], chain [0 ][1 ], fee , 1 )
66
+ (replacable_txid , replacable_orig_value ) = chain_transaction (self .nodes [0 ], [chain [0 ][0 ]], [1 ], chain [0 ][1 ], fee , 1 )
80
67
# and the second chain should work just fine
81
- self . chain_transaction (self .nodes [0 ], [second_chain ], [0 ], second_chain_value , fee , 1 )
68
+ chain_transaction (self .nodes [0 ], [second_chain ], [0 ], second_chain_value , fee , 1 )
82
69
83
70
# Make sure we can RBF the chain which used our carve-out rule
84
71
second_tx_outputs = {self .nodes [0 ].getrawtransaction (replacable_txid , True )["vout" ][0 ]['scriptPubKey' ]['address' ]: replacable_orig_value - (Decimal (1 ) / Decimal (100 ))}
0 commit comments