Skip to content

Commit 9d9390d

Browse files
committed
[tests] add wallet backwards compatility tests
1 parent c7ca630 commit 9d9390d

File tree

1 file changed

+173
-6
lines changed

1 file changed

+173
-6
lines changed

test/functional/feature_backwards_compatibility.py

Lines changed: 173 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@
1616
"""
1717

1818
import os
19+
import shutil
1920

2021
from test_framework.test_framework import BitcoinTestFramework, SkipTest
2122

2223
from test_framework.util import (
2324
assert_equal,
24-
sync_blocks
25+
sync_blocks,
26+
sync_mempools
2527
)
2628

2729
class BackwardsCompatibilityTest(BitcoinTestFramework):
@@ -30,10 +32,10 @@ def set_test_params(self):
3032
self.num_nodes = 4
3133
# Add new version after each release:
3234
self.extra_args = [
33-
[], # Pre-release: use to mine blocks
34-
[], # Pre-release: use to receive coins, swap wallets, etc
35-
[], # v0.18.1
36-
[] # v0.17.1
35+
["-addresstype=bech32"], # Pre-release: use to mine blocks
36+
["-nowallet", "-walletrbf=1", "-addresstype=bech32"], # Pre-release: use to receive coins, swap wallets, etc
37+
["-nowallet", "-walletrbf=1", "-addresstype=bech32"], # v0.18.1
38+
["-nowallet", "-walletrbf=1", "-addresstype=bech32"] # v0.17.1
3739
]
3840

3941
def setup_nodes(self):
@@ -66,13 +68,178 @@ def setup_nodes(self):
6668
self.start_nodes()
6769

6870
def run_test(self):
69-
self.nodes[0].generate(101)
71+
self.nodes[0].generatetoaddress(101, self.nodes[0].getnewaddress())
7072

7173
sync_blocks(self.nodes)
7274

7375
# Sanity check the test framework:
7476
res = self.nodes[self.num_nodes - 1].getblockchaininfo()
7577
assert_equal(res['blocks'], 101)
7678

79+
node_master = self.nodes[self.num_nodes - 3]
80+
node_v18 = self.nodes[self.num_nodes - 2]
81+
node_v17 = self.nodes[self.num_nodes - 1]
82+
83+
self.log.info("Test wallet backwards compatibility...")
84+
# Create a number of wallets and open them in older versions:
85+
86+
# w1: regular wallet, created on master: update this test when default
87+
# wallets can no longer be opened by older versions.
88+
node_master.createwallet(wallet_name="w1")
89+
wallet = node_master.get_wallet_rpc("w1")
90+
info = wallet.getwalletinfo()
91+
assert info['private_keys_enabled']
92+
assert info['keypoolsize'] > 0
93+
# Create a confirmed transaction, receiving coins
94+
address = wallet.getnewaddress()
95+
self.nodes[0].sendtoaddress(address, 10)
96+
sync_mempools(self.nodes)
97+
self.nodes[0].generate(1)
98+
sync_blocks(self.nodes)
99+
# Create a conflicting transaction using RBF
100+
return_address = self.nodes[0].getnewaddress()
101+
tx1_id = self.nodes[1].sendtoaddress(return_address, 1)
102+
tx2_id = self.nodes[1].bumpfee(tx1_id)["txid"]
103+
# Confirm the transaction
104+
sync_mempools(self.nodes)
105+
self.nodes[0].generate(1)
106+
sync_blocks(self.nodes)
107+
# Create another conflicting transaction using RBF
108+
tx3_id = self.nodes[1].sendtoaddress(return_address, 1)
109+
tx4_id = self.nodes[1].bumpfee(tx3_id)["txid"]
110+
# Abondon transaction, but don't confirm
111+
self.nodes[1].abandontransaction(tx3_id)
112+
113+
# w1_v18: regular wallet, created with v0.18
114+
node_v18.createwallet(wallet_name="w1_v18")
115+
wallet = node_v18.get_wallet_rpc("w1_v18")
116+
info = wallet.getwalletinfo()
117+
assert info['private_keys_enabled']
118+
assert info['keypoolsize'] > 0
119+
120+
# w2: wallet with private keys disabled, created on master: update this
121+
# test when default wallets private keys disabled can no longer be
122+
# opened by older versions.
123+
node_master.createwallet(wallet_name="w2", disable_private_keys=True)
124+
wallet = node_master.get_wallet_rpc("w2")
125+
info = wallet.getwalletinfo()
126+
assert info['private_keys_enabled'] == False
127+
assert info['keypoolsize'] == 0
128+
129+
# w2_v18: wallet with private keys disabled, created with v0.18
130+
node_v18.createwallet(wallet_name="w2_v18", disable_private_keys=True)
131+
wallet = node_v18.get_wallet_rpc("w2_v18")
132+
info = wallet.getwalletinfo()
133+
assert info['private_keys_enabled'] == False
134+
assert info['keypoolsize'] == 0
135+
136+
# w3: blank wallet, created on master: update this
137+
# test when default blank wallets can no longer be opened by older versions.
138+
node_master.createwallet(wallet_name="w3", blank=True)
139+
wallet = node_master.get_wallet_rpc("w3")
140+
info = wallet.getwalletinfo()
141+
assert info['private_keys_enabled']
142+
assert info['keypoolsize'] == 0
143+
144+
# w3_v18: blank wallet, created with v0.18
145+
node_v18.createwallet(wallet_name="w3_v18", blank=True)
146+
wallet = node_v18.get_wallet_rpc("w3_v18")
147+
info = wallet.getwalletinfo()
148+
assert info['private_keys_enabled']
149+
assert info['keypoolsize'] == 0
150+
151+
# Copy the wallets to older nodes:
152+
node_master_wallets_dir = os.path.join(node_master.datadir, "regtest/wallets")
153+
node_v18_wallets_dir = os.path.join(node_v18.datadir, "regtest/wallets")
154+
node_v17_wallets_dir = os.path.join(node_v17.datadir, "regtest/wallets")
155+
node_master.unloadwallet("w1")
156+
node_master.unloadwallet("w2")
157+
node_v18.unloadwallet("w1_v18")
158+
node_v18.unloadwallet("w2_v18")
159+
160+
# Copy wallets to v0.17
161+
for wallet in os.listdir(node_master_wallets_dir):
162+
shutil.copytree(
163+
os.path.join(node_master_wallets_dir, wallet),
164+
os.path.join(node_v17_wallets_dir, wallet)
165+
)
166+
for wallet in os.listdir(node_v18_wallets_dir):
167+
shutil.copytree(
168+
os.path.join(node_v18_wallets_dir, wallet),
169+
os.path.join(node_v17_wallets_dir, wallet)
170+
)
171+
172+
# Copy wallets to v0.18
173+
for wallet in os.listdir(node_master_wallets_dir):
174+
shutil.copytree(
175+
os.path.join(node_master_wallets_dir, wallet),
176+
os.path.join(node_v18_wallets_dir, wallet)
177+
)
178+
179+
# Open the wallets in v0.18
180+
node_v18.loadwallet("w1")
181+
wallet = node_v18.get_wallet_rpc("w1")
182+
info = wallet.getwalletinfo()
183+
assert info['private_keys_enabled']
184+
assert info['keypoolsize'] > 0
185+
txs = wallet.listtransactions()
186+
assert_equal(len(txs), 5)
187+
assert_equal(txs[1]["txid"], tx1_id)
188+
assert_equal(txs[2]["walletconflicts"], [tx1_id])
189+
assert_equal(txs[1]["replaced_by_txid"], tx2_id)
190+
assert not(txs[1]["abandoned"])
191+
assert_equal(txs[1]["confirmations"], -1)
192+
assert_equal(txs[2]["blockindex"], 1)
193+
assert txs[3]["abandoned"]
194+
assert_equal(txs[4]["walletconflicts"], [tx3_id])
195+
assert_equal(txs[3]["replaced_by_txid"], tx4_id)
196+
assert not(hasattr(txs[3], "blockindex"))
197+
198+
node_v18.loadwallet("w2")
199+
wallet = node_v18.get_wallet_rpc("w2")
200+
info = wallet.getwalletinfo()
201+
assert info['private_keys_enabled'] == False
202+
assert info['keypoolsize'] == 0
203+
204+
node_v18.loadwallet("w3")
205+
wallet = node_v18.get_wallet_rpc("w3")
206+
info = wallet.getwalletinfo()
207+
assert info['private_keys_enabled']
208+
assert info['keypoolsize'] == 0
209+
210+
# Open the wallets in v0.17
211+
node_v17.loadwallet("w1_v18")
212+
wallet = node_v17.get_wallet_rpc("w1_v18")
213+
info = wallet.getwalletinfo()
214+
assert info['private_keys_enabled']
215+
assert info['keypoolsize'] > 0
216+
217+
node_v17.loadwallet("w1")
218+
wallet = node_v17.get_wallet_rpc("w1")
219+
info = wallet.getwalletinfo()
220+
assert info['private_keys_enabled']
221+
assert info['keypoolsize'] > 0
222+
223+
node_v17.loadwallet("w2_v18")
224+
wallet = node_v17.get_wallet_rpc("w2_v18")
225+
info = wallet.getwalletinfo()
226+
assert info['private_keys_enabled'] == False
227+
assert info['keypoolsize'] == 0
228+
229+
node_v17.loadwallet("w2")
230+
wallet = node_v17.get_wallet_rpc("w2")
231+
info = wallet.getwalletinfo()
232+
assert info['private_keys_enabled'] == False
233+
assert info['keypoolsize'] == 0
234+
235+
# RPC loadwallet failure causes bitcoind to exit, in addition to the RPC
236+
# call failure, so the following test won't work:
237+
# assert_raises_rpc_error(-4, "Wallet loading failed.", node_v17.loadwallet, 'w3_v18')
238+
239+
# Instead, we stop node and try to launch it with the wallet:
240+
self.stop_node(self.num_nodes - 1)
241+
node_v17.assert_start_raises_init_error(["-wallet=w3_v18"], "Error: Error loading w3_v18: Wallet requires newer version of Bitcoin Core")
242+
node_v17.assert_start_raises_init_error(["-wallet=w3"], "Error: Error loading w3: Wallet requires newer version of Bitcoin Core")
243+
77244
if __name__ == '__main__':
78245
BackwardsCompatibilityTest().main()

0 commit comments

Comments
 (0)