1414from test_framework .test_framework import BitcoinTestFramework
1515from 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
491529if __name__ == '__main__' :
492530 ToolWalletTest ().main ()
0 commit comments