reth_network/transactions/
config.rs

1use std::str::FromStr;
2
3use super::{
4    PeerMetadata, DEFAULT_MAX_COUNT_TRANSACTIONS_SEEN_BY_PEER,
5    DEFAULT_SOFT_LIMIT_BYTE_SIZE_POOLED_TRANSACTIONS_RESP_ON_PACK_GET_POOLED_TRANSACTIONS_REQ,
6    SOFT_LIMIT_BYTE_SIZE_POOLED_TRANSACTIONS_RESPONSE,
7};
8use crate::transactions::constants::tx_fetcher::{
9    DEFAULT_MAX_CAPACITY_CACHE_PENDING_FETCH, DEFAULT_MAX_COUNT_CONCURRENT_REQUESTS,
10    DEFAULT_MAX_COUNT_CONCURRENT_REQUESTS_PER_PEER,
11};
12use derive_more::{Constructor, Display};
13use reth_eth_wire::NetworkPrimitives;
14
15/// Configuration for managing transactions within the network.
16#[derive(Debug, Clone)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18pub struct TransactionsManagerConfig {
19    /// Configuration for fetching transactions.
20    pub transaction_fetcher_config: TransactionFetcherConfig,
21    /// Max number of seen transactions to store for each peer.
22    pub max_transactions_seen_by_peer_history: u32,
23    /// How new pending transactions are propagated.
24    #[cfg_attr(feature = "serde", serde(default))]
25    pub propagation_mode: TransactionPropagationMode,
26}
27
28impl Default for TransactionsManagerConfig {
29    fn default() -> Self {
30        Self {
31            transaction_fetcher_config: TransactionFetcherConfig::default(),
32            max_transactions_seen_by_peer_history: DEFAULT_MAX_COUNT_TRANSACTIONS_SEEN_BY_PEER,
33            propagation_mode: TransactionPropagationMode::default(),
34        }
35    }
36}
37
38/// Determines how new pending transactions are propagated to other peers in full.
39#[derive(Debug, Clone, Default)]
40#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
41pub enum TransactionPropagationMode {
42    /// Send full transactions to sqrt of current peers.
43    #[default]
44    Sqrt,
45    /// Always send transactions in full.
46    All,
47    /// Send full transactions to a maximum number of peers
48    Max(usize),
49}
50
51impl TransactionPropagationMode {
52    /// Returns the number of peers full transactions should be propagated to.
53    pub(crate) fn full_peer_count(&self, peer_count: usize) -> usize {
54        match self {
55            Self::Sqrt => (peer_count as f64).sqrt().round() as usize,
56            Self::All => peer_count,
57            Self::Max(max) => peer_count.min(*max),
58        }
59    }
60}
61
62/// Configuration for fetching transactions.
63#[derive(Debug, Constructor, Clone)]
64#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
65pub struct TransactionFetcherConfig {
66    /// Max inflight [`GetPooledTransactions`](reth_eth_wire::GetPooledTransactions) requests.
67    pub max_inflight_requests: u32,
68    /// Max inflight [`GetPooledTransactions`](reth_eth_wire::GetPooledTransactions) requests per
69    /// peer.
70    pub max_inflight_requests_per_peer: u8,
71    /// Soft limit for the byte size of a
72    /// [`PooledTransactions`](reth_eth_wire::PooledTransactions) response on assembling a
73    /// [`GetPooledTransactions`](reth_eth_wire::GetPooledTransactions) request. Spec'd at 2
74    /// MiB.
75    pub soft_limit_byte_size_pooled_transactions_response: usize,
76    /// Soft limit for the byte size of the expected
77    /// [`PooledTransactions`](reth_eth_wire::PooledTransactions) response on packing a
78    /// [`GetPooledTransactions`](reth_eth_wire::GetPooledTransactions) request with hashes.
79    pub soft_limit_byte_size_pooled_transactions_response_on_pack_request: usize,
80    /// Max capacity of the cache of transaction hashes, for transactions that weren't yet fetched.
81    /// A transaction is pending fetch if its hash didn't fit into a
82    /// [`GetPooledTransactions`](reth_eth_wire::GetPooledTransactions) yet, or it wasn't returned
83    /// upon request to peers.
84    pub max_capacity_cache_txns_pending_fetch: u32,
85}
86
87impl Default for TransactionFetcherConfig {
88    fn default() -> Self {
89        Self {
90            max_inflight_requests: DEFAULT_MAX_COUNT_CONCURRENT_REQUESTS,
91            max_inflight_requests_per_peer: DEFAULT_MAX_COUNT_CONCURRENT_REQUESTS_PER_PEER,
92            soft_limit_byte_size_pooled_transactions_response:
93                SOFT_LIMIT_BYTE_SIZE_POOLED_TRANSACTIONS_RESPONSE,
94            soft_limit_byte_size_pooled_transactions_response_on_pack_request:
95                DEFAULT_SOFT_LIMIT_BYTE_SIZE_POOLED_TRANSACTIONS_RESP_ON_PACK_GET_POOLED_TRANSACTIONS_REQ,
96                max_capacity_cache_txns_pending_fetch: DEFAULT_MAX_CAPACITY_CACHE_PENDING_FETCH,
97        }
98    }
99}
100
101/// A policy defining which peers pending transactions are gossiped to.
102pub trait TransactionPropagationPolicy: Send + Sync + Unpin + 'static {
103    /// Filter a given peer based on the policy.
104    ///
105    /// This determines whether transactions can be propagated to this peer.
106    fn can_propagate<N: NetworkPrimitives>(&self, peer: &mut PeerMetadata<N>) -> bool;
107
108    /// A callback on the policy when a new peer session is established.
109    fn on_session_established<N: NetworkPrimitives>(&mut self, peer: &mut PeerMetadata<N>);
110
111    /// A callback on the policy when a peer session is closed.
112    fn on_session_closed<N: NetworkPrimitives>(&mut self, peer: &mut PeerMetadata<N>);
113}
114
115/// Determines which peers pending transactions are propagated to.
116#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Display)]
117#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
118pub enum TransactionPropagationKind {
119    /// Propagate transactions to all peers.
120    ///
121    /// No restructions
122    #[default]
123    All,
124    /// Propagate transactions to only trusted peers.
125    Trusted,
126}
127
128impl TransactionPropagationPolicy for TransactionPropagationKind {
129    fn can_propagate<N: NetworkPrimitives>(&self, peer: &mut PeerMetadata<N>) -> bool {
130        match self {
131            Self::All => true,
132            Self::Trusted => peer.peer_kind.is_trusted(),
133        }
134    }
135
136    fn on_session_established<N: NetworkPrimitives>(&mut self, _peer: &mut PeerMetadata<N>) {}
137
138    fn on_session_closed<N: NetworkPrimitives>(&mut self, _peer: &mut PeerMetadata<N>) {}
139}
140
141impl FromStr for TransactionPropagationKind {
142    type Err = String;
143
144    fn from_str(s: &str) -> Result<Self, Self::Err> {
145        match s {
146            "All" | "all" => Ok(Self::All),
147            "Trusted" | "trusted" => Ok(Self::Trusted),
148            _ => Err(format!("Invalid transaction propagation policy: {s}")),
149        }
150    }
151}