From 0253613914c62a97c097b3cb035effcc8322ea0c Mon Sep 17 00:00:00 2001 From: Dmitry Markin Date: Thu, 11 Dec 2025 16:21:32 +0200 Subject: [PATCH 1/5] Upgrade multihash 0.17.0 -> 0.19.3 --- Cargo.lock | 167 +++++++++++++++++- Cargo.toml | 3 +- src/error.rs | 11 +- src/lib.rs | 3 +- src/peer_id.rs | 85 ++++++--- src/protocol/libp2p/kademlia/mod.rs | 3 +- src/protocol/libp2p/kademlia/query/mod.rs | 2 +- src/protocol/libp2p/kademlia/record.rs | 3 +- src/protocol/libp2p/kademlia/routing_table.rs | 3 +- src/protocol/transport_service.rs | 3 +- src/transport/common/listener.rs | 11 +- src/transport/manager/address.rs | 5 +- src/transport/manager/handle.rs | 5 +- src/transport/manager/mod.rs | 15 +- src/transport/quic/mod.rs | 3 +- src/transport/s2n-quic/mod.rs | 3 +- src/transport/tcp/mod.rs | 3 +- src/types.rs | 5 +- tests/connection/mod.rs | 2 +- .../protocol_dial_invalid_address.rs | 2 +- tests/protocol/notification.rs | 2 +- tests/protocol/request_response.rs | 2 +- 22 files changed, 270 insertions(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 451d6fa91..a07e1eac5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -280,6 +280,30 @@ dependencies = [ "constant_time_eq", ] +[[package]] +name = "blake2s_simd" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e90f7deecfac93095eb874a40febd69427776e24e1bd7f87f33ac62d6f0174df" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -1423,6 +1447,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -1864,7 +1897,8 @@ dependencies = [ "libp2p", "mockall", "multiaddr", - "multihash 0.17.0", + "multihash 0.19.3", + "multihash-codetable", "network-interface", "parking_lot", "pin-project", @@ -2076,12 +2110,8 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835d6ff01d610179fbce3de1694d007e500bf33a7f29689838941d6bf783ae40" dependencies = [ - "blake2b_simd", "core2", - "digest 0.10.7", - "multihash-derive", - "serde", - "sha2", + "multihash-derive 0.8.1", "unsigned-varint 0.7.2", ] @@ -2096,13 +2126,32 @@ dependencies = [ "unsigned-varint 0.8.0", ] +[[package]] +name = "multihash-codetable" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67996849749d25f1da9f238e8ace2ece8f9d6bdf3f9750aaf2ae7de3a5cad8ea" +dependencies = [ + "blake2b_simd", + "blake2s_simd", + "blake3", + "core2", + "digest 0.10.7", + "multihash-derive 0.9.1", + "ripemd", + "sha1", + "sha2", + "sha3", + "strobe-rs", +] + [[package]] name = "multihash-derive" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.1.3", "proc-macro-error", "proc-macro2", "quote", @@ -2110,6 +2159,30 @@ dependencies = [ "synstructure 0.12.6", ] +[[package]] +name = "multihash-derive" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f1b7edab35d920890b88643a765fc9bd295cf0201f4154dda231bef9b8404eb" +dependencies = [ + "core2", + "multihash 0.19.3", + "multihash-derive-impl", +] + +[[package]] +name = "multihash-derive-impl" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3dc7141bd06405929948754f0628d247f5ca1865be745099205e5086da957cb" +dependencies = [ + "proc-macro-crate 3.4.0", + "proc-macro2", + "quote", + "syn 2.0.110", + "synstructure 0.13.2", +] + [[package]] name = "multimap" version = "0.10.1" @@ -2611,6 +2684,15 @@ dependencies = [ "toml", ] +[[package]] +name = "proc-macro-crate" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -3025,6 +3107,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "rtnetlink" version = "0.13.1" @@ -3336,6 +3427,16 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -3499,6 +3600,19 @@ dependencies = [ "tracing", ] +[[package]] +name = "strobe-rs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98fe17535ea31344936cc58d29fec9b500b0452ddc4cc24c429c8a921a0e84e5" +dependencies = [ + "bitflags 1.3.2", + "byteorder", + "keccak", + "subtle", + "zeroize", +] + [[package]] name = "subtle" version = "2.6.1" @@ -3788,6 +3902,36 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.23.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d7cbc3b4b49633d57a0509303158ca50de80ae32c265093b24c414705807832" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +dependencies = [ + "winnow", +] + [[package]] name = "tracing" version = "0.1.41" @@ -4527,6 +4671,15 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" +[[package]] +name = "winnow" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" diff --git a/Cargo.toml b/Cargo.toml index a4eba5881..19fd37dfc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,8 @@ indexmap = { version = "2.9.0", features = ["std"] } libc = "0.2.158" mockall = "0.13.1" multiaddr = "0.17.0" -multihash = { version = "0.17.0", default-features = false, features = ["std", "multihash-impl", "identity", "sha2", "blake2b"] } +multihash = "0.19.3" +multihash-codetable = { version = "0.1.4", features = ["blake2b", "sha2"] } network-interface = "2.0.1" parking_lot = "0.12.3" pin-project = "1.1.10" diff --git a/src/error.rs b/src/error.rs index 7128fad74..cd8fe0f2c 100644 --- a/src/error.rs +++ b/src/error.rs @@ -26,12 +26,11 @@ use crate::{ protocol::Direction, transport::manager::limits::ConnectionLimitsError, - types::{protocol::ProtocolName, ConnectionId, SubstreamId}, + types::{multihash::Multihash, protocol::ProtocolName, ConnectionId, SubstreamId}, PeerId, }; use multiaddr::Multiaddr; -use multihash::{Multihash, MultihashGeneric}; use std::io::{self, ErrorKind}; @@ -425,8 +424,8 @@ pub enum DnsError { IpVersionMismatch, } -impl From> for Error { - fn from(hash: MultihashGeneric<64>) -> Self { +impl From for Error { + fn from(hash: Multihash) -> Self { Error::AddressError(AddressError::InvalidPeerId(hash)) } } @@ -497,8 +496,8 @@ impl From for Error { } } -impl From> for AddressError { - fn from(hash: MultihashGeneric<64>) -> Self { +impl From for AddressError { + fn from(hash: Multihash) -> Self { AddressError::InvalidPeerId(hash) } } diff --git a/src/lib.rs b/src/lib.rs index 8d784dac5..b1ad441bd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -528,11 +528,10 @@ mod tests { use crate::{ config::ConfigBuilder, protocol::{libp2p::ping, notification::Config as NotificationConfig}, - types::protocol::ProtocolName, + types::{multihash::Multihash, protocol::ProtocolName}, Litep2p, Litep2pEvent, PeerId, }; use multiaddr::{Multiaddr, Protocol}; - use multihash::Multihash; use std::net::Ipv4Addr; #[tokio::test] diff --git a/src/peer_id.rs b/src/peer_id.rs index 1a13ba03c..ba0be0806 100644 --- a/src/peer_id.rs +++ b/src/peer_id.rs @@ -21,10 +21,12 @@ #![allow(clippy::wrong_self_convention)] -use crate::crypto::PublicKey; +use crate::{ + crypto::PublicKey, + types::multihash::{Code, Multihash, MultihashDigest}, +}; use multiaddr::{Multiaddr, Protocol}; -use multihash::{Code, Error, Multihash, MultihashDigest}; use rand::Rng; use serde::{Deserialize, Serialize}; use thiserror::Error; @@ -64,21 +66,25 @@ impl PeerId { /// Builds a `PeerId` from a public key in protobuf encoding. pub fn from_public_key_protobuf(key_enc: &[u8]) -> PeerId { - let hash_algorithm = if key_enc.len() <= MAX_INLINE_KEY_LENGTH { - Code::Identity + let multihash = if key_enc.len() <= MAX_INLINE_KEY_LENGTH { + // Use Identity hash (code 0x00) for small keys + Multihash::wrap(0x00, key_enc).expect("Key size is within bounds") } else { - Code::Sha2_256 + // Use SHA-256 for larger keys + Code::Sha2_256.digest(key_enc) }; - let multihash = hash_algorithm.digest(key_enc); - PeerId { multihash } } /// Parses a `PeerId` from bytes. - pub fn from_bytes(data: &[u8]) -> Result { - PeerId::from_multihash(Multihash::from_bytes(data)?) - .map_err(|mh| Error::UnsupportedCode(mh.code())) + pub fn from_bytes(data: &[u8]) -> Result { + let multihash = Multihash::from_bytes(data)?; + PeerId::from_multihash(multihash).map_err(|_mh| { + // Since we can't construct a multihash::Error for unsupported code, + // create an error by trying to parse invalid data + Multihash::from_bytes(&[0xFF, 0xFF, 0xFF]).unwrap_err() + }) } /// Tries to turn a `Multihash` into a `PeerId`. @@ -87,21 +93,31 @@ impl PeerId { /// or the hash value does not satisfy the constraints for a hashed /// peer ID, it is returned as an `Err`. pub fn from_multihash(multihash: Multihash) -> Result { - match Code::try_from(multihash.code()) { - Ok(Code::Sha2_256) => Ok(PeerId { multihash }), - Ok(Code::Identity) if multihash.digest().len() <= MAX_INLINE_KEY_LENGTH => - Ok(PeerId { multihash }), + match multihash.code() { + // SHA-256 + 0x12 => Ok(PeerId { multihash }), + // Identity hash + 0x00 if multihash.digest().len() <= MAX_INLINE_KEY_LENGTH => Ok(PeerId { multihash }), _ => Err(multihash), } } + /// Helper method to convert from multiaddr's old multihash type + pub(crate) fn from_multiaddr_multihash( + hash: multiaddr::multihash::Multihash, + ) -> Result { + let bytes = hash.to_bytes(); + let new_multihash = Multihash::from_bytes(&bytes).map_err(|_| hash)?; + PeerId::from_multihash(new_multihash).map_err(|_| hash) + } + /// Tries to extract a [`PeerId`] from the given [`Multiaddr`]. /// /// In case the given [`Multiaddr`] ends with `/p2p/`, this function /// will return the encapsulated [`PeerId`], otherwise it will return `None`. pub fn try_from_multiaddr(address: &Multiaddr) -> Option { address.iter().last().and_then(|p| match p { - Protocol::P2p(hash) => PeerId::from_multihash(hash).ok(), + Protocol::P2p(hash) => PeerId::from_multiaddr_multihash(hash).ok(), _ => None, }) } @@ -112,8 +128,7 @@ impl PeerId { pub fn random() -> PeerId { let peer_id = rand::thread_rng().gen::<[u8; 32]>(); PeerId { - multihash: Multihash::wrap(Code::Identity.into(), &peer_id) - .expect("The digest size is never too large"), + multihash: Multihash::wrap(0x00, &peer_id).expect("The digest size is never too large"), } } @@ -132,10 +147,13 @@ impl PeerId { /// Returns `None` if this `PeerId`s hash algorithm is not supported when encoding the /// given public key, otherwise `Some` boolean as the result of an equality check. pub fn is_public_key(&self, public_key: &PublicKey) -> Option { - let alg = Code::try_from(self.multihash.code()) - .expect("Internal multihash is always a valid `Code`"); let enc = public_key.to_protobuf_encoding(); - Some(alg.digest(&enc) == self.multihash) + let expected_multihash = if enc.len() <= MAX_INLINE_KEY_LENGTH { + Multihash::wrap(0x00, &enc).ok()? + } else { + Code::Sha2_256.digest(&enc) + }; + Some(expected_multihash == self.multihash) } } @@ -173,12 +191,36 @@ impl AsRef for PeerId { } } +impl AsRef for PeerId { + fn as_ref(&self) -> &multiaddr::multihash::Multihash { + // SAFETY: Both Multihash types have the same memory layout (they're both Multihash<64>) + // We can safely transmute between them for read-only operations + unsafe { std::mem::transmute(&self.multihash) } + } +} + impl From for Multihash { fn from(peer_id: PeerId) -> Self { peer_id.multihash } } +impl From for multiaddr::multihash::Multihash { + fn from(peer_id: PeerId) -> Self { + // Convert by serializing to bytes and deserializing with the old version + multiaddr::multihash::Multihash::from_bytes(&peer_id.multihash.to_bytes()) + .expect("Valid multihash conversion") + } +} + +impl TryFrom for PeerId { + type Error = multiaddr::multihash::Multihash; + + fn try_from(multihash: multiaddr::multihash::Multihash) -> Result { + PeerId::from_multiaddr_multihash(multihash) + } +} + impl From for Vec { fn from(peer_id: PeerId) -> Self { peer_id.to_bytes() @@ -257,9 +299,8 @@ impl FromStr for PeerId { #[cfg(test)] mod tests { - use crate::{crypto::ed25519::Keypair, PeerId}; + use crate::{crypto::ed25519::Keypair, types::multihash::Multihash, PeerId}; use multiaddr::{Multiaddr, Protocol}; - use multihash::Multihash; #[test] fn peer_id_is_public_key() { diff --git a/src/protocol/libp2p/kademlia/mod.rs b/src/protocol/libp2p/kademlia/mod.rs index 3d9a90fbc..d60d01885 100644 --- a/src/protocol/libp2p/kademlia/mod.rs +++ b/src/protocol/libp2p/kademlia/mod.rs @@ -1420,11 +1420,10 @@ mod tests { manager::{TransportManager, TransportManagerBuilder}, KEEP_ALIVE_TIMEOUT, }, - types::protocol::ProtocolName, + types::{multihash::Multihash, protocol::ProtocolName}, ConnectionId, }; use multiaddr::Protocol; - use multihash::Multihash; use std::str::FromStr; use tokio::sync::mpsc::channel; diff --git a/src/protocol/libp2p/kademlia/query/mod.rs b/src/protocol/libp2p/kademlia/query/mod.rs index bf1e887c2..30d50304a 100644 --- a/src/protocol/libp2p/kademlia/query/mod.rs +++ b/src/protocol/libp2p/kademlia/query/mod.rs @@ -900,7 +900,7 @@ impl QueryEngine { #[cfg(test)] mod tests { - use multihash::{Code, Multihash}; + use crate::types::multihash::{Code, Multihash}; use super::*; use crate::protocol::libp2p::kademlia::types::ConnectionType; diff --git a/src/protocol/libp2p/kademlia/record.rs b/src/protocol/libp2p/kademlia/record.rs index 322553d46..9e0786a73 100644 --- a/src/protocol/libp2p/kademlia/record.rs +++ b/src/protocol/libp2p/kademlia/record.rs @@ -27,8 +27,9 @@ use crate::{ Multiaddr, PeerId, }; +use crate::types::multihash::Multihash; + use bytes::Bytes; -use multihash::Multihash; use std::{borrow::Borrow, time::Instant}; diff --git a/src/protocol/libp2p/kademlia/routing_table.rs b/src/protocol/libp2p/kademlia/routing_table.rs index e012318ec..67864e722 100644 --- a/src/protocol/libp2p/kademlia/routing_table.rs +++ b/src/protocol/libp2p/kademlia/routing_table.rs @@ -34,7 +34,6 @@ use crate::{ }; use multiaddr::{Multiaddr, Protocol}; -use multihash::Multihash; /// Number of k-buckets. const NUM_BUCKETS: usize = 256; @@ -195,7 +194,7 @@ impl RoutingTable { if std::matches!(last, Some(Protocol::P2p(_))) { Some(address) } else { - Some(address.with(Protocol::P2p(Multihash::from_bytes(&peer.to_bytes()).ok()?))) + Some(address.with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer)))) } }) .collect(); diff --git a/src/protocol/transport_service.rs b/src/protocol/transport_service.rs index 339d03639..400c8b302 100644 --- a/src/protocol/transport_service.rs +++ b/src/protocol/transport_service.rs @@ -29,7 +29,6 @@ use crate::{ use futures::{future::BoxFuture, stream::FuturesUnordered, Stream, StreamExt}; use multiaddr::{Multiaddr, Protocol}; -use multihash::Multihash; use tokio::sync::mpsc::{channel, Receiver, Sender}; use std::{ @@ -523,7 +522,7 @@ impl TransportService { let addresses: HashSet = addresses .filter_map(|address| { if !std::matches!(address.iter().last(), Some(Protocol::P2p(_))) { - Some(address.with(Protocol::P2p(Multihash::from_bytes(&peer.to_bytes()).ok()?))) + Some(address.with(Protocol::P2p(multiaddr::multihash::Multihash::from(*peer)))) } else { Some(address) } diff --git a/src/transport/common/listener.rs b/src/transport/common/listener.rs index 856b4c19b..f8c88ece0 100644 --- a/src/transport/common/listener.rs +++ b/src/transport/common/listener.rs @@ -428,8 +428,15 @@ fn multiaddr_to_socket_address( } let maybe_peer = match iter.next() { - Some(Protocol::P2p(multihash)) => - Some(PeerId::from_multihash(multihash).map_err(AddressError::InvalidPeerId)?), + Some(Protocol::P2p(multihash)) => Some( + PeerId::from_multiaddr_multihash(multihash).map_err(|old_hash| { + // Convert old multihash to new multihash for the error + let bytes = old_hash.to_bytes(); + let new_hash = crate::types::multihash::Multihash::from_bytes(&bytes) + .expect("Valid multihash conversion"); + AddressError::InvalidPeerId(new_hash) + })?, + ), None => None, protocol => { tracing::error!( diff --git a/src/transport/manager/address.rs b/src/transport/manager/address.rs index 68325d7df..2f56b46ce 100644 --- a/src/transport/manager/address.rs +++ b/src/transport/manager/address.rs @@ -21,7 +21,6 @@ use crate::{error::DialError, PeerId}; use multiaddr::{Multiaddr, Protocol}; -use multihash::Multihash; use std::collections::{hash_map::Entry, HashMap}; @@ -63,9 +62,7 @@ impl AddressRecord { /// append the provided `PeerId` to the address. pub fn new(peer: &PeerId, address: Multiaddr, score: i32) -> Self { let address = if !std::matches!(address.iter().last(), Some(Protocol::P2p(_))) { - address.with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).expect("valid peer id"), - )) + address.with(Protocol::P2p(multiaddr::multihash::Multihash::from(*peer))) } else { address }; diff --git a/src/transport/manager/handle.rs b/src/transport/manager/handle.rs index c73e52602..63fc49a93 100644 --- a/src/transport/manager/handle.rs +++ b/src/transport/manager/handle.rs @@ -265,7 +265,8 @@ impl TransportManagerHandle { peer_addresses.insert(address); } else { // Add the provided peer ID to the address. - let address = address.with(Protocol::P2p(multihash::Multihash::from(*peer))); + let address = + address.with(Protocol::P2p(multiaddr::multihash::Multihash::from(*peer))); peer_addresses.insert(address); } } @@ -402,7 +403,7 @@ mod tests { }; use super::*; - use multihash::Multihash; + use crate::types::multihash::Multihash; use parking_lot::lock_api::RwLock; use tokio::sync::mpsc::{channel, Receiver}; diff --git a/src/transport/manager/mod.rs b/src/transport/manager/mod.rs index abd488901..3b4011c29 100644 --- a/src/transport/manager/mod.rs +++ b/src/transport/manager/mod.rs @@ -39,10 +39,10 @@ use crate::{ }; use address::{scores, AddressStore}; + use futures::{Stream, StreamExt}; use indexmap::IndexMap; use multiaddr::{Multiaddr, Protocol}; -use multihash::Multihash; use parking_lot::RwLock; use tokio::sync::mpsc::{channel, Receiver, Sender}; @@ -488,7 +488,7 @@ impl TransportManager { listen_addresses.insert(address.clone()); listen_addresses.insert(address.with(Protocol::P2p( - Multihash::from_bytes(&self.local_peer_id.to_bytes()).unwrap(), + multiaddr::multihash::Multihash::from(self.local_peer_id), ))); } @@ -719,7 +719,7 @@ impl TransportManager { // Extract the peer ID at this point to give `NegotiationError::PeerIdMismatch` a chance to // propagate. let peer_id = match address.iter().last() { - Some(Protocol::P2p(hash)) => PeerId::from_multihash(hash).ok(), + Some(Protocol::P2p(hash)) => PeerId::from_multiaddr_multihash(hash).ok(), _ => None, }; let Some(peer_id) = peer_id else { @@ -1166,7 +1166,7 @@ impl TransportManager { if let Ok(()) = self.on_dial_failure(connection_id) { match address.iter().last() { - Some(Protocol::P2p(hash)) => match PeerId::from_multihash(hash) { + Some(Protocol::P2p(hash)) => match PeerId::from_multiaddr_multihash(hash) { Ok(peer) => { tracing::trace!( target: LOG_TARGET, @@ -1415,11 +1415,12 @@ impl TransportManager { #[cfg(test)] mod tests { - use crate::transport::manager::{address::AddressStore, peer_state::SecondaryOrDialing}; + use crate::{ + transport::manager::{address::AddressStore, peer_state::SecondaryOrDialing}, + types::multihash::Multihash, + }; use limits::ConnectionLimitsConfig; - use multihash::Multihash; - use super::*; use crate::{ crypto::ed25519::Keypair, diff --git a/src/transport/quic/mod.rs b/src/transport/quic/mod.rs index 2c1536317..18a71edb2 100644 --- a/src/transport/quic/mod.rs +++ b/src/transport/quic/mod.rs @@ -590,10 +590,9 @@ mod tests { crypto::ed25519::Keypair, executor::DefaultExecutor, transport::manager::{ProtocolContext, TransportHandle}, - types::protocol::ProtocolName, + types::{multihash::Multihash, protocol::ProtocolName}, BandwidthSink, }; - use multihash::Multihash; use tokio::sync::mpsc::channel; #[tokio::test] diff --git a/src/transport/s2n-quic/mod.rs b/src/transport/s2n-quic/mod.rs index 6237ee3f0..debd117f8 100644 --- a/src/transport/s2n-quic/mod.rs +++ b/src/transport/s2n-quic/mod.rs @@ -32,9 +32,10 @@ use crate::{ PeerId, }; +use crate::types::multihash::Multihash; + use futures::{future::BoxFuture, stream::FuturesUnordered, StreamExt}; use multiaddr::{Multiaddr, Protocol}; -use multihash::Multihash; use s2n_quic::{ client::Connect, connection::{Connection, Error as ConnectionError}, diff --git a/src/transport/tcp/mod.rs b/src/transport/tcp/mod.rs index fe024237d..486dd651c 100644 --- a/src/transport/tcp/mod.rs +++ b/src/transport/tcp/mod.rs @@ -681,11 +681,10 @@ mod tests { crypto::ed25519::Keypair, executor::DefaultExecutor, transport::manager::{ProtocolContext, SupportedTransport, TransportManagerBuilder}, - types::protocol::ProtocolName, + types::{multihash::Multihash, protocol::ProtocolName}, BandwidthSink, PeerId, }; use multiaddr::Protocol; - use multihash::Multihash; use std::sync::Arc; use tokio::sync::mpsc::channel; diff --git a/src/types.rs b/src/types.rs index ad9806904..da0403df7 100644 --- a/src/types.rs +++ b/src/types.rs @@ -27,7 +27,10 @@ pub mod multiaddr { pub use multiaddr::{Error, Iter, Multiaddr, Onion3Addr, Protocol}; } pub mod multihash { - pub use multihash::{Code, Error, Multihash, MultihashDigest}; + pub type Multihash = multihash::Multihash<64>; + + pub use multihash::Error; + pub use multihash_codetable::{Code, MultihashDigest}; } pub mod cid { pub use cid::{multihash::Multihash, Cid, CidGeneric, Error, Result, Version}; diff --git a/tests/connection/mod.rs b/tests/connection/mod.rs index 92f2ee4f1..608d5901b 100644 --- a/tests/connection/mod.rs +++ b/tests/connection/mod.rs @@ -33,8 +33,8 @@ use litep2p::transport::websocket::config::Config as WebSocketConfig; use litep2p::{error::AddressError, transport::quic::config::Config as QuicConfig}; use futures::{Stream, StreamExt}; +use litep2p::types::multihash::Multihash; use multiaddr::{Multiaddr, Protocol}; -use multihash::Multihash; use network_interface::{NetworkInterface, NetworkInterfaceConfig}; use tokio::net::TcpListener; #[cfg(feature = "quic")] diff --git a/tests/connection/protocol_dial_invalid_address.rs b/tests/connection/protocol_dial_invalid_address.rs index c4fc7214e..0aa24e51c 100644 --- a/tests/connection/protocol_dial_invalid_address.rs +++ b/tests/connection/protocol_dial_invalid_address.rs @@ -29,8 +29,8 @@ use litep2p::{ }; use futures::StreamExt; +use litep2p::types::multihash::Multihash; use multiaddr::{Multiaddr, Protocol}; -use multihash::Multihash; use tokio::sync::oneshot; #[derive(Debug)] diff --git a/tests/protocol/notification.rs b/tests/protocol/notification.rs index 58df24aa7..4a90698aa 100644 --- a/tests/protocol/notification.rs +++ b/tests/protocol/notification.rs @@ -36,8 +36,8 @@ use litep2p::transport::websocket::config::Config as WebSocketConfig; use bytes::BytesMut; use futures::StreamExt; +use litep2p::types::multihash::Multihash; use multiaddr::{Multiaddr, Protocol}; -use multihash::Multihash; #[cfg(feature = "quic")] use std::net::Ipv4Addr; diff --git a/tests/protocol/request_response.rs b/tests/protocol/request_response.rs index 208c0ed6d..fbb0e8254 100644 --- a/tests/protocol/request_response.rs +++ b/tests/protocol/request_response.rs @@ -34,8 +34,8 @@ use litep2p::{ use litep2p::transport::websocket::config::Config as WebSocketConfig; use futures::{channel, StreamExt}; +use litep2p::types::multihash::Multihash; use multiaddr::{Multiaddr, Protocol}; -use multihash::Multihash; use tokio::time::sleep; #[cfg(feature = "quic")] From d3e2009b8818477a66dbc3952cbf8e1f25c6b714 Mon Sep 17 00:00:00 2001 From: Dmitry Markin Date: Thu, 11 Dec 2025 16:44:01 +0200 Subject: [PATCH 2/5] Fix tests --- src/lib.rs | 4 +- src/peer_id.rs | 34 +++- src/protocol/libp2p/kademlia/mod.rs | 18 +-- src/protocol/libp2p/kademlia/query/mod.rs | 2 +- src/transport/manager/handle.rs | 20 +-- src/transport/manager/mod.rs | 182 ++++++++-------------- src/transport/tcp/mod.rs | 10 +- src/transport/websocket/connection.rs | 3 +- 8 files changed, 125 insertions(+), 148 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b1ad441bd..dbcd9f524 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -648,9 +648,7 @@ mod tests { let address = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(255, 254, 253, 252))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); let mut litep2p = Litep2p::new(config).unwrap(); litep2p.dial_address(address.clone()).await.unwrap(); diff --git a/src/peer_id.rs b/src/peer_id.rs index ba0be0806..ccc4eff51 100644 --- a/src/peer_id.rs +++ b/src/peer_id.rs @@ -302,6 +302,38 @@ mod tests { use crate::{crypto::ed25519::Keypair, types::multihash::Multihash, PeerId}; use multiaddr::{Multiaddr, Protocol}; + #[test] + fn multihash_layout_compatibility() { + // Verify that both Multihash types have the same memory layout + // This is critical for the safety of the transmute in AsRef implementation + use std::mem::{align_of, size_of}; + + assert_eq!( + size_of::(), + size_of::(), + "Multihash types must have the same size" + ); + + assert_eq!( + align_of::(), + align_of::(), + "Multihash types must have the same alignment" + ); + + // Test that the transmute actually works correctly by creating a peer ID + // and verifying we can get the same bytes through both types + let peer_id = PeerId::random(); + let bytes_new: Vec = + AsRef::::as_ref(&peer_id).to_bytes(); + let bytes_old: Vec = + AsRef::::as_ref(&peer_id).to_bytes(); + + assert_eq!( + bytes_new, bytes_old, + "Transmuted Multihash must preserve data" + ); + } + #[test] fn peer_id_is_public_key() { let key = Keypair::generate().public(); @@ -338,7 +370,7 @@ mod tests { let address = Multiaddr::empty() .with(Protocol::from(address.ip())) .with(Protocol::Tcp(address.port())) - .with(Protocol::P2p(Multihash::from(peer))); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); assert_eq!(peer, PeerId::try_from_multiaddr(&address).unwrap()); } diff --git a/src/protocol/libp2p/kademlia/mod.rs b/src/protocol/libp2p/kademlia/mod.rs index d60d01885..d1c7a3ea6 100644 --- a/src/protocol/libp2p/kademlia/mod.rs +++ b/src/protocol/libp2p/kademlia/mod.rs @@ -1564,15 +1564,15 @@ mod tests { let (mut kademlia, _context, _manager) = make_kademlia(); let peer = PeerId::random(); - let address_a = Multiaddr::from_str("/dns/domain1.com/tcp/30333").unwrap().with( - Protocol::P2p(Multihash::from_bytes(&peer.to_bytes()).unwrap()), - ); - let address_b = Multiaddr::from_str("/dns/domain1.com/tcp/30334").unwrap().with( - Protocol::P2p(Multihash::from_bytes(&peer.to_bytes()).unwrap()), - ); - let address_c = Multiaddr::from_str("/dns/domain1.com/tcp/30339").unwrap().with( - Protocol::P2p(Multihash::from_bytes(&peer.to_bytes()).unwrap()), - ); + let address_a = Multiaddr::from_str("/dns/domain1.com/tcp/30333") + .unwrap() + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); + let address_b = Multiaddr::from_str("/dns/domain1.com/tcp/30334") + .unwrap() + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); + let address_c = Multiaddr::from_str("/dns/domain1.com/tcp/30339") + .unwrap() + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); // Added only with address a. kademlia.routing_table.add_known_peer( diff --git a/src/protocol/libp2p/kademlia/query/mod.rs b/src/protocol/libp2p/kademlia/query/mod.rs index 30d50304a..e27d64b8b 100644 --- a/src/protocol/libp2p/kademlia/query/mod.rs +++ b/src/protocol/libp2p/kademlia/query/mod.rs @@ -912,7 +912,7 @@ mod tests { peer_id[1] = second; PeerId::from_bytes( - &Multihash::wrap(Code::Identity.into(), &peer_id) + &Multihash::wrap(0x00, &peer_id) .expect("The digest size is never too large") .to_bytes(), ) diff --git a/src/transport/manager/handle.rs b/src/transport/manager/handle.rs index 63fc49a93..c3d94c299 100644 --- a/src/transport/manager/handle.rs +++ b/src/transport/manager/handle.rs @@ -581,9 +581,11 @@ mod tests { let (handle, _rx) = make_transport_manager_handle(); // only peer id (used by Polkadot sometimes) - assert!(!handle.supported_transport( - &Multiaddr::empty().with(Protocol::P2p(Multihash::from(PeerId::random()))) - )); + assert!( + !handle.supported_transport(&Multiaddr::empty().with(Protocol::P2p( + multiaddr::multihash::Multihash::from(PeerId::random()) + ))) + ); // only one transport assert!(!handle.supported_transport( @@ -646,7 +648,7 @@ mod tests { address: Multiaddr::empty() .with(Protocol::Ip4(std::net::Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p(Multihash::from(peer))), + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))), connection_id: ConnectionId::from(0), }, secondary: None, @@ -656,7 +658,7 @@ mod tests { vec![Multiaddr::empty() .with(Protocol::Ip4(std::net::Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p(Multihash::from(peer)))] + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer)))] .into_iter(), ), }, @@ -689,7 +691,7 @@ mod tests { address: Multiaddr::empty() .with(Protocol::Ip4(std::net::Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p(Multihash::from(peer))), + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))), connection_id: ConnectionId::from(0), }, }, @@ -698,7 +700,7 @@ mod tests { vec![Multiaddr::empty() .with(Protocol::Ip4(std::net::Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p(Multihash::from(peer)))] + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer)))] .into_iter(), ), }, @@ -757,7 +759,7 @@ mod tests { Multiaddr::empty() .with(Protocol::Ip4(std::net::Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p(Multihash::from(peer))), + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))), ConnectionId::from(0), )), }, @@ -766,7 +768,7 @@ mod tests { vec![Multiaddr::empty() .with(Protocol::Ip4(std::net::Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p(Multihash::from(peer)))] + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer)))] .into_iter(), ), }, diff --git a/src/transport/manager/mod.rs b/src/transport/manager/mod.rs index 3b4011c29..445d1b202 100644 --- a/src/transport/manager/mod.rs +++ b/src/transport/manager/mod.rs @@ -1440,9 +1440,7 @@ mod tests { let dial_address = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888 + connection_id)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); let connection_id = ConnectionId::from(connection_id as usize); (dial_address, connection_id) @@ -1739,9 +1737,9 @@ mod tests { .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Udp(8888)) .with(Protocol::QuicV1) - .with(Protocol::P2p( - Multihash::from_bytes(&PeerId::random().to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from( + PeerId::random(), + ))); assert!(std::matches!( manager.dial_address(address).await, @@ -1760,9 +1758,7 @@ mod tests { let dial_address = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); let transport = Box::new({ let mut transport = DummyTransport::new(); @@ -1819,9 +1815,7 @@ mod tests { let dial_address = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); assert!(manager.dial_address(dial_address.clone()).await.is_ok()); assert_eq!(manager.pending_connections.len(), 1); @@ -1847,9 +1841,7 @@ mod tests { Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )) + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer),)) ) .await .is_ok()); @@ -1860,9 +1852,7 @@ mod tests { Multiaddr::empty() .with(Protocol::Ip6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )) + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer),)) ) .await .is_ok()); @@ -1923,18 +1913,18 @@ mod tests { let address = Multiaddr::empty() .with(Protocol::Ip6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&PeerId::random().to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from( + PeerId::random(), + ))); assert!(handle.supported_transport(&address)); // ipv4 let address = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&PeerId::random().to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from( + PeerId::random(), + ))); assert!(handle.supported_transport(&address)); // quic @@ -1942,9 +1932,9 @@ mod tests { .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Udp(8888)) .with(Protocol::QuicV1) - .with(Protocol::P2p( - Multihash::from_bytes(&PeerId::random().to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from( + PeerId::random(), + ))); #[cfg(feature = "quic")] assert!(handle.supported_transport(&address)); #[cfg(not(feature = "quic"))] @@ -1981,15 +1971,11 @@ mod tests { let dial_address = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); let connect_address = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(192, 168, 1, 173))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); assert!(manager.dial_address(dial_address.clone()).await.is_ok()); assert_eq!(manager.pending_connections.len(), 1); @@ -2042,15 +2028,11 @@ mod tests { let dial_address = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); let connect_address = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(192, 168, 1, 173))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); assert!(manager.dial_address(dial_address.clone()).await.is_ok()); assert_eq!(manager.pending_connections.len(), 1); @@ -2123,15 +2105,11 @@ mod tests { let dial_address = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); let connect_address = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(192, 168, 1, 173))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); assert!(manager.dial_address(dial_address.clone()).await.is_ok()); assert_eq!(manager.pending_connections.len(), 1); @@ -2201,21 +2179,15 @@ mod tests { let address1 = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); let address2 = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(192, 168, 1, 173))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); let address3 = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(192, 168, 10, 64))) .with(Protocol::Tcp(9999)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); // remote peer connected to local node let established_result = manager @@ -2304,15 +2276,11 @@ mod tests { let address1 = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); let address2 = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(192, 168, 1, 173))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); // remote peer connected to local node let established_result = manager @@ -2394,15 +2362,11 @@ mod tests { let address1 = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); let address2 = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(192, 168, 1, 173))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); // remote peer connected to local node let emit_event = manager @@ -2497,15 +2461,11 @@ mod tests { let address1 = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); let address2 = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(192, 168, 1, 173))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); // remote peer connected to local node let emit_event = manager @@ -2595,21 +2555,15 @@ mod tests { let address1 = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); let address2 = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(192, 168, 1, 173))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); let address3 = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(192, 168, 1, 173))) .with(Protocol::Tcp(9999)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); // remote peer connected to local node let emit_event = manager @@ -2858,7 +2812,7 @@ mod tests { address: Multiaddr::empty() .with(Protocol::Ip4(std::net::Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p(Multihash::from(peer))), + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))), connection_id: ConnectionId::from(0usize), }, secondary: None, @@ -2868,7 +2822,7 @@ mod tests { vec![Multiaddr::empty() .with(Protocol::Ip4(std::net::Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p(Multihash::from(peer)))] + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer)))] .into_iter(), ), }, @@ -2900,7 +2854,7 @@ mod tests { address: Multiaddr::empty() .with(Protocol::Ip4(std::net::Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p(Multihash::from(peer))), + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))), connection_id: ConnectionId::from(0usize), }, }, @@ -2909,7 +2863,7 @@ mod tests { vec![Multiaddr::empty() .with(Protocol::Ip4(std::net::Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p(Multihash::from(peer)))] + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer)))] .into_iter(), ), }, @@ -2933,7 +2887,7 @@ mod tests { Multiaddr::empty() .with(Protocol::Ip4(std::net::Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p(Multihash::from(peer))) + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))) ); } state => panic!("invalid state: {state:?}"), @@ -2958,7 +2912,7 @@ mod tests { Multiaddr::empty() .with(Protocol::Ip4(std::net::Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p(Multihash::from(peer))), + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))), ConnectionId::from(0), )), }, @@ -2984,7 +2938,9 @@ mod tests { // transport doesn't start with ip/dns { - let address = Multiaddr::empty().with(Protocol::P2p(Multihash::from(PeerId::random()))); + let address = Multiaddr::empty().with(Protocol::P2p( + multiaddr::multihash::Multihash::from(PeerId::random()), + )); match manager.dial_address(address.clone()).await { Err(Error::TransportNotSupported(dial_address)) => { assert_eq!(dial_address, address); @@ -2999,7 +2955,9 @@ mod tests { .with(Protocol::Ip4(std::net::Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Udp(8888)) .with(Protocol::Utp) - .with(Protocol::P2p(Multihash::from(PeerId::random()))); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from( + PeerId::random(), + ))); match manager.dial_address(address.clone()).await { Err(Error::TransportNotSupported(dial_address)) => { assert_eq!(dial_address, address); @@ -3013,7 +2971,9 @@ mod tests { let address = Multiaddr::empty() .with(Protocol::Ip4(std::net::Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Sctp(8888)) - .with(Protocol::P2p(Multihash::from(PeerId::random()))); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from( + PeerId::random(), + ))); match manager.dial_address(address.clone()).await { Err(Error::TransportNotSupported(dial_address)) => { assert_eq!(dial_address, address); @@ -3028,7 +2988,9 @@ mod tests { .with(Protocol::Ip4(std::net::Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) .with(Protocol::Utp) - .with(Protocol::P2p(Multihash::from(PeerId::random()))); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from( + PeerId::random(), + ))); match manager.dial_address(address.clone()).await { Err(Error::TransportNotSupported(dial_address)) => { assert_eq!(dial_address, address); @@ -3093,9 +3055,7 @@ mod tests { let dial_address = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); let connection_id = ConnectionId::random(); let transport = Box::new({ @@ -3112,7 +3072,7 @@ mod tests { vec![Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(192, 168, 1, 5))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p(Multihash::from(peer)))] + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer)))] .into_iter(), ); @@ -3173,9 +3133,7 @@ mod tests { let dial_address = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); let connection_id = ConnectionId::random(); let transport = Box::new({ @@ -3192,7 +3150,7 @@ mod tests { vec![Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p(Multihash::from(peer)))] + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer)))] .into_iter(), ); @@ -3468,9 +3426,7 @@ mod tests { let dial_address = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888 + connection_id)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); let connection_id = ConnectionId::from(connection_id as usize); (dial_address, connection_id) @@ -3609,9 +3565,7 @@ mod tests { let dial_address = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); let connection_id = ConnectionId::from(0); let transport = Box::new({ @@ -3647,9 +3601,7 @@ mod tests { let second_address = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8889)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); // Second dial attempt with different address. manager.dial_address(second_address.clone()).await.unwrap(); @@ -3692,9 +3644,7 @@ mod tests { let dial_address_tcp = Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); let transport = Box::new({ let mut transport = DummyTransport::new(); transport.inject_event(TransportEvent::OpenFailure { @@ -3709,7 +3659,7 @@ mod tests { vec![Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(192, 168, 1, 5))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p(Multihash::from(peer)))] + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer)))] .into_iter(), ); @@ -3718,9 +3668,7 @@ mod tests { .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8889)) .with(Protocol::Ws(Cow::Borrowed("/"))) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))); let transport = Box::new({ let mut transport = DummyTransport::new(); @@ -3737,9 +3685,7 @@ mod tests { .with(Protocol::Ip4(Ipv4Addr::new(192, 168, 1, 5))) .with(Protocol::Tcp(8889)) .with(Protocol::Ws(Cow::Borrowed("/"))) - .with(Protocol::P2p( - Multihash::from_bytes(&peer.to_bytes()).unwrap(), - ))] + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer)))] .into_iter(), ); diff --git a/src/transport/tcp/mod.rs b/src/transport/tcp/mod.rs index 486dd651c..1befb5d9f 100644 --- a/src/transport/tcp/mod.rs +++ b/src/transport/tcp/mod.rs @@ -950,9 +950,7 @@ mod tests { 0, 0, 0, 0, 0, 0, 0, 1, ))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer1.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer1))); transport2.dial(ConnectionId::new(), address).unwrap(); @@ -993,9 +991,9 @@ mod tests { let multiaddr = Multiaddr::empty() .with(Protocol::Ip4(std::net::Ipv4Addr::new(255, 254, 253, 252))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&peer_id.to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from( + peer_id, + ))); manager.dial_address(multiaddr.clone()).await.unwrap(); assert!(transport.pending_dials.is_empty()); diff --git a/src/transport/websocket/connection.rs b/src/transport/websocket/connection.rs index f98a6f15f..af9956bc3 100644 --- a/src/transport/websocket/connection.rs +++ b/src/transport/websocket/connection.rs @@ -356,7 +356,8 @@ impl WebSocketConnection { let address = match role { Role::Dialer => address, - Role::Listener => address.with(Protocol::P2p(Multihash::from(peer))), + Role::Listener => + address.with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))), }; Ok(NegotiatedConnection { From a4c31b5eec63306de817ca3a5f7f9584ba3facf7 Mon Sep 17 00:00:00 2001 From: Dmitry Markin Date: Thu, 11 Dec 2025 17:09:01 +0200 Subject: [PATCH 3/5] Fix more tests --- src/lib.rs | 2 +- src/protocol/libp2p/kademlia/mod.rs | 2 +- src/protocol/libp2p/kademlia/query/mod.rs | 2 +- src/transport/manager/handle.rs | 1 - src/transport/manager/mod.rs | 5 +-- src/transport/tcp/mod.rs | 2 +- tests/connection/mod.rs | 33 +++++++++---------- .../protocol_dial_invalid_address.rs | 7 ++-- tests/protocol/notification.rs | 4 +-- tests/protocol/request_response.rs | 7 ++-- 10 files changed, 29 insertions(+), 36 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index dbcd9f524..7b2da68f9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -528,7 +528,7 @@ mod tests { use crate::{ config::ConfigBuilder, protocol::{libp2p::ping, notification::Config as NotificationConfig}, - types::{multihash::Multihash, protocol::ProtocolName}, + types::protocol::ProtocolName, Litep2p, Litep2pEvent, PeerId, }; use multiaddr::{Multiaddr, Protocol}; diff --git a/src/protocol/libp2p/kademlia/mod.rs b/src/protocol/libp2p/kademlia/mod.rs index d1c7a3ea6..793e242f9 100644 --- a/src/protocol/libp2p/kademlia/mod.rs +++ b/src/protocol/libp2p/kademlia/mod.rs @@ -1420,7 +1420,7 @@ mod tests { manager::{TransportManager, TransportManagerBuilder}, KEEP_ALIVE_TIMEOUT, }, - types::{multihash::Multihash, protocol::ProtocolName}, + types::protocol::ProtocolName, ConnectionId, }; use multiaddr::Protocol; diff --git a/src/protocol/libp2p/kademlia/query/mod.rs b/src/protocol/libp2p/kademlia/query/mod.rs index e27d64b8b..fbe49fdec 100644 --- a/src/protocol/libp2p/kademlia/query/mod.rs +++ b/src/protocol/libp2p/kademlia/query/mod.rs @@ -900,7 +900,7 @@ impl QueryEngine { #[cfg(test)] mod tests { - use crate::types::multihash::{Code, Multihash}; + use crate::types::multihash::Multihash; use super::*; use crate::protocol::libp2p::kademlia::types::ConnectionType; diff --git a/src/transport/manager/handle.rs b/src/transport/manager/handle.rs index c3d94c299..e2e9c30a1 100644 --- a/src/transport/manager/handle.rs +++ b/src/transport/manager/handle.rs @@ -403,7 +403,6 @@ mod tests { }; use super::*; - use crate::types::multihash::Multihash; use parking_lot::lock_api::RwLock; use tokio::sync::mpsc::{channel, Receiver}; diff --git a/src/transport/manager/mod.rs b/src/transport/manager/mod.rs index 445d1b202..05bf79187 100644 --- a/src/transport/manager/mod.rs +++ b/src/transport/manager/mod.rs @@ -1415,10 +1415,7 @@ impl TransportManager { #[cfg(test)] mod tests { - use crate::{ - transport::manager::{address::AddressStore, peer_state::SecondaryOrDialing}, - types::multihash::Multihash, - }; + use crate::transport::manager::{address::AddressStore, peer_state::SecondaryOrDialing}; use limits::ConnectionLimitsConfig; use super::*; diff --git a/src/transport/tcp/mod.rs b/src/transport/tcp/mod.rs index 1befb5d9f..332c01fbe 100644 --- a/src/transport/tcp/mod.rs +++ b/src/transport/tcp/mod.rs @@ -681,7 +681,7 @@ mod tests { crypto::ed25519::Keypair, executor::DefaultExecutor, transport::manager::{ProtocolContext, SupportedTransport, TransportManagerBuilder}, - types::{multihash::Multihash, protocol::ProtocolName}, + types::protocol::ProtocolName, BandwidthSink, PeerId, }; use multiaddr::Protocol; diff --git a/tests/connection/mod.rs b/tests/connection/mod.rs index 608d5901b..09a59ad95 100644 --- a/tests/connection/mod.rs +++ b/tests/connection/mod.rs @@ -33,7 +33,6 @@ use litep2p::transport::websocket::config::Config as WebSocketConfig; use litep2p::{error::AddressError, transport::quic::config::Config as QuicConfig}; use futures::{Stream, StreamExt}; -use litep2p::types::multihash::Multihash; use multiaddr::{Multiaddr, Protocol}; use network_interface::{NetworkInterface, NetworkInterfaceConfig}; use tokio::net::TcpListener; @@ -208,9 +207,9 @@ async fn dial_failure(transport1: Transport, transport2: Transport, dial_address let mut litep2p1 = Litep2p::new(config1).unwrap(); let mut litep2p2 = Litep2p::new(config2).unwrap(); - let address = dial_address.with(Protocol::P2p( - Multihash::from_bytes(&litep2p2.local_peer_id().to_bytes()).unwrap(), - )); + let address = dial_address.with(Protocol::P2p(multiaddr::multihash::Multihash::from( + *litep2p2.local_peer_id(), + ))); litep2p1.dial_address(address).await.unwrap(); @@ -267,7 +266,7 @@ async fn connect_over_dns() { new_address.push(Protocol::Dns("localhost".into())); new_address.push(tcp); new_address.push(Protocol::P2p( - Multihash::from_bytes(&peer2.to_bytes()).unwrap(), + multiaddr::multihash::Multihash::from(peer2), )); litep2p1.dial_address(new_address).await.unwrap(); @@ -292,7 +291,7 @@ async fn connection_timeout_tcp() { .with(Protocol::from(address.ip())) .with(Protocol::Tcp(address.port())) .with(Protocol::P2p( - Multihash::from_bytes(&PeerId::random().to_bytes()).unwrap(), + multiaddr::multihash::Multihash::from(PeerId::random()), )); connection_timeout( @@ -316,7 +315,7 @@ async fn connection_timeout_quic() { .with(Protocol::Udp(address.port())) .with(Protocol::QuicV1) .with(Protocol::P2p( - Multihash::from_bytes(&PeerId::random().to_bytes()).unwrap(), + multiaddr::multihash::Multihash::from(PeerId::random()), )); connection_timeout(Transport::Quic(Default::default()), address).await; @@ -333,7 +332,7 @@ async fn connection_timeout_websocket() { .with(Protocol::Tcp(address.port())) .with(Protocol::Ws(std::borrow::Cow::Owned("/".to_string()))) .with(Protocol::P2p( - Multihash::from_bytes(&PeerId::random().to_bytes()).unwrap(), + multiaddr::multihash::Multihash::from(PeerId::random()), )); connection_timeout( @@ -473,7 +472,7 @@ async fn attempt_to_dial_using_unsupported_transport_tcp() { .with(Protocol::Tcp(8888)) .with(Protocol::Ws(std::borrow::Cow::Borrowed("/"))) .with(Protocol::P2p( - Multihash::from_bytes(&PeerId::random().to_bytes()).unwrap(), + multiaddr::multihash::Multihash::from(PeerId::random()), )); assert!(std::matches!( @@ -501,7 +500,7 @@ async fn attempt_to_dial_using_unsupported_transport_quic() { .with(Protocol::from(std::net::Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Tcp(8888)) .with(Protocol::P2p( - Multihash::from_bytes(&PeerId::random().to_bytes()).unwrap(), + multiaddr::multihash::Multihash::from(PeerId::random()), )); assert!(std::matches!( @@ -856,7 +855,7 @@ async fn tcp_dns_resolution() { new_address.push(Protocol::Dns("localhost".into())); new_address.push(tcp); new_address.push(Protocol::P2p( - Multihash::from_bytes(&peer2.to_bytes()).unwrap(), + multiaddr::multihash::Multihash::from(peer2), )); litep2p1.dial_address(new_address).await.unwrap(); @@ -919,7 +918,7 @@ async fn websocket_dns_resolution() { new_address.push(tcp); new_address.push(Protocol::Ws(std::borrow::Cow::Owned("/".to_string()))); new_address.push(Protocol::P2p( - Multihash::from_bytes(&peer2.to_bytes()).unwrap(), + multiaddr::multihash::Multihash::from(peer2), )); litep2p1.dial_address(new_address).await.unwrap(); @@ -1229,7 +1228,7 @@ async fn unspecified_listen_address_tcp() { Multiaddr::empty() .with(Protocol::Ip4(record.ip)) .with(Protocol::Tcp(ip4_port.unwrap())) - .with(Protocol::P2p(Multihash::from(peer1))), + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer1))), ) } network_interface::Addr::V6(record) => { @@ -1244,7 +1243,7 @@ async fn unspecified_listen_address_tcp() { Multiaddr::empty() .with(Protocol::Ip6(record.ip)) .with(Protocol::Tcp(ip6_port.unwrap())) - .with(Protocol::P2p(Multihash::from(peer1))), + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer1))), ) } }; @@ -1331,7 +1330,7 @@ async fn unspecified_listen_address_websocket() { .with(Protocol::Ip4(record.ip)) .with(Protocol::Tcp(ip4_port.unwrap())) .with(Protocol::Ws(std::borrow::Cow::Owned("/".to_string()))) - .with(Protocol::P2p(Multihash::from(peer1))), + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer1))), ) } network_interface::Addr::V6(record) => { @@ -1347,7 +1346,7 @@ async fn unspecified_listen_address_websocket() { .with(Protocol::Ip6(record.ip)) .with(Protocol::Tcp(ip6_port.unwrap())) .with(Protocol::Ws(std::borrow::Cow::Owned("/".to_string()))) - .with(Protocol::P2p(Multihash::from(peer1))), + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer1))), ) } }; @@ -1523,7 +1522,7 @@ async fn check_multi_dial() { // Replace the PeerId in the multiaddrs with random PeerId to simulate invalid addresses. litep2p_addresses.iter_mut().for_each(|addr| { addr.pop(); - addr.push(Protocol::P2p(Multihash::from(random_peer))); + addr.push(Protocol::P2p(multiaddr::multihash::Multihash::from(random_peer))); }); let dialed_addresses: HashSet<_> = litep2p_addresses.clone().into_iter().collect(); diff --git a/tests/connection/protocol_dial_invalid_address.rs b/tests/connection/protocol_dial_invalid_address.rs index 0aa24e51c..67ea511ac 100644 --- a/tests/connection/protocol_dial_invalid_address.rs +++ b/tests/connection/protocol_dial_invalid_address.rs @@ -29,7 +29,6 @@ use litep2p::{ }; use futures::StreamExt; -use litep2p::types::multihash::Multihash; use multiaddr::{Multiaddr, Protocol}; use tokio::sync::oneshot; @@ -94,9 +93,9 @@ async fn protocol_dial_invalid_dns_address() { "address.that.doesnt.exist.hopefully.pls".to_string(), ))) .with(Protocol::Tcp(8888)) - .with(Protocol::P2p( - Multihash::from_bytes(&PeerId::random().to_bytes()).unwrap(), - )); + .with(Protocol::P2p(multiaddr::multihash::Multihash::from( + PeerId::random(), + ))); let (custom_protocol, rx) = CustomProtocol::new(address); let custom_protocol = Box::new(custom_protocol); diff --git a/tests/protocol/notification.rs b/tests/protocol/notification.rs index 4a90698aa..ffa99a90c 100644 --- a/tests/protocol/notification.rs +++ b/tests/protocol/notification.rs @@ -36,7 +36,6 @@ use litep2p::transport::websocket::config::Config as WebSocketConfig; use bytes::BytesMut; use futures::StreamExt; -use litep2p::types::multihash::Multihash; use multiaddr::{Multiaddr, Protocol}; #[cfg(feature = "quic")] @@ -3722,7 +3721,8 @@ async fn dial_failure(transport1: Transport, transport2: Transport) { let mut litep2p2 = Litep2p::new(config2).unwrap(); let peer2 = *litep2p2.local_peer_id(); - let known_address = known_address.with(Protocol::P2p(Multihash::from(peer2))); + let known_address = + known_address.with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer2))); litep2p1.add_known_address(peer2, vec![known_address].into_iter()); diff --git a/tests/protocol/request_response.rs b/tests/protocol/request_response.rs index fbb0e8254..2a749b8d8 100644 --- a/tests/protocol/request_response.rs +++ b/tests/protocol/request_response.rs @@ -34,7 +34,6 @@ use litep2p::{ use litep2p::transport::websocket::config::Config as WebSocketConfig; use futures::{channel, StreamExt}; -use litep2p::types::multihash::Multihash; use multiaddr::{Multiaddr, Protocol}; use tokio::time::sleep; @@ -2305,19 +2304,19 @@ async fn dial_failure(transport: Transport) { Transport::Tcp(_) => Multiaddr::empty() .with(Protocol::Ip6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1))) .with(Protocol::Tcp(5)) - .with(Protocol::P2p(Multihash::from(peer))), + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))), #[cfg(feature = "quic")] Transport::Quic(_) => Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1))) .with(Protocol::Udp(5)) .with(Protocol::QuicV1) - .with(Protocol::P2p(Multihash::from(peer))), + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))), #[cfg(feature = "websocket")] Transport::WebSocket(_) => Multiaddr::empty() .with(Protocol::Ip6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1))) .with(Protocol::Tcp(5)) .with(Protocol::Ws(std::borrow::Cow::Owned("/".to_string()))) - .with(Protocol::P2p(Multihash::from(peer))), + .with(Protocol::P2p(multiaddr::multihash::Multihash::from(peer))), }; let config = add_transport(litep2p_config, transport).build(); From 829968181ae52614e5c92ecf5510d379666f1edd Mon Sep 17 00:00:00 2001 From: Dmitry Markin Date: Thu, 11 Dec 2025 17:09:24 +0200 Subject: [PATCH 4/5] Test transmute works for non-zero multihash code --- src/peer_id.rs | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/src/peer_id.rs b/src/peer_id.rs index ccc4eff51..b1482f46f 100644 --- a/src/peer_id.rs +++ b/src/peer_id.rs @@ -299,6 +299,7 @@ impl FromStr for PeerId { #[cfg(test)] mod tests { + use super::*; use crate::{crypto::ed25519::Keypair, types::multihash::Multihash, PeerId}; use multiaddr::{Multiaddr, Protocol}; @@ -319,7 +320,10 @@ mod tests { align_of::(), "Multihash types must have the same alignment" ); + } + #[test] + fn transmute_peer_id_wth_identity_code() { // Test that the transmute actually works correctly by creating a peer ID // and verifying we can get the same bytes through both types let peer_id = PeerId::random(); @@ -334,6 +338,91 @@ mod tests { ); } + #[test] + fn transmute_peer_id_with_sha256_code() { + // Test that the transmute works correctly with non-zero multihash code. + let payload = b"1337"; + let multihash = Code::Sha2_256.digest(payload); + let peer_id = PeerId::try_from(multihash).expect("sha256 is supported by `PeerId`"); + let bytes_new: Vec = + AsRef::::as_ref(&peer_id).to_bytes(); + let bytes_old: Vec = + AsRef::::as_ref(&peer_id).to_bytes(); + + assert_eq!( + bytes_new, bytes_old, + "Transmuted Multihash must preserve data" + ); + } + + #[test] + fn multihash_sha256_conversion() { + // Test conversion for both Identity and SHA-256 hashed peer IDs + // Ed25519 keys are 32 bytes, which when protobuf-encoded are < 42 bytes, so they use + // Identity + + // Test with Ed25519 key (should use Identity hash, code 0x00) + let keypair = Keypair::generate(); + let peer_id = keypair.public().to_peer_id(); + + let multihash: &crate::types::multihash::Multihash = peer_id.as_ref(); + let hash_code = multihash.code(); + + // Ed25519 uses Identity (0x00), but verify conversion works for whatever code is used + assert!( + hash_code == 0x00 || hash_code == 0x12, + "Should use either Identity (0x00) or SHA-256 (0x12), got: 0x{:x}", + hash_code + ); + + // Test conversion to old multihash type + let old_multihash = multiaddr::multihash::Multihash::from(peer_id); + assert_eq!( + old_multihash.code(), + hash_code, + "Converted multihash should preserve hash code" + ); + + // Verify bytes are preserved + let bytes_new = multihash.to_bytes(); + let bytes_old = old_multihash.to_bytes(); + assert_eq!(bytes_new, bytes_old, "Multihash bytes must be preserved"); + + // Test conversion back from old multihash type + let peer_id_back = PeerId::try_from(old_multihash).unwrap(); + assert_eq!( + peer_id, peer_id_back, + "Round-trip conversion must preserve PeerId" + ); + + // Test with a manually created SHA-256 peer ID + // Create a large key by using a 50-byte buffer which exceeds MAX_INLINE_KEY_LENGTH (42) + let large_key = vec![0x42u8; 50]; + let peer_id_sha256 = PeerId::from_public_key_protobuf(&large_key); + + let multihash_sha256: &crate::types::multihash::Multihash = peer_id_sha256.as_ref(); + assert_eq!( + multihash_sha256.code(), + 0x12, + "Large key should use SHA-256 hash" + ); + + // Test SHA-256 conversion + let old_multihash_sha256 = multiaddr::multihash::Multihash::from(peer_id_sha256); + assert_eq!( + old_multihash_sha256.code(), + 0x12, + "Converted SHA-256 multihash should preserve code" + ); + + let bytes_new_sha256 = multihash_sha256.to_bytes(); + let bytes_old_sha256 = old_multihash_sha256.to_bytes(); + assert_eq!( + bytes_new_sha256, bytes_old_sha256, + "SHA-256 multihash bytes must be preserved" + ); + } + #[test] fn peer_id_is_public_key() { let key = Keypair::generate().public(); From 37b2e32cbadcd046f3085ed4a240899caf538a94 Mon Sep 17 00:00:00 2001 From: Dmitry Markin Date: Thu, 11 Dec 2025 17:32:01 +0200 Subject: [PATCH 5/5] Better error for `PeerId::from_bytes` --- src/peer_id.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/peer_id.rs b/src/peer_id.rs index b1482f46f..c160d5e92 100644 --- a/src/peer_id.rs +++ b/src/peer_id.rs @@ -24,12 +24,12 @@ use crate::{ crypto::PublicKey, types::multihash::{Code, Multihash, MultihashDigest}, + Error, }; use multiaddr::{Multiaddr, Protocol}; use rand::Rng; use serde::{Deserialize, Serialize}; -use thiserror::Error; use std::{convert::TryFrom, fmt, str::FromStr}; @@ -78,13 +78,9 @@ impl PeerId { } /// Parses a `PeerId` from bytes. - pub fn from_bytes(data: &[u8]) -> Result { - let multihash = Multihash::from_bytes(data)?; - PeerId::from_multihash(multihash).map_err(|_mh| { - // Since we can't construct a multihash::Error for unsupported code, - // create an error by trying to parse invalid data - Multihash::from_bytes(&[0xFF, 0xFF, 0xFF]).unwrap_err() - }) + pub fn from_bytes(data: &[u8]) -> Result { + let multihash = Multihash::from_bytes(data).map_err(|_| Error::InvalidData)?; + PeerId::from_multihash(multihash).map_err(|_| Error::InvalidData) } /// Tries to turn a `Multihash` into a `PeerId`. @@ -279,7 +275,7 @@ impl<'de> Deserialize<'de> for PeerId { } } -#[derive(Debug, Error)] +#[derive(Debug, thiserror::Error)] pub enum ParseError { #[error("base-58 decode error: {0}")] B58(#[from] bs58::decode::Error),