hotshot_libp2p_networking/network/node/
config.rs

1// Copyright (c) 2021-2024 Espresso Systems (espressosys.com)
2// This file is part of the HotShot repository.
3
4// You should have received a copy of the MIT License
5// along with the HotShot repository. If not, see <https://mit-license.org/>.
6
7use std::{collections::HashSet, num::NonZeroUsize, time::Duration};
8
9use libp2p::{identity::Keypair, Multiaddr};
10use libp2p_identity::PeerId;
11
12use super::MAX_GOSSIP_MSG_SIZE;
13
14/// The default Kademlia replication factor
15pub const DEFAULT_REPLICATION_FACTOR: Option<NonZeroUsize> = NonZeroUsize::new(20);
16
17/// describe the configuration of the network
18#[derive(Default, derive_builder::Builder, derive_more::Debug)]
19pub struct NetworkNodeConfig {
20    /// The keypair for the node
21    #[builder(setter(into, strip_option), default)]
22    #[debug(skip)]
23    pub keypair: Option<Keypair>,
24
25    /// The address to bind to
26    #[builder(default)]
27    pub bind_address: Option<Multiaddr>,
28
29    /// Replication factor for entries in the DHT
30    #[builder(setter(into, strip_option), default = "DEFAULT_REPLICATION_FACTOR")]
31    pub replication_factor: Option<NonZeroUsize>,
32
33    #[builder(default)]
34    /// Configuration for `GossipSub`
35    pub gossip_config: GossipConfig,
36
37    #[builder(default)]
38    /// Configuration for `RequestResponse`
39    pub request_response_config: RequestResponseConfig,
40
41    /// list of addresses to connect to at initialization
42    pub to_connect_addrs: HashSet<(PeerId, Multiaddr)>,
43
44    /// republication interval in DHT, must be much less than `ttl`
45    #[builder(default)]
46    pub republication_interval: Option<Duration>,
47
48    /// expiratiry for records in DHT
49    #[builder(default)]
50    pub ttl: Option<Duration>,
51
52    /// The path to the file to save the DHT to
53    #[builder(default)]
54    pub dht_file_path: Option<String>,
55
56    /// The signed authentication message sent to the remote peer
57    /// If not supplied we will not send an authentication message during the handshake
58    #[builder(default)]
59    pub auth_message: Option<Vec<u8>>,
60
61    #[builder(default)]
62    /// The timeout for DHT lookups.
63    pub dht_timeout: Option<Duration>,
64}
65
66impl Clone for NetworkNodeConfig {
67    fn clone(&self) -> Self {
68        Self {
69            keypair: self.keypair.clone(),
70            bind_address: self.bind_address.clone(),
71            replication_factor: self.replication_factor,
72            gossip_config: self.gossip_config.clone(),
73            request_response_config: self.request_response_config.clone(),
74            to_connect_addrs: self.to_connect_addrs.clone(),
75            republication_interval: self.republication_interval,
76            ttl: self.ttl,
77            dht_file_path: self.dht_file_path.clone(),
78            auth_message: self.auth_message.clone(),
79            dht_timeout: self.dht_timeout,
80        }
81    }
82}
83
84/// Configuration for Libp2p's Gossipsub
85#[derive(Clone, Debug)]
86#[allow(missing_docs)]
87pub struct GossipConfig {
88    /// The heartbeat interval
89    pub heartbeat_interval: Duration,
90
91    /// The number of past heartbeats to gossip about
92    pub history_gossip: usize,
93    /// The number of past heartbeats to remember the full messages for
94    pub history_length: usize,
95
96    /// The target number of peers in the mesh
97    pub mesh_n: usize,
98    /// The maximum number of peers in the mesh
99    pub mesh_n_high: usize,
100    /// The minimum number of peers in the mesh
101    pub mesh_n_low: usize,
102    /// The minimum number of mesh peers that must be outbound
103    pub mesh_outbound_min: usize,
104
105    /// The maximum gossip message size
106    pub max_transmit_size: usize,
107
108    /// The maximum number of messages in an IHAVE message
109    pub max_ihave_length: usize,
110
111    /// Maximum number of IHAVE messages to accept from a peer within a heartbeat
112    pub max_ihave_messages: usize,
113
114    /// Cache duration for published message IDs
115    pub published_message_ids_cache_time: Duration,
116
117    /// Time to wait for a message requested through IWANT following an IHAVE advertisement
118    pub iwant_followup_time: Duration,
119
120    /// The maximum number of messages we will process in a given RPC
121    pub max_messages_per_rpc: Option<usize>,
122
123    /// Controls how many times we will allow a peer to request the same message id through IWANT gossip before we start ignoring them.
124    pub gossip_retransmission: u32,
125
126    /// If enabled newly created messages will always be sent to all peers that are subscribed to the topic and have a good enough score.
127    pub flood_publish: bool,
128
129    /// The time period that messages are stored in the cache
130    pub duplicate_cache_time: Duration,
131
132    /// Time to live for fanout peers
133    pub fanout_ttl: Duration,
134
135    /// Initial delay in each heartbeat
136    pub heartbeat_initial_delay: Duration,
137
138    /// Affects how many peers we will emit gossip to at each heartbeat
139    pub gossip_factor: f64,
140
141    /// Minimum number of peers to emit gossip to during a heartbeat
142    pub gossip_lazy: usize,
143}
144
145impl Default for GossipConfig {
146    fn default() -> Self {
147        Self {
148            heartbeat_interval: Duration::from_secs(1), // Default of Libp2p
149
150            // The following are slightly modified defaults of Libp2p
151            history_gossip: 6, // The number of past heartbeats to gossip about
152            history_length: 8, // The number of past heartbeats to remember the full messages for
153
154            // The mesh parameters are borrowed from Ethereum:
155            // https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#the-gossip-domain-gossipsub
156            mesh_n: 8,            // The target number of peers in the mesh
157            mesh_n_high: 12,      // The maximum number of peers in the mesh
158            mesh_n_low: 6,        // The minimum number of peers in the mesh
159            mesh_outbound_min: 2, // The minimum number of mesh peers that must be outbound
160
161            max_ihave_length: 5000,
162            max_ihave_messages: 10,
163            published_message_ids_cache_time: Duration::from_secs(60 * 20), // 20 minutes
164            iwant_followup_time: Duration::from_secs(3),
165            max_messages_per_rpc: None,
166            gossip_retransmission: 3,
167            flood_publish: true,
168            duplicate_cache_time: Duration::from_secs(60),
169            fanout_ttl: Duration::from_secs(60),
170            heartbeat_initial_delay: Duration::from_secs(5),
171            gossip_factor: 0.25,
172            gossip_lazy: 6,
173
174            max_transmit_size: MAX_GOSSIP_MSG_SIZE, // The maximum gossip message size
175        }
176    }
177}
178
179/// Configuration for Libp2p's request-response
180#[derive(Clone, Debug)]
181pub struct RequestResponseConfig {
182    /// The maximum request size in bytes
183    pub request_size_maximum: u64,
184    /// The maximum response size in bytes
185    pub response_size_maximum: u64,
186}
187
188impl Default for RequestResponseConfig {
189    fn default() -> Self {
190        Self {
191            request_size_maximum: 20 * 1024 * 1024,
192            response_size_maximum: 20 * 1024 * 1024,
193        }
194    }
195}