diff --git a/Cargo.lock b/Cargo.lock index 4ca1a6bd..f7f6a418 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -862,8 +862,7 @@ dependencies = [ [[package]] name = "ant-protocol" version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e950d12c9f6d08d0ea560573729d93f15e105d53b669defa682f5e6f92da4b1" +source = "git+https://github.com/WithAutonomi/ant-protocol?branch=codex/remove-bootstrap-cache#0acca731194ef999fd539bda87da53f24b18945c" dependencies = [ "blake3", "bytes", @@ -1555,9 +1554,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", "js-sys", @@ -3520,9 +3519,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.31" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "113b30b4cd05f7c06868fdb2854f66a7b9fece9a48425351cd532e810d74024f" +checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" [[package]] name = "lru" @@ -4867,8 +4866,7 @@ dependencies = [ [[package]] name = "saorsa-core" version = "0.24.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0f8952fc5a4d37eb0bca7de0740830f40347f9da663effde3ddd6b68bcd2fb" +source = "git+https://github.com/saorsa-labs/saorsa-core?branch=codex/remove-bootstrap-cache#07b85f5ed9b2f4cda9445ff49d4ad4c35073d9ab" dependencies = [ "anyhow", "async-trait", @@ -4982,8 +4980,7 @@ dependencies = [ [[package]] name = "saorsa-transport" version = "0.34.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852400712537856ab6fec5293be4290daf0130df0dbcb249a6e8280f9257665f" +source = "git+https://github.com/saorsa-labs/saorsa-transport?branch=codex/remove-bootstrap-cache#cafdce42c3e8574380dadbbe03f16a360f08096f" dependencies = [ "anyhow", "async-trait", @@ -7066,9 +7063,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" dependencies = [ "stable_deref_trait", "yoke-derive", diff --git a/Cargo.toml b/Cargo.toml index e89ab459..e65082f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,14 +35,12 @@ mimalloc = "0.1" # node-only DHT internals (DHTNode, TrustEvent, DhtNetworkEvent), which # Cargo unifies with ant-protocol's version constraint. # -# TODO: swap to `ant-protocol = "2.0.0"` once 2.0.0 is on crates.io. -# Until then, the git pin tracks the matching saorsa-core lineage -# (the rc-2026.4.2 branch) so Cargo can unify the wire types here -# with ant-protocol's re-exports. -ant-protocol = "2.1.2" +# Track the bootstrap-cache removal dependency chain until the dependent +# releases are published. +ant-protocol = { git = "https://github.com/WithAutonomi/ant-protocol", branch = "codex/remove-bootstrap-cache" } # Core (provides EVERYTHING: networking, DHT, security, trust, storage) -saorsa-core = "0.24.5" +saorsa-core = { git = "https://github.com/saorsa-labs/saorsa-core", branch = "codex/remove-bootstrap-cache" } saorsa-pqc = "0.5" # Payment verification - autonomi network lookup + EVM payment diff --git a/docs/DESIGN.md b/docs/DESIGN.md index 3d71990c..94c39fdc 100644 --- a/docs/DESIGN.md +++ b/docs/DESIGN.md @@ -185,7 +185,6 @@ use saorsa_core::{ P2PNode, NodeConfig, NodeMode, adaptive::trust::TrustEngine, adaptive::dht::AdaptiveDhtConfig, - BootstrapConfig, BootstrapManager, IPDiversityConfig, identity::peer_id::PeerId, }; @@ -194,7 +193,6 @@ pub struct RunningNode { shutdown_sender: watch::Sender, // USE ANT-CORE DIRECTLY - NO REIMPLEMENTATION! node: Arc, // Integrates ALL components - bootstrap: Arc, // 30,000 peer cache // Events node_events_channel: NodeEventsChannel, root_dir_path: PathBuf, diff --git a/src/bin/ant-node/cli.rs b/src/bin/ant-node/cli.rs index b1d68c66..9d1c6356 100644 --- a/src/bin/ant-node/cli.rs +++ b/src/bin/ant-node/cli.rs @@ -1,8 +1,8 @@ //! Command-line interface definition. use ant_node::config::{ - BootstrapCacheConfig, BootstrapPeersConfig, BootstrapSource, EvmNetworkConfig, NetworkMode, - NodeConfig, PaymentConfig, UpgradeChannel, + BootstrapPeersConfig, BootstrapSource, EvmNetworkConfig, NetworkMode, NodeConfig, + PaymentConfig, UpgradeChannel, }; use clap::{Parser, ValueEnum}; use std::net::SocketAddr; @@ -133,18 +133,6 @@ pub struct Cli { /// that will restart the process automatically. #[arg(long)] pub stop_on_upgrade: bool, - - /// Disable persistent bootstrap cache. - #[arg(long)] - pub disable_bootstrap_cache: bool, - - /// Directory for bootstrap cache files. - #[arg(long, env = "ANT_BOOTSTRAP_CACHE_DIR")] - pub bootstrap_cache_dir: Option, - - /// Maximum peers to cache in the bootstrap cache. - #[arg(long, default_value = "10000", env = "ANT_BOOTSTRAP_CACHE_CAPACITY")] - pub bootstrap_cache_capacity: usize, } /// Upgrade channel CLI enum. @@ -282,14 +270,6 @@ impl Cli { metrics_port: self.metrics_port, }; - // Bootstrap cache config - config.bootstrap_cache = BootstrapCacheConfig { - enabled: !self.disable_bootstrap_cache, - cache_dir: self.bootstrap_cache_dir, - max_contacts: self.bootstrap_cache_capacity, - ..config.bootstrap_cache - }; - // Determine bootstrap source and apply auto-discovery if needed. let bootstrap_source = if cli_bootstrap_provided { BootstrapSource::Cli diff --git a/src/config.rs b/src/config.rs index e1d9d743..2319f96b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -116,10 +116,6 @@ pub struct NodeConfig { #[serde(default)] pub payment: PaymentConfig, - /// Bootstrap cache configuration for persistent peer storage. - #[serde(default)] - pub bootstrap_cache: BootstrapCacheConfig, - /// Storage configuration for chunk persistence. #[serde(default)] pub storage: StorageConfig, @@ -282,7 +278,6 @@ impl Default for NodeConfig { testnet: TestnetConfig::default(), upgrade: UpgradeConfig::default(), payment: PaymentConfig::default(), - bootstrap_cache: BootstrapCacheConfig::default(), storage: StorageConfig::default(), close_group_cache_dir: None, max_message_size: default_max_message_size(), @@ -405,63 +400,6 @@ const fn default_staged_rollout_hours() -> u64 { 24 // 24 hour window for staged rollout } -// ============================================================================ -// Bootstrap Cache Configuration -// ============================================================================ - -/// Bootstrap cache configuration for persistent peer storage. -/// -/// The bootstrap cache stores discovered peers across node restarts, -/// ranking them by quality metrics (success rate, latency, recency). -/// This reduces dependency on hardcoded bootstrap nodes and enables -/// faster network reconnection after restarts. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct BootstrapCacheConfig { - /// Enable persistent bootstrap cache. - /// Default: true - #[serde(default = "default_bootstrap_cache_enabled")] - pub enabled: bool, - - /// Directory for cache files. - /// Default: `{root_dir}/bootstrap_cache/` - #[serde(default)] - pub cache_dir: Option, - - /// Maximum contacts to store in the cache. - /// Default: 10,000 - #[serde(default = "default_bootstrap_max_contacts")] - pub max_contacts: usize, - - /// Stale contact threshold in days. - /// Contacts older than this are removed during cleanup. - /// Default: 7 days - #[serde(default = "default_bootstrap_stale_days")] - pub stale_threshold_days: u64, -} - -impl Default for BootstrapCacheConfig { - fn default() -> Self { - Self { - enabled: default_bootstrap_cache_enabled(), - cache_dir: None, - max_contacts: default_bootstrap_max_contacts(), - stale_threshold_days: default_bootstrap_stale_days(), - } - } -} - -const fn default_bootstrap_cache_enabled() -> bool { - true -} - -const fn default_bootstrap_max_contacts() -> usize { - 10_000 -} - -const fn default_bootstrap_stale_days() -> u64 { - 7 -} - // ============================================================================ // Storage Configuration // ============================================================================ @@ -537,8 +475,6 @@ pub const BOOTSTRAP_PEERS_ENV: &str = "ANT_BOOTSTRAP_PEERS_PATH"; /// Bootstrap peers loaded from a shipped configuration file. /// /// This file provides initial peers for first-time network joins. -/// It is separate from the bootstrap *cache* (which stores quality-ranked -/// peers discovered at runtime). #[derive(Debug, Clone, Serialize, Deserialize)] pub struct BootstrapPeersConfig { /// The bootstrap peer socket addresses. @@ -583,24 +519,37 @@ impl BootstrapPeersConfig { /// Returns `None` if no file is found in any location. #[must_use] pub fn discover() -> Option<(Self, PathBuf)> { - let candidates = Self::search_paths(); - for path in candidates { - if path.is_file() { - match Self::from_file(&path) { - Ok(config) if !config.peers.is_empty() => return Some((config, path)), - Ok(_) => {} - Err(err) => { - crate::logging::warn!( - "Failed to load bootstrap peers from {}: {err}", - path.display(), - ); - } - } + if let Ok(env_path) = std::env::var(BOOTSTRAP_PEERS_ENV) { + return Self::load_non_empty_candidate(PathBuf::from(env_path)); + } + + for path in Self::search_paths() { + if let Some(discovered) = Self::load_non_empty_candidate(path) { + return Some(discovered); } } + None } + fn load_non_empty_candidate(path: PathBuf) -> Option<(Self, PathBuf)> { + if !path.is_file() { + return None; + } + + match Self::from_file(&path) { + Ok(config) if !config.peers.is_empty() => Some((config, path)), + Ok(_) => None, + Err(err) => { + crate::logging::warn!( + "Failed to load bootstrap peers from {}: {err}", + path.display(), + ); + None + } + } + } + /// Build the ordered list of candidate paths to search. fn search_paths() -> Vec { let mut paths = Vec::new(); diff --git a/src/lib.rs b/src/lib.rs index bcad4850..38cc9096 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -64,7 +64,7 @@ pub use client::{ compute_address, hex_node_id_to_encoded_peer_id, peer_id_to_xor_name, xor_distance, DataChunk, XorName, }; -pub use config::{BootstrapCacheConfig, NodeConfig, StorageConfig}; +pub use config::{NodeConfig, StorageConfig}; pub use devnet::{Devnet, DevnetConfig, DevnetEvmInfo, DevnetManifest}; pub use error::{Error, Result}; pub use event::{NodeEvent, NodeEventsChannel}; diff --git a/src/node.rs b/src/node.rs index e63ec272..0926df24 100644 --- a/src/node.rs +++ b/src/node.rs @@ -20,7 +20,6 @@ use crate::upgrade::{ use rand::Rng; use saorsa_core::identity::NodeIdentity; use saorsa_core::{ - BootstrapConfig as CoreBootstrapConfig, BootstrapManager, IPDiversityConfig as CoreDiversityConfig, MultiAddr, NodeConfig as CoreNodeConfig, P2PEvent, P2PNode, }; @@ -108,14 +107,6 @@ impl NodeBuilder { Some(Self::build_upgrade_monitor(&self.config, node_id_seed)) }; - // Initialize bootstrap cache manager if enabled - let bootstrap_manager = if self.config.bootstrap_cache.enabled { - Self::build_bootstrap_manager(&self.config).await - } else { - info!("Bootstrap cache disabled"); - None - }; - // Initialize ANT protocol handler for chunk storage and // wire the fresh-write channel so PUTs trigger replication. let (ant_protocol, fresh_write_rx) = if self.config.storage.enabled { @@ -173,7 +164,6 @@ impl NodeBuilder { events_tx, events_rx: Some(events_rx), upgrade_monitor, - bootstrap_manager, ant_protocol, replication_engine, protocol_task: None, @@ -409,41 +399,6 @@ impl NodeBuilder { Ok(protocol) } - - /// Build the bootstrap cache manager from config. - async fn build_bootstrap_manager(config: &NodeConfig) -> Option { - let cache_dir = config - .bootstrap_cache - .cache_dir - .clone() - .unwrap_or_else(|| config.root_dir.join("bootstrap_cache")); - - // Create cache directory - if let Err(e) = std::fs::create_dir_all(&cache_dir) { - warn!("Failed to create bootstrap cache directory: {e}"); - return None; - } - - let bootstrap_config = CoreBootstrapConfig { - cache_dir, - max_peers: config.bootstrap_cache.max_contacts, - ..CoreBootstrapConfig::default() - }; - - match BootstrapManager::with_config(bootstrap_config).await { - Ok(manager) => { - info!( - "Bootstrap cache initialized with {} max contacts", - config.bootstrap_cache.max_contacts - ); - Some(manager) - } - Err(e) => { - warn!("Failed to initialize bootstrap cache: {e}"); - None - } - } - } } /// A running Ant node. @@ -454,8 +409,6 @@ pub struct RunningNode { events_tx: NodeEventsSender, events_rx: Option, upgrade_monitor: Option, - /// Bootstrap cache manager for persistent peer storage. - bootstrap_manager: Option, /// ANT protocol handler for chunk storage. ant_protocol: Option>, /// Replication engine (manages neighbor sync, verification, audits). @@ -690,15 +643,6 @@ impl RunningNode { // Run the main event loop with signal handling self.run_event_loop().await?; - // Log bootstrap cache stats before shutdown - if let Some(ref manager) = self.bootstrap_manager { - let stats = manager.stats().await; - info!( - "Bootstrap cache shutdown: {} peers, avg quality {:.2}", - stats.total_peers, stats.average_quality - ); - } - // Shutdown replication engine before P2P so background tasks don't // use a dead P2P layer, and Arc references are released. if let Some(ref mut engine) = self.replication_engine {