Skip to content

Commit c1984f1

Browse files
committed
test: Test dumping dbs with overflow pages
1 parent fd7b16e commit c1984f1

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

test/functional/tool_wallet.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from test_framework.test_framework import BitcoinTestFramework
1515
from test_framework.util import (
1616
assert_equal,
17+
assert_greater_than,
1718
sha256sum_file,
1819
)
1920

@@ -473,6 +474,42 @@ def test_dump_endianness(self):
473474
other_dump = self.read_dump(self.nodes[0].datadir_path / "rt-other_endian.dump")
474475
self.assert_dump(expected_dump, other_dump)
475476

477+
def test_dump_very_large_records(self):
478+
self.log.info("Test that wallets with large records are successfully dumped")
479+
480+
self.start_node(0)
481+
self.nodes[0].createwallet("bigrecords")
482+
wallet = self.nodes[0].get_wallet_rpc("bigrecords")
483+
484+
# Both BDB and sqlite have maximum page sizes of 65536 bytes, with defaults of 4096
485+
# When a record exceeds some size threshold, both BDB and SQLite will store the data
486+
# in one or more overflow pages. We want to make sure that our tooling can dump such
487+
# records, even when they span multiple pages. To make a large record, we just need
488+
# to make a very big transaction.
489+
self.generate(self.nodes[0], 101)
490+
def_wallet = self.nodes[0].get_wallet_rpc(self.default_wallet_name)
491+
outputs = {}
492+
for i in range(500):
493+
outputs[wallet.getnewaddress(address_type="p2sh-segwit")] = 0.01
494+
def_wallet.sendmany(amounts=outputs)
495+
self.generate(self.nodes[0], 1)
496+
send_res = wallet.sendall([def_wallet.getnewaddress()])
497+
self.generate(self.nodes[0], 1)
498+
assert_equal(send_res["complete"], True)
499+
tx = wallet.gettransaction(txid=send_res["txid"], verbose=True)
500+
assert_greater_than(tx["decoded"]["size"], 70000)
501+
502+
self.stop_node(0)
503+
504+
wallet_dump = self.nodes[0].datadir_path / "bigrecords.dump"
505+
self.assert_tool_output("The dumpfile may contain private keys. To ensure the safety of your Bitcoin, do not share the dumpfile.\n", "-wallet=bigrecords", f"-dumpfile={wallet_dump}", "dump")
506+
dump = self.read_dump(wallet_dump)
507+
for k,v in dump.items():
508+
if tx["hex"] in v:
509+
break
510+
else:
511+
assert False, "Big transaction was not found in wallet dump"
512+
476513
def run_test(self):
477514
self.wallet_path = self.nodes[0].wallets_path / self.default_wallet_name / self.wallet_data_filename
478515
self.test_invalid_tool_commands_and_args()
@@ -487,6 +524,7 @@ def run_test(self):
487524
self.test_dump_endianness()
488525
self.test_dump_createfromdump()
489526
self.test_chainless_conflicts()
527+
self.test_dump_very_large_records()
490528

491529
if __name__ == '__main__':
492530
ToolWalletTest().main()

0 commit comments

Comments
 (0)