#34824 net: encapsulate TxRelay state and replace recursive mutexes

full analysis

https://github.com/bitcoin/bitcoin/pull/34824 · w0xlt · +803/-192 in 7 files, 6 commits · labels: P2P

Goal

  • Make transaction relay concurrency safer by encapsulating internal peer state and removing recursive locks
  • Enables compile-time lock analysis and reduces deadlock risks during peer message processing

This PR extracts per-peer transaction relay state from `net_processing.cpp` into a dedicated `node::TxRelay` type, making all member state private. Callers in `SendMessages()` now operate on a move-only `TxInventoryBatch` snapshot instead of locking and mutating `TxRelay` internals directly. With lock boundaries strictly encapsulated, both `RecursiveMutex` members are replaced with plain `Mutex` and annotated with Clang thread-safety annotations, accompanied by new unit and fuzz tests.

Problem: Previously, `Peer::TxRelay` exposed its fields and `RecursiveMutex` instances publicly in `net_processing.cpp`, making lock ordering fragile and preventing safe replacement of recursive mutexes without risking deadlocks or subtle concurrency regressions.

Category: P2P (#16 of 65)

P3 · cleanup

  • P3 because this is an internal refactoring that improves concurrency safety without changing wire behavior
  • Helps unblock broader efforts to eliminate recursive mutexes across networking code

P3 because this is an internal refactoring and encapsulation effort that cleans up net_processing and helps resolve #19303. It does not alter wire behavior or fix an active bug, but improves thread safety by eliminating recursive mutexes and enforcing compile-time lock annotations.

Membership: Directly touches net_processing and manages p2p transaction inventory and bloom filter relay state.

Factors: security/stability 1, bug 0, performance 0, user value 0, leverage 1

Reviewability: Ready

  • Ready for review: cleanly rebased, passes CI, and incorporates previous reviewer feedback

The code is cleanly rebased, passes CI, and incorporates previous review feedback regarding mutex encapsulation.

Author status: Active; addressed all structural feedback with substantial reworks and recently rebased.

Resolved concerns:

  • sedited noted that changing mutex types without encapsulation was brittle
  • maflcko warned that exposing mutex getters or using callable callbacks under lock undermined Clang thread safety analysis, prompting the author to hide mutexes completely and introduce TxInventoryBatch

Agreement: Strong

  • Strong support for modularizing peer relay state and eliminating recursive mutexes
  • Concept approval without stated reasons (theuni, hebasto)
  • Support for the encapsulation approach (sedited)
  • Confirmed earlier concerns about thread-safety analysis leaks are addressed (pablomartin4btc)

Strong: reviewers endorsed the modularization and pablomartin4btc re-ACKed after maflcko's concerns were resolved.

Reviewers sedited and pablomartin4btc supported the encapsulation approach with detailed rationales, and maflcko's objections regarding thread-safety analysis leaks were directly addressed by reworking the PR to eliminate public mutex accessors and callbacks.

  • theuni and hebasto Concept ACKed the direction
  • sedited ACKed commit 67527c709
  • maflcko pointed out that exposing mutex getters negated thread-safety guarantees
  • w0xlt reworked the patch to remove mutex getters and use TxInventoryBatch
  • pablomartin4btc re-ACKed commit e8dbc6e confirming maflcko's concerns were addressed

Review verdicts (DrahtBot): 0 (+2)

Dependencies

Enables:

Files

407 lines under test/bench/ci.

  • src/test/txrelay_tests.cpp +310/-0
  • src/net_processing.cpp +114/-190
  • src/node/txrelay.h +280/-0
  • src/test/fuzz/txrelay.cpp +95/-0
  • src/net_processing.h +2/-2
  • src/test/CMakeLists.txt +1/-0
  • src/test/fuzz/CMakeLists.txt +1/-0

Card

This PR encapsulates per-peer transaction relay state into a dedicated node::TxRelay class and converts its RecursiveMutex members to plain Mutexes. It replaces direct internal field manipulation in net_processing with private state transitions and an inventory batch snapshotting mechanism. The change addresses issue #19303 by removing recursive locking while introducing Clang thread safety annotations, unit tests, and a fuzz harness. Reviewers strongly support the architecture, with earlier thread-safety concerns raised by maflcko addressed in subsequent revisions.

Data

dossier JSON · extract JSON · model openrouter/google/gemini-3.8-flash, generated 2026-09-17T16:18, confidence high, input hash 8d3bb9b6b63bcede