Skip to content
Merged
77 changes: 47 additions & 30 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 24 additions & 14 deletions ant-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ use std::time::Duration;
use clap::Parser;
use indicatif::{ProgressBar, ProgressStyle};
use tracing::info;
use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};

use ant_core::data::{
Client, ClientConfig, CoreNodeConfig, CustomNetwork, DevnetManifest, EvmAddress, EvmNetwork,
MultiAddr, NodeMode, P2PNode, Wallet, MAX_WIRE_MESSAGE_SIZE,
IPDiversityConfig, MultiAddr, NodeMode, P2PNode, Wallet, MAX_WIRE_MESSAGE_SIZE,
};
use cli::{Cli, Commands};

Expand Down Expand Up @@ -46,21 +47,24 @@ async fn main() {
async fn run() -> anyhow::Result<()> {
let cli = Cli::parse();

// Privacy by design: no logs unless the user explicitly opts in with -v.
// A decentralized network client must not emit metadata by default.
// Privacy by design: no logs unless the user explicitly opts in with -v
// or by setting RUST_LOG. A decentralized network client must not emit
// metadata by default.
let needs_tracing = !matches!(cli.command, Commands::Node { .. });
if needs_tracing && cli.verbose > 0 {
use tracing_subscriber::{fmt, prelude::*, EnvFilter};

let filter = match cli.verbose {
1 => EnvFilter::new("ant_core=info,ant_cli=info"),
2 => EnvFilter::new("ant_core=debug,ant_cli=debug"),
_ => EnvFilter::new("trace"),
if needs_tracing {
let filter = match (EnvFilter::try_from_default_env().ok(), cli.verbose) {
(Some(f), _) => Some(f),
(None, 0) => None,
(None, 1) => Some(EnvFilter::new("ant_core=info,ant_cli=info")),
(None, 2) => Some(EnvFilter::new("ant_core=debug,ant_cli=debug")),
(None, _) => Some(EnvFilter::new("trace")),
};
tracing_subscriber::registry()
.with(fmt::layer().with_writer(std::io::stderr))
.with(filter)
.init();
if let Some(filter) = filter {
tracing_subscriber::registry()
.with(fmt::layer().with_writer(std::io::stderr))
.with(filter)
.init();
}
}

// Separate the command from the rest of the CLI args to avoid partial-move issues.
Expand Down Expand Up @@ -399,6 +403,12 @@ async fn create_client_node_raw(
.build()
.map_err(|e| anyhow::anyhow!("Failed to create core config: {e}"))?;

// Clients never enforce IP-diversity limits: they don't host data and
// their routing table exists only to find peers, not to be defended
// against Sybil clustering. Strict per-IP / per-subnet caps would
// silently drop legitimate testnet peers that share an IP or /24.
core_config.diversity_config = Some(IPDiversityConfig::permissive());

core_config.bootstrap_peers = bootstrap
.iter()
.map(|addr| MultiAddr::quic(*addr))
Expand Down
2 changes: 1 addition & 1 deletion ant-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ tracing = "0.1"
bytes = "1"
lru = "0.16"
rand = "0.8"
ant-node = "0.10.1"
ant-node = { git = "https://github.com/withAutonomi/ant-node.git", branch = "mick/always-masque-relay-rebased" }
saorsa-pqc = "0.5"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }

Expand Down
18 changes: 10 additions & 8 deletions ant-core/src/data/client/quote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use evmlib::common::Amount;
use evmlib::PaymentQuote;
use futures::stream::{FuturesUnordered, StreamExt};
use std::time::Duration;
use tracing::{debug, warn};
use tracing::{debug, info, warn};

/// Compute XOR distance between a peer's ID bytes and a target address.
///
Expand Down Expand Up @@ -167,7 +167,7 @@ impl Client {
quotes.push((peer_id, addrs, quote, price));
}
Err(Error::AlreadyStored) => {
debug!("Peer {peer_id} reports chunk already stored");
info!("Peer {peer_id} reports chunk already stored");
let dist = xor_distance(&peer_id, address);
already_stored_peers.push((peer_id, dist));
}
Expand Down Expand Up @@ -221,9 +221,12 @@ impl Client {
}
}

if quotes.len() >= CLOSE_GROUP_SIZE {
let total_responses = quotes.len() + failures.len() + already_stored_peers.len();
let already_stored_count = already_stored_peers.len();
let failure_count = failures.len();
let quote_count = quotes.len();
let total_responses = quote_count + failure_count + already_stored_count;

if quotes.len() >= CLOSE_GROUP_SIZE {
// Sort by XOR distance to target, keep the closest CLOSE_GROUP_SIZE.
quotes.sort_by(|a, b| {
let dist_a = xor_distance(&a.0, address);
Expand All @@ -232,17 +235,16 @@ impl Client {
});
quotes.truncate(CLOSE_GROUP_SIZE);

debug!(
"Collected {} quotes for address {} (from {total_responses} responses)",
info!(
"Collected {} quotes for address {} ({total_responses} responses: {quote_count} ok, {already_stored_count} already_stored, {failure_count} failed)",
quotes.len(),
hex::encode(address),
);
return Ok(quotes);
}

Err(Error::InsufficientPeers(format!(
"Got {} quotes, need {CLOSE_GROUP_SIZE}. Failures: [{}]",
quotes.len(),
"Got {quote_count} quotes, need {CLOSE_GROUP_SIZE} ({total_responses} responses: {already_stored_count} already_stored, {failure_count} failed). Failures: [{}]",
failures.join("; ")
)))
}
Expand Down
2 changes: 1 addition & 1 deletion ant-core/src/data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub use self_encryption::DataMap;

// Re-export networking types needed by CLI for P2P node creation
pub use ant_node::ant_protocol::{MAX_CHUNK_SIZE, MAX_WIRE_MESSAGE_SIZE};
pub use ant_node::core::{CoreNodeConfig, MultiAddr, NodeMode, P2PNode};
pub use ant_node::core::{CoreNodeConfig, IPDiversityConfig, MultiAddr, NodeMode, P2PNode};
pub use ant_node::devnet::DevnetManifest;

// Re-export EVM types needed by CLI for wallet and network setup
Expand Down
13 changes: 11 additions & 2 deletions ant-core/src/data/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

use crate::data::error::{Error, Result};
use ant_node::ant_protocol::MAX_WIRE_MESSAGE_SIZE;
use ant_node::core::{CoreNodeConfig, MultiAddr, NodeMode, P2PNode, PeerId};
use ant_node::core::{CoreNodeConfig, IPDiversityConfig, MultiAddr, NodeMode, P2PNode, PeerId};
use std::net::SocketAddr;
use std::sync::Arc;

Expand Down Expand Up @@ -41,6 +41,12 @@ impl Network {
.build()
.map_err(|e| Error::Network(format!("Failed to create core config: {e}")))?;

// Clients never enforce IP-diversity limits: they don't host data and
// their routing table exists only to find peers, not to be defended
// against Sybil clustering. Strict per-IP / per-subnet caps would
// silently drop legitimate testnet peers that share an IP or /24.
core_config.diversity_config = Some(IPDiversityConfig::permissive());

core_config.bootstrap_peers = bootstrap_peers
.iter()
.map(|addr| MultiAddr::quic(*addr))
Expand Down Expand Up @@ -105,7 +111,10 @@ impl Network {
.into_iter()
.filter(|n| n.peer_id != *local_peer_id)
.take(count)
.map(|n| (n.peer_id, n.addresses))
.map(|n| {
let addrs = n.addresses_by_priority();
(n.peer_id, addrs)
})
.collect())
}

Expand Down
Loading