ant_bootstrap/
config.rs

1// Copyright 2024 MaidSafe.net limited.
2//
3// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3.
4// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed
5// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
6// KIND, either express or implied. Please review the Licences for the specific language governing
7// permissions and limitations relating to use of the SAFE Network Software.
8
9use crate::{
10    InitialPeersConfig,
11    error::{Error, Result},
12};
13use std::{
14    path::{Path, PathBuf},
15    time::Duration,
16};
17
18/// The duration since last)seen before removing the address of a Peer.
19const ADDR_EXPIRY_DURATION: Duration = Duration::from_secs(24 * 60 * 60); // 24 hours
20
21/// Maximum peers to store
22const MAX_PEERS: usize = 1500;
23
24/// Maximum number of addresses to store for a Peer
25const MAX_ADDRS_PER_PEER: usize = 3;
26
27// Min time until we save the bootstrap cache to disk. 30 secs
28const MIN_BOOTSTRAP_CACHE_SAVE_INTERVAL: Duration = Duration::from_secs(30);
29
30// Max time until we save the bootstrap cache to disk. 3 hours
31const MAX_BOOTSTRAP_CACHE_SAVE_INTERVAL: Duration = Duration::from_secs(3 * 60 * 60);
32
33/// Configuration for the bootstrap cache
34#[derive(Clone, Debug)]
35pub struct BootstrapCacheConfig {
36    /// The duration since last)seen before removing the address of a Peer.
37    pub addr_expiry_duration: Duration,
38    /// Enable backwards compatibility while writing the cache file.
39    /// This will write the cache file in all versions of the cache file format.
40    pub backwards_compatible_writes: bool,
41    /// The directory to load and store the bootstrap cache. If not provided, the default path will be used.
42    pub cache_dir: PathBuf,
43    /// The cache save scaling factor. We start with the min_cache_save_duration and scale it up to the max_cache_save_duration.
44    pub cache_save_scaling_factor: u32,
45    /// Flag to disable writing to the cache file
46    pub disable_cache_writing: bool,
47    /// If set to true, the cache filename will be suffixed with "_local"
48    pub local: bool,
49    /// The max time duration until we save the bootstrap cache to disk.
50    pub max_cache_save_duration: Duration,
51    /// Maximum number of peers to keep in the cache
52    pub max_peers: usize,
53    /// Maximum number of addresses stored per peer.
54    pub max_addrs_per_peer: usize,
55    /// The min time duration until we save the bootstrap cache to disk.
56    pub min_cache_save_duration: Duration,
57}
58
59impl TryFrom<&InitialPeersConfig> for BootstrapCacheConfig {
60    type Error = Error;
61    fn try_from(config: &InitialPeersConfig) -> Result<Self> {
62        let mut bootstrap_config = BootstrapCacheConfig::empty();
63        bootstrap_config.local = config.local;
64        let cache_dir = if let Some(cache_dir) = &config.bootstrap_cache_dir {
65            cache_dir.clone()
66        } else {
67            default_cache_dir()?
68        };
69        bootstrap_config.cache_dir = cache_dir;
70        Ok(bootstrap_config)
71    }
72}
73
74impl BootstrapCacheConfig {
75    /// Creates a new BootstrapConfig with default settings
76    pub fn new(local: bool) -> Result<Self> {
77        Ok(Self {
78            local,
79            cache_dir: default_cache_dir()?,
80            ..Self::empty()
81        })
82    }
83
84    /// Creates a new BootstrapConfig with empty settings
85    pub fn empty() -> Self {
86        Self {
87            addr_expiry_duration: ADDR_EXPIRY_DURATION,
88            backwards_compatible_writes: false,
89            max_peers: MAX_PEERS,
90            max_addrs_per_peer: MAX_ADDRS_PER_PEER,
91            cache_dir: PathBuf::new(),
92            disable_cache_writing: false,
93            local: false,
94            min_cache_save_duration: MIN_BOOTSTRAP_CACHE_SAVE_INTERVAL,
95            max_cache_save_duration: MAX_BOOTSTRAP_CACHE_SAVE_INTERVAL,
96            cache_save_scaling_factor: 2,
97        }
98    }
99
100    /// Set backwards compatible writes
101    pub fn with_backwards_compatible_writes(mut self, enable: bool) -> Self {
102        self.backwards_compatible_writes = enable;
103        self
104    }
105
106    /// Set the local flag
107    pub fn with_local(mut self, enable: bool) -> Self {
108        self.local = enable;
109        self
110    }
111
112    /// Set a new addr expiry duration
113    pub fn with_addr_expiry_duration(mut self, duration: Duration) -> Self {
114        self.addr_expiry_duration = duration;
115        self
116    }
117
118    /// Update the config with a custom cache file path
119    pub fn with_cache_dir<P: AsRef<Path>>(mut self, path: P) -> Self {
120        self.cache_dir = path.as_ref().to_path_buf();
121        self
122    }
123
124    /// Sets the maximum number of peers
125    pub fn with_max_peers(mut self, max_peers: usize) -> Self {
126        self.max_peers = max_peers;
127        self
128    }
129
130    /// Sets the maximum number of addresses for a single peer.
131    pub fn with_addrs_per_peer(mut self, max_addrs: usize) -> Self {
132        self.max_addrs_per_peer = max_addrs;
133        self
134    }
135
136    /// Sets the flag to disable writing to the cache file
137    pub fn with_disable_cache_writing(mut self, disable: bool) -> Self {
138        self.disable_cache_writing = disable;
139        self
140    }
141}
142
143/// Returns the default dir that should contain the bootstrap cache file
144fn default_cache_dir() -> Result<PathBuf> {
145    let dir = dirs_next::data_dir()
146        .ok_or_else(|| Error::CouldNotObtainDataDir)
147        .inspect_err(|err| {
148            error!("Failed to obtain data directory: {err}");
149        })?
150        .join("autonomi")
151        .join("bootstrap_cache");
152
153    std::fs::create_dir_all(&dir).inspect_err(|err| {
154        error!("Failed to create bootstrap cache directory at {dir:?}: {err}");
155    })?;
156
157    Ok(dir)
158}