2626)
2727
2828import collections
29+ from decimal import Decimal
2930import enum
3031import itertools
32+ import random
3133
3234Call = enum .Enum ("Call" , "single multiaddress multiscript" )
3335Data = enum .Enum ("Data" , "address pub priv" )
@@ -50,7 +52,7 @@ def do_import(self, timestamp):
5052 assert_equal (response , None )
5153
5254 elif self .call in (Call .multiaddress , Call .multiscript ):
53- response = self . node . importmulti ([ {
55+ request = {
5456 "scriptPubKey" : {
5557 "address" : self .address ["address" ]
5658 } if self .call == Call .multiaddress else self .address ["scriptPubKey" ],
@@ -59,13 +61,18 @@ def do_import(self, timestamp):
5961 "keys" : [self .key ] if self .data == Data .priv else [],
6062 "label" : self .label ,
6163 "watchonly" : self .data != Data .priv
62- }], {"rescan" : self .rescan in (Rescan .yes , Rescan .late_timestamp )})
64+ }
65+ response = self .node .importmulti (
66+ requests = [request ],
67+ options = {"rescan" : self .rescan in (Rescan .yes , Rescan .late_timestamp )},
68+ )
6369 assert_equal (response , [{"success" : True }])
6470
65- def check (self , txid = None , amount = None , confirmations = None ):
71+ def check (self , txid = None , amount = None , confirmation_height = None ):
6672 """Verify that listtransactions/listreceivedbyaddress return expected values."""
6773
6874 txs = self .node .listtransactions (label = self .label , count = 10000 , include_watchonly = True )
75+ current_height = self .node .getblockcount ()
6976 assert_equal (len (txs ), self .expected_txs )
7077
7178 addresses = self .node .listreceivedbyaddress (minconf = 0 , include_watchonly = True , address_filter = self .address ['address' ])
@@ -80,13 +87,13 @@ def check(self, txid=None, amount=None, confirmations=None):
8087 assert_equal (tx ["category" ], "receive" )
8188 assert_equal (tx ["label" ], self .label )
8289 assert_equal (tx ["txid" ], txid )
83- assert_equal (tx ["confirmations" ], confirmations )
90+ assert_equal (tx ["confirmations" ], 1 + current_height - confirmation_height )
8491 assert_equal ("trusted" not in tx , True )
8592
8693 address , = [ad for ad in addresses if txid in ad ["txids" ]]
8794 assert_equal (address ["address" ], self .address ["address" ])
8895 assert_equal (address ["amount" ], self .expected_balance )
89- assert_equal (address ["confirmations" ], confirmations )
96+ assert_equal (address ["confirmations" ], 1 + current_height - confirmation_height )
9097 # Verify the transaction is correctly marked watchonly depending on
9198 # whether the transaction pays to an imported public key or
9299 # imported private key. The test setup ensures that transaction
@@ -114,6 +121,13 @@ def check(self, txid=None, amount=None, confirmations=None):
114121# Rescans start at the earliest block up to 2 hours before the key timestamp.
115122TIMESTAMP_WINDOW = 2 * 60 * 60
116123
124+ AMOUNT_DUST = 0.00000546
125+
126+
127+ def get_rand_amount ():
128+ r = random .uniform (AMOUNT_DUST , 1 )
129+ return Decimal (str (round (r , 8 )))
130+
117131
118132class ImportRescanTest (BitcoinTestFramework ):
119133 def set_test_params (self ):
@@ -125,13 +139,13 @@ def skip_test_if_missing_module(self):
125139 self .skip_if_no_wallet ()
126140
127141 def setup_network (self ):
128- extra_args = [[] for _ in range (self .num_nodes )]
142+ self . extra_args = [[] for _ in range (self .num_nodes )]
129143 for i , import_node in enumerate (IMPORT_NODES , 2 ):
130144 if import_node .prune :
131145 # txindex is enabled by default in Dash and needs to be disabled for import-rescan.py
132- extra_args [i ] += ["-prune=1" , "-txindex=0" , "-reindex" ]
146+ self . extra_args [i ] += ["-prune=1" , "-txindex=0" , "-reindex" ]
133147
134- self .add_nodes (self .num_nodes , extra_args = extra_args )
148+ self .add_nodes (self .num_nodes , extra_args = self . extra_args )
135149
136150 # Import keys with pruning disabled
137151 self .start_nodes (extra_args = [[]] * self .num_nodes )
@@ -149,15 +163,18 @@ def run_test(self):
149163 variant .label = "label {} {}" .format (i , variant )
150164 variant .address = self .nodes [1 ].getaddressinfo (self .nodes [1 ].getnewaddress (variant .label ))
151165 variant .key = self .nodes [1 ].dumpprivkey (variant .address ["address" ])
152- variant .initial_amount = 1 - ( i + 1 ) / 64
166+ variant .initial_amount = get_rand_amount ()
153167 variant .initial_txid = self .nodes [0 ].sendtoaddress (variant .address ["address" ], variant .initial_amount )
168+ self .nodes [0 ].generate (1 ) # Generate one block for each send
169+ variant .confirmation_height = self .nodes [0 ].getblockcount ()
170+ variant .timestamp = self .nodes [0 ].getblockheader (self .nodes [0 ].getbestblockhash ())["time" ]
154171
155- # Generate a block containing the initial transactions, then another
156- # block further in the future (past the rescan window).
157- self .nodes [0 ].generate (1 )
172+ # Generate a block further in the future (past the rescan window).
158173 assert_equal (self .nodes [0 ].getrawmempool (), [])
159- timestamp = self .nodes [0 ].getblockheader (self .nodes [0 ].getbestblockhash ())["time" ]
160- set_node_times (self .nodes , timestamp + TIMESTAMP_WINDOW + 1 )
174+ set_node_times (
175+ self .nodes ,
176+ self .nodes [0 ].getblockheader (self .nodes [0 ].getbestblockhash ())["time" ] + TIMESTAMP_WINDOW + 1 ,
177+ )
161178 self .nodes [0 ].generate (1 )
162179 self .sync_all ()
163180
@@ -167,23 +184,23 @@ def run_test(self):
167184 self .log .info ('Run import for variant {}' .format (variant ))
168185 expect_rescan = variant .rescan == Rescan .yes
169186 variant .node = self .nodes [2 + IMPORT_NODES .index (ImportNode (variant .prune , expect_rescan ))]
170- variant .do_import (timestamp )
187+ variant .do_import (variant . timestamp )
171188 if expect_rescan :
172189 variant .expected_balance = variant .initial_amount
173190 variant .expected_txs = 1
174- variant .check (variant .initial_txid , variant .initial_amount , 2 )
191+ variant .check (variant .initial_txid , variant .initial_amount , variant . confirmation_height )
175192 else :
176193 variant .expected_balance = 0
177194 variant .expected_txs = 0
178195 variant .check ()
179196
180197 # Create new transactions sending to each address.
181198 for i , variant in enumerate (IMPORT_VARIANTS ):
182- variant .sent_amount = 1 - ( 2 * i + 1 ) / 128
199+ variant .sent_amount = get_rand_amount ()
183200 variant .sent_txid = self .nodes [0 ].sendtoaddress (variant .address ["address" ], variant .sent_amount )
201+ self .nodes [0 ].generate (1 ) # Generate one block for each send
202+ variant .confirmation_height = self .nodes [0 ].getblockcount ()
184203
185- # Generate a block containing the new transactions.
186- self .nodes [0 ].generate (1 )
187204 assert_equal (self .nodes [0 ].getrawmempool (), [])
188205 self .sync_all ()
189206
@@ -192,7 +209,7 @@ def run_test(self):
192209 self .log .info ('Run check for variant {}' .format (variant ))
193210 variant .expected_balance += variant .sent_amount
194211 variant .expected_txs += 1
195- variant .check (variant .sent_txid , variant .sent_amount , 1 )
212+ variant .check (variant .sent_txid , variant .sent_amount , variant . confirmation_height )
196213 for i , import_node in enumerate (IMPORT_NODES , 2 ):
197214 if import_node .prune :
198215 self .stop_node (i , expected_stderr = 'Warning: You are starting with governance validation disabled. This is expected because you are running a pruned node.' )
0 commit comments