From e68de2b985e02555352e4385e37ab4ff5438abf3 Mon Sep 17 00:00:00 2001 From: Warm Beer Date: Thu, 26 Feb 2026 19:30:24 +0100 Subject: [PATCH 01/12] feat: wire app-level peer authentication from saorsa-core Pass NodeIdentity to saorsa-core's NodeConfig for message signing. Fix peer ID type conversions to use NodeId hex strings consistently. - Set core_config.node_identity in NodeBuilder and Devnet - Use NodeId::to_hex() for peer_id instead of node_id_to_peer_id - Validate target peer as hex NodeId in chunk_protocol - Fix pick_target_peer to clone peer_id String correctly Co-Authored-By: Claude Opus 4.6 --- src/client/chunk_protocol.rs | 6 ++---- src/devnet.rs | 8 ++++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/client/chunk_protocol.rs b/src/client/chunk_protocol.rs index abfe08d4..b0fe8da7 100644 --- a/src/client/chunk_protocol.rs +++ b/src/client/chunk_protocol.rs @@ -41,9 +41,7 @@ pub async fn send_and_await_chunk_response( // Subscribe before sending so we don't miss the response let mut events = node.subscribe_events(); - let target_peer_id = *target_peer; - - node.send_message(&target_peer_id, CHUNK_PROTOCOL_ID, message_bytes) + node.send_message(target_peer, CHUNK_PROTOCOL_ID, message_bytes) .await .map_err(|e| send_error(e.to_string()))?; @@ -56,7 +54,7 @@ pub async fn send_and_await_chunk_response( topic, source: Some(source), data, - })) if topic == CHUNK_PROTOCOL_ID && source == target_peer_id => { + })) if topic == CHUNK_PROTOCOL_ID && source == target_peer => { let response = match ChunkMessage::decode(&data) { Ok(r) => r, Err(e) => { diff --git a/src/devnet.rs b/src/devnet.rs index f2491d92..09392edf 100644 --- a/src/devnet.rs +++ b/src/devnet.rs @@ -620,6 +620,14 @@ impl Devnet { let mut core_config = CoreNodeConfig::new() .map_err(|e| DevnetError::Core(format!("Failed to create core config: {e}")))?; + // Load the node identity for app-level message signing + let identity = NodeIdentity::load_from_file( + &node.data_dir.join(crate::config::NODE_IDENTITY_FILENAME), + ) + .await + .map_err(|e| DevnetError::Core(format!("Failed to load node identity: {e}")))?; + + core_config.node_identity = Some(Arc::new(identity)); core_config.listen_addr = node.address; core_config.listen_addrs = vec![node.address]; core_config.enable_ipv6 = false; From 1e0ca04e732342fe13a173fd06410af27fdb06be Mon Sep 17 00:00:00 2001 From: Warm Beer Date: Fri, 27 Feb 2026 13:21:42 +0100 Subject: [PATCH 02/12] refactor: align naming with saorsa-core multi-channel rename MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update for saorsa-core 817e193 which decoupled channel IDs from peer IDs. Rename transport_peer_id() → channel_id() at call sites, clarify misleading names: DevnetNode.node_id → label (it's a human label, not a NodeId), node_id_to_peer_id() → node_id_to_hex() (it's just hex encoding), and target_peer_id → target_channel_id where the value comes from channel_id(). Co-Authored-By: Claude Opus 4.6 --- src/devnet.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/devnet.rs b/src/devnet.rs index 09392edf..222a0940 100644 --- a/src/devnet.rs +++ b/src/devnet.rs @@ -291,7 +291,7 @@ pub enum NodeState { #[allow(dead_code)] pub struct DevnetNode { index: usize, - node_id: String, + label: String, peer_id: String, port: u16, address: SocketAddr, @@ -532,7 +532,7 @@ impl Devnet { let identity = NodeIdentity::generate() .map_err(|e| DevnetError::Core(format!("Failed to generate node identity: {e}")))?; let peer_id = identity.peer_id().to_hex(); - let node_id = format!("devnet_node_{index}"); + let label = format!("devnet_node_{index}"); let data_dir = self.config.data_dir.join(NODES_SUBDIR).join(&peer_id); tokio::fs::create_dir_all(&data_dir).await?; @@ -546,7 +546,7 @@ impl Devnet { Ok(DevnetNode { index, - node_id, + label, peer_id, port, address, From b917b0aa1df179a3a75527de9228234d0292f0e0 Mon Sep 17 00:00:00 2001 From: Warm Beer Date: Sat, 28 Feb 2026 00:02:05 +0100 Subject: [PATCH 03/12] refactor: update for saorsa-core NodeId to PeerId rename Align with saorsa-core's PeerId struct rename: update imports from NodeId to PeerId, rename node_id_to_hex to peer_id_to_hex, and change .node_id() calls to .peer_id() throughout. Co-Authored-By: Claude Opus 4.6 --- Cargo.toml | 3 +++ tests/e2e/testnet.rs | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index a9779ef6..66b4bd83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -177,3 +177,6 @@ assets = [ [package.metadata.generate-rpm.requires] # Runtime dependencies auto-detected + +[patch.crates-io] +saorsa-core = { path = "../saorsa-core" } diff --git a/tests/e2e/testnet.rs b/tests/e2e/testnet.rs index c153b653..cc0f4d4d 100644 --- a/tests/e2e/testnet.rs +++ b/tests/e2e/testnet.rs @@ -1285,6 +1285,14 @@ impl TestNetwork { // Override the transport-layer message size to accommodate max-size // chunks (4 MiB payload + serialization overhead = 5 MiB wire). core_config.max_message_size = Some(saorsa_node::ant_protocol::MAX_WIRE_MESSAGE_SIZE); + // Generate a node identity so auto identity announce works on connect. + let identity = NodeIdentity::generate().map_err(|e| { + TestnetError::Core(format!( + "Failed to generate identity for node {}: {e}", + node.index + )) + })?; + core_config.node_identity = Some(Arc::new(identity)); // Allow localhost peers in DHT routing for test environments // This prevents diversity filters from excluding peers on 127.0.0.1 From 23d12109f8ff2b527a91a4a762a6245060630891 Mon Sep 17 00:00:00 2001 From: Warm Beer Date: Sat, 28 Feb 2026 23:23:49 +0100 Subject: [PATCH 04/12] refactor: switch content hashing from SHA256 to BLAKE3 Replace SHA256 with BLAKE3 for chunk content-addressing across the codebase. Update all relevant functions, comments, and tests to reflect the change. Adjust error handling and PeerId type usage for consistency. --- Cargo.toml | 4 +- saorsa-transport-overview.png | Bin 0 -> 156739 bytes src/ant_protocol/chunk.rs | 4 +- src/client/chunk_protocol.rs | 2 +- src/client/data_types.rs | 31 ++--- src/client/mod.rs | 2 +- src/client/quantum.rs | 6 +- src/storage/handler.rs | 2 +- src/storage/lmdb.rs | 8 +- src/upgrade/rollout.rs | 28 ++-- tests/e2e/data_types/chunk.rs | 10 +- tests/e2e/data_types/graph_entry.rs | 7 +- tests/e2e/data_types/pointer.rs | 8 +- tests/e2e/data_types/scratchpad.rs | 8 +- tests/e2e/get_latency_bench.rs | 202 ++++++++++++++++++++++++++++ tests/e2e/integration_tests.rs | 2 +- tests/e2e/live_testnet.rs | 2 +- tests/e2e/testnet.rs | 15 +-- 18 files changed, 260 insertions(+), 81 deletions(-) create mode 100644 saorsa-transport-overview.png create mode 100644 tests/e2e/get_latency_bench.rs diff --git a/Cargo.toml b/Cargo.toml index 66b4bd83..a1f69eb3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,7 +52,9 @@ heed = "0.22" # Migration: Decrypt ant-node data (read-only) aes-gcm-siv = "0.11" hkdf = "0.12" -sha2 = "0.10" + +# Hashing (aligned with saorsa-core) +blake3 = "1" # Async runtime tokio = { version = "1.35", features = ["full", "signal"] } diff --git a/saorsa-transport-overview.png b/saorsa-transport-overview.png new file mode 100644 index 0000000000000000000000000000000000000000..81a79dde6889128b51ac3e4c71dcf13574f0f8da GIT binary patch literal 156739 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, diff --git a/src/client/chunk_protocol.rs b/src/client/chunk_protocol.rs index b0fe8da7..369ca031 100644 --- a/src/client/chunk_protocol.rs +++ b/src/client/chunk_protocol.rs @@ -54,7 +54,7 @@ pub async fn send_and_await_chunk_response( topic, source: Some(source), data, - })) if topic == CHUNK_PROTOCOL_ID && source == target_peer => { + })) if topic == CHUNK_PROTOCOL_ID && source.as_ref() == Some(target_peer) => { let response = match ChunkMessage::decode(&data) { Ok(r) => r, Err(e) => { diff --git a/src/client/data_types.rs b/src/client/data_types.rs index 0c205e9b..4d1912d0 100644 --- a/src/client/data_types.rs +++ b/src/client/data_types.rs @@ -2,20 +2,13 @@ //! //! This module provides the core data types for content-addressed chunk storage //! on the saorsa network. Chunks are immutable, content-addressed blobs where -//! the address is the SHA256 hash of the content. +//! the address is the BLAKE3 hash of the content. use bytes::Bytes; -use sha2::{Digest, Sha256}; - -/// Compute the content address (SHA256 hash) for the given data. +/// Compute the content address (BLAKE3 hash) for the given data. #[must_use] pub fn compute_address(content: &[u8]) -> XorName { - let mut hasher = Sha256::new(); - hasher.update(content); - let result = hasher.finalize(); - let mut address = [0u8; 32]; - address.copy_from_slice(&result); - address + *blake3::hash(content).as_bytes() } /// Compute the XOR distance between two 32-byte addresses. @@ -46,7 +39,7 @@ pub fn peer_id_to_xor_name(peer_id: &str) -> Option { /// A content-addressed identifier (32 bytes). /// -/// The address is computed as SHA256(content) for chunks, +/// The address is computed as BLAKE3(content) for chunks, /// ensuring content-addressed storage. pub type XorName = [u8; 32]; @@ -54,11 +47,11 @@ pub type XorName = [u8; 32]; /// /// Chunks are the fundamental storage unit in saorsa. They are: /// - **Immutable**: Content cannot be changed after storage -/// - **Content-addressed**: Address = SHA256(content) +/// - **Content-addressed**: Address = BLAKE3(content) /// - **Paid**: Storage requires EVM payment on Arbitrum #[derive(Debug, Clone)] pub struct DataChunk { - /// The content-addressed identifier (SHA256 of content). + /// The content-addressed identifier (BLAKE3 of content). pub address: XorName, /// The raw data content. pub content: Bytes, @@ -67,7 +60,7 @@ pub struct DataChunk { impl DataChunk { /// Create a new data chunk. /// - /// Note: This does NOT verify that address == SHA256(content). + /// Note: This does NOT verify that address == BLAKE3(content). /// Use `from_content` for automatic address computation. #[must_use] pub fn new(address: XorName, content: Bytes) -> Self { @@ -87,7 +80,7 @@ impl DataChunk { self.content.len() } - /// Verify that the address matches SHA256(content). + /// Verify that the address matches BLAKE3(content). #[must_use] pub fn verify(&self) -> bool { self.address == compute_address(&self.content) @@ -132,11 +125,11 @@ mod tests { let content = Bytes::from("hello world"); let chunk = DataChunk::from_content(content.clone()); - // SHA256 of "hello world" + // BLAKE3 of "hello world" let expected: [u8; 32] = [ - 0xb9, 0x4d, 0x27, 0xb9, 0x93, 0x4d, 0x3e, 0x08, 0xa5, 0x2e, 0x52, 0xd7, 0xda, 0x7d, - 0xab, 0xfa, 0xc4, 0x84, 0xef, 0xe3, 0x7a, 0x53, 0x80, 0xee, 0x90, 0x88, 0xf7, 0xac, - 0xe2, 0xef, 0xcd, 0xe9, + 0xd7, 0x49, 0x81, 0xef, 0xa7, 0x0a, 0x0c, 0x88, 0x0b, 0x8d, 0x8c, 0x19, 0x85, 0xd0, + 0x75, 0xdb, 0xcb, 0xf6, 0x79, 0xb9, 0x9a, 0x5f, 0x99, 0x14, 0xe5, 0xaa, 0xf9, 0x6b, + 0x83, 0x1a, 0x9e, 0x24, ]; assert_eq!(chunk.address, expected); diff --git a/src/client/mod.rs b/src/client/mod.rs index 3604c6c1..d161f9c2 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -7,7 +7,7 @@ //! //! The chunk client provides: //! -//! 1. **Content-addressed storage**: Chunk address = SHA256(content) +//! 1. **Content-addressed storage**: Chunk address = BLAKE3(content) //! 2. **PQC security**: All data uses ML-KEM-768 and ML-DSA-65 //! 3. **EVM payment**: Chunks are paid for on Arbitrum network //! diff --git a/src/client/quantum.rs b/src/client/quantum.rs index 468c4b4e..98402e88 100644 --- a/src/client/quantum.rs +++ b/src/client/quantum.rs @@ -6,7 +6,7 @@ //! ## Data Model //! //! Chunks are the only data type supported: -//! - **Content-addressed**: Address = SHA256(content) +//! - **Content-addressed**: Address = BLAKE3(content) //! - **Immutable**: Once stored, content cannot change //! - **Paid**: Storage requires EVM payment on Arbitrum when a wallet is configured; //! devnets with EVM disabled accept unpaid puts @@ -77,7 +77,7 @@ impl Default for QuantumConfig { /// /// ## Chunk Storage Model /// -/// Chunks are content-addressed: the address is the SHA256 hash of the content. +/// Chunks are content-addressed: the address is the BLAKE3 hash of the content. /// This ensures data integrity - if the content matches the address, the data /// is authentic. When a wallet is configured, chunk storage requires EVM payment /// on Arbitrum. Without a wallet, chunks can be stored on devnets with EVM disabled. @@ -128,7 +128,7 @@ impl QuantumClient { /// /// # Arguments /// - /// * `address` - The `XorName` address of the chunk (SHA256 of content) + /// * `address` - The `XorName` address of the chunk (BLAKE3 of content) /// /// # Returns /// diff --git a/src/storage/handler.rs b/src/storage/handler.rs index 2c8e58ff..55b7f188 100644 --- a/src/storage/handler.rs +++ b/src/storage/handler.rs @@ -141,7 +141,7 @@ impl AntProtocol { }); } - // 2. Verify content address matches SHA256(content) + // 2. Verify content address matches BLAKE3(content) let computed = crate::client::compute_address(&request.content); if computed != address { return ChunkPutResponse::Error(ProtocolError::AddressMismatch { diff --git a/src/storage/lmdb.rs b/src/storage/lmdb.rs index 2d16e7f6..c7b93e6c 100644 --- a/src/storage/lmdb.rs +++ b/src/storage/lmdb.rs @@ -151,7 +151,7 @@ impl LmdbStorage { /// /// # Arguments /// - /// * `address` - Content address (should be SHA256 of content) + /// * `address` - Content address (should be BLAKE3 of content) /// * `content` - Chunk data /// /// # Returns @@ -397,7 +397,7 @@ impl LmdbStorage { Ok(entries as u64) } - /// Compute content address (SHA256 hash). + /// Compute content address (BLAKE3 hash). #[must_use] pub fn compute_address(content: &[u8]) -> XorName { crate::client::compute_address(content) @@ -551,11 +551,11 @@ mod tests { #[test] fn test_compute_address() { - // Known SHA256 hash of "hello world" + // Known BLAKE3 hash of "hello world" let content = b"hello world"; let address = LmdbStorage::compute_address(content); - let expected_hex = "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"; + let expected_hex = "d74981efa70a0c880b8d8c1985d075dbcbf679b99a5f9914e5aaf96b831a9e24"; assert_eq!(hex::encode(address), expected_hex); } diff --git a/src/upgrade/rollout.rs b/src/upgrade/rollout.rs index 0d2509f5..ef680fd0 100644 --- a/src/upgrade/rollout.rs +++ b/src/upgrade/rollout.rs @@ -23,7 +23,6 @@ //! - Nodes are evenly distributed across the rollout window //! - The same node always upgrades at the same point in the window -use sha2::{Digest, Sha256}; use std::time::Duration; use tracing::debug; @@ -45,12 +44,7 @@ impl StagedRollout { /// * `max_delay_hours` - Maximum rollout window (default: 24 hours) #[must_use] pub fn new(node_id: &[u8], max_delay_hours: u64) -> Self { - let mut hasher = Sha256::new(); - hasher.update(node_id); - let hash_result = hasher.finalize(); - - let mut node_id_hash = [0u8; 32]; - node_id_hash.copy_from_slice(&hash_result); + let node_id_hash = *blake3::hash(node_id).as_bytes(); Self { max_delay_hours, @@ -133,20 +127,20 @@ impl StagedRollout { } // Include version in the hash for version-specific delays - let mut hasher = Sha256::new(); - hasher.update(self.node_id_hash); + let mut hasher = blake3::Hasher::new(); + hasher.update(&self.node_id_hash); hasher.update(version.to_string().as_bytes()); let hash_result = hasher.finalize(); let hash_value = u64::from_le_bytes([ - hash_result[0], - hash_result[1], - hash_result[2], - hash_result[3], - hash_result[4], - hash_result[5], - hash_result[6], - hash_result[7], + hash_result.as_bytes()[0], + hash_result.as_bytes()[1], + hash_result.as_bytes()[2], + hash_result.as_bytes()[3], + hash_result.as_bytes()[4], + hash_result.as_bytes()[5], + hash_result.as_bytes()[6], + hash_result.as_bytes()[7], ]); let max_delay_secs = self.max_delay_hours * 3600; diff --git a/tests/e2e/data_types/chunk.rs b/tests/e2e/data_types/chunk.rs index b495ac05..8f25ebd3 100644 --- a/tests/e2e/data_types/chunk.rs +++ b/tests/e2e/data_types/chunk.rs @@ -1,7 +1,7 @@ //! Chunk data type E2E tests. //! //! Chunks are immutable, content-addressed data blocks (up to 4MB). -//! The address is derived from the content hash (SHA256 -> `XorName`). +//! The address is derived from the content hash (BLAKE3 -> `XorName`). //! //! ## Test Coverage //! @@ -50,7 +50,7 @@ impl ChunkTestFixture { } } - /// Compute content address for data (SHA256 hash). + /// Compute content address for data (BLAKE3 hash). #[must_use] pub fn compute_address(data: &[u8]) -> [u8; 32] { saorsa_node::compute_address(data) @@ -101,10 +101,10 @@ mod tests { #[test] fn test_empty_data_address() { let addr = ChunkTestFixture::compute_address(&[]); - // SHA256 of empty string is well-known + // BLAKE3 of empty string is well-known assert_eq!( hex::encode(addr), - "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262" ); } @@ -152,7 +152,7 @@ mod tests { .await .expect("Failed to store chunk"); - // Verify the address is a valid SHA256 hash + // Verify the address is a valid BLAKE3 hash let expected_address = ChunkTestFixture::compute_address(&fixture.small); assert_eq!( address, expected_address, diff --git a/tests/e2e/data_types/graph_entry.rs b/tests/e2e/data_types/graph_entry.rs index 810e7d49..2653b712 100644 --- a/tests/e2e/data_types/graph_entry.rs +++ b/tests/e2e/data_types/graph_entry.rs @@ -85,17 +85,14 @@ impl GraphEntryTestFixture { /// Compute graph entry address from owner and content. #[must_use] pub fn compute_address(owner: &[u8; 32], content: &[u8], parents: &[[u8; 32]]) -> [u8; 32] { - use sha2::{Digest, Sha256}; - let mut hasher = Sha256::new(); + let mut hasher = blake3::Hasher::new(); hasher.update(b"graph_entry:"); hasher.update(owner); hasher.update(content); for parent in parents { hasher.update(parent); } - let hash = hasher.finalize(); - let mut address = [0u8; 32]; - address.copy_from_slice(&hash); + let address = *hasher.finalize().as_bytes(); address } } diff --git a/tests/e2e/data_types/pointer.rs b/tests/e2e/data_types/pointer.rs index a46e1742..93f043ce 100644 --- a/tests/e2e/data_types/pointer.rs +++ b/tests/e2e/data_types/pointer.rs @@ -80,14 +80,10 @@ impl PointerTestFixture { /// Compute pointer address from owner public key. #[must_use] pub fn compute_address(owner: &[u8; 32]) -> [u8; 32] { - use sha2::{Digest, Sha256}; - let mut hasher = Sha256::new(); + let mut hasher = blake3::Hasher::new(); hasher.update(b"pointer:"); hasher.update(owner); - let hash = hasher.finalize(); - let mut address = [0u8; 32]; - address.copy_from_slice(&hash); - address + *hasher.finalize().as_bytes() } } diff --git a/tests/e2e/data_types/scratchpad.rs b/tests/e2e/data_types/scratchpad.rs index 0949908a..0a332444 100644 --- a/tests/e2e/data_types/scratchpad.rs +++ b/tests/e2e/data_types/scratchpad.rs @@ -64,14 +64,10 @@ impl ScratchpadTestFixture { /// Compute scratchpad address from owner public key. #[must_use] pub fn compute_address(owner: &[u8; 32]) -> [u8; 32] { - use sha2::{Digest, Sha256}; - let mut hasher = Sha256::new(); + let mut hasher = blake3::Hasher::new(); hasher.update(b"scratchpad:"); hasher.update(owner); - let hash = hasher.finalize(); - let mut address = [0u8; 32]; - address.copy_from_slice(&hash); - address + *hasher.finalize().as_bytes() } } diff --git a/tests/e2e/get_latency_bench.rs b/tests/e2e/get_latency_bench.rs new file mode 100644 index 00000000..40af89d7 --- /dev/null +++ b/tests/e2e/get_latency_bench.rs @@ -0,0 +1,202 @@ +//! Benchmark: measure per-GET latency on a 25-node testnet. +//! +//! Stores one chunk via `QuantumClient`, then retrieves it many times, +//! printing timing for each GET to identify outliers. +//! +//! Run with: +//! ```sh +//! cargo test --test e2e get_latency_bench -- --ignored --nocapture +//! ``` + +#![allow(clippy::unwrap_used, clippy::expect_used)] + +use bytes::Bytes; +use saorsa_core::P2PNode; +use saorsa_node::client::{QuantumClient, QuantumConfig}; +use std::sync::Arc; +use std::time::{Duration, Instant}; + +use crate::{TestHarness, TestNetworkConfig}; + +/// Number of sequential GETs to run after PUT. +const GET_ITERATIONS: usize = 50; + +/// Client timeout (seconds). +const CLIENT_TIMEOUT_SECS: u64 = 30; + +/// Number of closest peers to query (matches QuantumClient::CLOSE_GROUP_SIZE). +const CLOSE_GROUP_SIZE: usize = 8; + +/// Benchmark chunk GET latency on a 25-node testnet. +#[tokio::test(flavor = "multi_thread")] +#[ignore = "Benchmark - run with --ignored --nocapture"] +async fn get_latency_bench() { + let harness = TestHarness::setup_with_config(TestNetworkConfig::default()) + .await + .expect("Failed to setup 25-node testnet"); + + let node = harness.node(5).expect("Node 5 should exist"); + let config = QuantumConfig { + timeout_secs: CLIENT_TIMEOUT_SECS, + replica_count: 1, + encrypt_data: false, + }; + let client = QuantumClient::new(config).with_node(Arc::clone(&node)); + + // --- PUT --- + let content = Bytes::from(vec![0xABu8; 1024]); + let put_start = Instant::now(); + let address = client + .put_chunk(content.clone()) + .await + .expect("put_chunk failed"); + let put_elapsed = put_start.elapsed(); + + println!("\n===== GET LATENCY BENCHMARK (25 nodes, 1 KB chunk) ====="); + println!("PUT took {put_elapsed:?}"); + println!("Chunk address: {}", hex::encode(address)); + println!("Running {GET_ITERATIONS} sequential GETs…\n"); + println!("{:>4} {:>12}", "#", "latency"); + println!("{}", "-".repeat(20)); + + let mut latencies = Vec::with_capacity(GET_ITERATIONS); + + for i in 0..GET_ITERATIONS { + let start = Instant::now(); + let result = client.get_chunk(&address).await.expect("get_chunk failed"); + let elapsed = start.elapsed(); + + assert!(result.is_some(), "Chunk should be found (iteration {i})"); + let chunk = result.unwrap(); + assert_eq!(chunk.content.as_ref(), &[0xABu8; 1024]); + + println!("{:>4} {:>12?}", i, elapsed); + latencies.push(elapsed); + } + + print_stats(&latencies); + + drop(client); + drop(node); + harness + .teardown() + .await + .expect("Failed to teardown harness"); +} + +/// Breakdown: compare local DHT lookup (no network) vs full network lookup +/// vs full GET to identify where the linear growth comes from. +#[tokio::test(flavor = "multi_thread")] +#[ignore = "Benchmark - run with --ignored --nocapture"] +async fn get_latency_breakdown() { + let harness = TestHarness::setup_with_config(TestNetworkConfig::default()) + .await + .expect("Failed to setup 25-node testnet"); + + let node = harness.node(5).expect("Node 5 should exist"); + let config = QuantumConfig { + timeout_secs: CLIENT_TIMEOUT_SECS, + replica_count: 1, + encrypt_data: false, + }; + let client = QuantumClient::new(config).with_node(Arc::clone(&node)); + + // --- PUT --- + let content = Bytes::from(vec![0xABu8; 1024]); + let address = client + .put_chunk(content.clone()) + .await + .expect("put_chunk failed"); + + println!("\n===== GET LATENCY BREAKDOWN (25 nodes, 1 KB chunk) ====="); + println!("Chunk address: {}", hex::encode(address)); + println!("Running {GET_ITERATIONS} sequential GETs with breakdown…\n"); + println!( + "{:>4} {:>12} {:>12} {:>12} {:>10}", + "#", "dht_local", "dht_network", "get_chunk", "bg_events" + ); + println!("{}", "-".repeat(60)); + + let mut totals = Vec::with_capacity(GET_ITERATIONS); + + for i in 0..GET_ITERATIONS { + let bg_events = drain_pending_events(&node); + + // Phase 1: Local-only DHT lookup (no network RPCs) + let local_start = Instant::now(); + let _local_closest = node + .dht() + .find_closest_nodes_local(&address, CLOSE_GROUP_SIZE) + .await; + let local_dur = local_start.elapsed(); + + // Phase 2: Full network DHT lookup (iterative Kademlia) + let net_start = Instant::now(); + let _net_closest = node + .dht() + .find_closest_nodes(&address, CLOSE_GROUP_SIZE) + .await + .expect("DHT network lookup failed"); + let net_dur = net_start.elapsed(); + + // Phase 3: Full client GET (includes its own DHT lookup + send + wait) + let get_start = Instant::now(); + let result = client.get_chunk(&address).await.expect("get_chunk failed"); + let get_dur = get_start.elapsed(); + + assert!(result.is_some(), "Chunk should be found (iteration {i})"); + + println!( + "{:>4} {:>12?} {:>12?} {:>12?} {:>10}", + i, local_dur, net_dur, get_dur, bg_events + ); + totals.push(get_dur); + } + + print_stats(&totals); + + drop(client); + drop(node); + harness + .teardown() + .await + .expect("Failed to teardown harness"); +} + +/// Drain all pending events from the broadcast channel without blocking. +fn drain_pending_events(node: &P2PNode) -> usize { + let mut rx = node.subscribe_events(); + let mut count = 0; + loop { + match rx.try_recv() { + Ok(_) => count += 1, + Err(_) => break, + } + } + count +} + +fn print_stats(latencies: &[Duration]) { + let mut sorted = latencies.to_vec(); + sorted.sort(); + let total: Duration = sorted.iter().sum(); + let min = sorted[0]; + let max = sorted[sorted.len() - 1]; + let mean = total / sorted.len() as u32; + let median = sorted[sorted.len() / 2]; + let p90 = sorted[(sorted.len() as f64 * 0.9) as usize]; + let p99 = sorted[(sorted.len() as f64 * 0.99) as usize]; + + let outlier_threshold = median * 3; + let outlier_count = sorted.iter().filter(|d| **d > outlier_threshold).count(); + + println!("\n===== STATS (get_chunk) ====="); + println!(" min: {min:?}"); + println!(" max: {max:?}"); + println!(" mean: {mean:?}"); + println!(" median: {median:?}"); + println!(" p90: {p90:?}"); + println!(" p99: {p99:?}"); + println!(" outliers: {outlier_count} (> 3x median = {outlier_threshold:?})"); + println!(" total: {total:?}"); +} diff --git a/tests/e2e/integration_tests.rs b/tests/e2e/integration_tests.rs index ae52a8c0..54058328 100644 --- a/tests/e2e/integration_tests.rs +++ b/tests/e2e/integration_tests.rs @@ -317,7 +317,7 @@ async fn test_quantum_client_chunk_round_trip() { .await .expect("QuantumClient::put_chunk_with_proof should succeed"); - // Address must equal SHA256(content) + // Address must equal BLAKE3(content) let expected_address = saorsa_node::compute_address(&content); assert_eq!( address, expected_address, diff --git a/tests/e2e/live_testnet.rs b/tests/e2e/live_testnet.rs index 35010e0e..87affe1b 100644 --- a/tests/e2e/live_testnet.rs +++ b/tests/e2e/live_testnet.rs @@ -65,7 +65,7 @@ async fn create_testnet_client() -> P2PNode { node } -/// Compute content address (SHA256 hash). +/// Compute content address (BLAKE3 hash). fn compute_address(data: &[u8]) -> XorName { saorsa_node::compute_address(data) } diff --git a/tests/e2e/testnet.rs b/tests/e2e/testnet.rs index cc0f4d4d..eb45585c 100644 --- a/tests/e2e/testnet.rs +++ b/tests/e2e/testnet.rs @@ -19,6 +19,7 @@ use evmlib::wallet::Wallet; use evmlib::Network as EvmNetwork; use futures::future::join_all; use rand::Rng; +use saorsa_core::identity::PeerId; use saorsa_core::{ identity::NodeIdentity, IPDiversityConfig as CoreDiversityConfig, NodeConfig as CoreNodeConfig, P2PEvent, P2PNode, @@ -595,7 +596,7 @@ impl TestNode { } /// Get the list of connected peer IDs. - pub async fn connected_peers(&self) -> Vec { + pub async fn connected_peers(&self) -> Vec { if let Some(ref node) = self.p2p_node { node.connected_peers().await } else { @@ -778,11 +779,10 @@ impl TestNode { /// sent, the response times out, or the remote peer reports an error. pub async fn store_chunk_on_peer( &self, - target_peer_id: &saorsa_core::identity::PeerId, + target_peer_id: &PeerId, data: &[u8], ) -> Result { let p2p = self.p2p_node.as_ref().ok_or(TestnetError::NodeNotRunning)?; - let target_peer_id = *target_peer_id; // Create PUT request WITHOUT payment proof (EVM disabled in tests) let address = Self::compute_chunk_address(data); @@ -802,7 +802,7 @@ impl TestNode { send_and_await_chunk_response( p2p, - &target_peer_id, + target_peer_id, message_bytes, request_id, timeout, @@ -877,11 +877,10 @@ impl TestNode { /// sent, the response times out, or the remote peer reports an error. pub async fn get_chunk_from_peer( &self, - target_peer_id: &saorsa_core::identity::PeerId, + target_peer_id: &PeerId, address: &XorName, ) -> Result> { let p2p = self.p2p_node.as_ref().ok_or(TestnetError::NodeNotRunning)?; - let target_peer_id = *target_peer_id; // Create GET request let request_id: u64 = rand::thread_rng().gen(); @@ -899,7 +898,7 @@ impl TestNode { send_and_await_chunk_response( p2p, - &target_peer_id, + target_peer_id, message_bytes, request_id, timeout, @@ -941,7 +940,7 @@ impl TestNode { .await } - /// Compute content address for chunk data (SHA256 hash). + /// Compute content address for chunk data (BLAKE3 hash). #[must_use] pub fn compute_chunk_address(data: &[u8]) -> XorName { saorsa_node::compute_address(data) From 67e1191329efd72bb349186286039b30acf5ab4f Mon Sep 17 00:00:00 2001 From: Warm Beer Date: Tue, 3 Mar 2026 10:50:07 +0100 Subject: [PATCH 05/12] refactor: simplify PeerId usage and remove redundant conversions Refactor across the codebase to directly use PeerId instances instead of hex-encoded strings where possible. Remove `peer_id_to_hex` utility and update related data structures, imports, and tests accordingly. --- src/devnet.rs | 12 ++++++++---- src/node.rs | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/devnet.rs b/src/devnet.rs index 222a0940..60cceaa1 100644 --- a/src/devnet.rs +++ b/src/devnet.rs @@ -14,7 +14,7 @@ use ant_evm::RewardsAddress; use evmlib::Network as EvmNetwork; use rand::Rng; use saorsa_core::identity::NodeIdentity; -use saorsa_core::{NodeConfig as CoreNodeConfig, P2PEvent, P2PNode}; +use saorsa_core::{NodeConfig as CoreNodeConfig, P2PEvent, P2PNode, PeerId}; use serde::{Deserialize, Serialize}; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::path::PathBuf; @@ -292,7 +292,7 @@ pub enum NodeState { pub struct DevnetNode { index: usize, label: String, - peer_id: String, + peer_id: PeerId, port: u16, address: SocketAddr, data_dir: PathBuf, @@ -531,9 +531,13 @@ impl Devnet { // Generate identity first so we can use peer_id as the directory name let identity = NodeIdentity::generate() .map_err(|e| DevnetError::Core(format!("Failed to generate node identity: {e}")))?; - let peer_id = identity.peer_id().to_hex(); + let peer_id = identity.peer_id().clone(); let label = format!("devnet_node_{index}"); - let data_dir = self.config.data_dir.join(NODES_SUBDIR).join(&peer_id); + let data_dir = self + .config + .data_dir + .join(NODES_SUBDIR) + .join(peer_id.to_hex()); tokio::fs::create_dir_all(&data_dir).await?; diff --git a/src/node.rs b/src/node.rs index 716f726f..c0806f6f 100644 --- a/src/node.rs +++ b/src/node.rs @@ -708,6 +708,7 @@ impl RunningNode { mod tests { use super::*; use crate::config::NODES_SUBDIR; + use saorsa_core::identity::PeerId; #[test] fn test_build_upgrade_monitor_staged_rollout_enabled() { From 5b5d9cd16520ad4320f03d0ba85a1f3f4939ffb3 Mon Sep 17 00:00:00 2001 From: Warm Beer Date: Wed, 4 Mar 2026 12:03:15 +0100 Subject: [PATCH 06/12] refactor: simplify PeerId handling by removing unnecessary clones Optimize by directly dereferencing PeerId instances instead of cloning, streamlining identity resolution and configuration setup. --- src/devnet.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devnet.rs b/src/devnet.rs index 60cceaa1..e75aae3b 100644 --- a/src/devnet.rs +++ b/src/devnet.rs @@ -531,7 +531,7 @@ impl Devnet { // Generate identity first so we can use peer_id as the directory name let identity = NodeIdentity::generate() .map_err(|e| DevnetError::Core(format!("Failed to generate node identity: {e}")))?; - let peer_id = identity.peer_id().clone(); + let peer_id = *identity.peer_id(); let label = format!("devnet_node_{index}"); let data_dir = self .config From 3a2c044c6fa64ed1c66f5f3c607e81aa4a1d0690 Mon Sep 17 00:00:00 2001 From: Warm Beer Date: Wed, 4 Mar 2026 16:54:39 +0100 Subject: [PATCH 07/12] fix: align with saorsa-core bootstrap_peers unification Update node.rs and testnet.rs to match saorsa-core's simplified bootstrap_peers field (removed bootstrap_peers_str, uses wait_for_peer_identity() for real PeerIds). Co-Authored-By: Claude Opus 4.6 --- src/node.rs | 2 +- tests/e2e/testnet.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/node.rs b/src/node.rs index c0806f6f..44a47f83 100644 --- a/src/node.rs +++ b/src/node.rs @@ -193,7 +193,7 @@ impl NodeBuilder { // Enable IPv6 if configured core_config.enable_ipv6 = matches!(config.ip_version, IpVersion::Ipv6 | IpVersion::Dual); - // Add bootstrap peers + // Add bootstrap peers. core_config.bootstrap_peers.clone_from(&config.bootstrap); // Forward max_message_size to the transport layer. diff --git a/tests/e2e/testnet.rs b/tests/e2e/testnet.rs index eb45585c..7460b74e 100644 --- a/tests/e2e/testnet.rs +++ b/tests/e2e/testnet.rs @@ -1109,7 +1109,6 @@ impl TestNetwork { let regular_count = self.config.node_count - self.config.bootstrap_count; info!("Starting {} regular nodes", regular_count); - // Get bootstrap addresses let bootstrap_addrs: Vec = self .nodes .get(0..self.config.bootstrap_count) From 78badbf49fb2ec6942bac694cf4a4fbc4e17049d Mon Sep 17 00:00:00 2001 From: Warm Beer Date: Fri, 6 Mar 2026 09:18:59 +0100 Subject: [PATCH 08/12] chore: bump saorsa-core to 0.13.0 in Cargo.toml --- Cargo.toml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a1f69eb3..c6c1bf87 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -178,7 +178,4 @@ assets = [ ] [package.metadata.generate-rpm.requires] -# Runtime dependencies auto-detected - -[patch.crates-io] -saorsa-core = { path = "../saorsa-core" } +# Runtime dependencies auto-detected \ No newline at end of file From 220f2245a6efacff311234ded3a701f730460762 Mon Sep 17 00:00:00 2001 From: Warm Beer Date: Fri, 6 Mar 2026 11:40:32 +0100 Subject: [PATCH 09/12] refactor: remove unnecessary PeerId clones in tests Simplify test code by directly dereferencing PeerId instances instead of cloning. Update affected functions in `testnet.rs` and `integration_tests.rs` for consistency. --- tests/e2e/integration_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/integration_tests.rs b/tests/e2e/integration_tests.rs index 54058328..d140c2fa 100644 --- a/tests/e2e/integration_tests.rs +++ b/tests/e2e/integration_tests.rs @@ -216,7 +216,7 @@ async fn test_node_to_node_messaging() { !peers.is_empty(), "Node 3 should have at least one connected peer" ); - let target_peer_id = *peers.first().expect("Should have at least one peer"); + let target_peer_id = peers[0]; let sender_p2p = sender.p2p_node.as_ref().expect("Node 3 should be running"); From 3cb58ca038b72b0442ba1381c130811a1c570669 Mon Sep 17 00:00:00 2001 From: Warm Beer Date: Fri, 6 Mar 2026 15:36:50 +0100 Subject: [PATCH 10/12] fix: simplify peer comparison in chunk_protocol Directly compare `source` with dereferenced `target_peer` to remove redundant `as_ref` call. --- src/client/chunk_protocol.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/chunk_protocol.rs b/src/client/chunk_protocol.rs index 369ca031..4b141112 100644 --- a/src/client/chunk_protocol.rs +++ b/src/client/chunk_protocol.rs @@ -54,7 +54,7 @@ pub async fn send_and_await_chunk_response( topic, source: Some(source), data, - })) if topic == CHUNK_PROTOCOL_ID && source.as_ref() == Some(target_peer) => { + })) if topic == CHUNK_PROTOCOL_ID && source == *target_peer => { let response = match ChunkMessage::decode(&data) { Ok(r) => r, Err(e) => { From 030123ab9656cebde4538c4e26bf1828302cdc96 Mon Sep 17 00:00:00 2001 From: Warm Beer Date: Fri, 6 Mar 2026 15:54:06 +0100 Subject: [PATCH 11/12] refactor: remove unused PeerId import in node.rs tests --- src/node.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/node.rs b/src/node.rs index 44a47f83..8a3f1ea0 100644 --- a/src/node.rs +++ b/src/node.rs @@ -708,7 +708,6 @@ impl RunningNode { mod tests { use super::*; use crate::config::NODES_SUBDIR; - use saorsa_core::identity::PeerId; #[test] fn test_build_upgrade_monitor_staged_rollout_enabled() { From c0e3c7701a1ea97f71a2fa102a7c11a220785170 Mon Sep 17 00:00:00 2001 From: Warm Beer Date: Fri, 6 Mar 2026 16:01:50 +0100 Subject: [PATCH 12/12] chore: remove get_latency_bench from PR scope Co-Authored-By: Claude Opus 4.6 --- tests/e2e/get_latency_bench.rs | 202 --------------------------------- 1 file changed, 202 deletions(-) delete mode 100644 tests/e2e/get_latency_bench.rs diff --git a/tests/e2e/get_latency_bench.rs b/tests/e2e/get_latency_bench.rs deleted file mode 100644 index 40af89d7..00000000 --- a/tests/e2e/get_latency_bench.rs +++ /dev/null @@ -1,202 +0,0 @@ -//! Benchmark: measure per-GET latency on a 25-node testnet. -//! -//! Stores one chunk via `QuantumClient`, then retrieves it many times, -//! printing timing for each GET to identify outliers. -//! -//! Run with: -//! ```sh -//! cargo test --test e2e get_latency_bench -- --ignored --nocapture -//! ``` - -#![allow(clippy::unwrap_used, clippy::expect_used)] - -use bytes::Bytes; -use saorsa_core::P2PNode; -use saorsa_node::client::{QuantumClient, QuantumConfig}; -use std::sync::Arc; -use std::time::{Duration, Instant}; - -use crate::{TestHarness, TestNetworkConfig}; - -/// Number of sequential GETs to run after PUT. -const GET_ITERATIONS: usize = 50; - -/// Client timeout (seconds). -const CLIENT_TIMEOUT_SECS: u64 = 30; - -/// Number of closest peers to query (matches QuantumClient::CLOSE_GROUP_SIZE). -const CLOSE_GROUP_SIZE: usize = 8; - -/// Benchmark chunk GET latency on a 25-node testnet. -#[tokio::test(flavor = "multi_thread")] -#[ignore = "Benchmark - run with --ignored --nocapture"] -async fn get_latency_bench() { - let harness = TestHarness::setup_with_config(TestNetworkConfig::default()) - .await - .expect("Failed to setup 25-node testnet"); - - let node = harness.node(5).expect("Node 5 should exist"); - let config = QuantumConfig { - timeout_secs: CLIENT_TIMEOUT_SECS, - replica_count: 1, - encrypt_data: false, - }; - let client = QuantumClient::new(config).with_node(Arc::clone(&node)); - - // --- PUT --- - let content = Bytes::from(vec![0xABu8; 1024]); - let put_start = Instant::now(); - let address = client - .put_chunk(content.clone()) - .await - .expect("put_chunk failed"); - let put_elapsed = put_start.elapsed(); - - println!("\n===== GET LATENCY BENCHMARK (25 nodes, 1 KB chunk) ====="); - println!("PUT took {put_elapsed:?}"); - println!("Chunk address: {}", hex::encode(address)); - println!("Running {GET_ITERATIONS} sequential GETs…\n"); - println!("{:>4} {:>12}", "#", "latency"); - println!("{}", "-".repeat(20)); - - let mut latencies = Vec::with_capacity(GET_ITERATIONS); - - for i in 0..GET_ITERATIONS { - let start = Instant::now(); - let result = client.get_chunk(&address).await.expect("get_chunk failed"); - let elapsed = start.elapsed(); - - assert!(result.is_some(), "Chunk should be found (iteration {i})"); - let chunk = result.unwrap(); - assert_eq!(chunk.content.as_ref(), &[0xABu8; 1024]); - - println!("{:>4} {:>12?}", i, elapsed); - latencies.push(elapsed); - } - - print_stats(&latencies); - - drop(client); - drop(node); - harness - .teardown() - .await - .expect("Failed to teardown harness"); -} - -/// Breakdown: compare local DHT lookup (no network) vs full network lookup -/// vs full GET to identify where the linear growth comes from. -#[tokio::test(flavor = "multi_thread")] -#[ignore = "Benchmark - run with --ignored --nocapture"] -async fn get_latency_breakdown() { - let harness = TestHarness::setup_with_config(TestNetworkConfig::default()) - .await - .expect("Failed to setup 25-node testnet"); - - let node = harness.node(5).expect("Node 5 should exist"); - let config = QuantumConfig { - timeout_secs: CLIENT_TIMEOUT_SECS, - replica_count: 1, - encrypt_data: false, - }; - let client = QuantumClient::new(config).with_node(Arc::clone(&node)); - - // --- PUT --- - let content = Bytes::from(vec![0xABu8; 1024]); - let address = client - .put_chunk(content.clone()) - .await - .expect("put_chunk failed"); - - println!("\n===== GET LATENCY BREAKDOWN (25 nodes, 1 KB chunk) ====="); - println!("Chunk address: {}", hex::encode(address)); - println!("Running {GET_ITERATIONS} sequential GETs with breakdown…\n"); - println!( - "{:>4} {:>12} {:>12} {:>12} {:>10}", - "#", "dht_local", "dht_network", "get_chunk", "bg_events" - ); - println!("{}", "-".repeat(60)); - - let mut totals = Vec::with_capacity(GET_ITERATIONS); - - for i in 0..GET_ITERATIONS { - let bg_events = drain_pending_events(&node); - - // Phase 1: Local-only DHT lookup (no network RPCs) - let local_start = Instant::now(); - let _local_closest = node - .dht() - .find_closest_nodes_local(&address, CLOSE_GROUP_SIZE) - .await; - let local_dur = local_start.elapsed(); - - // Phase 2: Full network DHT lookup (iterative Kademlia) - let net_start = Instant::now(); - let _net_closest = node - .dht() - .find_closest_nodes(&address, CLOSE_GROUP_SIZE) - .await - .expect("DHT network lookup failed"); - let net_dur = net_start.elapsed(); - - // Phase 3: Full client GET (includes its own DHT lookup + send + wait) - let get_start = Instant::now(); - let result = client.get_chunk(&address).await.expect("get_chunk failed"); - let get_dur = get_start.elapsed(); - - assert!(result.is_some(), "Chunk should be found (iteration {i})"); - - println!( - "{:>4} {:>12?} {:>12?} {:>12?} {:>10}", - i, local_dur, net_dur, get_dur, bg_events - ); - totals.push(get_dur); - } - - print_stats(&totals); - - drop(client); - drop(node); - harness - .teardown() - .await - .expect("Failed to teardown harness"); -} - -/// Drain all pending events from the broadcast channel without blocking. -fn drain_pending_events(node: &P2PNode) -> usize { - let mut rx = node.subscribe_events(); - let mut count = 0; - loop { - match rx.try_recv() { - Ok(_) => count += 1, - Err(_) => break, - } - } - count -} - -fn print_stats(latencies: &[Duration]) { - let mut sorted = latencies.to_vec(); - sorted.sort(); - let total: Duration = sorted.iter().sum(); - let min = sorted[0]; - let max = sorted[sorted.len() - 1]; - let mean = total / sorted.len() as u32; - let median = sorted[sorted.len() / 2]; - let p90 = sorted[(sorted.len() as f64 * 0.9) as usize]; - let p99 = sorted[(sorted.len() as f64 * 0.99) as usize]; - - let outlier_threshold = median * 3; - let outlier_count = sorted.iter().filter(|d| **d > outlier_threshold).count(); - - println!("\n===== STATS (get_chunk) ====="); - println!(" min: {min:?}"); - println!(" max: {max:?}"); - println!(" mean: {mean:?}"); - println!(" median: {median:?}"); - println!(" p90: {p90:?}"); - println!(" p99: {p99:?}"); - println!(" outliers: {outlier_count} (> 3x median = {outlier_threshold:?})"); - println!(" total: {total:?}"); -}