diff --git a/Cargo.lock b/Cargo.lock index 13b5520..a8ececc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -862,8 +862,7 @@ dependencies = [ [[package]] name = "ant-protocol" version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4d0ba3f671c08a1d52291b601ec35a7353f4f4e10f221b5f0ee372d154636dd" +source = "git+https://github.com/WithAutonomi/ant-protocol?branch=codex/remove-bootstrap-cache#6bc35372986474fa9f31844b034790d0b84ffb97" dependencies = [ "blake3", "bytes", @@ -4866,9 +4865,8 @@ dependencies = [ [[package]] name = "saorsa-core" -version = "0.24.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c1267928da1bcc91748c314f95f7952bc01c0359a4ac70a0b111b0386898934" +version = "0.24.5-rc.2" +source = "git+https://github.com/saorsa-labs/saorsa-core?branch=codex/remove-bootstrap-cache#ac285f212185486b1d1ee6eee33932865413f42f" 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#00447926f8847d5de99c271fb689740f749177f6" dependencies = [ "anyhow", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 0ef01ea..76f8154 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.1" +# 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.4" +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 3d71990..94c39fd 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 b1d68c6..9d1c635 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 e1d9d74..2319f96 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 bcad485..38cc909 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 ebee324..db36b5c 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, @@ -410,41 +400,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. @@ -455,8 +410,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). @@ -691,15 +644,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 {