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) 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 all three initial private sends complete even after receiving the transaction back."""7from test_framework.messages import CAddress, msg_tx8from test_framework.p2p import P2PInterface, P2P_SERVICES, p2p_lock, start_p2p_listener9from test_framework.socks5 import Socks5Server, start_socks5_server10from test_framework.test_framework import BitcoinTestFramework11from test_framework.util import assert_equal12from test_framework.wallet import MiniWallet15class DelayedPrivateBroadcastPeer(P2PInterface):16def __init__(self, private_peers):17super().__init__()18self.private_peers = private_peers20def on_version(self, message):21# Private broadcast connections have zero services. Hold them at verack.22if message.nServices == 0:23self.private_peers.append(self)24else:25super().on_version(message)28class PrivateBroadcastCompletionTest(BitcoinTestFramework):29def set_test_params(self):30self.num_nodes = 131self.disable_autoconnect = False33def setup_nodes(self):34self.private_peers = [] # Guarded by p2p_lock36def destinations_factory(_requested_to_addr, _requested_to_port, _proxy_client):37peer = DelayedPrivateBroadcastPeer(self.private_peers)38peer.peer_connect_helper(dstaddr="0.0.0.0", dstport=0, net=self.chain, timeout_factor=self.options.timeout_factor)39peer.peer_connect_send_version(services=P2P_SERVICES)40addr, port = start_p2p_listener(self.network_thread, peer)41return {"actual_to_addr": addr, "actual_to_port": port}43self.proxy = start_socks5_server(destinations_factory)44self.extra_args = [[45"-privatebroadcast",46f"-proxy={self.proxy.conf.addr[0]}:{self.proxy.conf.addr[1]}",47]]48super().setup_nodes()50def run_test(self):51node = self.nodes[0]52returner = node.add_p2p_connection(P2PInterface())53self.fill_node_addrman(node_index=0, address_types_to_add=[CAddress.NET_TORV3])54wallet = MiniWallet(node)55tx = wallet.create_self_transfer()56node.sendrawtransaction(tx["hex"])58def three_private_peers():59with p2p_lock:60return len(self.private_peers) == 361self.wait_until(three_private_peers)62with p2p_lock:63peers = list(self.private_peers)64self.private_peers.clear()66self.log.info("Ensure each peer receives the transaction before disconnecting")67for i, peer in enumerate(peers):68P2PInterface.on_version(peer, peer.last_message["version"])69peer.wait_for_disconnect()70assert_equal(peer.last_message["tx"].tx.txid_hex, tx["txid"])71if i == 0:72self.log.info("Return the transaction while the other two peers still wait on handshake")73returner.send_and_ping(msg_tx(tx["tx"]))75self.log.info("Receive another transaction while the proxy is unavailable")76self.proxy.stop()77self.proxy.s.close()78next_tx = wallet.create_self_transfer()79with node.assert_debug_log(["will retry to a different address"], timeout=10):80node.sendrawtransaction(next_tx["hex"])81returner.send_and_ping(msg_tx(next_tx["tx"]))83self.log.info("Restoring the proxy opens all three connections for the received transaction")84self.proxy = Socks5Server(self.proxy.conf)85self.proxy.start()86self.wait_until(three_private_peers)87with p2p_lock:88peers = list(self.private_peers)89for peer in peers:90P2PInterface.on_version(peer, peer.last_message["version"])91peer.wait_for_disconnect()92assert_equal(peer.last_message["tx"].tx.txid_hex, next_tx["txid"])94self.stop_node(0)95self.proxy.stop()98if __name__ == "__main__":99PrivateBroadcastCompletionTest(__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.