Skip to content

Commit 995b940

Browse files
MarcoFalkeknst
authored andcommitted
Merge bitcoin#16465: test: Test p2sh-witness and bech32 in wallet_import_rescan
fa3c657 lint: Add false positive to python dead code linter (MarcoFalke) fa25668 test: Test p2sh-witness and bech32 in wallet_import_rescan (MarcoFalke) fa79af2 test: Replace fragile "rng" with call to random() (MarcoFalke) fac3dcf test: Generate one block for each send in wallet_import_rescan (MarcoFalke) Pull request description: This adds test coverage for segwit in the `wallet_import_rescan` test, among other cleanups. ACKs for top commit: jnewbery: ACK fa3c657 Tree-SHA512: 877741763c62c1bf9d868864a1e3f0699857e8c028e9fcd65c7eeb73600c22cbe97b7b51093737743d9e87bcb991c1fe1086f673e18765aef0fcfe27951402f0
1 parent 879f832 commit 995b940

File tree

1 file changed

+37
-20
lines changed

1 file changed

+37
-20
lines changed

test/functional/wallet_import_rescan.py

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@
2626
)
2727

2828
import collections
29+
from decimal import Decimal
2930
import enum
3031
import itertools
32+
import random
3133

3234
Call = enum.Enum("Call", "single multiaddress multiscript")
3335
Data = 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.
115122
TIMESTAMP_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

118132
class 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

Comments
 (0)