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}