6
6
7
7
from decimal import Decimal
8
8
9
- from test_framework .blocktools import COINBASE_MATURITY
10
9
from test_framework .messages import (
11
10
COIN ,
12
11
DEFAULT_ANCESTOR_LIMIT ,
17
16
from test_framework .util import (
18
17
assert_equal ,
19
18
assert_raises_rpc_error ,
20
- chain_transaction ,
21
19
)
22
-
20
+ from test_framework . wallet import MiniWallet
23
21
24
22
# custom limits for node1
25
23
CUSTOM_ANCESTOR_LIMIT = 5
@@ -45,43 +43,33 @@ def set_test_params(self):
45
43
],
46
44
]
47
45
48
- def skip_test_if_missing_module (self ):
49
- self .skip_if_no_wallet ()
50
-
51
46
def run_test (self ):
52
- # Mine some blocks and have them mature.
47
+ self .wallet = MiniWallet (self .nodes [0 ])
48
+ self .wallet .rescan_utxos ()
49
+
50
+ if self .is_specified_wallet_compiled ():
51
+ self .nodes [0 ].createwallet ("watch_wallet" , disable_private_keys = True )
52
+ self .nodes [0 ].importaddress (self .wallet .get_address ())
53
+
53
54
peer_inv_store = self .nodes [0 ].add_p2p_connection (P2PTxInvStore ()) # keep track of invs
54
- self .generate (self .nodes [0 ], COINBASE_MATURITY + 1 )
55
- utxo = self .nodes [0 ].listunspent (10 )
56
- txid = utxo [0 ]['txid' ]
57
- vout = utxo [0 ]['vout' ]
58
- value = utxo [0 ]['amount' ]
59
- assert 'ancestorcount' not in utxo [0 ]
60
- assert 'ancestorsize' not in utxo [0 ]
61
- assert 'ancestorfees' not in utxo [0 ]
62
-
63
- fee = Decimal ("0.0001" )
55
+
64
56
# DEFAULT_ANCESTOR_LIMIT transactions off a confirmed tx should be fine
65
- chain = []
66
- witness_chain = []
57
+ chain = self . wallet . create_self_transfer_chain ( chain_length = DEFAULT_ANCESTOR_LIMIT )
58
+ witness_chain = [t [ "wtxid" ] for t in chain ]
67
59
ancestor_vsize = 0
68
60
ancestor_fees = Decimal (0 )
69
- for i in range (DEFAULT_ANCESTOR_LIMIT ):
70
- (txid , sent_value ) = chain_transaction (self .nodes [0 ], [txid ], [0 ], value , fee , 1 )
71
- value = sent_value
72
- chain .append (txid )
73
- # We need the wtxids to check P2P announcements
74
- witnesstx = self .nodes [0 ].gettransaction (txid = txid , verbose = True )['decoded' ]
75
- witness_chain .append (witnesstx ['hash' ])
76
61
62
+ for i , t in enumerate (chain ):
63
+ ancestor_vsize += t ["tx" ].get_vsize ()
64
+ ancestor_fees += t ["fee" ]
65
+ self .wallet .sendrawtransaction (from_node = self .nodes [0 ], tx_hex = t ["hex" ])
77
66
# Check that listunspent ancestor{count, size, fees} yield the correct results
78
- wallet_unspent = self .nodes [0 ].listunspent (minconf = 0 )
79
- this_unspent = next (utxo_info for utxo_info in wallet_unspent if utxo_info ['txid' ] == txid )
80
- assert_equal (this_unspent ['ancestorcount' ], i + 1 )
81
- ancestor_vsize += self .nodes [0 ].getrawtransaction (txid = txid , verbose = True )['vsize' ]
82
- assert_equal (this_unspent ['ancestorsize' ], ancestor_vsize )
83
- ancestor_fees -= self .nodes [0 ].gettransaction (txid = txid )['fee' ]
84
- assert_equal (this_unspent ['ancestorfees' ], ancestor_fees * COIN )
67
+ if self .is_specified_wallet_compiled ():
68
+ wallet_unspent = self .nodes [0 ].listunspent (minconf = 0 )
69
+ this_unspent = next (utxo_info for utxo_info in wallet_unspent if utxo_info ["txid" ] == t ["txid" ])
70
+ assert_equal (this_unspent ['ancestorcount' ], i + 1 )
71
+ assert_equal (this_unspent ['ancestorsize' ], ancestor_vsize )
72
+ assert_equal (this_unspent ['ancestorfees' ], ancestor_fees * COIN )
85
73
86
74
# Wait until mempool transactions have passed initial broadcast (sent inv and received getdata)
87
75
# Otherwise, getrawmempool may be inconsistent with getmempoolentry if unbroadcast changes in between
@@ -99,15 +87,20 @@ def run_test(self):
99
87
ancestor_count = DEFAULT_ANCESTOR_LIMIT
100
88
assert_equal (ancestor_fees , sum ([mempool [tx ]['fees' ]['base' ] for tx in mempool ]))
101
89
90
+ # Adding one more transaction on to the chain should fail.
91
+ next_hop = self .wallet .create_self_transfer (utxo_to_spend = chain [- 1 ]["new_utxo" ])["hex" ]
92
+ assert_raises_rpc_error (- 26 , "too-long-mempool-chain" , lambda : self .nodes [0 ].sendrawtransaction (next_hop ))
93
+
102
94
descendants = []
103
- ancestors = list (chain )
95
+ ancestors = [t ["txid" ] for t in chain ]
96
+ chain = [t ["txid" ] for t in chain ]
104
97
for x in reversed (chain ):
105
98
# Check that getmempoolentry is consistent with getrawmempool
106
99
entry = self .nodes [0 ].getmempoolentry (x )
107
100
assert_equal (entry , mempool [x ])
108
101
109
102
# Check that gettxspendingprevout is consistent with getrawmempool
110
- witnesstx = self .nodes [0 ].gettransaction (txid = x , verbose = True )[ 'decoded' ]
103
+ witnesstx = self .nodes [0 ].getrawtransaction (txid = x , verbose = True )
111
104
for tx_in in witnesstx ["vin" ]:
112
105
spending_result = self .nodes [0 ].gettxspendingprevout ([ {'txid' : tx_in ["txid" ], 'vout' : tx_in ["vout" ]} ])
113
106
assert_equal (spending_result , [ {'txid' : tx_in ["txid" ], 'vout' : tx_in ["vout" ], 'spendingtxid' : x } ])
@@ -193,9 +186,6 @@ def run_test(self):
193
186
descendant_fees += entry ['fees' ]['base' ]
194
187
assert_equal (entry ['fees' ]['descendant' ], descendant_fees + Decimal ('0.00001' ))
195
188
196
- # Adding one more transaction on to the chain should fail.
197
- assert_raises_rpc_error (- 26 , "too-long-mempool-chain" , chain_transaction , self .nodes [0 ], [txid ], [vout ], value , fee , 1 )
198
-
199
189
# Check that prioritising a tx before it's added to the mempool works
200
190
# First clear the mempool by mining a block.
201
191
self .generate (self .nodes [0 ], 1 )
@@ -232,28 +222,23 @@ def run_test(self):
232
222
# TODO: test ancestor size limits
233
223
234
224
# Now test descendant chain limits
235
- txid = utxo [1 ]['txid' ]
236
- value = utxo [1 ]['amount' ]
237
- vout = utxo [1 ]['vout' ]
238
225
239
- transaction_package = []
240
226
tx_children = []
241
227
# First create one parent tx with 10 children
242
- (txid , sent_value ) = chain_transaction (self .nodes [0 ], [txid ], [vout ], value , fee , 10 )
243
- parent_transaction = txid
244
- for i in range (10 ):
245
- transaction_package .append ({'txid' : txid , 'vout' : i , 'amount' : sent_value })
228
+ tx_with_children = self .wallet .send_self_transfer_multi (from_node = self .nodes [0 ], num_outputs = 10 )
229
+ parent_transaction = tx_with_children ["txid" ]
230
+ transaction_package = tx_with_children ["new_utxos" ]
246
231
247
232
# Sign and send up to MAX_DESCENDANT transactions chained off the parent tx
248
233
chain = [] # save sent txs for the purpose of checking node1's mempool later (see below)
249
234
for _ in range (DEFAULT_DESCENDANT_LIMIT - 1 ):
250
235
utxo = transaction_package .pop (0 )
251
- (txid , sent_value ) = chain_transaction (self .nodes [0 ], [utxo ['txid' ]], [utxo ['vout' ]], utxo ['amount' ], fee , 10 )
236
+ new_tx = self .wallet .send_self_transfer_multi (from_node = self .nodes [0 ], num_outputs = 10 , utxos_to_spend = [utxo ])
237
+ txid = new_tx ["txid" ]
252
238
chain .append (txid )
253
239
if utxo ['txid' ] is parent_transaction :
254
240
tx_children .append (txid )
255
- for j in range (10 ):
256
- transaction_package .append ({'txid' : txid , 'vout' : j , 'amount' : sent_value })
241
+ transaction_package .extend (new_tx ["new_utxos" ])
257
242
258
243
mempool = self .nodes [0 ].getrawmempool (True )
259
244
assert_equal (mempool [parent_transaction ]['descendantcount' ], DEFAULT_DESCENDANT_LIMIT )
@@ -263,8 +248,8 @@ def run_test(self):
263
248
assert_equal (mempool [child ]['depends' ], [parent_transaction ])
264
249
265
250
# Sending one more chained transaction will fail
266
- utxo = transaction_package .pop (0 )
267
- assert_raises_rpc_error (- 26 , "too-long-mempool-chain" , chain_transaction , self .nodes [0 ], [ utxo [ 'txid' ]], [ utxo [ 'vout' ]], utxo [ 'amount' ], fee , 10 )
251
+ next_hop = self . wallet . create_self_transfer ( utxo_to_spend = transaction_package .pop (0 ))[ "hex" ]
252
+ assert_raises_rpc_error (- 26 , "too-long-mempool-chain" , lambda : self .nodes [0 ]. sendrawtransaction ( next_hop ) )
268
253
269
254
# Check that node1's mempool is as expected, containing:
270
255
# - txs from previous ancestor test (-> custom ancestor limit)
@@ -304,42 +289,19 @@ def run_test(self):
304
289
# last block.
305
290
306
291
# Create tx0 with 2 outputs
307
- utxo = self .nodes [0 ].listunspent ()
308
- txid = utxo [0 ]['txid' ]
309
- value = utxo [0 ]['amount' ]
310
- vout = utxo [0 ]['vout' ]
311
-
312
- send_value = (value - fee ) / 2
313
- inputs = [ {'txid' : txid , 'vout' : vout } ]
314
- outputs = {}
315
- for _ in range (2 ):
316
- outputs [self .nodes [0 ].getnewaddress ()] = send_value
317
- rawtx = self .nodes [0 ].createrawtransaction (inputs , outputs )
318
- signedtx = self .nodes [0 ].signrawtransactionwithwallet (rawtx )
319
- txid = self .nodes [0 ].sendrawtransaction (signedtx ['hex' ])
320
- tx0_id = txid
321
- value = send_value
292
+ tx0 = self .wallet .send_self_transfer_multi (from_node = self .nodes [0 ], num_outputs = 2 )
322
293
323
294
# Create tx1
324
- tx1_id , _ = chain_transaction ( self .nodes [0 ], [ tx0_id ], [0 ], value , fee , 1 )
295
+ tx1 = self . wallet . send_self_transfer ( from_node = self .nodes [0 ], utxo_to_spend = tx0 [ "new_utxos" ] [0 ])
325
296
326
297
# Create tx2-7
327
- vout = 1
328
- txid = tx0_id
329
- for _ in range (6 ):
330
- (txid , sent_value ) = chain_transaction (self .nodes [0 ], [txid ], [vout ], value , fee , 1 )
331
- vout = 0
332
- value = sent_value
298
+ tx7 = self .wallet .send_self_transfer_chain (from_node = self .nodes [0 ], utxo_to_spend = tx0 ["new_utxos" ][1 ], chain_length = 6 )[- 1 ]
333
299
334
300
# Mine these in a block
335
301
self .generate (self .nodes [0 ], 1 )
336
302
337
303
# Now generate tx8, with a big fee
338
- inputs = [ {'txid' : tx1_id , 'vout' : 0 }, {'txid' : txid , 'vout' : 0 } ]
339
- outputs = { self .nodes [0 ].getnewaddress () : send_value + value - 4 * fee }
340
- rawtx = self .nodes [0 ].createrawtransaction (inputs , outputs )
341
- signedtx = self .nodes [0 ].signrawtransactionwithwallet (rawtx )
342
- txid = self .nodes [0 ].sendrawtransaction (signedtx ['hex' ])
304
+ self .wallet .send_self_transfer_multi (from_node = self .nodes [0 ], utxos_to_spend = [tx1 ["new_utxo" ], tx7 ["new_utxo" ]], fee_per_output = 40000 )
343
305
self .sync_mempools ()
344
306
345
307
# Now try to disconnect the tip on each node...
0 commit comments