@@ -63,19 +63,27 @@ def setup_nodes(self):
63
63
self .start_nodes ()
64
64
self .import_deterministic_coinbase_privkeys ()
65
65
66
- def run_test (self ):
67
- self .generatetoaddress (self .nodes [0 ], COINBASE_MATURITY + 1 , self .nodes [0 ].getnewaddress ())
68
-
69
- # Sanity check the test framework:
70
- res = self .nodes [self .num_nodes - 1 ].getblockchaininfo ()
71
- assert_equal (res ['blocks' ], COINBASE_MATURITY + 1 )
66
+ def nodes_wallet_dir (self , node ):
67
+ if node .version < 170000 :
68
+ return os .path .join (node .datadir , "regtest" )
69
+ return os .path .join (node .datadir , "regtest/wallets" )
72
70
73
- node_master = self .nodes [self .num_nodes - 5 ]
71
+ def run_test (self ):
72
+ node_miner = self .nodes [0 ]
73
+ node_master = self .nodes [1 ]
74
74
node_v19 = self .nodes [self .num_nodes - 4 ]
75
75
node_v18 = self .nodes [self .num_nodes - 3 ]
76
76
node_v17 = self .nodes [self .num_nodes - 2 ]
77
77
node_v16 = self .nodes [self .num_nodes - 1 ]
78
78
79
+ legacy_nodes = self .nodes [2 :]
80
+
81
+ self .generatetoaddress (node_miner , COINBASE_MATURITY + 1 , node_miner .getnewaddress ())
82
+
83
+ # Sanity check the test framework:
84
+ res = node_v16 .getblockchaininfo ()
85
+ assert_equal (res ['blocks' ], COINBASE_MATURITY + 1 )
86
+
79
87
self .log .info ("Test wallet backwards compatibility..." )
80
88
# Create a number of wallets and open them in older versions:
81
89
@@ -88,21 +96,21 @@ def run_test(self):
88
96
assert info ['keypoolsize' ] > 0
89
97
# Create a confirmed transaction, receiving coins
90
98
address = wallet .getnewaddress ()
91
- self . nodes [ 0 ] .sendtoaddress (address , 10 )
99
+ node_miner .sendtoaddress (address , 10 )
92
100
self .sync_mempools ()
93
- self .generate (self . nodes [ 0 ] , 1 )
101
+ self .generate (node_miner , 1 )
94
102
# Create a conflicting transaction using RBF
95
- return_address = self . nodes [ 0 ] .getnewaddress ()
96
- tx1_id = self . nodes [ 1 ] .sendtoaddress (return_address , 1 )
97
- tx2_id = self . nodes [ 1 ] .bumpfee (tx1_id )["txid" ]
103
+ return_address = node_miner .getnewaddress ()
104
+ tx1_id = node_master .sendtoaddress (return_address , 1 )
105
+ tx2_id = node_master .bumpfee (tx1_id )["txid" ]
98
106
# Confirm the transaction
99
107
self .sync_mempools ()
100
- self .generate (self . nodes [ 0 ] , 1 )
108
+ self .generate (node_miner , 1 )
101
109
# Create another conflicting transaction using RBF
102
- tx3_id = self . nodes [ 1 ] .sendtoaddress (return_address , 1 )
103
- tx4_id = self . nodes [ 1 ] .bumpfee (tx3_id )["txid" ]
110
+ tx3_id = node_master .sendtoaddress (return_address , 1 )
111
+ tx4_id = node_master .bumpfee (tx3_id )["txid" ]
104
112
# Abandon transaction, but don't confirm
105
- self . nodes [ 1 ] .abandontransaction (tx3_id )
113
+ node_master .abandontransaction (tx3_id )
106
114
107
115
# w1_v19: regular wallet, created with v0.19
108
116
node_v19 .rpc .createwallet (wallet_name = "w1_v19" )
@@ -113,6 +121,7 @@ def run_test(self):
113
121
# Use addmultisigaddress (see #18075)
114
122
address_18075 = wallet .rpc .addmultisigaddress (1 , ["0296b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52" , "037211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073" ], "" , "legacy" )["address" ]
115
123
assert wallet .getaddressinfo (address_18075 )["solvable" ]
124
+ node_v19 .unloadwallet ("w1_v19" )
116
125
117
126
# w1_v18: regular wallet, created with v0.18
118
127
node_v18 .rpc .createwallet (wallet_name = "w1_v18" )
@@ -130,20 +139,6 @@ def run_test(self):
130
139
assert info ['private_keys_enabled' ] == False
131
140
assert info ['keypoolsize' ] == 0
132
141
133
- # w2_v19: wallet with private keys disabled, created with v0.19
134
- node_v19 .rpc .createwallet (wallet_name = "w2_v19" , disable_private_keys = True )
135
- wallet = node_v19 .get_wallet_rpc ("w2_v19" )
136
- info = wallet .getwalletinfo ()
137
- assert info ['private_keys_enabled' ] == False
138
- assert info ['keypoolsize' ] == 0
139
-
140
- # w2_v18: wallet with private keys disabled, created with v0.18
141
- node_v18 .rpc .createwallet (wallet_name = "w2_v18" , disable_private_keys = True )
142
- wallet = node_v18 .get_wallet_rpc ("w2_v18" )
143
- info = wallet .getwalletinfo ()
144
- assert info ['private_keys_enabled' ] == False
145
- assert info ['keypoolsize' ] == 0
146
-
147
142
# w3: blank wallet, created on master: update this
148
143
# test when default blank wallets can no longer be opened by older versions.
149
144
node_master .createwallet (wallet_name = "w3" , blank = True )
@@ -152,194 +147,96 @@ def run_test(self):
152
147
assert info ['private_keys_enabled' ]
153
148
assert info ['keypoolsize' ] == 0
154
149
155
- # w3_v19: blank wallet, created with v0.19
156
- node_v19 .rpc .createwallet (wallet_name = "w3_v19" , blank = True )
157
- wallet = node_v19 .get_wallet_rpc ("w3_v19" )
158
- info = wallet .getwalletinfo ()
159
- assert info ['private_keys_enabled' ]
160
- assert info ['keypoolsize' ] == 0
161
-
162
- # w3_v18: blank wallet, created with v0.18
163
- node_v18 .rpc .createwallet (wallet_name = "w3_v18" , blank = True )
164
- wallet = node_v18 .get_wallet_rpc ("w3_v18" )
165
- info = wallet .getwalletinfo ()
166
- assert info ['private_keys_enabled' ]
167
- assert info ['keypoolsize' ] == 0
168
-
169
- # Copy the wallets to older nodes:
150
+ # Unload wallets and copy to older nodes:
170
151
node_master_wallets_dir = os .path .join (node_master .datadir , "regtest/wallets" )
171
152
node_v19_wallets_dir = os .path .join (node_v19 .datadir , "regtest/wallets" )
172
- node_v18_wallets_dir = os .path .join (node_v18 .datadir , "regtest/wallets" )
173
153
node_v17_wallets_dir = os .path .join (node_v17 .datadir , "regtest/wallets" )
174
154
node_v16_wallets_dir = os .path .join (node_v16 .datadir , "regtest" )
175
155
node_master .unloadwallet ("w1" )
176
156
node_master .unloadwallet ("w2" )
177
- node_v19 .unloadwallet ("w1_v19" )
178
- node_v19 .unloadwallet ("w2_v19" )
179
- node_v18 .unloadwallet ("w1_v18" )
180
- node_v18 .unloadwallet ("w2_v18" )
181
-
182
- # Copy wallets to v0.16
183
- for wallet in os .listdir (node_master_wallets_dir ):
184
- shutil .copytree (
185
- os .path .join (node_master_wallets_dir , wallet ),
186
- os .path .join (node_v16_wallets_dir , wallet )
187
- )
157
+ node_master .unloadwallet ("w3" )
188
158
189
- # Copy wallets to v0.17
190
- for wallet in os .listdir (node_master_wallets_dir ):
191
- shutil .copytree (
192
- os .path .join (node_master_wallets_dir , wallet ),
193
- os .path .join (node_v17_wallets_dir , wallet )
194
- )
195
- for wallet in os .listdir (node_v18_wallets_dir ):
196
- shutil .copytree (
197
- os .path .join (node_v18_wallets_dir , wallet ),
198
- os .path .join (node_v17_wallets_dir , wallet )
199
- )
200
-
201
- # Copy wallets to v0.18
202
- for wallet in os .listdir (node_master_wallets_dir ):
203
- shutil .copytree (
204
- os .path .join (node_master_wallets_dir , wallet ),
205
- os .path .join (node_v18_wallets_dir , wallet )
206
- )
207
-
208
- # Copy wallets to v0.19
209
- for wallet in os .listdir (node_master_wallets_dir ):
210
- shutil .copytree (
211
- os .path .join (node_master_wallets_dir , wallet ),
212
- os .path .join (node_v19_wallets_dir , wallet )
213
- )
159
+ for node in legacy_nodes :
160
+ # Copy wallets to previous version
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 (self .nodes_wallet_dir (node ), wallet )
165
+ )
214
166
215
167
if not self .options .descriptors :
216
168
# Descriptor wallets break compatibility, only run this test for legacy wallet
217
- # Open the wallets in v0.19
218
- node_v19 .loadwallet ("w1" )
219
- wallet = node_v19 .get_wallet_rpc ("w1" )
220
- info = wallet .getwalletinfo ()
221
- assert info ['private_keys_enabled' ]
222
- assert info ['keypoolsize' ] > 0
223
- txs = wallet .listtransactions ()
224
- assert_equal (len (txs ), 5 )
225
- assert_equal (txs [1 ]["txid" ], tx1_id )
226
- assert_equal (txs [2 ]["walletconflicts" ], [tx1_id ])
227
- assert_equal (txs [1 ]["replaced_by_txid" ], tx2_id )
228
- assert not (txs [1 ]["abandoned" ])
229
- assert_equal (txs [1 ]["confirmations" ], - 1 )
230
- assert_equal (txs [2 ]["blockindex" ], 1 )
231
- assert txs [3 ]["abandoned" ]
232
- assert_equal (txs [4 ]["walletconflicts" ], [tx3_id ])
233
- assert_equal (txs [3 ]["replaced_by_txid" ], tx4_id )
234
- assert not (hasattr (txs [3 ], "blockindex" ))
235
-
236
- node_v19 .loadwallet ("w2" )
237
- wallet = node_v19 .get_wallet_rpc ("w2" )
238
- info = wallet .getwalletinfo ()
239
- assert info ['private_keys_enabled' ] == False
240
- assert info ['keypoolsize' ] == 0
241
-
242
- node_v19 .loadwallet ("w3" )
243
- wallet = node_v19 .get_wallet_rpc ("w3" )
244
- info = wallet .getwalletinfo ()
245
- assert info ['private_keys_enabled' ]
246
- assert info ['keypoolsize' ] == 0
247
-
248
- # Open the wallets in v0.18
249
- node_v18 .loadwallet ("w1" )
250
- wallet = node_v18 .get_wallet_rpc ("w1" )
251
- info = wallet .getwalletinfo ()
252
- assert info ['private_keys_enabled' ]
253
- assert info ['keypoolsize' ] > 0
254
- txs = wallet .listtransactions ()
255
- assert_equal (len (txs ), 5 )
256
- assert_equal (txs [1 ]["txid" ], tx1_id )
257
- assert_equal (txs [2 ]["walletconflicts" ], [tx1_id ])
258
- assert_equal (txs [1 ]["replaced_by_txid" ], tx2_id )
259
- assert not (txs [1 ]["abandoned" ])
260
- assert_equal (txs [1 ]["confirmations" ], - 1 )
261
- assert_equal (txs [2 ]["blockindex" ], 1 )
262
- assert txs [3 ]["abandoned" ]
263
- assert_equal (txs [4 ]["walletconflicts" ], [tx3_id ])
264
- assert_equal (txs [3 ]["replaced_by_txid" ], tx4_id )
265
- assert not (hasattr (txs [3 ], "blockindex" ))
266
-
267
- node_v18 .loadwallet ("w2" )
268
- wallet = node_v18 .get_wallet_rpc ("w2" )
269
- info = wallet .getwalletinfo ()
270
- assert info ['private_keys_enabled' ] == False
271
- assert info ['keypoolsize' ] == 0
272
-
273
- node_v18 .loadwallet ("w3" )
274
- wallet = node_v18 .get_wallet_rpc ("w3" )
275
- info = wallet .getwalletinfo ()
276
- assert info ['private_keys_enabled' ]
277
- assert info ['keypoolsize' ] == 0
278
-
279
- node_v17 .loadwallet ("w1" )
280
- wallet = node_v17 .get_wallet_rpc ("w1" )
281
- info = wallet .getwalletinfo ()
282
- assert info ['private_keys_enabled' ]
283
- assert info ['keypoolsize' ] > 0
284
-
285
- node_v17 .loadwallet ("w2" )
286
- wallet = node_v17 .get_wallet_rpc ("w2" )
287
- info = wallet .getwalletinfo ()
288
- assert info ['private_keys_enabled' ] == False
289
- assert info ['keypoolsize' ] == 0
169
+ # Load modern wallet with older nodes
170
+ for node in legacy_nodes :
171
+ for wallet_name in ["w1" , "w2" , "w3" ]:
172
+ if node .version < 170000 :
173
+ # loadwallet was introduced in v0.17.0
174
+ continue
175
+ if node .version < 180000 and wallet_name == "w3" :
176
+ # Blank wallets were introduced in v0.18.0. We test the loading error below.
177
+ continue
178
+ node .loadwallet (wallet_name )
179
+ wallet = node .get_wallet_rpc (wallet_name )
180
+ info = wallet .getwalletinfo ()
181
+ if wallet_name == "w1" :
182
+ assert info ['private_keys_enabled' ] == True
183
+ assert info ['keypoolsize' ] > 0
184
+ txs = wallet .listtransactions ()
185
+ assert_equal (len (txs ), 5 )
186
+ assert_equal (txs [1 ]["txid" ], tx1_id )
187
+ assert_equal (txs [2 ]["walletconflicts" ], [tx1_id ])
188
+ assert_equal (txs [1 ]["replaced_by_txid" ], tx2_id )
189
+ assert not (txs [1 ]["abandoned" ])
190
+ assert_equal (txs [1 ]["confirmations" ], - 1 )
191
+ assert_equal (txs [2 ]["blockindex" ], 1 )
192
+ assert txs [3 ]["abandoned" ]
193
+ assert_equal (txs [4 ]["walletconflicts" ], [tx3_id ])
194
+ assert_equal (txs [3 ]["replaced_by_txid" ], tx4_id )
195
+ assert not (hasattr (txs [3 ], "blockindex" ))
196
+ elif wallet_name == "w2" :
197
+ assert (info ['private_keys_enabled' ] == False )
198
+ assert info ['keypoolsize' ] == 0
199
+ else :
200
+ assert (info ['private_keys_enabled' ] == True )
201
+ assert info ['keypoolsize' ] == 0
290
202
else :
291
- # Descriptor wallets appear to be corrupted wallets to old software
292
- assert_raises_rpc_error (- 4 , "Wallet file verification failed: wallet.dat corrupt, salvage failed" , node_v19 .loadwallet , "w1" )
293
- assert_raises_rpc_error (- 4 , "Wallet file verification failed: wallet.dat corrupt, salvage failed" , node_v19 .loadwallet , "w2" )
294
- assert_raises_rpc_error (- 4 , "Wallet file verification failed: wallet.dat corrupt, salvage failed" , node_v19 .loadwallet , "w3" )
295
- assert_raises_rpc_error (- 4 , "Wallet file verification failed: wallet.dat corrupt, salvage failed" , node_v18 .loadwallet , "w1" )
296
- assert_raises_rpc_error (- 4 , "Wallet file verification failed: wallet.dat corrupt, salvage failed" , node_v18 .loadwallet , "w2" )
297
- assert_raises_rpc_error (- 4 , "Wallet file verification failed: wallet.dat corrupt, salvage failed" , node_v18 .loadwallet , "w3" )
298
-
299
- # Open the wallets in v0.17
300
- node_v17 .loadwallet ("w1_v18" )
301
- wallet = node_v17 .get_wallet_rpc ("w1_v18" )
302
- info = wallet .getwalletinfo ()
303
- assert info ['private_keys_enabled' ]
304
- assert info ['keypoolsize' ] > 0
305
-
306
- node_v17 .loadwallet ("w2_v18" )
307
- wallet = node_v17 .get_wallet_rpc ("w2_v18" )
308
- info = wallet .getwalletinfo ()
309
- assert info ['private_keys_enabled' ] == False
310
- assert info ['keypoolsize' ] == 0
203
+ for node in legacy_nodes :
204
+ # Descriptor wallets appear to be corrupted wallets to old software
205
+ # and loadwallet is introduced in v0.17.0
206
+ if node .version >= 170000 and node .version < 210000 :
207
+ for wallet_name in ["w1" , "w2" , "w3" ]:
208
+ assert_raises_rpc_error (- 4 , "Wallet file verification failed: wallet.dat corrupt, salvage failed" , node .loadwallet , wallet_name )
311
209
312
210
# RPC loadwallet failure causes bitcoind to exit, in addition to the RPC
313
211
# call failure, so the following test won't work:
314
- # assert_raises_rpc_error(-4, "Wallet loading failed.", node_v17.loadwallet, 'w3_v18 ')
212
+ # assert_raises_rpc_error(-4, "Wallet loading failed.", node_v17.loadwallet, 'w3 ')
315
213
316
214
# Instead, we stop node and try to launch it with the wallet:
317
- self .stop_node (4 )
318
- node_v17 .assert_start_raises_init_error (["-wallet=w3_v18" ], "Error: Error loading w3_v18: Wallet requires newer version of Bitcoin Core" )
215
+ self .stop_node (node_v17 .index )
319
216
if self .options .descriptors :
320
217
# Descriptor wallets appear to be corrupted wallets to old software
321
218
node_v17 .assert_start_raises_init_error (["-wallet=w1" ], "Error: wallet.dat corrupt, salvage failed" )
322
219
node_v17 .assert_start_raises_init_error (["-wallet=w2" ], "Error: wallet.dat corrupt, salvage failed" )
323
220
node_v17 .assert_start_raises_init_error (["-wallet=w3" ], "Error: wallet.dat corrupt, salvage failed" )
324
221
else :
325
222
node_v17 .assert_start_raises_init_error (["-wallet=w3" ], "Error: Error loading w3: Wallet requires newer version of Bitcoin Core" )
326
- self .start_node (4 )
223
+ self .start_node (node_v17 . index )
327
224
328
225
if not self .options .descriptors :
329
226
# Descriptor wallets break compatibility, only run this test for legacy wallets
330
227
# Open most recent wallet in v0.16 (no loadwallet RPC)
331
- self .restart_node (5 , extra_args = ["-wallet=w2" ])
228
+ self .restart_node (node_v16 . index , extra_args = ["-wallet=w2" ])
332
229
wallet = node_v16 .get_wallet_rpc ("w2" )
333
230
info = wallet .getwalletinfo ()
334
231
assert info ['keypoolsize' ] == 1
335
232
336
233
# Create upgrade wallet in v0.16
337
- self .restart_node (- 1 , extra_args = ["-wallet=u1_v16" ])
234
+ self .restart_node (node_v16 . index , extra_args = ["-wallet=u1_v16" ])
338
235
wallet = node_v16 .get_wallet_rpc ("u1_v16" )
339
236
v16_addr = wallet .getnewaddress ('' , "bech32" )
340
237
v16_info = wallet .validateaddress (v16_addr )
341
238
v16_pubkey = v16_info ['pubkey' ]
342
- self .stop_node (- 1 )
239
+ self .stop_node (node_v16 . index )
343
240
344
241
self .log .info ("Test wallet upgrade path..." )
345
242
# u1: regular wallet, created with v0.17
@@ -371,7 +268,7 @@ def run_test(self):
371
268
os .path .join (node_master_wallets_dir , "u1_v16" ),
372
269
os .path .join (node_v16_wallets_dir , "wallets/u1_v16" )
373
270
)
374
- self .start_node (- 1 , extra_args = ["-wallet=u1_v16" ])
271
+ self .start_node (node_v16 . index , extra_args = ["-wallet=u1_v16" ])
375
272
wallet = node_v16 .get_wallet_rpc ("u1_v16" )
376
273
info = wallet .validateaddress (v16_addr )
377
274
assert_equal (info , v16_info )
0 commit comments