Skip to content

Commit e302830

Browse files
author
MarcoFalke
committed
Merge #18774: test: added test for upgradewallet RPC
66fe7b1 test: added test for upgradewallet RPC (Harris) Pull request description: This PR adds tests for the newly merged *upgradewallet* RPC. Additionally, it expands `test_framework/util.py` by adding the function `adjust_bitcoin_conf_for_pre_17` to support nodes that don't parse configuration sections. This test uses two older node versions, v0.15.2 and v0.16.3, to create older wallet versions to be used by `upgradewallet`. Fixes bitcoin/bitcoin#18767 Top commit has no ACKs. Tree-SHA512: bb72ff1e829e2c3954386cc308842820ef0828a4fbb754202b225a8748f92d4dcc5ec77fb146bfd5484a5c2f29ce95adf9f3fb4483437088ff3ea4a8d2c442c1
2 parents af2ec6b + 66fe7b1 commit e302830

File tree

4 files changed

+165
-1
lines changed

4 files changed

+165
-1
lines changed

ci/test/05_before_script.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,6 @@ if [ -z "$NO_DEPENDS" ]; then
3737
fi
3838
if [ "$TEST_PREVIOUS_RELEASES" = "true" ]; then
3939
BEGIN_FOLD previous-versions
40-
DOCKER_EXEC contrib/devtools/previous_release.sh -b -t "$PREVIOUS_RELEASES_DIR" v0.17.1 v0.18.1 v0.19.0.1
40+
DOCKER_EXEC contrib/devtools/previous_release.sh -b -t "$PREVIOUS_RELEASES_DIR" v0.15.2 v0.16.3 v0.17.1 v0.18.1 v0.19.0.1
4141
END_FOLD
4242
fi

test/functional/test_framework/util.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,13 @@ def initialize_datadir(dirname, n, chain):
326326
os.makedirs(os.path.join(datadir, 'stdout'), exist_ok=True)
327327
return datadir
328328

329+
def adjust_bitcoin_conf_for_pre_17(conf_file):
330+
with open(conf_file,'r', encoding='utf8') as conf:
331+
conf_data = conf.read()
332+
with open(conf_file, 'w', encoding='utf8') as conf:
333+
conf_data_changed = conf_data.replace('[regtest]', '')
334+
conf.write(conf_data_changed)
335+
329336
def get_datadir_path(dirname, n):
330337
return os.path.join(dirname, "node" + str(n))
331338

test/functional/test_runner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@
190190
'wallet_import_rescan.py',
191191
'wallet_import_with_label.py',
192192
'wallet_importdescriptors.py',
193+
'wallet_upgradewallet.py',
193194
'rpc_bind.py --ipv4',
194195
'rpc_bind.py --ipv6',
195196
'rpc_bind.py --nonloopback',
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2018-2020 The Bitcoin Core developers
3+
# Distributed under the MIT software license, see the accompanying
4+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
"""upgradewallet RPC functional test
6+
7+
Test upgradewallet RPC. Download v0.15.2 v0.16.3 node binaries:
8+
9+
contrib/devtools/previous_release.sh -b v0.15.2 v0.16.3
10+
"""
11+
12+
import os
13+
import shutil
14+
15+
from test_framework.test_framework import BitcoinTestFramework, SkipTest
16+
from test_framework.util import (
17+
adjust_bitcoin_conf_for_pre_17,
18+
assert_equal,
19+
assert_greater_than,
20+
assert_is_hex_string
21+
)
22+
23+
class UpgradeWalletTest(BitcoinTestFramework):
24+
def set_test_params(self):
25+
self.setup_clean_chain = True
26+
self.num_nodes = 3
27+
self.extra_args = [
28+
["-addresstype=bech32"], # current wallet version
29+
["-usehd=1"], # v0.16.3 wallet
30+
["-usehd=0"] # v0.15.2 wallet
31+
]
32+
33+
def skip_test_if_missing_module(self):
34+
self.skip_if_no_wallet()
35+
36+
def setup_network(self):
37+
self.setup_nodes()
38+
39+
def setup_nodes(self):
40+
if os.getenv("TEST_PREVIOUS_RELEASES") == "false":
41+
raise SkipTest("upgradewallet RPC tests")
42+
43+
releases_path = os.getenv("PREVIOUS_RELEASES_DIR") or os.getcwd() + "/releases"
44+
if not os.path.isdir(releases_path):
45+
if os.getenv("TEST_PREVIOUS_RELEASES") == "true":
46+
raise AssertionError("TEST_PREVIOUS_RELEASES=1 but releases missing: " + releases_path)
47+
raise SkipTest("This test requires binaries for previous releases")
48+
49+
self.add_nodes(self.num_nodes, extra_args=self.extra_args, versions=[
50+
None,
51+
160300,
52+
150200
53+
], binary=[
54+
self.options.bitcoind,
55+
releases_path + "/v0.16.3/bin/bitcoind",
56+
releases_path + "/v0.15.2/bin/bitcoind",
57+
], binary_cli=[
58+
self.options.bitcoincli,
59+
releases_path + "/v0.16.3/bin/bitcoin-cli",
60+
releases_path + "/v0.15.2/bin/bitcoin-cli",
61+
])
62+
# adapt bitcoin.conf, because older bitcoind's don't recognize config sections
63+
adjust_bitcoin_conf_for_pre_17(self.nodes[1].bitcoinconf)
64+
adjust_bitcoin_conf_for_pre_17(self.nodes[2].bitcoinconf)
65+
self.start_nodes()
66+
67+
def dumb_sync_blocks(self):
68+
"""
69+
Little helper to sync older wallets.
70+
Notice that v0.15.2's regtest is hardforked, so there is
71+
no sync for it.
72+
v0.15.2 is only being used to test for version upgrade
73+
and master hash key presence.
74+
v0.16.3 is being used to test for version upgrade and balances.
75+
Further info: https://github.com/bitcoin/bitcoin/pull/18774#discussion_r416967844
76+
"""
77+
node_from = self.nodes[0]
78+
v16_3_node = self.nodes[1]
79+
to_height = node_from.getblockcount()
80+
height = self.nodes[1].getblockcount()
81+
for i in range(height, to_height+1):
82+
b = node_from.getblock(blockhash=node_from.getblockhash(i), verbose=0)
83+
v16_3_node.submitblock(b)
84+
assert_equal(v16_3_node.getblockcount(), to_height)
85+
86+
def run_test(self):
87+
self.nodes[0].generatetoaddress(101, self.nodes[0].getnewaddress())
88+
self.dumb_sync_blocks()
89+
# # Sanity check the test framework:
90+
res = self.nodes[0].getblockchaininfo()
91+
assert_equal(res['blocks'], 101)
92+
node_master = self.nodes[0]
93+
v16_3_node = self.nodes[1]
94+
v15_2_node = self.nodes[2]
95+
96+
# Send coins to old wallets for later conversion checks.
97+
v16_3_wallet = v16_3_node.get_wallet_rpc('wallet.dat')
98+
v16_3_address = v16_3_wallet.getnewaddress()
99+
node_master.generatetoaddress(101, v16_3_address)
100+
self.dumb_sync_blocks()
101+
v16_3_balance = v16_3_wallet.getbalance()
102+
103+
self.log.info("Test upgradewallet RPC...")
104+
# Prepare for copying of the older wallet
105+
node_master_wallet_dir = os.path.join(node_master.datadir, "regtest/wallets")
106+
v16_3_wallet = os.path.join(v16_3_node.datadir, "regtest/wallets/wallet.dat")
107+
v15_2_wallet = os.path.join(v15_2_node.datadir, "regtest/wallet.dat")
108+
self.stop_nodes()
109+
110+
# Copy the 0.16.3 wallet to the last Bitcoin Core version and open it:
111+
shutil.rmtree(node_master_wallet_dir)
112+
os.mkdir(node_master_wallet_dir)
113+
shutil.copy(
114+
v16_3_wallet,
115+
node_master_wallet_dir
116+
)
117+
self.restart_node(0, ['-nowallet'])
118+
node_master.loadwallet('')
119+
120+
wallet = node_master.get_wallet_rpc('')
121+
old_version = wallet.getwalletinfo()["walletversion"]
122+
123+
# calling upgradewallet without version arguments
124+
# should return nothing if successful
125+
assert_equal(wallet.upgradewallet(), "")
126+
new_version = wallet.getwalletinfo()["walletversion"]
127+
# upgraded wallet version should be greater than older one
128+
assert_greater_than(new_version, old_version)
129+
# wallet should still contain the same balance
130+
assert_equal(wallet.getbalance(), v16_3_balance)
131+
132+
self.stop_node(0)
133+
# Copy the 0.15.2 wallet to the last Bitcoin Core version and open it:
134+
shutil.rmtree(node_master_wallet_dir)
135+
os.mkdir(node_master_wallet_dir)
136+
shutil.copy(
137+
v15_2_wallet,
138+
node_master_wallet_dir
139+
)
140+
self.restart_node(0, ['-nowallet'])
141+
node_master.loadwallet('')
142+
143+
wallet = node_master.get_wallet_rpc('')
144+
# should have no master key hash before conversion
145+
assert_equal('hdseedid' in wallet.getwalletinfo(), False)
146+
# calling upgradewallet with explicit version number
147+
# should return nothing if successful
148+
assert_equal(wallet.upgradewallet(169900), "")
149+
new_version = wallet.getwalletinfo()["walletversion"]
150+
# upgraded wallet should have version 169900
151+
assert_equal(new_version, 169900)
152+
# after conversion master key hash should be present
153+
assert_is_hex_string(wallet.getwalletinfo()['hdseedid'])
154+
155+
if __name__ == '__main__':
156+
UpgradeWalletTest().main()

0 commit comments

Comments
 (0)