cuprated/config/
p2p.rs

1use std::{
2    net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
3    path::Path,
4    time::Duration,
5};
6
7use serde::{Deserialize, Serialize};
8
9use cuprate_helper::{fs::address_book_path, network::Network};
10
11/// P2P config.
12#[derive(Debug, Default, Deserialize, Serialize, PartialEq)]
13#[serde(deny_unknown_fields, default)]
14pub struct P2PConfig {
15    /// Clear-net config.
16    pub clear_net: ClearNetConfig,
17    /// Block downloader config.
18    pub block_downloader: BlockDownloaderConfig,
19}
20
21#[derive(Debug, Clone, Deserialize, Serialize, Eq, PartialEq)]
22#[serde(deny_unknown_fields, default)]
23pub struct BlockDownloaderConfig {
24    /// The size in bytes of the buffer between the block downloader and the place which
25    /// is consuming the downloaded blocks.
26    pub buffer_bytes: usize,
27    /// The size of the in progress queue (in bytes) at which we stop requesting more blocks.
28    pub in_progress_queue_bytes: usize,
29    /// The [`Duration`] between checking the client pool for free peers.
30    pub check_client_pool_interval: Duration,
31    /// The target size of a single batch of blocks (in bytes).
32    pub target_batch_bytes: usize,
33}
34
35impl From<BlockDownloaderConfig> for cuprate_p2p::block_downloader::BlockDownloaderConfig {
36    fn from(value: BlockDownloaderConfig) -> Self {
37        Self {
38            buffer_bytes: value.buffer_bytes,
39            in_progress_queue_bytes: value.in_progress_queue_bytes,
40            check_client_pool_interval: value.check_client_pool_interval,
41            target_batch_bytes: value.target_batch_bytes,
42            initial_batch_len: 1,
43        }
44    }
45}
46
47impl Default for BlockDownloaderConfig {
48    fn default() -> Self {
49        Self {
50            buffer_bytes: 1_000_000_000,
51            in_progress_queue_bytes: 500_000_000,
52            check_client_pool_interval: Duration::from_secs(30),
53            target_batch_bytes: 10_000_000,
54        }
55    }
56}
57
58/// The config values for P2P clear-net.
59#[derive(Debug, Deserialize, Serialize, PartialEq)]
60#[serde(deny_unknown_fields, default)]
61pub struct ClearNetConfig {
62    /// The server config.
63    pub listen_on: IpAddr,
64    #[serde(flatten)]
65    pub general: SharedNetConfig,
66}
67
68impl Default for ClearNetConfig {
69    fn default() -> Self {
70        Self {
71            listen_on: IpAddr::V4(Ipv4Addr::UNSPECIFIED),
72            general: Default::default(),
73        }
74    }
75}
76
77/// Network config values shared between all network zones.
78#[derive(Debug, Deserialize, Serialize, PartialEq)]
79#[serde(deny_unknown_fields, default)]
80pub struct SharedNetConfig {
81    /// The number of outbound connections to make and try keep.
82    pub outbound_connections: usize,
83    /// The amount of extra connections we can make if we are under load from the rest of Cuprate.
84    pub extra_outbound_connections: usize,
85    /// The maximum amount of inbound connections
86    pub max_inbound_connections: usize,
87    /// The percent of connections that should be to peers we haven't connected to before.
88    pub gray_peers_percent: f64,
89    /// port to use to accept p2p connections.
90    pub p2p_port: u16,
91    /// The address book config.
92    address_book_config: AddressBookConfig,
93}
94
95impl SharedNetConfig {
96    /// Returns the [`AddressBookConfig`].
97    pub fn address_book_config(
98        &self,
99        cache_dir: &Path,
100        network: Network,
101    ) -> cuprate_address_book::AddressBookConfig {
102        cuprate_address_book::AddressBookConfig {
103            max_white_list_length: self.address_book_config.max_white_list_length,
104            max_gray_list_length: self.address_book_config.max_gray_list_length,
105            peer_store_directory: address_book_path(cache_dir, network),
106            peer_save_period: self.address_book_config.peer_save_period,
107        }
108    }
109}
110
111impl Default for SharedNetConfig {
112    fn default() -> Self {
113        Self {
114            outbound_connections: 64,
115            extra_outbound_connections: 8,
116            max_inbound_connections: 128,
117            gray_peers_percent: 0.7,
118            p2p_port: 0,
119            address_book_config: AddressBookConfig::default(),
120        }
121    }
122}
123
124#[derive(Debug, Deserialize, Serialize, Eq, PartialEq)]
125#[serde(deny_unknown_fields, default)]
126pub struct AddressBookConfig {
127    max_white_list_length: usize,
128    max_gray_list_length: usize,
129    peer_save_period: Duration,
130}
131
132impl Default for AddressBookConfig {
133    fn default() -> Self {
134        Self {
135            max_white_list_length: 1_000,
136            max_gray_list_length: 5_000,
137            peer_save_period: Duration::from_secs(90),
138        }
139    }
140}
141
142/// Seed nodes for [`ClearNet`](cuprate_p2p_core::ClearNet).
143pub fn clear_net_seed_nodes(network: Network) -> Vec<SocketAddr> {
144    let seeds = match network {
145        Network::Mainnet => [
146            "176.9.0.187:18080",
147            "88.198.163.90:18080",
148            "66.85.74.134:18080",
149            "51.79.173.165:18080",
150            "192.99.8.110:18080",
151            "37.187.74.171:18080",
152            "77.172.183.193:18080",
153        ]
154        .as_slice(),
155        Network::Stagenet => [
156            "176.9.0.187:38080",
157            "51.79.173.165:38080",
158            "192.99.8.110:38080",
159            "37.187.74.171:38080",
160            "77.172.183.193:38080",
161        ]
162        .as_slice(),
163        Network::Testnet => [
164            "176.9.0.187:28080",
165            "51.79.173.165:28080",
166            "192.99.8.110:28080",
167            "37.187.74.171:28080",
168            "77.172.183.193:28080",
169        ]
170        .as_slice(),
171    };
172
173    seeds
174        .iter()
175        .map(|s| s.parse())
176        .collect::<Result<_, _>>()
177        .unwrap()
178}