diff --git a/Cargo.lock b/Cargo.lock index 61c999f1..d289fc23 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -848,15 +848,15 @@ dependencies = [ [[package]] name = "ant-core" -version = "0.1.1" +version = "0.2.0" dependencies = [ "alloy", "ant-node", + "ant-protocol", "anyhow", "async-stream", "axum", "bytes", - "evmlib", "flate2", "fs2", "futures", @@ -870,8 +870,7 @@ dependencies = [ "rand 0.8.6", "reqwest 0.12.28", "rmp-serde", - "saorsa-core 0.23.1", - "saorsa-pqc 0.5.1", + "saorsa-core", "self-replace", "self_encryption", "semver 1.0.28", @@ -933,7 +932,7 @@ dependencies = [ "rand 0.8.6", "reqwest 0.13.2", "rmp-serde", - "saorsa-core 0.24.0", + "saorsa-core", "saorsa-pqc 0.5.1", "self-replace", "self_encryption", @@ -954,6 +953,25 @@ dependencies = [ "zip", ] +[[package]] +name = "ant-protocol" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe630f23f4adae05beba7e2c0861ab9c1a6d2cc88c98898e3742bed3a5a4ce35" +dependencies = [ + "blake3", + "bytes", + "evmlib", + "hex", + "postcard", + "rmp-serde", + "saorsa-core", + "saorsa-pqc 0.5.1", + "serde", + "tokio", + "tracing", +] + [[package]] name = "anyhow" version = "1.0.102" @@ -5136,38 +5154,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "saorsa-core" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d459ba0e4f1a3ac918a1d6b17db392cccde2ee74569545d171d7644fc6463cc7" -dependencies = [ - "anyhow", - "async-trait", - "blake3", - "bytes", - "dashmap", - "dirs 6.0.0", - "futures", - "hex", - "lru", - "once_cell", - "parking_lot", - "postcard", - "rand 0.8.6", - "saorsa-pqc 0.5.1", - "saorsa-transport 0.32.0", - "serde", - "serde_json", - "tempfile", - "thiserror 2.0.18", - "tokio", - "tokio-util", - "tracing", - "uuid", - "wyz", -] - [[package]] name = "saorsa-core" version = "0.24.0" @@ -5188,7 +5174,7 @@ dependencies = [ "postcard", "rand 0.8.6", "saorsa-pqc 0.5.1", - "saorsa-transport 0.33.0", + "saorsa-transport", "serde", "serde_json", "tempfile", @@ -5283,65 +5269,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "saorsa-transport" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "250826f52ac60992947359218d83c21f658aa85407e3980a5dbb258eff4c0cc3" -dependencies = [ - "anyhow", - "async-trait", - "aws-lc-rs", - "blake3", - "bytes", - "chrono", - "clap", - "core-foundation 0.9.4", - "dashmap", - "dirs 5.0.1", - "futures-util", - "hex", - "igd-next", - "indexmap 2.14.0", - "keyring", - "libc", - "lru-slab", - "nix", - "once_cell", - "parking_lot", - "pin-project-lite", - "quinn-udp 0.6.1", - "rand 0.8.6", - "rcgen", - "regex", - "reqwest 0.13.2", - "rustc-hash", - "rustls", - "rustls-native-certs", - "rustls-pemfile", - "rustls-platform-verifier", - "rustls-post-quantum", - "saorsa-pqc 0.4.2", - "serde", - "serde_json", - "serde_yaml", - "slab", - "socket2 0.5.10", - "system-configuration 0.6.1", - "thiserror 2.0.18", - "time", - "tinyvec", - "tokio", - "tokio-util", - "tracing", - "tracing-subscriber", - "unicode-width", - "uuid", - "windows 0.58.0", - "x25519-dalek", - "zeroize", -] - [[package]] name = "saorsa-transport" version = "0.33.0" diff --git a/ant-core/Cargo.toml b/ant-core/Cargo.toml index ab3c0187..b8ea97cf 100644 --- a/ant-core/Cargo.toml +++ b/ant-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ant-core" -version = "0.1.1" +version = "0.2.0" edition = "2021" [dependencies] @@ -27,7 +27,12 @@ zip = "2" tower-http = { version = "0.6.8", features = ["cors"] } # Data operations -evmlib = "0.8" +# Wire protocol crate: gives us `ant_protocol::{chunk, payment, …}` plus +# re-exports of `evmlib`, `saorsa-core` (transport), and `saorsa-pqc` +# under `ant_protocol::{evm, transport, pqc}`. This is the ONE pin for +# those three deps — do not add direct evmlib/saorsa-core/saorsa-pqc +# deps here or the version can skew between ant-client and ant-node. +ant-protocol = "2.0.1" xor_name = "5" self_encryption = "0.35.0" futures = "0.3" @@ -44,8 +49,10 @@ rand = "0.8" # sysinfo, so the crate is loaded lazily and the cost is bounded to first-time # upgrade scenarios. sysinfo = { version = "0.32", default-features = false, features = ["system"] } -ant-node = "0.11.0" -saorsa-pqc = "0.5" +# ant-node is optional. It is only linked for the `LocalDevnet` wrapper +# that spawns a local in-process network for development and testing. +# Enable with `--features devnet`. +ant-node = { version = "0.11.0", optional = true } tracing-subscriber = { version = "0.3", features = ["env-filter"] } [target.'cfg(unix)'.dependencies] @@ -58,7 +65,20 @@ openssl = { version = "0.10", features = ["vendored"] } [target.'cfg(windows)'.dependencies] windows-sys = { version = "0.61", features = ["Win32_Foundation", "Win32_System_Console", "Win32_System_Threading"] } +[features] +# No features enabled by default — consumers that want to spawn a local +# devnet opt in with `features = ["devnet"]`. +default = [] +# Enable `LocalDevnet` (ant-core/src/node/devnet.rs) which wraps +# `ant_node::devnet::Devnet` and an Anvil EVM testnet. +devnet = ["dep:ant-node"] + [dev-dependencies] +# Test infrastructure in tests/support/mod.rs spawns real ant-nodes +# in-process to exercise the wire protocol end-to-end. ant-node is a +# dev-dep here (separate from the optional runtime dep above) so tests +# always compile even without the `devnet` feature. +ant-node = "0.11.0" serial_test = "3" anyhow = "1" alloy = { version = "1.6", features = ["node-bindings"] } @@ -66,13 +86,17 @@ tokio-test = "0.4" rmp-serde = "1" # Direct access to BootstrapManager used by the cold-start-from-disk test, # which populates a cache via `add_peer_trusted` (bypasses Sybil rate limits) -# and then verifies reload after save. Version tracks ant-node's transitive -# saorsa-core dep. -saorsa-core = "0.23" +# and then verifies reload after save. Test-only — no runtime version-pin +# concern. Tracks ant-node's transitive saorsa-core dep. +saorsa-core = "0.24" [[example]] name = "start-local-devnet" path = "examples/start-local-devnet.rs" +# `LocalDevnet` (and therefore this example) is gated behind `devnet`. +# Running under default features would produce a confusing "LocalDevnet +# not found" error, so require the feature explicitly. +required-features = ["devnet"] [[test]] name = "e2e_chunk" diff --git a/ant-core/src/data/client/batch.rs b/ant-core/src/data/client/batch.rs index ff3c5750..4fae14a4 100644 --- a/ant-core/src/data/client/batch.rs +++ b/ant-core/src/data/client/batch.rs @@ -8,14 +8,14 @@ use crate::data::client::file::UploadEvent; use crate::data::client::payment::peer_id_to_encoded; use crate::data::client::Client; use crate::data::error::{Error, Result}; -use ant_node::ant_protocol::DATA_TYPE_CHUNK; -use ant_node::client::{compute_address, XorName}; -use ant_node::core::{MultiAddr, PeerId}; -use ant_node::payment::{serialize_single_node_proof, PaymentProof, SingleNodePayment}; +use ant_protocol::evm::{ + Amount, EncodedPeerId, PayForQuotesError, PaymentQuote, ProofOfPayment, QuoteHash, + RewardsAddress, TxHash, +}; +use ant_protocol::payment::{serialize_single_node_proof, PaymentProof, SingleNodePayment}; +use ant_protocol::transport::{MultiAddr, PeerId}; +use ant_protocol::{compute_address, XorName, DATA_TYPE_CHUNK}; use bytes::Bytes; -use evmlib::common::{Amount, QuoteHash, TxHash}; -use evmlib::wallet::PayForQuotesError; -use evmlib::{EncodedPeerId, PaymentQuote, ProofOfPayment, RewardsAddress}; use futures::stream::{self, StreamExt}; use std::collections::{HashMap, HashSet}; use std::time::Duration; @@ -628,8 +628,8 @@ mod send_assertions { #[allow(clippy::unwrap_used)] mod tests { use super::*; - use ant_node::payment::single_node::QuotePaymentInfo; - use ant_node::CLOSE_GROUP_SIZE; + use ant_protocol::payment::QuotePaymentInfo; + use ant_protocol::CLOSE_GROUP_SIZE; /// Median index in the quotes array. const MEDIAN_INDEX: usize = CLOSE_GROUP_SIZE / 2; diff --git a/ant-core/src/data/client/cache.rs b/ant-core/src/data/client/cache.rs index 3e8957eb..893d6c3d 100644 --- a/ant-core/src/data/client/cache.rs +++ b/ant-core/src/data/client/cache.rs @@ -3,7 +3,7 @@ //! Caches recently fetched chunks in memory to avoid re-fetching //! the same content-addressed data from the network. -use ant_node::client::XorName; +use ant_protocol::XorName; use bytes::Bytes; use lru::LruCache; use std::num::NonZeroUsize; diff --git a/ant-core/src/data/client/chunk.rs b/ant-core/src/data/client/chunk.rs index 46174e1d..3dca2149 100644 --- a/ant-core/src/data/client/chunk.rs +++ b/ant-core/src/data/client/chunk.rs @@ -6,13 +6,12 @@ use crate::data::client::peer_cache::record_peer_outcome; use crate::data::client::Client; use crate::data::error::{Error, Result}; -use ant_node::ant_protocol::{ - ChunkGetRequest, ChunkGetResponse, ChunkMessage, ChunkMessageBody, ChunkPutRequest, - ChunkPutResponse, +use ant_protocol::transport::{MultiAddr, PeerId}; +use ant_protocol::{ + compute_address, send_and_await_chunk_response, ChunkGetRequest, ChunkGetResponse, + ChunkMessage, ChunkMessageBody, ChunkPutRequest, ChunkPutResponse, DataChunk, XorName, + CLOSE_GROUP_MAJORITY, }; -use ant_node::client::{compute_address, send_and_await_chunk_response, DataChunk, XorName}; -use ant_node::core::{MultiAddr, PeerId}; -use ant_node::CLOSE_GROUP_MAJORITY; use bytes::Bytes; use futures::stream::{FuturesUnordered, StreamExt}; use std::future::Future; diff --git a/ant-core/src/data/client/data.rs b/ant-core/src/data/client/data.rs index 2541b636..19ec6e89 100644 --- a/ant-core/src/data/client/data.rs +++ b/ant-core/src/data/client/data.rs @@ -11,8 +11,7 @@ use crate::data::client::file::{ExternalPaymentInfo, PreparedUpload}; use crate::data::client::merkle::PaymentMode; use crate::data::client::Client; use crate::data::error::{Error, Result}; -use ant_node::ant_protocol::DATA_TYPE_CHUNK; -use ant_node::client::compute_address; +use ant_protocol::{compute_address, DATA_TYPE_CHUNK}; use bytes::Bytes; use futures::stream::{self, StreamExt, TryStreamExt}; use self_encryption::{decrypt, encrypt, DataMap, EncryptedChunk}; diff --git a/ant-core/src/data/client/file.rs b/ant-core/src/data/client/file.rs index 41c36abb..f808a7a9 100644 --- a/ant-core/src/data/client/file.rs +++ b/ant-core/src/data/client/file.rs @@ -17,13 +17,10 @@ use crate::data::client::merkle::{ }; use crate::data::client::Client; use crate::data::error::{Error, Result}; -use ant_node::ant_protocol::DATA_TYPE_CHUNK; -use ant_node::client::compute_address; -use ant_node::core::{MultiAddr, PeerId}; +use ant_protocol::evm::{Amount, PaymentQuote, QuoteHash, TxHash, MAX_LEAVES}; +use ant_protocol::transport::{MultiAddr, PeerId}; +use ant_protocol::{compute_address, DATA_TYPE_CHUNK}; use bytes::Bytes; -use evmlib::common::{Amount, QuoteHash, TxHash}; -use evmlib::merkle_payments::MAX_LEAVES; -use evmlib::PaymentQuote; use fs2::FileExt; use futures::stream::{self, StreamExt}; use self_encryption::{get_root_data_map_parallel, stream_encrypt, streaming_decrypt, DataMap}; @@ -1246,7 +1243,7 @@ impl Client { progress: Option<&mpsc::Sender>, ) -> Result<(usize, String, u128)> { let mut total_stored = 0usize; - let mut total_storage = evmlib::common::Amount::ZERO; + let mut total_storage = Amount::ZERO; let mut total_gas: u128 = 0; let total_chunks = spill.len(); let waves: Vec<&[[u8; 32]]> = spill.waves().collect(); @@ -1276,7 +1273,7 @@ impl Client { .batch_upload_chunks_with_events(wave_data, progress, total_stored, total_chunks) .await?; total_stored += addresses.len(); - if let Ok(cost) = wave_storage.parse::() { + if let Ok(cost) = wave_storage.parse::() { total_storage += cost; } total_gas = total_gas.saturating_add(wave_gas); diff --git a/ant-core/src/data/client/merkle.rs b/ant-core/src/data/client/merkle.rs index d9ccd885..a8a07712 100644 --- a/ant-core/src/data/client/merkle.rs +++ b/ant-core/src/data/client/merkle.rs @@ -6,19 +6,17 @@ use crate::data::client::Client; use crate::data::error::{Error, Result}; -use ant_node::ant_protocol::{ - ChunkMessage, ChunkMessageBody, MerkleCandidateQuoteRequest, MerkleCandidateQuoteResponse, +use ant_protocol::evm::{ + Amount, MerklePaymentCandidateNode, MerklePaymentCandidatePool, MerklePaymentProof, MerkleTree, + MidpointProof, PoolCommitment, CANDIDATES_PER_POOL, MAX_LEAVES, }; -use ant_node::client::send_and_await_chunk_response; -use ant_node::payment::quote::verify_merkle_candidate_signature; -use ant_node::payment::serialize_merkle_proof; -use bytes::Bytes; -use evmlib::common::Amount; -use evmlib::merkle_batch_payment::PoolCommitment; -use evmlib::merkle_payments::{ - MerklePaymentCandidateNode, MerklePaymentCandidatePool, MerklePaymentProof, MerkleTree, - MidpointProof, CANDIDATES_PER_POOL, MAX_LEAVES, +use ant_protocol::payment::{serialize_merkle_proof, verify_merkle_candidate_signature}; +use ant_protocol::transport::PeerId; +use ant_protocol::{ + send_and_await_chunk_response, ChunkMessage, ChunkMessageBody, MerkleCandidateQuoteRequest, + MerkleCandidateQuoteResponse, }; +use bytes::Bytes; use futures::stream::{self, FuturesUnordered, StreamExt}; use std::collections::HashMap; use std::time::Duration; @@ -453,7 +451,7 @@ impl Client { futures: &mut FuturesUnordered< impl std::future::Future< Output = ( - ant_node::core::PeerId, + PeerId, std::result::Result, ), >, @@ -624,9 +622,7 @@ mod send_assertions { #[allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] mod tests { use super::*; - use evmlib::common::Amount; - use evmlib::merkle_payments::{MerkleTree, CANDIDATES_PER_POOL}; - use evmlib::RewardsAddress; + use ant_protocol::evm::{Amount, MerkleTree, RewardsAddress, CANDIDATES_PER_POOL}; // ========================================================================= // should_use_merkle (free function, no Client needed) @@ -743,10 +739,8 @@ mod tests { #[test] fn test_merkle_proof_serialize_deserialize_roundtrip() { - use ant_node::payment::{deserialize_merkle_proof, serialize_merkle_proof}; - use evmlib::common::Amount; - use evmlib::merkle_payments::MerklePaymentCandidateNode; - use evmlib::RewardsAddress; + use ant_protocol::evm::{Amount, MerklePaymentCandidateNode, RewardsAddress}; + use ant_protocol::payment::{deserialize_merkle_proof, serialize_merkle_proof}; let addrs = make_test_addresses(4); let xornames: Vec = addrs.iter().map(|a| XorName(*a)).collect(); @@ -803,8 +797,8 @@ mod tests { // Simulates what collect_validated_candidates checks let candidate = MerklePaymentCandidateNode { pub_key: vec![0u8; 32], - price: evmlib::common::Amount::ZERO, - reward_address: evmlib::RewardsAddress::new([0u8; 20]), + price: ant_protocol::evm::Amount::ZERO, + reward_address: ant_protocol::evm::RewardsAddress::new([0u8; 20]), merkle_payment_timestamp: 1000, signature: vec![0u8; 64], }; @@ -898,7 +892,7 @@ mod tests { #[test] fn test_finalize_merkle_batch_proofs_are_deserializable() { - use ant_node::payment::deserialize_merkle_proof; + use ant_protocol::payment::deserialize_merkle_proof; let prepared = make_prepared_merkle_batch(8); let winner_hash = prepared.candidate_pools[0].hash(); diff --git a/ant-core/src/data/client/mod.rs b/ant-core/src/data/client/mod.rs index cda985b0..03a31cf5 100644 --- a/ant-core/src/data/client/mod.rs +++ b/ant-core/src/data/client/mod.rs @@ -16,10 +16,9 @@ pub mod quote; use crate::data::client::cache::ChunkCache; use crate::data::error::{Error, Result}; use crate::data::network::Network; -use ant_node::client::XorName; -use ant_node::core::{MultiAddr, P2PNode, PeerId}; -use ant_node::CLOSE_GROUP_SIZE; -use evmlib::wallet::Wallet; +use ant_protocol::evm::Wallet; +use ant_protocol::transport::{MultiAddr, P2PNode, PeerId}; +use ant_protocol::{XorName, CLOSE_GROUP_SIZE}; use std::sync::atomic::{AtomicU64, Ordering}; use std::sync::Arc; use tracing::debug; @@ -111,7 +110,7 @@ pub struct Client { config: ClientConfig, network: Network, wallet: Option>, - evm_network: Option, + evm_network: Option, chunk_cache: ChunkCache, next_request_id: AtomicU64, } @@ -178,7 +177,7 @@ impl Client { /// This enables token approval and contract interactions /// for external-signer flows where the private key lives outside Rust. #[must_use] - pub fn with_evm_network(mut self, network: evmlib::Network) -> Self { + pub fn with_evm_network(mut self, network: ant_protocol::evm::Network) -> Self { self.evm_network = Some(network); self } @@ -188,7 +187,7 @@ impl Client { /// # Errors /// /// Returns an error if neither `with_evm_network` nor `with_wallet` was called. - pub(crate) fn require_evm_network(&self) -> Result<&evmlib::Network> { + pub(crate) fn require_evm_network(&self) -> Result<&ant_protocol::evm::Network> { if let Some(ref net) = self.evm_network { return Ok(net); } diff --git a/ant-core/src/data/client/payment.rs b/ant-core/src/data/client/payment.rs index 651bdb63..014f8bd8 100644 --- a/ant-core/src/data/client/payment.rs +++ b/ant-core/src/data/client/payment.rs @@ -5,10 +5,9 @@ use crate::data::client::Client; use crate::data::error::{Error, Result}; -use ant_node::core::{MultiAddr, PeerId}; -use ant_node::payment::{serialize_single_node_proof, PaymentProof, SingleNodePayment}; -use evmlib::wallet::Wallet; -use evmlib::{EncodedPeerId, ProofOfPayment}; +use ant_protocol::evm::{EncodedPeerId, ProofOfPayment, Wallet}; +use ant_protocol::payment::{serialize_single_node_proof, PaymentProof, SingleNodePayment}; +use ant_protocol::transport::{MultiAddr, PeerId}; use std::sync::Arc; use tracing::{debug, info}; @@ -110,7 +109,7 @@ impl Client { let vault_address = evm_network.payment_vault_address(); wallet - .approve_to_spend_tokens(*vault_address, evmlib::common::U256::MAX) + .approve_to_spend_tokens(*vault_address, ant_protocol::evm::U256::MAX) .await .map_err(|e| Error::Payment(format!("Token approval failed: {e}")))?; info!("Token spend approved for payment vault contract"); diff --git a/ant-core/src/data/client/peer_cache.rs b/ant-core/src/data/client/peer_cache.rs index dc67aa00..0673f182 100644 --- a/ant-core/src/data/client/peer_cache.rs +++ b/ant-core/src/data/client/peer_cache.rs @@ -3,7 +3,7 @@ //! Wires client-side peer contacts into saorsa-core's `BootstrapManager` //! so the persistent cache reflects real peer quality across sessions. -use ant_node::core::{MultiAddr, P2PNode, PeerId}; +use ant_protocol::transport::{MultiAddr, P2PNode, PeerId}; use std::net::{IpAddr, SocketAddr}; use std::sync::Arc; use tracing::debug; diff --git a/ant-core/src/data/client/quote.rs b/ant-core/src/data/client/quote.rs index c0d2ebd6..357abc6b 100644 --- a/ant-core/src/data/client/quote.rs +++ b/ant-core/src/data/client/quote.rs @@ -6,14 +6,12 @@ use crate::data::client::peer_cache::record_peer_outcome; use crate::data::client::Client; use crate::data::error::{Error, Result}; -use ant_node::ant_protocol::{ - ChunkMessage, ChunkMessageBody, ChunkQuoteRequest, ChunkQuoteResponse, +use ant_protocol::evm::{Amount, PaymentQuote}; +use ant_protocol::transport::{MultiAddr, PeerId}; +use ant_protocol::{ + send_and_await_chunk_response, ChunkMessage, ChunkMessageBody, ChunkQuoteRequest, + ChunkQuoteResponse, CLOSE_GROUP_MAJORITY, CLOSE_GROUP_SIZE, }; -use ant_node::client::send_and_await_chunk_response; -use ant_node::core::{MultiAddr, PeerId}; -use ant_node::{CLOSE_GROUP_MAJORITY, CLOSE_GROUP_SIZE}; -use evmlib::common::Amount; -use evmlib::PaymentQuote; use futures::stream::{FuturesUnordered, StreamExt}; use std::time::{Duration, Instant}; use tracing::{debug, info, warn}; diff --git a/ant-core/src/data/error.rs b/ant-core/src/data/error.rs index 3b0de5f2..9cfb62f2 100644 --- a/ant-core/src/data/error.rs +++ b/ant-core/src/data/error.rs @@ -95,6 +95,10 @@ pub enum Error { }, } +// ant-node is only linked when the `devnet` feature is on, so the +// blanket `From` impl follows that gate. LocalDevnet maps node errors +// to `Error::Network` via this conversion; default builds never see it. +#[cfg(feature = "devnet")] impl From for Error { fn from(e: ant_node::Error) -> Self { Self::Network(e.to_string()) diff --git a/ant-core/src/data/mod.rs b/ant-core/src/data/mod.rs index 97a7daf7..382be964 100644 --- a/ant-core/src/data/mod.rs +++ b/ant-core/src/data/mod.rs @@ -12,11 +12,13 @@ pub use client::{Client, ClientConfig}; pub use error::{Error, Result}; pub use network::Network; -// Re-export LocalDevnet from its new home in the node module +// LocalDevnet (and the optional node-side dep it pulls in) is gated behind +// the `devnet` feature. Default builds of ant-core do not link ant-node. +#[cfg(feature = "devnet")] pub use crate::node::devnet::LocalDevnet; -// Re-export commonly used types from ant-node -pub use ant_node::client::{compute_address, DataChunk, XorName}; +// Re-export commonly used types from the wire protocol crate. +pub use ant_protocol::{compute_address, DataChunk, XorName}; // Re-export client data types pub use client::batch::{finalize_batch_payment, PaidChunk, PaymentIntent, PreparedChunk}; @@ -33,13 +35,16 @@ pub use client::merkle::{ // Re-export self-encryption types 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, IPDiversityConfig, MultiAddr, NodeMode, P2PNode}; -pub use ant_node::devnet::DevnetManifest; +// Re-export networking types needed by CLI for P2P node creation. The +// devnet manifest types live in ant-protocol because both the node +// (writer) and the CLI (reader) need them; they are always available +// regardless of the `devnet` feature. +pub use ant_protocol::transport::{ + CoreNodeConfig, IPDiversityConfig, MultiAddr, NodeMode, P2PNode, +}; +pub use ant_protocol::{DevnetManifest, MAX_CHUNK_SIZE, MAX_WIRE_MESSAGE_SIZE}; // Re-export EVM types needed by CLI for wallet and network setup -pub use evmlib::common::{Address as EvmAddress, U256}; -pub use evmlib::wallet::Wallet; -pub use evmlib::CustomNetwork; -pub use evmlib::Network as EvmNetwork; +pub use ant_protocol::evm::{ + Address as EvmAddress, CustomNetwork, Network as EvmNetwork, Wallet, U256, +}; diff --git a/ant-core/src/data/network.rs b/ant-core/src/data/network.rs index 76da7c7b..dc370ef0 100644 --- a/ant-core/src/data/network.rs +++ b/ant-core/src/data/network.rs @@ -4,8 +4,10 @@ //! for the client library. use crate::data::error::{Error, Result}; -use ant_node::ant_protocol::MAX_WIRE_MESSAGE_SIZE; -use ant_node::core::{CoreNodeConfig, IPDiversityConfig, MultiAddr, NodeMode, P2PNode, PeerId}; +use ant_protocol::transport::{ + CoreNodeConfig, IPDiversityConfig, MultiAddr, NodeMode, P2PNode, PeerId, +}; +use ant_protocol::MAX_WIRE_MESSAGE_SIZE; use std::net::SocketAddr; use std::sync::Arc; diff --git a/ant-core/src/node/devnet.rs b/ant-core/src/node/devnet.rs index 9d1f0124..969fc262 100644 --- a/ant-core/src/node/devnet.rs +++ b/ant-core/src/node/devnet.rs @@ -6,11 +6,11 @@ use crate::data::client::ClientConfig; use crate::data::error::{Error, Result}; use crate::data::Client; -use ant_node::core::MultiAddr; -use ant_node::devnet::{Devnet, DevnetConfig, DevnetEvmInfo, DevnetManifest}; -use evmlib::testnet::Testnet; -use evmlib::wallet::Wallet; -use evmlib::Network as EvmNetwork; +use ant_node::devnet::{Devnet, DevnetConfig}; +use ant_protocol::evm::testnet::Testnet; +use ant_protocol::evm::{Network as EvmNetwork, Wallet}; +use ant_protocol::transport::MultiAddr; +use ant_protocol::{DevnetEvmInfo, DevnetManifest}; use std::path::Path; use std::time::SystemTime; use tracing::info; diff --git a/ant-core/src/node/mod.rs b/ant-core/src/node/mod.rs index 63c3eaa2..b2b3ec57 100644 --- a/ant-core/src/node/mod.rs +++ b/ant-core/src/node/mod.rs @@ -1,5 +1,8 @@ pub mod binary; pub mod daemon; +// `LocalDevnet` wraps `ant_node::devnet::Devnet`. Gated behind `devnet` +// so default builds of ant-core don't link ant-node at all. +#[cfg(feature = "devnet")] pub mod devnet; pub mod events; pub mod process; diff --git a/ant-core/src/update.rs b/ant-core/src/update.rs index 071fdcef..10bee1ec 100644 --- a/ant-core/src/update.rs +++ b/ant-core/src/update.rs @@ -1,7 +1,7 @@ use std::path::{Path, PathBuf}; +use ant_protocol::pqc::api::{ml_dsa_65, MlDsaPublicKey, MlDsaSignature, MlDsaVariant}; use futures_util::StreamExt; -use saorsa_pqc::api::sig::{ml_dsa_65, MlDsaPublicKey, MlDsaSignature, MlDsaVariant}; use serde::{Deserialize, Serialize}; use crate::error::{Error, Result}; diff --git a/ant-core/tests/e2e_file.rs b/ant-core/tests/e2e_file.rs index fb068972..7106de82 100644 --- a/ant-core/tests/e2e_file.rs +++ b/ant-core/tests/e2e_file.rs @@ -5,7 +5,7 @@ mod support; use ant_core::data::{compute_address, Client, ExternalPaymentInfo, Visibility}; -use evmlib::common::{QuoteHash, TxHash}; +use ant_protocol::evm::{QuoteHash, TxHash}; use serial_test::serial; use std::collections::HashMap; use std::io::Write; diff --git a/ant-core/tests/e2e_payment.rs b/ant-core/tests/e2e_payment.rs index c2051cfa..3275c348 100644 --- a/ant-core/tests/e2e_payment.rs +++ b/ant-core/tests/e2e_payment.rs @@ -292,7 +292,7 @@ async fn test_chunk_put_fails_with_insufficient_funds() { // Create a wallet with zero balance by using a random private key // (not the Anvil-funded default key) let evm_network = testnet.evm_network().clone(); - let empty_wallet = evmlib::wallet::Wallet::new_from_private_key( + let empty_wallet = ant_protocol::evm::Wallet::new_from_private_key( evm_network, "0x0000000000000000000000000000000000000000000000000000000000000001", ) diff --git a/ant-core/tests/e2e_security.rs b/ant-core/tests/e2e_security.rs index 6ca89b00..888b418c 100644 --- a/ant-core/tests/e2e_security.rs +++ b/ant-core/tests/e2e_security.rs @@ -8,11 +8,10 @@ mod support; use ant_core::data::{compute_address, Client}; -use ant_node::core::PeerId; -use ant_node::payment::{serialize_single_node_proof, PaymentProof, SingleNodePayment}; +use ant_protocol::evm::{Amount, EncodedPeerId, ProofOfPayment, RewardsAddress, TxHash}; +use ant_protocol::payment::{serialize_single_node_proof, PaymentProof, SingleNodePayment}; +use ant_protocol::transport::PeerId; use bytes::Bytes; -use evmlib::common::{Amount, TxHash}; -use evmlib::{EncodedPeerId, ProofOfPayment, RewardsAddress}; use serial_test::serial; use std::sync::Arc; use support::{test_client_config, MiniTestnet, DEFAULT_NODE_COUNT, MEDIAN_QUOTE_INDEX}; diff --git a/ant-core/tests/e2e_upload_costs.rs b/ant-core/tests/e2e_upload_costs.rs index e729a0e0..a4b7c498 100644 --- a/ant-core/tests/e2e_upload_costs.rs +++ b/ant-core/tests/e2e_upload_costs.rs @@ -69,7 +69,7 @@ struct CostResult { /// Measure ANT and gas cost for a single upload. async fn measure_upload_cost( client: &Client, - wallet: &evmlib::wallet::Wallet, + wallet: &ant_protocol::evm::Wallet, path: &Path, mode: PaymentMode, file_size_mb: u64, diff --git a/ant-core/tests/support/mod.rs b/ant-core/tests/support/mod.rs index 6cc8734b..45d514e9 100644 --- a/ant-core/tests/support/mod.rs +++ b/ant-core/tests/support/mod.rs @@ -16,20 +16,21 @@ )] use ant_core::data::ClientConfig; -use ant_node::ant_protocol::MAX_WIRE_MESSAGE_SIZE; -use ant_node::core::{ - CoreNodeConfig, IPDiversityConfig, MlDsa65, MultiAddr, NodeIdentity, P2PEvent, P2PNode, -}; +// Node-internal types (test harness needs to *be* a node) — direct +// ant-node import is correct here. ant-node is a dev-dep so this is +// only linked into test binaries. use ant_node::payment::{ EvmVerifierConfig, PaymentVerifier, PaymentVerifierConfig, QuoteGenerator, QuotingMetricsTracker, }; use ant_node::storage::{AntProtocol, LmdbStorage, LmdbStorageConfig}; -use ant_node::CLOSE_GROUP_SIZE; -use evmlib::testnet::Testnet; -use evmlib::wallet::Wallet; -use evmlib::Network as EvmNetwork; -use evmlib::RewardsAddress; +// Wire / transport / EVM types: route through ant-protocol so the test +// harness exercises the same surface the client does. +use ant_protocol::evm::{testnet::Testnet, Network as EvmNetwork, RewardsAddress, Wallet}; +use ant_protocol::transport::{ + CoreNodeConfig, IPDiversityConfig, MlDsa65, MultiAddr, NodeIdentity, P2PEvent, P2PNode, +}; +use ant_protocol::{CLOSE_GROUP_SIZE, MAX_WIRE_MESSAGE_SIZE}; use rand::Rng; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::sync::Arc; @@ -199,7 +200,7 @@ impl MiniTestnet { // Approve token spend for the unified payment vault contract let vault_address = evm_network.payment_vault_address(); wallet - .approve_to_spend_tokens(*vault_address, evmlib::common::U256::MAX) + .approve_to_spend_tokens(*vault_address, ant_protocol::evm::U256::MAX) .await .expect("approve payment vault token spend"); @@ -288,6 +289,10 @@ impl MiniTestnet { local_rewards_address: rewards_address, }; let payment_verifier = Arc::new(PaymentVerifier::new(payment_config)); + // Wire the P2P node into the verifier so the merkle pay-yourself + // closeness check can do its DHT lookup. Without this, the + // verifier fail-closes on every merkle payment (PR #77 defense). + payment_verifier.attach_p2p_node(Arc::clone(&node)); let metrics_tracker = QuotingMetricsTracker::new(TEST_MAX_RECORDS); let mut quote_generator = QuoteGenerator::new(rewards_address, metrics_tracker); @@ -295,11 +300,11 @@ impl MiniTestnet { let pub_key_bytes = identity.public_key().as_bytes().to_vec(); let sk_bytes = identity.secret_key_bytes().to_vec(); let sk = { - use saorsa_pqc::pqc::types::MlDsaSecretKey; + use ant_protocol::pqc::ops::MlDsaSecretKey; MlDsaSecretKey::from_bytes(&sk_bytes).expect("deserialize ML-DSA-65 secret key") }; quote_generator.set_signer(pub_key_bytes, move |msg| { - use saorsa_pqc::pqc::MlDsaOperations; + use ant_protocol::pqc::ops::MlDsaOperations; let ml_dsa = MlDsa65::new(); ml_dsa .sign(&sk, msg) @@ -329,7 +334,7 @@ impl MiniTestnet { let node = Arc::clone(&handler_node); let topic_clone = topic.clone(); tokio::spawn(async move { - if topic_clone != ant_node::CHUNK_PROTOCOL_ID { + if topic_clone != ant_protocol::CHUNK_PROTOCOL_ID { return; } match protocol.try_handle_request(&data).await {