diff --git a/Cargo.lock b/Cargo.lock index a4d8275dec..13455606fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4491,6 +4491,7 @@ dependencies = [ "libp2p", "rmp-serde", "serde", + "sha2", "sn_registers", "sn_transfers", "thiserror", diff --git a/sn_networking/src/driver.rs b/sn_networking/src/driver.rs index 274adf741c..b0aa242bc7 100644 --- a/sn_networking/src/driver.rs +++ b/sn_networking/src/driver.rs @@ -47,7 +47,7 @@ use libp2p_quic as quic; use prometheus_client::registry::Registry; use sn_protocol::{ messages::{Request, Response}, - NetworkAddress, PrettyPrintRecordKey, + NetworkAddress, PrettyPrintKBucketKey, }; use std::{ collections::{HashMap, HashSet}, @@ -299,8 +299,8 @@ impl NetworkBuilder { let peer_id = PeerId::from(self.keypair.public()); info!("Node (PID: {}) with PeerId: {peer_id}", std::process::id()); info!( - "Self PeerID {peer_id} is represented as record_key {:?}", - PrettyPrintRecordKey::from(NetworkAddress::from_peer(peer_id).to_record_key()) + "Self PeerID {peer_id} is represented as kbucket_key {:?}", + PrettyPrintKBucketKey(NetworkAddress::from_peer(peer_id).as_kbucket_key()) ); #[cfg(feature = "open-metrics")] diff --git a/sn_networking/src/error.rs b/sn_networking/src/error.rs index da8a147ed0..135f65cdf6 100644 --- a/sn_networking/src/error.rs +++ b/sn_networking/src/error.rs @@ -123,7 +123,7 @@ pub enum Error { #[cfg(test)] mod tests { - use sn_protocol::{storage::ChunkAddress, NetworkAddress}; + use sn_protocol::{storage::ChunkAddress, NetworkAddress, PrettyPrintKBucketKey}; use xor_name::XorName; use super::*; @@ -133,10 +133,15 @@ mod tests { let mut rng = rand::thread_rng(); let xor_name = XorName::random(&mut rng); let address = ChunkAddress::new(xor_name); - let record_key = NetworkAddress::from_chunk_address(address).to_record_key(); + let network_address = NetworkAddress::from_chunk_address(address); + let record_key = network_address.to_record_key(); let pretty_record: PrettyPrintRecordKey = record_key.into(); let record_str = format!("{}", pretty_record); - let xor_name_str = format!("{:64x}", xor_name); + let xor_name_str = format!( + "{:64x}({:?})", + xor_name, + PrettyPrintKBucketKey(network_address.as_kbucket_key()) + ); println!("record_str: {}", record_str); println!("xor_name_str: {}", xor_name_str); assert_eq!(record_str, xor_name_str); diff --git a/sn_networking/src/lib.rs b/sn_networking/src/lib.rs index 1c0559496f..f7a440e361 100644 --- a/sn_networking/src/lib.rs +++ b/sn_networking/src/lib.rs @@ -45,7 +45,7 @@ use libp2p::{ use sn_protocol::{ messages::{Query, QueryResponse, Request, Response}, storage::{RecordHeader, RecordKind}, - NetworkAddress, PrettyPrintRecordKey, + NetworkAddress, PrettyPrintKBucketKey, PrettyPrintRecordKey, }; use sn_transfers::MainPubkey; use sn_transfers::NanoTokens; @@ -169,8 +169,8 @@ impl Network { .map(|peer_id| { format!( "{peer_id:?}({:?})", - PrettyPrintRecordKey::from( - NetworkAddress::from_peer(*peer_id).to_record_key() + PrettyPrintKBucketKey( + NetworkAddress::from_peer(*peer_id).as_kbucket_key() ) ) }) @@ -618,7 +618,7 @@ impl Network { .map(|peer_id| { format!( "{peer_id:?}({:?})", - PrettyPrintRecordKey::from(NetworkAddress::from_peer(*peer_id).to_record_key()) + PrettyPrintKBucketKey(NetworkAddress::from_peer(*peer_id).as_kbucket_key()) ) }) .collect(); diff --git a/sn_node/src/replication.rs b/sn_node/src/replication.rs index 51dd63f5ce..57d1b95048 100644 --- a/sn_node/src/replication.rs +++ b/sn_node/src/replication.rs @@ -15,7 +15,7 @@ use libp2p::{ use sn_networking::{sort_peers_by_address, GetQuorum, CLOSE_GROUP_SIZE}; use sn_protocol::{ messages::{Cmd, Query, QueryResponse, Request, Response}, - NetworkAddress, PrettyPrintRecordKey, + NetworkAddress, PrettyPrintKBucketKey, PrettyPrintRecordKey, }; use std::collections::BTreeMap; use tokio::task::JoinHandle; @@ -72,9 +72,7 @@ impl Node { .map(|peer_id| { format!( "{peer_id:?}({:?})", - PrettyPrintRecordKey::from( - NetworkAddress::from_peer(*peer_id).to_record_key() - ) + PrettyPrintKBucketKey(NetworkAddress::from_peer(*peer_id).as_kbucket_key()) ) }) .collect(); diff --git a/sn_protocol/Cargo.toml b/sn_protocol/Cargo.toml index f642201d54..c0275e4501 100644 --- a/sn_protocol/Cargo.toml +++ b/sn_protocol/Cargo.toml @@ -18,6 +18,7 @@ hex = "~0.4.3" libp2p = { version="0.52", features = ["identify", "kad"] } rmp-serde = "1.1.1" serde = { version = "1.0.133", features = [ "derive", "rc" ]} +sha2 = "0.10.7" sn_transfers = { path = "../sn_transfers", version = "0.14.3" } sn_registers = { path = "../sn_registers", version = "0.3.2" } thiserror = "1.0.23" diff --git a/sn_protocol/src/lib.rs b/sn_protocol/src/lib.rs index 06de4ea1a6..d799006823 100644 --- a/sn_protocol/src/lib.rs +++ b/sn_protocol/src/lib.rs @@ -23,6 +23,7 @@ use libp2p::{ PeerId, }; use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use sha2::{Digest, Sha256}; use std::fmt::{self, Debug, Display, Formatter}; use xor_name::XorName; @@ -184,12 +185,15 @@ impl Debug for NetworkAddress { "NetworkAddress::RegisterAddress({:?} - ", register_address.xorname() ), - NetworkAddress::RecordKey(_) => "NetworkAddress::RecordKey(".to_string(), + NetworkAddress::RecordKey(bytes) => format!( + "NetworkAddress::RecordKey({:?} - ", + PrettyPrintRecordKey::from(RecordKey::new(bytes)) + ), }; write!( f, "{name_str}{:?})", - PrettyPrintRecordKey::from(self.to_record_key()), + PrettyPrintKBucketKey(self.as_kbucket_key()), ) } } @@ -216,6 +220,26 @@ impl Display for NetworkAddress { } } +/// Pretty print a `kad::KBucketKey` as a hex string. +#[derive(Clone)] +pub struct PrettyPrintKBucketKey(pub Key>); + +impl std::fmt::Display for PrettyPrintKBucketKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // The `KeyBytes` part of `KBucketKey` is private and no API to expose it. + // Hence here we have to carry out a hash manually to simulate its behaviour. + let generic_array = Sha256::digest(self.0.preimage()); + let kbucket_key_b = Bytes::from(generic_array.to_vec()); + write!(f, "{:64x}", kbucket_key_b) + } +} + +impl std::fmt::Debug for PrettyPrintKBucketKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self) + } +} + /// Pretty print a `kad::RecordKey` as a hex string. /// So clients can use the hex string for xorname and record keys interchangeably. /// This makes errors actionable for clients. @@ -258,7 +282,12 @@ impl std::fmt::Display for PrettyPrintRecordKey { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let b: Vec = self.0.as_ref().to_vec(); let record_key_b = Bytes::from(b); - write!(f, "{:64x}", record_key_b) + write!( + f, + "{:64x}({:?})", + record_key_b, + PrettyPrintKBucketKey(NetworkAddress::from_record_key(self.0.clone()).as_kbucket_key()) + ) } }