Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1#!/usr/bin/env python32# Copyright (c) 2017-present The Bitcoin Core developers3# Distributed under the MIT software license, see the accompanying4# file COPYING or http://www.opensource.org/licenses/mit-license.php.5"""Test HD Wallet keypool restore function.7Two nodes. Node1 is under test. Node0 is providing transactions and generating blocks.9- Start node1, shutdown and backup wallet.10- Generate 110 keys (enough to drain the keypool). Store key 90 (in the initial keypool) and key 110 (beyond the initial keypool). Send funds to key 90 and key 110.11- Stop node1, clear the datadir, move wallet file back into the datadir and restart node1.12- connect node1 to node0. Verify that they sync and node1 receives its funds."""13import shutil15from test_framework.blocktools import COINBASE_MATURITY16from test_framework.test_framework import BitcoinTestFramework17from test_framework.util import (18assert_equal,19)22class KeypoolRestoreTest(BitcoinTestFramework):23def set_test_params(self):24self.setup_clean_chain = True25self.num_nodes = 526self.extra_args = [[]]27for _ in range(self.num_nodes - 1):28self.extra_args.append(['-keypool=100'])30def skip_test_if_missing_module(self):31self.skip_if_no_wallet()33def run_test(self):34wallet_path = self.nodes[1].wallets_path / self.default_wallet_name / self.wallet_data_filename35wallet_backup_path = self.nodes[1].datadir_path / "wallet.bak"36self.generate(self.nodes[0], COINBASE_MATURITY + 1)38self.log.info("Make backup of wallet")39self.stop_node(1)40shutil.copyfile(wallet_path, wallet_backup_path)41self.start_node(1, self.extra_args[1])42for i in [1, 2, 3, 4]:43self.connect_nodes(0, i)45output_types = ["legacy", "p2sh-segwit", "bech32", "bech32m"]46for i, output_type in enumerate(output_types):47self.log.info("Generate keys for wallet with address type: {}".format(output_type))48idx = i+149for _ in range(90):50addr_oldpool = self.nodes[idx].getnewaddress(address_type=output_type)51for _ in range(20):52addr_extpool = self.nodes[idx].getnewaddress(address_type=output_type)54# Make sure we're creating the outputs we expect55address_details = self.nodes[idx].validateaddress(addr_extpool)56if i == 0:57assert not address_details["isscript"] and not address_details["iswitness"]58elif i == 1:59assert address_details["isscript"] and not address_details["iswitness"]60elif i == 2:61assert not address_details["isscript"] and address_details["iswitness"]62elif i == 3:63assert address_details["isscript"] and address_details["iswitness"]65self.log.info("Send funds to wallet")66self.nodes[0].sendtoaddress(addr_oldpool, 10)67self.generate(self.nodes[0], 1)68self.nodes[0].sendtoaddress(addr_extpool, 5)69self.generate(self.nodes[0], 1)71self.log.info("Restart node with wallet backup")72self.stop_node(idx)73shutil.copyfile(wallet_backup_path, wallet_path)74self.start_node(idx, self.extra_args[idx])75self.connect_nodes(0, idx)76self.sync_all()78self.log.info("Verify keypool is restored and balance is correct")79assert_equal(self.nodes[idx].getbalance(), 15)80assert_equal(self.nodes[idx].listtransactions()[0]['category'], "receive")81# Check that we have marked all keys up to the used keypool key as used82if output_type == 'legacy':83assert_equal(self.nodes[idx].getaddressinfo(self.nodes[idx].getnewaddress(address_type=output_type))['hdkeypath'], "m/44h/1h/0h/0/110")84elif output_type == 'p2sh-segwit':85assert_equal(self.nodes[idx].getaddressinfo(self.nodes[idx].getnewaddress(address_type=output_type))['hdkeypath'], "m/49h/1h/0h/0/110")86elif output_type == 'bech32':87assert_equal(self.nodes[idx].getaddressinfo(self.nodes[idx].getnewaddress(address_type=output_type))['hdkeypath'], "m/84h/1h/0h/0/110")88elif output_type == 'bech32m':89assert_equal(self.nodes[idx].getaddressinfo(self.nodes[idx].getnewaddress(address_type=output_type))['hdkeypath'], "m/86h/1h/0h/0/110")92if __name__ == '__main__':93KeypoolRestoreTest(__file__).main()
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.