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}