0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-08 10:31:50 -05:00

test: compare BDB dumps of test framework parser and wallet tool

This commit is contained in:
Sebastian Falbesoner 2024-05-16 19:08:57 +02:00
parent 01ddd9f646
commit d45eb3964f

View file

@ -6,18 +6,23 @@
import os import os
import platform import platform
import random
import stat import stat
import string
import subprocess import subprocess
import textwrap import textwrap
from collections import OrderedDict from collections import OrderedDict
from test_framework.bdb import dump_bdb_kv
from test_framework.messages import ser_string
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import ( from test_framework.util import (
assert_equal, assert_equal,
assert_greater_than, assert_greater_than,
sha256sum_file, sha256sum_file,
) )
from test_framework.wallet import getnewdestination
class ToolWalletTest(BitcoinTestFramework): class ToolWalletTest(BitcoinTestFramework):
@ -545,6 +550,44 @@ class ToolWalletTest(BitcoinTestFramework):
self.stop_node(0) self.stop_node(0)
self.assert_tool_output("The dumpfile may contain private keys. To ensure the safety of your Bitcoin, do not share the dumpfile.\n", "-wallet=unclean_lsn", f"-dumpfile={wallet_dump}", "dump") self.assert_tool_output("The dumpfile may contain private keys. To ensure the safety of your Bitcoin, do not share the dumpfile.\n", "-wallet=unclean_lsn", f"-dumpfile={wallet_dump}", "dump")
def test_compare_legacy_dump_with_framework_bdb_parser(self):
self.log.info("Verify that legacy wallet database dump matches the one from the test framework's BDB parser")
wallet_name = "bdb_ro_test"
self.start_node(0)
# add some really large labels (above twice the largest valid page size) to create BDB overflow pages
self.nodes[0].createwallet(wallet_name)
wallet_rpc = self.nodes[0].get_wallet_rpc(wallet_name)
generated_labels = {}
for i in range(10):
address = getnewdestination()[2]
large_label = ''.join([random.choice(string.ascii_letters) for _ in range(150000)])
wallet_rpc.setlabel(address, large_label)
generated_labels[address] = large_label
# fill the keypool to create BDB internal pages
wallet_rpc.keypoolrefill(1000)
self.stop_node(0)
wallet_dumpfile = self.nodes[0].datadir_path / "bdb_ro_test.dump"
self.assert_tool_output("The dumpfile may contain private keys. To ensure the safety of your Bitcoin, do not share the dumpfile.\n", "-wallet={}".format(wallet_name), "-dumpfile={}".format(wallet_dumpfile), "dump")
expected_dump = self.read_dump(wallet_dumpfile)
# remove extra entries from wallet tool dump that are not actual key/value pairs from the database
del expected_dump['BITCOIN_CORE_WALLET_DUMP']
del expected_dump['format']
del expected_dump['checksum']
bdb_ro_parser_dump_raw = dump_bdb_kv(self.nodes[0].wallets_path / wallet_name / "wallet.dat")
bdb_ro_parser_dump = OrderedDict()
assert any([len(bytes.fromhex(value)) >= 150000 for value in expected_dump.values()])
for key, value in sorted(bdb_ro_parser_dump_raw.items()):
bdb_ro_parser_dump[key.hex()] = value.hex()
assert_equal(bdb_ro_parser_dump, expected_dump)
# check that all labels were created with the correct address
for address, label in generated_labels.items():
key_bytes = b'\x04name' + ser_string(address.encode())
assert key_bytes in bdb_ro_parser_dump_raw
assert_equal(bdb_ro_parser_dump_raw[key_bytes], ser_string(label.encode()))
def run_test(self): def run_test(self):
self.wallet_path = self.nodes[0].wallets_path / self.default_wallet_name / self.wallet_data_filename self.wallet_path = self.nodes[0].wallets_path / self.default_wallet_name / self.wallet_data_filename
self.test_invalid_tool_commands_and_args() self.test_invalid_tool_commands_and_args()
@ -561,6 +604,9 @@ class ToolWalletTest(BitcoinTestFramework):
self.test_dump_createfromdump() self.test_dump_createfromdump()
self.test_chainless_conflicts() self.test_chainless_conflicts()
self.test_dump_very_large_records() self.test_dump_very_large_records()
if not self.options.descriptors and self.is_bdb_compiled() and not self.options.swap_bdb_endian:
self.test_compare_legacy_dump_with_framework_bdb_parser()
if __name__ == '__main__': if __name__ == '__main__':
ToolWalletTest(__file__).main() ToolWalletTest(__file__).main()