reth_network_types/session/
config.rs

1//! Configuration types for peer sessions manager.
2
3use crate::peers::config::{DEFAULT_MAX_COUNT_PEERS_INBOUND, DEFAULT_MAX_COUNT_PEERS_OUTBOUND};
4use std::time::Duration;
5
6/// Default request timeout for a single request.
7///
8/// This represents the amount of time we wait for a response until we consider it timed out.
9pub const INITIAL_REQUEST_TIMEOUT: Duration = Duration::from_secs(20);
10
11/// Default timeout after which a pending session attempt is considered failed.
12pub const PENDING_SESSION_TIMEOUT: Duration = Duration::from_secs(20);
13
14/// Default timeout after which we'll consider the peer to be in violation of the protocol.
15///
16/// This is the time a peer has to answer a response.
17pub const PROTOCOL_BREACH_REQUEST_TIMEOUT: Duration = Duration::from_secs(2 * 60);
18
19/// The default maximum number of peers.
20const DEFAULT_MAX_PEERS: usize =
21    DEFAULT_MAX_COUNT_PEERS_OUTBOUND as usize + DEFAULT_MAX_COUNT_PEERS_INBOUND as usize;
22
23/// The default session event buffer size.
24///
25/// The actual capacity of the event channel will be `buffer + num sessions`.
26/// With maxed out peers, this will allow for 3 messages per session (average)
27const DEFAULT_SESSION_EVENT_BUFFER_SIZE: usize = DEFAULT_MAX_PEERS * 2;
28
29/// Configuration options for peer session management.
30#[derive(Debug, Clone, PartialEq, Eq)]
31#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
32#[cfg_attr(feature = "serde", serde(default))]
33pub struct SessionsConfig {
34    /// Size of the session command buffer (per session task).
35    pub session_command_buffer: usize,
36    /// Size of the session event channel buffer.
37    pub session_event_buffer: usize,
38    /// Limits to enforce.
39    ///
40    /// By default, no limits will be enforced.
41    pub limits: SessionLimits,
42    /// The maximum initial time we wait for a response from the peer before we timeout a request
43    /// _internally_.
44    pub initial_internal_request_timeout: Duration,
45    /// The amount of time we continue to wait for a response from the peer, even if we timed it
46    /// out internally (`initial_internal_request_timeout`). Timeouts are not penalized but the
47    /// session directly, however if a peer fails to respond at all (within
48    /// `PROTOCOL_BREACH_REQUEST_TIMEOUT`) this is considered a protocol violation and results in a
49    /// dropped session.
50    pub protocol_breach_request_timeout: Duration,
51    /// The timeout after which a pending session attempt is considered failed.
52    pub pending_session_timeout: Duration,
53}
54
55impl Default for SessionsConfig {
56    fn default() -> Self {
57        Self {
58            // This should be sufficient to slots for handling commands sent to the session task,
59            // since the manager is the sender.
60            session_command_buffer: 32,
61            // This should be greater since the manager is the receiver. The total size will be
62            // `buffer + num sessions`. Each session can therefore fit at least 1 message in the
63            // channel. The buffer size is additional capacity. The channel is always drained on
64            // `poll`.
65            // The default is twice the maximum number of available slots, if all slots are occupied
66            // the buffer will have capacity for 3 messages per session (average).
67            session_event_buffer: DEFAULT_SESSION_EVENT_BUFFER_SIZE,
68            limits: Default::default(),
69            initial_internal_request_timeout: INITIAL_REQUEST_TIMEOUT,
70            protocol_breach_request_timeout: PROTOCOL_BREACH_REQUEST_TIMEOUT,
71            pending_session_timeout: PENDING_SESSION_TIMEOUT,
72        }
73    }
74}
75
76impl SessionsConfig {
77    /// Sets the buffer size for the bounded communication channel between the manager and its
78    /// sessions for events emitted by the sessions.
79    ///
80    /// It is expected, that the background session task will stall if they outpace the manager. The
81    /// buffer size provides backpressure on the network I/O.
82    pub const fn with_session_event_buffer(mut self, n: usize) -> Self {
83        self.session_event_buffer = n;
84        self
85    }
86
87    /// Helper function to set the buffer size for the bounded communication channel between the
88    /// manager and its sessions for events emitted by the sessions.
89    ///
90    /// This scales the buffer size based on the configured number of peers, where the base line is
91    /// the default buffer size.
92    ///
93    /// If the number of peers is greater than the default, the buffer size will be scaled up to
94    /// match the default `buffer size / max peers` ratio.
95    ///
96    /// Note: This is capped at 10 times the default buffer size.
97    pub fn with_upscaled_event_buffer(mut self, num_peers: usize) -> Self {
98        if num_peers > DEFAULT_MAX_PEERS {
99            self.session_event_buffer = (num_peers * 2).min(DEFAULT_SESSION_EVENT_BUFFER_SIZE * 10);
100        }
101        self
102    }
103}
104
105/// Limits for sessions.
106///
107/// By default, no session limits will be enforced
108#[derive(Debug, Clone, Default, PartialEq, Eq)]
109#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
110pub struct SessionLimits {
111    /// Maximum allowed inbound connections.
112    pub max_pending_inbound: Option<u32>,
113    /// Maximum allowed outbound connections.
114    pub max_pending_outbound: Option<u32>,
115    /// Maximum allowed established inbound connections.
116    pub max_established_inbound: Option<u32>,
117    /// Maximum allowed established outbound connections.
118    pub max_established_outbound: Option<u32>,
119}
120
121impl SessionLimits {
122    /// Sets the maximum number of pending incoming sessions.
123    pub const fn with_max_pending_inbound(mut self, limit: u32) -> Self {
124        self.max_pending_inbound = Some(limit);
125        self
126    }
127
128    /// Sets the maximum number of pending outbound sessions.
129    pub const fn with_max_pending_outbound(mut self, limit: u32) -> Self {
130        self.max_pending_outbound = Some(limit);
131        self
132    }
133
134    /// Sets the maximum number of active inbound sessions.
135    pub const fn with_max_established_inbound(mut self, limit: u32) -> Self {
136        self.max_established_inbound = Some(limit);
137        self
138    }
139
140    /// Sets the maximum number of active outbound sessions.
141    pub const fn with_max_established_outbound(mut self, limit: u32) -> Self {
142        self.max_established_outbound = Some(limit);
143        self
144    }
145}
146
147#[cfg(test)]
148mod tests {
149    use super::*;
150
151    #[test]
152    fn scale_session_event_buffer() {
153        let config = SessionsConfig::default().with_upscaled_event_buffer(10);
154        assert_eq!(config.session_event_buffer, DEFAULT_SESSION_EVENT_BUFFER_SIZE);
155        let default_ration = config.session_event_buffer / DEFAULT_MAX_PEERS;
156
157        let config = SessionsConfig::default().with_upscaled_event_buffer(DEFAULT_MAX_PEERS * 2);
158        let expected_ration = config.session_event_buffer / (DEFAULT_MAX_PEERS * 2);
159        assert_eq!(default_ration, expected_ration);
160    }
161}