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.
252def skip_test_if_missing_module(self):253self.skip_if_platform_not_linux()254self.skip_if_no_bitcoind_tracepoints()255self.skip_if_no_python_bcc()256self.skip_if_no_bpf_permissions()257self.skip_if_running_under_valgrind()259def run_test(self):260self.p2p_message_tracepoint_test()261self.inbound_conn_tracepoint_test()262self.outbound_conn_tracepoint_test()263self.evicted_inbound_conn_tracepoint_test()264self.misbehaving_conn_tracepoint_test()265self.closed_conn_tracepoint_test()267def p2p_message_tracepoint_test(self):268# Tests the net:inbound_message and net:outbound_message tracepoints269# See https://github.com/bitcoin/bitcoin/blob/master/doc/tracing.md#context-net271class P2PMessage(ctypes.Structure):272_fields_ = [273("peer_id", ctypes.c_uint64),274("peer_addr", ctypes.c_char * MAX_PEER_ADDR_LENGTH),275("peer_conn_type", ctypes.c_char * MAX_PEER_CONN_TYPE_LENGTH),276("msg_type", ctypes.c_char * MAX_MSG_TYPE_LENGTH),277("msg_size", ctypes.c_uint64),278("msg", ctypes.c_ubyte * MAX_MSG_DATA_LENGTH),279]281def __repr__(self):282return f"P2PMessage(peer={self.peer_id}, addr={self.peer_addr.decode('utf-8')}, conn_type={self.peer_conn_type.decode('utf-8')}, msg_type={self.msg_type.decode('utf-8')}, msg_size={self.msg_size})"284self.log.info(285"hook into the net:inbound_message and net:outbound_message tracepoints")286ctx = USDT(pid=self.nodes[0].process.pid)287ctx.enable_probe(probe="net:inbound_message",288fn_name="trace_inbound_message")289ctx.enable_probe(probe="net:outbound_message",290fn_name="trace_outbound_message")291bpf = BPF(text=net_tracepoints_program, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags())293EXPECTED_INOUTBOUND_VERSION_MSG = 1294checked_inbound_version_msg = 0295checked_outbound_version_msg = 0296events = []298def check_p2p_message(event, is_inbound):299nonlocal checked_inbound_version_msg, checked_outbound_version_msg300if event.msg_type.decode("utf-8") == "version":301self.log.info(302f"check_p2p_message(): {'inbound' if is_inbound else 'outbound'} {event}")303peer = self.nodes[0].getpeerinfo()[0]304msg = msg_version()305msg.deserialize(BytesIO(bytes(event.msg[:event.msg_size])))306assert_equal(peer["id"], event.peer_id, peer["id"])307assert_equal(peer["addr"], event.peer_addr.decode("utf-8"))308assert_equal(peer["connection_type"],309event.peer_conn_type.decode("utf-8"))310if is_inbound:311checked_inbound_version_msg += 1312else:313checked_outbound_version_msg += 1315def handle_inbound(_, data, __):316event = ctypes.cast(data, ctypes.POINTER(P2PMessage)).contents317events.append((event, True))319def handle_outbound(_, data, __):320event = ctypes.cast(data, ctypes.POINTER(P2PMessage)).contents321events.append((event, False))323bpf["inbound_messages"].open_perf_buffer(handle_inbound)324bpf["outbound_messages"].open_perf_buffer(handle_outbound)326self.log.info("connect a P2P test node to our bitcoind node")327test_node = P2PInterface()328self.nodes[0].add_p2p_connection(test_node)329bpf.perf_buffer_poll(timeout=200)331self.log.info(332"check receipt and content of in- and outbound version messages")333for event, is_inbound in events:334check_p2p_message(event, is_inbound)335assert_equal(EXPECTED_INOUTBOUND_VERSION_MSG,336checked_inbound_version_msg)337assert_equal(EXPECTED_INOUTBOUND_VERSION_MSG,338checked_outbound_version_msg)341bpf.cleanup()342test_node.peer_disconnect()344def inbound_conn_tracepoint_test(self):345self.log.info("hook into the net:inbound_connection tracepoint")346ctx = USDT(pid=self.nodes[0].process.pid)347ctx.enable_probe(probe="net:inbound_connection",348fn_name="trace_inbound_connection")349bpf = BPF(text=net_tracepoints_program, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags())351inbound_connections = []352EXPECTED_INBOUND_CONNECTIONS = 2354def handle_inbound_connection(_, data, __):355nonlocal inbound_connections356event = ctypes.cast(data, ctypes.POINTER(NewConnection)).contents357self.log.info(f"handle_inbound_connection(): {event}")358inbound_connections.append(event)360bpf["inbound_connections"].open_perf_buffer(handle_inbound_connection)362self.log.info("connect two P2P test nodes to our bitcoind node")363testnodes = list()364for _ in range(EXPECTED_INBOUND_CONNECTIONS):365testnode = P2PInterface()366self.nodes[0].add_p2p_connection(testnode)367testnodes.append(testnode)368bpf.perf_buffer_poll(timeout=200)370assert_equal(EXPECTED_INBOUND_CONNECTIONS, len(inbound_connections))371for inbound_connection in inbound_connections:372assert_greater_than(inbound_connection.conn.id, 0)373assert_greater_than(inbound_connection.existing, 0)374assert_equal(b'inbound', inbound_connection.conn.conn_type)375assert_equal(NETWORK_TYPE_UNROUTABLE, inbound_connection.conn.network)377bpf.cleanup()378for node in testnodes:379node.peer_disconnect()381def outbound_conn_tracepoint_test(self):382self.log.info("hook into the net:outbound_connection tracepoint")383ctx = USDT(pid=self.nodes[0].process.pid)384ctx.enable_probe(probe="net:outbound_connection",385fn_name="trace_outbound_connection")386bpf = BPF(text=net_tracepoints_program, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags())388# that the handle_* function succeeds.389EXPECTED_OUTBOUND_CONNECTIONS = 2390EXPECTED_CONNECTION_TYPE = "feeler"391outbound_connections = []393def handle_outbound_connection(_, data, __):394event = ctypes.cast(data, ctypes.POINTER(NewConnection)).contents395self.log.info(f"handle_outbound_connection(): {event}")396outbound_connections.append(event)398bpf["outbound_connections"].open_perf_buffer(399handle_outbound_connection)401self.log.info(402f"connect {EXPECTED_OUTBOUND_CONNECTIONS} P2P test nodes to our bitcoind node")403testnodes = list()404for p2p_idx in range(EXPECTED_OUTBOUND_CONNECTIONS):405testnode = P2PInterface()406self.nodes[0].add_outbound_p2p_connection(407testnode, p2p_idx=p2p_idx, connection_type=EXPECTED_CONNECTION_TYPE)408testnodes.append(testnode)409bpf.perf_buffer_poll(timeout=200)411assert_equal(EXPECTED_OUTBOUND_CONNECTIONS, len(outbound_connections))412for outbound_connection in outbound_connections:413assert_greater_than(outbound_connection.conn.id, 0)414assert_greater_than(outbound_connection.existing, 0)415assert_equal(EXPECTED_CONNECTION_TYPE, outbound_connection.conn.conn_type.decode('utf-8'))416assert_equal(NETWORK_TYPE_UNROUTABLE, outbound_connection.conn.network)418bpf.cleanup()419for node in testnodes:420node.peer_disconnect()422def evicted_inbound_conn_tracepoint_test(self):423self.log.info("hook into the net:evicted_inbound_connection tracepoint")424ctx = USDT(pid=self.nodes[0].process.pid)425ctx.enable_probe(probe="net:evicted_inbound_connection",426fn_name="trace_evicted_inbound_connection")427bpf = BPF(text=net_tracepoints_program, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags())429EXPECTED_EVICTED_CONNECTIONS = 2430evicted_connections = []432def handle_evicted_inbound_connection(_, data, __):433event = ctypes.cast(data, ctypes.POINTER(ClosedConnection)).contents434self.log.info(f"handle_evicted_inbound_connection(): {event}")435evicted_connections.append(event)437bpf["evicted_inbound_connections"].open_perf_buffer(handle_evicted_inbound_connection)439self.log.info(440f"connect {MAX_INBOUND_CONNECTIONS + EXPECTED_EVICTED_CONNECTIONS} P2P test nodes to our bitcoind node and expect {EXPECTED_EVICTED_CONNECTIONS} evictions")441testnodes = list()442for p2p_idx in range(MAX_INBOUND_CONNECTIONS + EXPECTED_EVICTED_CONNECTIONS):443testnode = P2PInterface()444self.nodes[0].add_p2p_connection(testnode)445testnodes.append(testnode)446bpf.perf_buffer_poll(timeout=200)448assert_equal(EXPECTED_EVICTED_CONNECTIONS, len(evicted_connections))449for evicted_connection in evicted_connections:450assert_greater_than(evicted_connection.conn.id, 0)451assert_greater_than(evicted_connection.time_established, 0)452assert_equal("inbound", evicted_connection.conn.conn_type.decode('utf-8'))453assert_equal(NETWORK_TYPE_UNROUTABLE, evicted_connection.conn.network)455bpf.cleanup()456for node in testnodes:457node.peer_disconnect()459def misbehaving_conn_tracepoint_test(self):460self.log.info("hook into the net:misbehaving_connection tracepoint")461ctx = USDT(pid=self.nodes[0].process.pid)462ctx.enable_probe(probe="net:misbehaving_connection",463fn_name="trace_misbehaving_connection")464bpf = BPF(text=net_tracepoints_program, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags())466EXPECTED_MISBEHAVING_CONNECTIONS = 2467misbehaving_connections = []469def handle_misbehaving_connection(_, data, __):470event = ctypes.cast(data, ctypes.POINTER(MisbehavingConnection)).contents471self.log.info(f"handle_misbehaving_connection(): {event}")472misbehaving_connections.append(event)474bpf["misbehaving_connections"].open_perf_buffer(handle_misbehaving_connection)476self.log.info("connect a misbehaving P2P test nodes to our bitcoind node")477msg = msg_headers([CBlockHeader()] * (MAX_HEADERS_RESULTS + 1))478for _ in range(EXPECTED_MISBEHAVING_CONNECTIONS):479testnode = P2PInterface()480self.nodes[0].add_p2p_connection(testnode)481testnode.send_without_ping(msg)482bpf.perf_buffer_poll(timeout=500)483testnode.peer_disconnect()485assert_equal(EXPECTED_MISBEHAVING_CONNECTIONS, len(misbehaving_connections))486for misbehaving_connection in misbehaving_connections:487assert_greater_than(misbehaving_connection.id, 0)488assert_greater_than(len(misbehaving_connection.message), 0)489assert_equal(misbehaving_connection.message, b"headers message size = 2001")491bpf.cleanup()493def closed_conn_tracepoint_test(self):494self.log.info("hook into the net:closed_connection tracepoint")495ctx = USDT(pid=self.nodes[0].process.pid)496ctx.enable_probe(probe="net:closed_connection",497fn_name="trace_closed_connection")498bpf = BPF(text=net_tracepoints_program, usdt_contexts=[ctx], debug=0, cflags=bpf_cflags())500EXPECTED_CLOSED_CONNECTIONS = 2
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.