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) 2016-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 processing of feefilter messages."""7from decimal import Decimal9from test_framework.messages import MSG_TX, MSG_WTX, msg_feefilter10from test_framework.p2p import P2PInterface, p2p_lock11from test_framework.test_framework import BitcoinTestFramework12from test_framework.util import assert_equal13from test_framework.wallet import MiniWallet16class FeefilterConn(P2PInterface):17feefilter_received = False19def on_feefilter(self, message):20self.feefilter_received = True22def assert_feefilter_received(self, recv: bool):23with p2p_lock:24assert_equal(self.feefilter_received, recv)27class TestP2PConn(P2PInterface):28def __init__(self):29super().__init__()30self.txinvs = []32def on_inv(self, message):33for i in message.inv:34if (i.type == MSG_TX) or (i.type == MSG_WTX):35self.txinvs.append('{:064x}'.format(i.hash))37def wait_for_invs_to_match(self, invs_expected):38invs_expected.sort()39self.wait_until(lambda: invs_expected == sorted(self.txinvs))41def clear_invs(self):42with p2p_lock:43self.txinvs = []46class FeeFilterTest(BitcoinTestFramework):47def set_test_params(self):48self.num_nodes = 249# whitelist peers to speed up tx relay / mempool sync50self.noban_tx_relay = True51# We lower the various required feerates for this test52# to catch a corner-case where feefilter used to slightly undercut53# mempool and wallet feerate calculation based on GetFee54# rounding down 3 places, leading to stranded transactions.55# See issue #1649956self.extra_args = [[57"-minrelaytxfee=0.00000100",58"-mintxfee=0.00000100"59]] * self.num_nodes61def run_test(self):62self.test_feefilter_forcerelay()63self.test_feefilter()64self.test_feefilter_blocksonly()66def test_feefilter_forcerelay(self):67self.log.info('Check that peers without forcerelay permission (default) get a feefilter message')68self.nodes[0].add_p2p_connection(FeefilterConn()).assert_feefilter_received(True)70self.log.info('Check that peers with forcerelay permission do not get a feefilter message')71self.restart_node(0, extra_args=['[email protected]'])72self.nodes[0].add_p2p_connection(FeefilterConn()).assert_feefilter_received(False)74# Restart to disconnect peers and load default extra_args75self.restart_node(0)76self.connect_nodes(1, 0)78def test_feefilter(self):79node1 = self.nodes[1]80node0 = self.nodes[0]81miniwallet = MiniWallet(node1)83conn = self.nodes[0].add_p2p_connection(TestP2PConn())85self.log.info("Test txs paying 0.2 sat/byte are received by test connection")86txids = [miniwallet.send_self_transfer(fee_rate=Decimal('0.00000200'), from_node=node1)['wtxid'] for _ in range(3)]87conn.wait_for_invs_to_match(txids)88conn.clear_invs()90# Set a fee filter of 0.15 sat/byte on test connection91conn.send_and_ping(msg_feefilter(150))93self.log.info("Test txs paying 0.15 sat/byte are received by test connection")94txids = [miniwallet.send_self_transfer(fee_rate=Decimal('0.00000150'), from_node=node1)['wtxid'] for _ in range(3)]95conn.wait_for_invs_to_match(txids)96conn.clear_invs()98self.log.info("Test txs paying 0.1 sat/byte are no longer received by test connection")99txids = [miniwallet.send_self_transfer(fee_rate=Decimal('0.00000100'), from_node=node1)['wtxid'] for _ in range(3)]100self.sync_mempools() # must be sure node 0 has received all txs102# Send one transaction from node0 that should be received, so that we103# we can sync the test on receipt (if node1's txs were relayed, they'd104# be received by the time this node0 tx is received). This is105# unfortunately reliant on the current relay behavior where we batch up106# to 35 entries in an inv, which means that when this next transaction107# is eligible for relay, the prior transactions from node1 are eligible108# as well.109txids = [miniwallet.send_self_transfer(fee_rate=Decimal('0.00020000'), from_node=node0)['wtxid'] for _ in range(1)]110conn.wait_for_invs_to_match(txids)111conn.clear_invs()112self.sync_mempools() # must be sure node 1 has received all txs114self.log.info("Remove fee filter and check txs are received again")115conn.send_and_ping(msg_feefilter(0))116txids = [miniwallet.send_self_transfer(fee_rate=Decimal('0.00020000'), from_node=node1)['wtxid'] for _ in range(3)]117conn.wait_for_invs_to_match(txids)118conn.clear_invs()120def test_feefilter_blocksonly(self):121"""Test that we don't send fee filters to block-relay-only peers and when we're in blocksonly mode."""122self.log.info("Check that we don't send fee filters to block-relay-only peers.")123feefilter_peer = self.nodes[0].add_outbound_p2p_connection(FeefilterConn(), p2p_idx=0, connection_type="block-relay-only")124feefilter_peer.sync_with_ping()125feefilter_peer.assert_feefilter_received(False)127self.log.info("Check that we don't send fee filters when in blocksonly mode.")128self.restart_node(0, ["-blocksonly"])129feefilter_peer = self.nodes[0].add_p2p_connection(FeefilterConn())130feefilter_peer.sync_with_ping()131feefilter_peer.assert_feefilter_received(False)134if __name__ == '__main__':135FeeFilterTest(__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.