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) 2022-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.6""" Tests the net:* tracepoint API interface.7See https://github.com/bitcoin/bitcoin/blob/master/doc/tracing.md#context-net8"""10import ctypes11from io import BytesIO12# Test will be skipped if we don't have bcc installed13try:14from bcc import BPF, USDT # type: ignore[import]15except ImportError:16pass17from test_framework.messages import CBlockHeader, MAX_HEADERS_RESULTS, msg_headers, msg_version18from test_framework.p2p import P2PInterface19from test_framework.test_framework import BitcoinTestFramework20from test_framework.util import (21assert_equal,22assert_greater_than,23bpf_cflags,24)26# Tor v3 addresses are 62 chars + 6 chars for the port (':12345').27MAX_PEER_ADDR_LENGTH = 6828MAX_PEER_CONN_TYPE_LENGTH = 2029MAX_MSG_TYPE_LENGTH = 2030MAX_MISBEHAVING_MESSAGE_LENGTH = 12831# We won't process messages larger than 150 byte in this test. For reading32# larger messanges see contrib/tracing/log_raw_p2p_msgs.py33MAX_MSG_DATA_LENGTH = 15035# from net_address.h36NETWORK_TYPE_UNROUTABLE = 037# Use in -maxconnections. Results in a maximum of 21 inbound connections38MAX_CONNECTIONS = 5339MAX_INBOUND_CONNECTIONS = 21 # 10 outbound and 1 feeler, (MAX_CONNECTIONS - 10 - 1) / 2 slots for tx-relaying inbounds41net_tracepoints_program = """42#include <uapi/linux/ptrace.h>44#define MAX_PEER_ADDR_LENGTH {}45#define MAX_PEER_CONN_TYPE_LENGTH {}46#define MAX_MSG_TYPE_LENGTH {}47#define MAX_MSG_DATA_LENGTH {}48#define MAX_MISBEHAVING_MESSAGE_LENGTH {}49""".format(50MAX_PEER_ADDR_LENGTH,51MAX_PEER_CONN_TYPE_LENGTH,52MAX_MSG_TYPE_LENGTH,53MAX_MSG_DATA_LENGTH,54MAX_MISBEHAVING_MESSAGE_LENGTH,55) + """56// A min() macro. Prefixed with _TRACEPOINT_TEST to avoid collision with other MIN macros.57#define _TRACEPOINT_TEST_MIN(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })59struct p2p_message60{61u64 peer_id;62char peer_addr[MAX_PEER_ADDR_LENGTH];63char peer_conn_type[MAX_PEER_CONN_TYPE_LENGTH];64char msg_type[MAX_MSG_TYPE_LENGTH];65u64 msg_size;66u8 msg[MAX_MSG_DATA_LENGTH];67};69struct Connection70{71u64 id;72char addr[MAX_PEER_ADDR_LENGTH];73char type[MAX_PEER_CONN_TYPE_LENGTH];74u32 network;75};77struct NewConnection78{79struct Connection conn;80u64 existing;81};83struct ClosedConnection84{85struct Connection conn;86u64 time_established;87};89struct MisbehavingConnection90{91u64 id;92char message[MAX_MISBEHAVING_MESSAGE_LENGTH];93};95BPF_PERF_OUTPUT(inbound_messages);96int trace_inbound_message(struct pt_regs *ctx) {97struct p2p_message msg = {};98void *paddr = NULL, *pconn_type = NULL, *pmsg_type = NULL, *pmsg = NULL;99bpf_usdt_readarg(1, ctx, &msg.peer_id);100bpf_usdt_readarg(2, ctx, &paddr);101bpf_probe_read_user_str(&msg.peer_addr, sizeof(msg.peer_addr), paddr);102bpf_usdt_readarg(3, ctx, &pconn_type);103bpf_probe_read_user_str(&msg.peer_conn_type, sizeof(msg.peer_conn_type), pconn_type);104bpf_usdt_readarg(4, ctx, &pmsg_type);105bpf_probe_read_user_str(&msg.msg_type, sizeof(msg.msg_type), pmsg_type);106bpf_usdt_readarg(5, ctx, &msg.msg_size);107bpf_usdt_readarg(6, ctx, &pmsg);108bpf_probe_read_user(&msg.msg, _TRACEPOINT_TEST_MIN(msg.msg_size, MAX_MSG_DATA_LENGTH), pmsg);109inbound_messages.perf_submit(ctx, &msg, sizeof(msg));110return 0;111}113BPF_PERF_OUTPUT(outbound_messages);114int trace_outbound_message(struct pt_regs *ctx) {115struct p2p_message msg = {};116void *paddr = NULL, *pconn_type = NULL, *pmsg_type = NULL, *pmsg = NULL;117bpf_usdt_readarg(1, ctx, &msg.peer_id);118bpf_usdt_readarg(1, ctx, &msg.peer_id);119bpf_usdt_readarg(2, ctx, &paddr);120bpf_probe_read_user_str(&msg.peer_addr, sizeof(msg.peer_addr), paddr);121bpf_usdt_readarg(3, ctx, &pconn_type);122bpf_probe_read_user_str(&msg.peer_conn_type, sizeof(msg.peer_conn_type), pconn_type);123bpf_usdt_readarg(4, ctx, &pmsg_type);124bpf_probe_read_user_str(&msg.msg_type, sizeof(msg.msg_type), pmsg_type);125bpf_usdt_readarg(5, ctx, &msg.msg_size);126bpf_usdt_readarg(6, ctx, &pmsg);127bpf_probe_read_user(&msg.msg, _TRACEPOINT_TEST_MIN(msg.msg_size, MAX_MSG_DATA_LENGTH), pmsg);128outbound_messages.perf_submit(ctx, &msg, sizeof(msg));129return 0;130};132BPF_PERF_OUTPUT(inbound_connections);133int trace_inbound_connection(struct pt_regs *ctx) {134struct NewConnection inbound = {};135void *conn_type_pointer = NULL, *address_pointer = NULL;136bpf_usdt_readarg(1, ctx, &inbound.conn.id);137bpf_usdt_readarg(2, ctx, &address_pointer);138bpf_usdt_readarg(3, ctx, &conn_type_pointer);139bpf_usdt_readarg(4, ctx, &inbound.conn.network);140bpf_usdt_readarg(5, ctx, &inbound.existing);141bpf_probe_read_user_str(&inbound.conn.addr, sizeof(inbound.conn.addr), address_pointer);142bpf_probe_read_user_str(&inbound.conn.type, sizeof(inbound.conn.type), conn_type_pointer);143inbound_connections.perf_submit(ctx, &inbound, sizeof(inbound));144return 0;145};147BPF_PERF_OUTPUT(outbound_connections);148int trace_outbound_connection(struct pt_regs *ctx) {149struct NewConnection outbound = {};150void *conn_type_pointer = NULL, *address_pointer = NULL;151bpf_usdt_readarg(1, ctx, &outbound.conn.id);152bpf_usdt_readarg(2, ctx, &address_pointer);153bpf_usdt_readarg(3, ctx, &conn_type_pointer);154bpf_usdt_readarg(4, ctx, &outbound.conn.network);155bpf_usdt_readarg(5, ctx, &outbound.existing);156bpf_probe_read_user_str(&outbound.conn.addr, sizeof(outbound.conn.addr), address_pointer);157bpf_probe_read_user_str(&outbound.conn.type, sizeof(outbound.conn.type), conn_type_pointer);158outbound_connections.perf_submit(ctx, &outbound, sizeof(outbound));159return 0;160};162BPF_PERF_OUTPUT(evicted_inbound_connections);163int trace_evicted_inbound_connection(struct pt_regs *ctx) {164struct ClosedConnection evicted = {};165void *conn_type_pointer = NULL, *address_pointer = NULL;166bpf_usdt_readarg(1, ctx, &evicted.conn.id);167bpf_usdt_readarg(2, ctx, &address_pointer);168bpf_usdt_readarg(3, ctx, &conn_type_pointer);169bpf_usdt_readarg(4, ctx, &evicted.conn.network);170bpf_usdt_readarg(5, ctx, &evicted.time_established);171bpf_probe_read_user_str(&evicted.conn.addr, sizeof(evicted.conn.addr), address_pointer);172bpf_probe_read_user_str(&evicted.conn.type, sizeof(evicted.conn.type), conn_type_pointer);173evicted_inbound_connections.perf_submit(ctx, &evicted, sizeof(evicted));174return 0;175};177BPF_PERF_OUTPUT(misbehaving_connections);178int trace_misbehaving_connection(struct pt_regs *ctx) {179struct MisbehavingConnection misbehaving = {};180void *message_pointer = NULL;181bpf_usdt_readarg(1, ctx, &misbehaving.id);182bpf_usdt_readarg(2, ctx, &message_pointer);183bpf_probe_read_user_str(&misbehaving.message, sizeof(misbehaving.message), message_pointer);184misbehaving_connections.perf_submit(ctx, &misbehaving, sizeof(misbehaving));185return 0;186};188BPF_PERF_OUTPUT(closed_connections);189int trace_closed_connection(struct pt_regs *ctx) {190struct ClosedConnection closed = {};191void *conn_type_pointer = NULL, *address_pointer = NULL;192bpf_usdt_readarg(1, ctx, &closed.conn.id);193bpf_usdt_readarg(2, ctx, &address_pointer);194bpf_usdt_readarg(3, ctx, &conn_type_pointer);195bpf_usdt_readarg(4, ctx, &closed.conn.network);196bpf_usdt_readarg(5, ctx, &closed.time_established);197bpf_probe_read_user_str(&closed.conn.addr, sizeof(closed.conn.addr), address_pointer);198bpf_probe_read_user_str(&closed.conn.type, sizeof(closed.conn.type), conn_type_pointer);199closed_connections.perf_submit(ctx, &closed, sizeof(closed));200return 0;201};202"""205class Connection(ctypes.Structure):206_fields_ = [207("id", ctypes.c_uint64),208("addr", ctypes.c_char * MAX_PEER_ADDR_LENGTH),209("conn_type", ctypes.c_char * MAX_PEER_CONN_TYPE_LENGTH),210("network", ctypes.c_uint32),211]213def __repr__(self):214return f"Connection(peer={self.id}, addr={self.addr.decode('utf-8')}, conn_type={self.conn_type.decode('utf-8')}, network={self.network})"217class NewConnection(ctypes.Structure):218_fields_ = [219("conn", Connection),220("existing", ctypes.c_uint64),221]223def __repr__(self):224return f"NewConnection(conn={self.conn}, existing={self.existing})"227class ClosedConnection(ctypes.Structure):228_fields_ = [229("conn", Connection),230("time_established", ctypes.c_uint64),231]233def __repr__(self):234return f"ClosedConnection(conn={self.conn}, time_established={self.time_established})"237class MisbehavingConnection(ctypes.Structure):238_fields_ = [239("id", ctypes.c_uint64),240("message", ctypes.c_char * MAX_MISBEHAVING_MESSAGE_LENGTH),241]243def __repr__(self):244return f"MisbehavingConnection(id={self.id}, message={self.message})"247class NetTracepointTest(BitcoinTestFramework):248def set_test_params(self):249self.num_nodes = 1250self.extra_args = [[f'-maxconnections={MAX_CONNECTIONS}']]
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.