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) 2020-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 orphaned block rewards in the wallet."""7from test_framework.test_framework import BitcoinTestFramework8from test_framework.util import assert_equal10class OrphanedBlockRewardTest(BitcoinTestFramework):11def set_test_params(self):12self.setup_clean_chain = True13self.num_nodes = 215def skip_test_if_missing_module(self):16self.skip_if_no_wallet()18def run_test(self):19# Generate some blocks and obtain some coins on node 0. We send20# some balance to node 1, which will hold it as a single coin.21self.generate(self.nodes[0], 150)22self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 10)23self.generate(self.nodes[0], 1)25# Get a block reward with node 1 and remember the block so we can orphan26# it later.27self.sync_blocks()28blk = self.generate(self.nodes[1], 1)[0]30# Let the block reward mature and send coins including both31# the existing balance and the block reward.32self.generate(self.nodes[0], 150)33assert_equal(self.nodes[1].getbalance(), 10 + 25)34pre_reorg_conf_bals = self.nodes[1].getbalances()35txid = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 30)36orig_chain_tip = self.nodes[0].getbestblockhash()37self.sync_mempools()39# Orphan the block reward and make sure that the original coins40# from the wallet can still be spent.41self.nodes[0].invalidateblock(blk)42blocks = self.generate(self.nodes[0], 152)43conflict_block = blocks[0]44# We expect the descendants of orphaned rewards to no longer be considered45assert_equal(self.nodes[1].getbalances()["mine"], {46"trusted": 10,47"untrusted_pending": 0,48"immature": 0,49"nonmempool": 0,50})51# And the unconfirmed tx to be abandoned52assert_equal(self.nodes[1].gettransaction(txid)["details"][0]["abandoned"], True)54# The abandoning should persist through reloading55self.nodes[1].unloadwallet(self.default_wallet_name)56self.nodes[1].loadwallet(self.default_wallet_name)57assert_equal(self.nodes[1].gettransaction(txid)["details"][0]["abandoned"], True)59# If the orphaned reward is reorged back into the main chain, any unconfirmed60# descendant txs at the time of the original reorg remain abandoned.61self.nodes[0].invalidateblock(conflict_block)62self.nodes[0].reconsiderblock(blk)63assert_equal(self.nodes[0].getbestblockhash(), orig_chain_tip)64self.generate(self.nodes[0], 3)66balances = self.nodes[1].getbalances()67del balances["lastprocessedblock"]68del pre_reorg_conf_bals["lastprocessedblock"]69assert_equal(balances, pre_reorg_conf_bals)70assert_equal(self.nodes[1].gettransaction(txid)["details"][0]["abandoned"], True)73if __name__ == '__main__':74OrphanedBlockRewardTest(__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.