Skip to content

Commit

Permalink
feat(bootstrap): allow writing or reading from custom bootstrap cache…
Browse files Browse the repository at this point in the history
… dir
  • Loading branch information
RolandSherwin committed Dec 9, 2024
1 parent 902db32 commit c1c9981
Show file tree
Hide file tree
Showing 10 changed files with 426 additions and 9 deletions.
10 changes: 8 additions & 2 deletions ant-bootstrap/src/cache_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,15 +181,21 @@ impl BootstrapCacheStore {
/// Create a empty CacheStore from the given peers argument.
/// This also modifies the cfg if provided based on the PeersArgs.
/// And also performs some actions based on the PeersArgs.
///
/// `PeersArgs::bootstrap_cache_dir` will take precedence over the path provided inside `config`.
pub fn new_from_peers_args(
peers_arg: &PeersArgs,
cfg: Option<BootstrapCacheConfig>,
config: Option<BootstrapCacheConfig>,
) -> Result<Self> {
let config = if let Some(cfg) = cfg {
let mut config = if let Some(cfg) = config {
cfg
} else {
BootstrapCacheConfig::default_config()?
};
if let Some(bootstrap_cache_path) = peers_arg.get_bootstrap_cache_path()? {
config.cache_file_path = bootstrap_cache_path;
}

let mut store = Self::new(config)?;

// If it is the first node, clear the cache.
Expand Down
9 changes: 7 additions & 2 deletions ant-bootstrap/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,13 @@ fn default_cache_path() -> Result<PathBuf> {

std::fs::create_dir_all(&dir)?;

let network_id = format!("{}_{}", get_key_version_str(), get_truncate_version_str());
let path = dir.join(format!("bootstrap_cache_{}.json", network_id));
let path = dir.join(cache_file_name());

Ok(path)
}

/// Returns the name of the cache file
pub fn cache_file_name() -> String {
let network_id = format!("{}_{}", get_key_version_str(), get_truncate_version_str());
format!("bootstrap_cache_{network_id}.json")
}
2 changes: 2 additions & 0 deletions ant-bootstrap/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ pub enum Error {
FailedToParseCacheData,
#[error("Could not obtain data directory")]
CouldNotObtainDataDir,
#[error("Invalid bootstrap cache directory")]
InvalidBootstrapCacheDir,
#[error("Could not obtain bootstrap addresses from {0} after {1} retries")]
FailedToObtainAddrsFromUrl(String, usize),
#[error("No Bootstrap Addresses found: {0}")]
Expand Down
41 changes: 37 additions & 4 deletions ant-bootstrap/src/initial_peers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
// permissions and limitations relating to use of the SAFE Network Software.

use crate::{
config::cache_file_name,
craft_valid_multiaddr, craft_valid_multiaddr_from_str,
error::{Error, Result},
BootstrapAddr, BootstrapCacheConfig, BootstrapCacheStore, ContactsFetcher,
};
use clap::Args;
use libp2p::Multiaddr;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use url::Url;

/// The name of the environment variable that can be used to pass peers to the node.
Expand Down Expand Up @@ -61,17 +63,27 @@ pub struct PeersArgs {
/// This disables fetching peers from the mainnet network contacts.
#[clap(name = "testnet", long)]
pub disable_mainnet_contacts: bool,

/// Set to not load the bootstrap addresses from the local cache.
#[clap(long, default_value = "false")]
pub ignore_cache: bool,
/// The directory to load and store the bootstrap cache. If not provided, the default path will be used.
///
/// The JSON filename will be derived automatically from the network ID
///
/// The default location is platform specific:
/// - Linux: $HOME/.local/share/autonomi/bootstrap_cache/bootstrap_cache_<network_id>.json
/// - macOS: $HOME/Library/Application Support/autonomi/bootstrap_cache/bootstrap_cache_<network_id>.json
/// - Windows: C:\Users\<username>\AppData\Roaming\autonomi\bootstrap_cache\bootstrap_cache_<network_id>.json
#[clap(long)]
pub bootstrap_cache_dir: Option<PathBuf>,
}

impl PeersArgs {
/// Get bootstrap peers
/// Order of precedence:
/// 1. Addresses from arguments
/// 2. Addresses from environment variable SAFE_PEERS
/// 3. Addresses from cache
/// 3. Addresses from cache. `Self::bootstrap_cache_dir` will take precedence over the path provided inside `config`
/// 4. Addresses from network contacts URL
pub async fn get_addrs(&self, config: Option<BootstrapCacheConfig>) -> Result<Vec<Multiaddr>> {
Ok(self
Expand All @@ -86,7 +98,7 @@ impl PeersArgs {
/// Order of precedence:
/// 1. Addresses from arguments
/// 2. Addresses from environment variable SAFE_PEERS
/// 3. Addresses from cache
/// 3. Addresses from cache. `Self::bootstrap_cache_dir` will take precedence over the path provided inside `config`
/// 4. Addresses from network contacts URL
pub async fn get_bootstrap_addr(
&self,
Expand Down Expand Up @@ -147,7 +159,10 @@ impl PeersArgs {
} else {
BootstrapCacheConfig::default_config().ok()
};
if let Some(cfg) = cfg {
if let Some(mut cfg) = cfg {
if let Some(file_path) = self.get_bootstrap_cache_path()? {
cfg.cache_file_path = file_path;
}
info!("Loading bootstrap addresses from cache");
if let Ok(data) = BootstrapCacheStore::load_cache_data(&cfg) {
bootstrap_addresses = data
Expand Down Expand Up @@ -206,4 +221,22 @@ impl PeersArgs {
}
bootstrap_addresses
}

/// Get the path to the bootstrap cache JSON file if `Self::bootstrap_cache_dir` is set
pub fn get_bootstrap_cache_path(&self) -> Result<Option<PathBuf>> {
if let Some(dir) = &self.bootstrap_cache_dir {
if dir.is_file() {
return Err(Error::InvalidBootstrapCacheDir);
}

if !dir.exists() {
std::fs::create_dir_all(dir)?;
}

let path = dir.join(cache_file_name());
Ok(Some(path))
} else {
Ok(None)
}
}
}
2 changes: 2 additions & 0 deletions ant-bootstrap/tests/address_format_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ async fn test_multiaddr_format_parsing() -> Result<(), Box<dyn std::error::Error
local: false,
disable_mainnet_contacts: false,
ignore_cache: false,
bootstrap_cache_dir: None,
};

let bootstrap_addresses = args.get_bootstrap_addr(None).await?;
Expand Down Expand Up @@ -86,6 +87,7 @@ async fn test_network_contacts_format() -> Result<(), Box<dyn std::error::Error>
local: false,
disable_mainnet_contacts: false,
ignore_cache: false,
bootstrap_cache_dir: None,
};

let addrs = args.get_bootstrap_addr(None).await?;
Expand Down
5 changes: 5 additions & 0 deletions ant-bootstrap/tests/cli_integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ async fn test_first_flag() -> Result<(), Box<dyn std::error::Error>> {
local: false,
disable_mainnet_contacts: false,
ignore_cache: false,
bootstrap_cache_dir: None,
};

let addrs = args.get_addrs(Some(config)).await?;
Expand All @@ -60,6 +61,7 @@ async fn test_peer_argument() -> Result<(), Box<dyn std::error::Error>> {
local: false,
disable_mainnet_contacts: true,
ignore_cache: false,
bootstrap_cache_dir: None,
};

let addrs = args.get_addrs(None).await?;
Expand Down Expand Up @@ -94,6 +96,7 @@ async fn test_network_contacts_fallback() -> Result<(), Box<dyn std::error::Erro
local: false,
disable_mainnet_contacts: false,
ignore_cache: false,
bootstrap_cache_dir: None,
};

let addrs = args.get_addrs(Some(config)).await?;
Expand Down Expand Up @@ -124,6 +127,7 @@ async fn test_local_mode() -> Result<(), Box<dyn std::error::Error>> {
local: true,
disable_mainnet_contacts: false,
ignore_cache: false,
bootstrap_cache_dir: None,
};

let addrs = args.get_addrs(Some(config)).await?;
Expand Down Expand Up @@ -159,6 +163,7 @@ async fn test_test_network_peers() -> Result<(), Box<dyn std::error::Error>> {
local: false,
disable_mainnet_contacts: true,
ignore_cache: false,
bootstrap_cache_dir: None,
};

let addrs = args.get_addrs(Some(config)).await?;
Expand Down
Loading

0 comments on commit c1c9981

Please sign in to comment.