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) 2024-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 that descriptor wallets rescan mempool transactions properly when importing."""7from test_framework.address import (8address_to_scriptpubkey,9ADDRESS_BCRT1_UNSPENDABLE,10)11from test_framework.messages import COIN12from test_framework.test_framework import BitcoinTestFramework13from test_framework.util import assert_equal14from test_framework.wallet import MiniWallet15from test_framework.wallet_util import test_address18class WalletRescanUnconfirmed(BitcoinTestFramework):19def set_test_params(self):20self.num_nodes = 122def skip_test_if_missing_module(self):23self.skip_if_no_wallet()25def run_test(self):26self.log.info("Create wallets and mine initial chain")27node = self.nodes[0]28tester_wallet = MiniWallet(node)30node.createwallet(wallet_name='w0', disable_private_keys=False)31w0 = node.get_wallet_rpc('w0')33self.log.info("Create a parent tx and mine it in a block that will later be disconnected")34parent_address = w0.getnewaddress()35tx_parent_to_reorg = tester_wallet.send_to(36from_node=node,37scriptPubKey=address_to_scriptpubkey(parent_address),38amount=COIN,39)40assert tx_parent_to_reorg["txid"] in node.getrawmempool()41block_to_reorg = self.generate(tester_wallet, 1)[0]42assert_equal(len(node.getrawmempool()), 0)43node.syncwithvalidationinterfacequeue()44assert_equal(w0.gettransaction(tx_parent_to_reorg["txid"])["confirmations"], 1)46# Create an unconfirmed child transaction from the parent tx, sending all47# the funds to an unspendable address. Importantly, no change output is created so the48# transaction can't be recognized using its outputs. The wallet rescan needs to know the49# inputs of the transaction to detect it, so the parent must be processed before the child.50w0_utxos = w0.listunspent()52self.log.info("Create a child tx and wait for it to propagate to all mempools")53# The only UTXO available to spend is tx_parent_to_reorg.54assert_equal(len(w0_utxos), 1)55assert_equal(w0_utxos[0]["txid"], tx_parent_to_reorg["txid"])56tx_child_unconfirmed_sweep = w0.sendall(recipients=[ADDRESS_BCRT1_UNSPENDABLE], options={"locktime":0})57assert tx_child_unconfirmed_sweep["txid"] in node.getrawmempool()58node.syncwithvalidationinterfacequeue()60self.log.info("Mock a reorg, causing parent to re-enter mempools after its child")61node.invalidateblock(block_to_reorg)62assert tx_parent_to_reorg["txid"] in node.getrawmempool()64self.log.info("Import descriptor wallet on another node")65# descriptor is ranged - label not allowed66descriptors_to_import = [{"desc": w0.getaddressinfo(parent_address)['parent_desc'], "timestamp": 0}]68node.createwallet(wallet_name="w1", disable_private_keys=True)69w1 = node.get_wallet_rpc("w1")70w1.importdescriptors(descriptors_to_import)72self.log.info("Check that the importing node has properly rescanned mempool transactions")73# Check that parent address is correctly determined as ismine74test_address(w1, parent_address, solvable=True, ismine=True)75# This would raise a JSONRPCError if the transactions were not identified as belonging to the wallet.76assert_equal(w1.gettransaction(tx_parent_to_reorg["txid"])["confirmations"], 0)77assert_equal(w1.gettransaction(tx_child_unconfirmed_sweep["txid"])["confirmations"], 0)79if __name__ == '__main__':80WalletRescanUnconfirmed(__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.