|
21 | 21 | from test_framework.blocktools import COINBASE_MATURITY |
22 | 22 | from test_framework.test_framework import BitcoinTestFramework |
23 | 23 | from test_framework.descriptors import descsum_create |
| 24 | +from test_framework.messages import ser_string |
24 | 25 |
|
25 | 26 | from test_framework.util import ( |
26 | 27 | assert_equal, |
| 28 | + assert_greater_than, |
27 | 29 | assert_raises_rpc_error, |
28 | 30 | ) |
29 | 31 |
|
@@ -149,18 +151,13 @@ def test_v22_inactivehdchain_path(self): |
149 | 151 | assert_equal(bad_deriv_wallet_master.getaddressinfo(bad_path_addr)["hdkeypath"], good_deriv_path) |
150 | 152 | bad_deriv_wallet_master.unloadwallet() |
151 | 153 |
|
152 | | - # If we have sqlite3, verify that there are no keymeta records |
153 | | - try: |
154 | | - import sqlite3 |
155 | | - wallet_db = node_master.wallets_path / wallet_name / "wallet.dat" |
156 | | - conn = sqlite3.connect(wallet_db) |
157 | | - with conn: |
158 | | - # Retrieve all records that have the "keymeta" prefix. The remaining key data varies for each record. |
159 | | - keymeta_rec = conn.execute("SELECT value FROM main where key >= x'076b65796d657461' AND key < x'076b65796d657462'").fetchone() |
160 | | - assert_equal(keymeta_rec, None) |
161 | | - conn.close() |
162 | | - except ImportError: |
163 | | - self.log.warning("sqlite3 module not available, skipping lack of keymeta records check") |
| 154 | + def check_keymeta(conn): |
| 155 | + # Retrieve all records that have the "keymeta" prefix. The remaining key data varies for each record. |
| 156 | + keymeta_rec = conn.execute(f"SELECT value FROM main where key >= x'{ser_string(b'keymeta').hex()}' AND key < x'{ser_string(b'keymetb').hex()}'").fetchone() |
| 157 | + assert_equal(keymeta_rec, None) |
| 158 | + |
| 159 | + wallet_db = node_master.wallets_path / wallet_name / "wallet.dat" |
| 160 | + self.inspect_sqlite_db(wallet_db, check_keymeta) |
164 | 161 |
|
165 | 162 | def test_ignore_legacy_during_startup(self, legacy_nodes, node_master): |
166 | 163 | self.log.info("Test that legacy wallets are ignored during startup on v29+") |
@@ -342,6 +339,13 @@ def run_test(self): |
342 | 339 | # Remove the wallet from old node |
343 | 340 | wallet_prev.unloadwallet() |
344 | 341 |
|
| 342 | + # Open backup with sqlite and get flags |
| 343 | + def get_flags(conn): |
| 344 | + flags_rec = conn.execute(f"SELECT value FROM main WHERE key = x'{ser_string(b'flags').hex()}'").fetchone() |
| 345 | + return int.from_bytes(flags_rec[0], byteorder="little") |
| 346 | + |
| 347 | + old_flags = self.inspect_sqlite_db(backup_path, get_flags) |
| 348 | + |
345 | 349 | # Restore the wallet to master |
346 | 350 | load_res = node_master.restorewallet(wallet_name, backup_path) |
347 | 351 |
|
@@ -378,6 +382,21 @@ def run_test(self): |
378 | 382 |
|
379 | 383 | wallet.unloadwallet() |
380 | 384 |
|
| 385 | + # Open the wallet with sqlite and inspect the flags and records |
| 386 | + def check_upgraded_records(conn, old_flags): |
| 387 | + flags_rec = conn.execute(f"SELECT value FROM main WHERE key = x'{ser_string(b'flags').hex()}'").fetchone() |
| 388 | + new_flags = int.from_bytes(flags_rec[0], byteorder="little") |
| 389 | + diff_flags = new_flags & ~old_flags |
| 390 | + |
| 391 | + # Check for last hardened xpubs if the flag is newly set |
| 392 | + if diff_flags & (1 << 2): |
| 393 | + self.log.debug("Checking descriptor cache was upgraded") |
| 394 | + # Fetch all records with the walletdescriptorlhcache prefix |
| 395 | + lh_cache_recs = conn.execute(f"SELECT value FROM main where key >= x'{ser_string(b'walletdescriptorlhcache').hex()}' AND key < x'{ser_string(b'walletdescriptorlhcachf').hex()}'").fetchall() |
| 396 | + assert_greater_than(len(lh_cache_recs), 0) |
| 397 | + |
| 398 | + self.inspect_sqlite_db(down_backup_path, check_upgraded_records, old_flags) |
| 399 | + |
381 | 400 | # Check that no automatic upgrade broke downgrading the wallet |
382 | 401 | target_dir = node.wallets_path / down_wallet_name |
383 | 402 | os.makedirs(target_dir, exist_ok=True) |
|
0 commit comments