From 2a09cdbabb46ce9fcaf549b28f421795927ddf95 Mon Sep 17 00:00:00 2001 From: drHuangMHT Date: Tue, 31 Dec 2024 18:07:37 +0800 Subject: [PATCH 01/20] implement signedPeerRecord --- protocols/identify/src/behaviour.rs | 66 ++++++++++++++++--- .../identify/src/generated/structs.proto | 7 ++ protocols/identify/src/generated/structs.rs | 6 +- protocols/identify/src/handler.rs | 24 +++++-- protocols/identify/src/protocol.rs | 21 ++++-- 5 files changed, 101 insertions(+), 23 deletions(-) diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 0cd27d90717..2dfed1001cd 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -26,9 +26,11 @@ use std::{ }; use libp2p_core::{ - multiaddr, multiaddr::Protocol, transport::PortUse, ConnectedPoint, Endpoint, Multiaddr, + multiaddr::{self, Protocol}, + transport::PortUse, + ConnectedPoint, Endpoint, Multiaddr, }; -use libp2p_identity::{PeerId, PublicKey}; +use libp2p_identity::{Keypair, PeerId, PublicKey}; use libp2p_swarm::{ behaviour::{ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}, ConnectionDenied, ConnectionId, DialError, ExternalAddresses, ListenAddresses, @@ -118,7 +120,7 @@ pub struct Config { /// e.g. `ipfs/1.0.0` or `polkadot/1.0.0`. protocol_version: String, /// The public key of the local node. To report on the wire. - local_public_key: PublicKey, + local_key: CryptoKey, /// Name and version of the local peer implementation, similar to the /// `User-Agent` header in the HTTP protocol. /// @@ -156,12 +158,25 @@ pub struct Config { impl Config { /// Creates a new configuration for the identify [`Behaviour`] that - /// advertises the given protocol version and public key. - pub fn new(protocol_version: String, local_public_key: PublicKey) -> Self { + /// advertises the given protocol version and public key. + /// Use `new_with_keypair` for `SignedPeerRecord` support. + pub fn new(protocol_version: String, public_key: PublicKey) -> Self { Self { protocol_version, agent_version: format!("rust-libp2p/{}", env!("CARGO_PKG_VERSION")), - local_public_key, + local_key: public_key.into(), + interval: Duration::from_secs(5 * 60), + push_listen_addr_updates: false, + cache_size: 100, + hide_listen_addrs: false, + } + } + + pub fn new_with_keypair(protocol_version: String, local_keypair: Keypair) -> Self { + Self { + protocol_version, + agent_version: format!("rust-libp2p/{}", env!("CARGO_PKG_VERSION")), + local_key: local_keypair.into(), interval: Duration::from_secs(5 * 60), push_listen_addr_updates: false, cache_size: 100, @@ -209,7 +224,7 @@ impl Config { /// Get the local public key of the Config. pub fn local_public_key(&self) -> &PublicKey { - &self.local_public_key + self.local_key.public_key() } /// Get the agent version of the Config. @@ -380,7 +395,7 @@ impl NetworkBehaviour for Behaviour { Ok(Handler::new( self.config.interval, peer, - self.config.local_public_key.clone(), + self.config.local_key.clone(), self.config.protocol_version.clone(), self.config.agent_version.clone(), remote_addr.clone(), @@ -413,7 +428,7 @@ impl NetworkBehaviour for Behaviour { Ok(Handler::new( self.config.interval, peer, - self.config.local_public_key.clone(), + self.config.local_key.clone(), self.config.protocol_version.clone(), self.config.agent_version.clone(), // TODO: This is weird? That is the public address we dialed, @@ -670,6 +685,39 @@ impl PeerCache { } } +#[derive(Debug, Clone)] +#[allow(clippy::large_enum_variant)] +pub enum CryptoKey { + // With public key only the behaviour will not + // be able to produce a `SignedEnvelope`. + Public(PublicKey), + Keypair { + keypair: Keypair, + public_key: PublicKey, + }, +} +impl From for CryptoKey { + fn from(value: PublicKey) -> Self { + Self::Public(value) + } +} +impl From for CryptoKey { + fn from(value: Keypair) -> Self { + Self::Keypair { + public_key: value.public(), + keypair: value, + } + } +} +impl CryptoKey { + pub(crate) fn public_key(&self) -> &PublicKey { + match &self { + CryptoKey::Public(pubkey) => pubkey, + CryptoKey::Keypair { public_key, .. } => public_key, + } + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/protocols/identify/src/generated/structs.proto b/protocols/identify/src/generated/structs.proto index fbe6836bfdb..c9df399294c 100644 --- a/protocols/identify/src/generated/structs.proto +++ b/protocols/identify/src/generated/structs.proto @@ -24,4 +24,11 @@ message Identify { optional bytes observedAddr = 4; repeated string protocols = 3; + + // signedPeerRecord contains a serialized SignedEnvelope containing a PeerRecord, + // signed by the sending node. It contains the same addresses as the listenAddrs field, but + // in a form that lets us share authenticated addrs with other peers. + // see github.com/libp2p/go-libp2p/core/record/pb/envelope.proto and + // github.com/libp2p/go-libp2p/core/peer/pb/peer_record.proto for message definitions. + optional bytes signedPeerRecord = 8; } diff --git a/protocols/identify/src/generated/structs.rs b/protocols/identify/src/generated/structs.rs index 3be9b6f94ad..1d790d011db 100644 --- a/protocols/identify/src/generated/structs.rs +++ b/protocols/identify/src/generated/structs.rs @@ -22,6 +22,7 @@ pub struct Identify { pub listenAddrs: Vec>, pub observedAddr: Option>, pub protocols: Vec, + pub signedPeerRecord: Option>, } impl<'a> MessageRead<'a> for Identify { @@ -35,6 +36,7 @@ impl<'a> MessageRead<'a> for Identify { Ok(18) => msg.listenAddrs.push(r.read_bytes(bytes)?.to_owned()), Ok(34) => msg.observedAddr = Some(r.read_bytes(bytes)?.to_owned()), Ok(26) => msg.protocols.push(r.read_string(bytes)?.to_owned()), + Ok(66) => msg.signedPeerRecord = Some(r.read_bytes(bytes)?.to_owned()), Ok(t) => { r.read_unknown(bytes, t)?; } Err(e) => return Err(e), } @@ -43,7 +45,7 @@ impl<'a> MessageRead<'a> for Identify { } } -impl MessageWrite for Identify { +impl<'a> MessageWrite for Identify { fn get_size(&self) -> usize { 0 + self.protocolVersion.as_ref().map_or(0, |m| 1 + sizeof_len((m).len())) @@ -52,6 +54,7 @@ impl MessageWrite for Identify { + self.listenAddrs.iter().map(|s| 1 + sizeof_len((s).len())).sum::() + self.observedAddr.as_ref().map_or(0, |m| 1 + sizeof_len((m).len())) + self.protocols.iter().map(|s| 1 + sizeof_len((s).len())).sum::() + + self.signedPeerRecord.as_ref().map_or(0, |m| 1 + sizeof_len((m).len())) } fn write_message(&self, w: &mut Writer) -> Result<()> { @@ -61,6 +64,7 @@ impl MessageWrite for Identify { for s in &self.listenAddrs { w.write_with_tag(18, |w| w.write_bytes(&**s))?; } if let Some(ref s) = self.observedAddr { w.write_with_tag(34, |w| w.write_bytes(&**s))?; } for s in &self.protocols { w.write_with_tag(26, |w| w.write_string(&**s))?; } + if let Some(ref s) = self.signedPeerRecord { w.write_with_tag(66, |w| w.write_bytes(&**s))?; } Ok(()) } } diff --git a/protocols/identify/src/handler.rs b/protocols/identify/src/handler.rs index 6e5af290cd2..693f7953104 100644 --- a/protocols/identify/src/handler.rs +++ b/protocols/identify/src/handler.rs @@ -32,7 +32,7 @@ use libp2p_core::{ upgrade::{ReadyUpgrade, SelectUpgrade}, Multiaddr, }; -use libp2p_identity::{PeerId, PublicKey}; +use libp2p_identity::PeerId; use libp2p_swarm::{ handler::{ ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, @@ -45,8 +45,8 @@ use smallvec::SmallVec; use tracing::Level; use crate::{ - protocol, - protocol::{Info, PushInfo, UpgradeError}, + behaviour::CryptoKey, + protocol::{self, Info, PushInfo, UpgradeError}, PROTOCOL_NAME, PUSH_PROTOCOL_NAME, }; @@ -81,7 +81,7 @@ pub struct Handler { interval: Duration, /// The public key of the local peer. - public_key: PublicKey, + local_key: CryptoKey, /// Application-specific version of the protocol family used by the peer, /// e.g. `ipfs/1.0.0` or `polkadot/1.0.0`. @@ -128,7 +128,7 @@ impl Handler { pub fn new( interval: Duration, remote_peer_id: PeerId, - public_key: PublicKey, + public_key: CryptoKey, protocol_version: String, agent_version: String, observed_addr: Multiaddr, @@ -144,7 +144,7 @@ impl Handler { trigger_next_identify: Delay::new(Duration::ZERO), exchanged_one_periodic_identify: false, interval, - public_key, + local_key: public_key, protocol_version, agent_version, observed_addr, @@ -232,13 +232,23 @@ impl Handler { } fn build_info(&mut self) -> Info { + let signed_envelope = match &self.local_key { + CryptoKey::Public(_) => None, + CryptoKey::Keypair { keypair, .. } => libp2p_core::PeerRecord::new( + keypair, + Vec::from_iter(self.external_addresses.iter().cloned()), + ) + .ok() + .map(|r| r.into_signed_envelope()), + }; Info { - public_key: self.public_key.clone(), + public_key: self.local_key.public_key().clone(), protocol_version: self.protocol_version.clone(), agent_version: self.agent_version.clone(), listen_addrs: Vec::from_iter(self.external_addresses.iter().cloned()), protocols: Vec::from_iter(self.local_supported_protocols.iter().cloned()), observed_addr: self.observed_addr.clone(), + signed_peer_record: signed_envelope, } } diff --git a/protocols/identify/src/protocol.rs b/protocols/identify/src/protocol.rs index 257ec1f88d2..9be53d61174 100644 --- a/protocols/identify/src/protocol.rs +++ b/protocols/identify/src/protocol.rs @@ -22,7 +22,7 @@ use std::io; use asynchronous_codec::{FramedRead, FramedWrite}; use futures::prelude::*; -use libp2p_core::{multiaddr, Multiaddr}; +use libp2p_core::{multiaddr, Multiaddr, SignedEnvelope}; use libp2p_identity as identity; use libp2p_identity::PublicKey; use libp2p_swarm::StreamProtocol; @@ -53,6 +53,7 @@ pub struct Info { pub protocols: Vec, /// Address observed by or for the remote. pub observed_addr: Multiaddr, + pub signed_peer_record: Option, } impl Info { @@ -108,6 +109,10 @@ where listenAddrs: listen_addrs, observedAddr: Some(info.observed_addr.to_vec()), protocols: info.protocols.iter().map(|p| p.to_string()).collect(), + signedPeerRecord: info + .signed_peer_record + .clone() + .map(|r| r.into_protobuf_encoding()), }; let mut framed_io = FramedWrite::new( @@ -166,7 +171,7 @@ where fn parse_listen_addrs(listen_addrs: Vec>) -> Vec { listen_addrs .into_iter() - .filter_map(|bytes| match Multiaddr::try_from(bytes) { + .filter_map(|bytes| match Multiaddr::try_from(bytes.to_vec()) { Ok(a) => Some(a), Err(e) => { tracing::debug!("Unable to parse multiaddr: {e:?}"); @@ -179,7 +184,7 @@ fn parse_listen_addrs(listen_addrs: Vec>) -> Vec { fn parse_protocols(protocols: Vec) -> Vec { protocols .into_iter() - .filter_map(|p| match StreamProtocol::try_from_owned(p) { + .filter_map(|p| match StreamProtocol::try_from_owned(p.to_string()) { Ok(p) => Some(p), Err(e) => { tracing::debug!("Received invalid protocol from peer: {e}"); @@ -200,7 +205,7 @@ fn parse_public_key(public_key: Option>) -> Option { } fn parse_observed_addr(observed_addr: Option>) -> Option { - observed_addr.and_then(|bytes| match Multiaddr::try_from(bytes) { + observed_addr.and_then(|bytes| match Multiaddr::try_from(bytes.to_vec()) { Ok(a) => Some(a), Err(e) => { tracing::debug!("Unable to parse observed multiaddr: {e:?}"); @@ -228,6 +233,9 @@ impl TryFrom for Info { listen_addrs: parse_listen_addrs(msg.listenAddrs), protocols: parse_protocols(msg.protocols), observed_addr: parse_observed_addr(msg.observedAddr).unwrap_or(Multiaddr::empty()), + signed_peer_record: msg + .signedPeerRecord + .and_then(|b| SignedEnvelope::from_protobuf_encoding(b.as_ref()).ok()), }; Ok(info) @@ -240,8 +248,8 @@ impl TryFrom for PushInfo { fn try_from(msg: proto::Identify) -> Result { let info = PushInfo { public_key: parse_public_key(msg.publicKey), - protocol_version: msg.protocolVersion, - agent_version: msg.agentVersion, + protocol_version: msg.protocolVersion.map(|v| v.to_string()), + agent_version: msg.agentVersion.map(|v| v.to_string()), listen_addrs: parse_listen_addrs(msg.listenAddrs), protocols: parse_protocols(msg.protocols), observed_addr: parse_observed_addr(msg.observedAddr), @@ -293,6 +301,7 @@ mod tests { .public() .encode_protobuf(), ), + signedPeerRecord: None, }; let info = PushInfo::try_from(payload).expect("not to fail"); From b5d7aec5e82594c499e14e8ded3a3b995870f45b Mon Sep 17 00:00:00 2001 From: drHuangMHT Date: Wed, 1 Jan 2025 17:51:08 +0800 Subject: [PATCH 02/20] apply suggestions --- protocols/identify/src/behaviour.rs | 34 +++++++++++++++++------------ protocols/identify/src/handler.rs | 14 ++++++------ 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 2dfed1001cd..5acee4f4945 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -119,8 +119,10 @@ pub struct Config { /// Application-specific version of the protocol family used by the peer, /// e.g. `ipfs/1.0.0` or `polkadot/1.0.0`. protocol_version: String, - /// The public key of the local node. To report on the wire. - local_key: CryptoKey, + /// The key of the local node. Only the public key will be report on the wire. + /// The behaviour will not produce [`PeerRecord`](libp2p_core::PeerRecord) when + /// supplied with a public key. + local_key: KeyType, /// Name and version of the local peer implementation, similar to the /// `User-Agent` header in the HTTP protocol. /// @@ -159,7 +161,7 @@ pub struct Config { impl Config { /// Creates a new configuration for the identify [`Behaviour`] that /// advertises the given protocol version and public key. - /// Use `new_with_keypair` for `SignedPeerRecord` support. + /// Use [`new_with_keypair`](Config::new_with_keypair) for `signedPeerRecord` support. pub fn new(protocol_version: String, public_key: PublicKey) -> Self { Self { protocol_version, @@ -172,7 +174,11 @@ impl Config { } } - pub fn new_with_keypair(protocol_version: String, local_keypair: Keypair) -> Self { + /// Creates a new configuration for the identify [`Behaviour`] that + /// advertises the given protocol version and public key. + /// The private key will be used to sign [`PeerRecord`](libp2p_core::PeerRecord) + /// for verifiable address advertisement. + pub fn new_with_keypair(protocol_version: String, local_keypair: &Keypair) -> Self { Self { protocol_version, agent_version: format!("rust-libp2p/{}", env!("CARGO_PKG_VERSION")), @@ -687,33 +693,33 @@ impl PeerCache { #[derive(Debug, Clone)] #[allow(clippy::large_enum_variant)] -pub enum CryptoKey { +pub(crate) enum KeyType { // With public key only the behaviour will not // be able to produce a `SignedEnvelope`. - Public(PublicKey), + PublicKey(PublicKey), Keypair { keypair: Keypair, public_key: PublicKey, }, } -impl From for CryptoKey { +impl From for KeyType { fn from(value: PublicKey) -> Self { - Self::Public(value) + Self::PublicKey(value.clone()) } } -impl From for CryptoKey { - fn from(value: Keypair) -> Self { +impl From<&Keypair> for KeyType { + fn from(value: &Keypair) -> Self { Self::Keypair { public_key: value.public(), - keypair: value, + keypair: value.clone(), } } } -impl CryptoKey { +impl KeyType { pub(crate) fn public_key(&self) -> &PublicKey { match &self { - CryptoKey::Public(pubkey) => pubkey, - CryptoKey::Keypair { public_key, .. } => public_key, + KeyType::PublicKey(pubkey) => pubkey, + KeyType::Keypair { public_key, .. } => public_key, } } } diff --git a/protocols/identify/src/handler.rs b/protocols/identify/src/handler.rs index 693f7953104..f3f1a9c25d5 100644 --- a/protocols/identify/src/handler.rs +++ b/protocols/identify/src/handler.rs @@ -45,7 +45,7 @@ use smallvec::SmallVec; use tracing::Level; use crate::{ - behaviour::CryptoKey, + behaviour::KeyType, protocol::{self, Info, PushInfo, UpgradeError}, PROTOCOL_NAME, PUSH_PROTOCOL_NAME, }; @@ -80,8 +80,8 @@ pub struct Handler { /// The interval of `trigger_next_identify`, i.e. the recurrent delay. interval: Duration, - /// The public key of the local peer. - local_key: CryptoKey, + /// The key of the local peer. + local_key: KeyType, /// Application-specific version of the protocol family used by the peer, /// e.g. `ipfs/1.0.0` or `polkadot/1.0.0`. @@ -125,10 +125,10 @@ pub enum Event { impl Handler { /// Creates a new `Handler`. - pub fn new( + pub(crate) fn new( interval: Duration, remote_peer_id: PeerId, - public_key: CryptoKey, + public_key: KeyType, protocol_version: String, agent_version: String, observed_addr: Multiaddr, @@ -233,8 +233,8 @@ impl Handler { fn build_info(&mut self) -> Info { let signed_envelope = match &self.local_key { - CryptoKey::Public(_) => None, - CryptoKey::Keypair { keypair, .. } => libp2p_core::PeerRecord::new( + KeyType::PublicKey(_) => None, + KeyType::Keypair { keypair, .. } => libp2p_core::PeerRecord::new( keypair, Vec::from_iter(self.external_addresses.iter().cloned()), ) From 4d3d692e10257ffb87981d2fdcf9f6ee884d5928 Mon Sep 17 00:00:00 2001 From: drHuangMHT Date: Fri, 3 Jan 2025 12:32:21 +0800 Subject: [PATCH 03/20] add test --- protocols/identify/src/protocol.rs | 80 ++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/protocols/identify/src/protocol.rs b/protocols/identify/src/protocol.rs index 9be53d61174..a4547301128 100644 --- a/protocols/identify/src/protocol.rs +++ b/protocols/identify/src/protocol.rs @@ -275,7 +275,11 @@ pub enum UpgradeError { #[cfg(test)] mod tests { + use std::str::FromStr; + + use libp2p_core::PeerRecord; use libp2p_identity as identity; + use quick_protobuf::{BytesReader, MessageRead, MessageWrite, Writer}; use super::*; @@ -308,4 +312,80 @@ mod tests { assert_eq!(info.listen_addrs, vec![valid_multiaddr]) } + + #[test] + fn protobuf_roundtrip() { + // from go implementation of identify, + // see https://github.com/libp2p/go-libp2p/blob/2209ae05976df6a1cc2631c961f57549d109008c/p2p/protocol/identify/pb/identify.pb.go#L133 + // signedPeerRecord field is a dummy one that can't be properly parsed into SignedEnvelope, + // but the wire format doesn't care. + let go_protobuf: [u8; 375] = [ + 0x0a, 0x27, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x2f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x2f, 0x70, 0x62, 0x2f, 0x69, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x0b, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x2e, 0x70, 0x62, 0x22, 0x86, + 0x02, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x12, 0x28, 0x0a, + 0x0f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, + 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x6c, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, + 0x52, 0x0b, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x73, 0x12, + 0x22, 0x0a, 0x0c, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x41, 0x64, 0x64, + 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6f, 0x62, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x64, 0x41, 0x64, 0x64, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x73, + 0x69, 0x67, 0x6e, 0x65, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x63, 0x6f, 0x72, + 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x73, 0x69, 0x67, 0x6e, 0x65, + 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x42, 0x36, 0x5a, + 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, + 0x62, 0x70, 0x32, 0x70, 0x2f, 0x67, 0x6f, 0x2d, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, + 0x2f, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x2f, 0x70, 0x62, + ]; + let mut buf = [0u8; 375]; + let mut message = + proto::Identify::from_reader(&mut BytesReader::from_bytes(&go_protobuf), &go_protobuf) + .expect("read to succeed"); + + // The actual bytes they put in is "github.com/libp2p/go-libp2p/p2p/protocol/identify/pb". + // Starting with Z4 means it is zig-zag-encoded 4-byte varint of string, appended by + // protobuf. + assert_eq!( + String::from_utf8( + message + .signedPeerRecord + .clone() + .expect("field to be present") + ) + .expect("parse to succeed"), + "Z4github.com/libp2p/go-libp2p/p2p/protocol/identify/pb".to_string() + ); + message + .write_message(&mut Writer::new(&mut buf[..])) + .expect("same length after roundtrip"); + assert_eq!(go_protobuf, buf); + + let identity = identity::Keypair::generate_ed25519(); + let record = PeerRecord::new( + &identity, + vec![Multiaddr::from_str("/ip4/0.0.0.0").expect("parse to succeed")], + ) + .expect("infallible siging using ed25519"); + message + .signedPeerRecord + .replace(record.into_signed_envelope().into_protobuf_encoding()); + let mut buf = Vec::new(); + message + .write_message(&mut Writer::new(&mut buf)) + .expect("write to succeed"); + let parsed_message = proto::Identify::from_reader(&mut BytesReader::from_bytes(&buf), &buf) + .expect("read to succeed"); + assert_eq!(message, parsed_message) + } } From 59f80f2864618d8dab97c57faf6300e629a11d39 Mon Sep 17 00:00:00 2001 From: drHuangMHT Date: Sat, 4 Jan 2025 13:23:14 +0800 Subject: [PATCH 04/20] reduce diff --- protocols/identify/src/generated/structs.rs | 2 +- protocols/identify/src/handler.rs | 4 ++-- protocols/identify/src/protocol.rs | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/protocols/identify/src/generated/structs.rs b/protocols/identify/src/generated/structs.rs index 1d790d011db..fcda2159a60 100644 --- a/protocols/identify/src/generated/structs.rs +++ b/protocols/identify/src/generated/structs.rs @@ -45,7 +45,7 @@ impl<'a> MessageRead<'a> for Identify { } } -impl<'a> MessageWrite for Identify { +impl MessageWrite for Identify { fn get_size(&self) -> usize { 0 + self.protocolVersion.as_ref().map_or(0, |m| 1 + sizeof_len((m).len())) diff --git a/protocols/identify/src/handler.rs b/protocols/identify/src/handler.rs index f3f1a9c25d5..c4ef7e91201 100644 --- a/protocols/identify/src/handler.rs +++ b/protocols/identify/src/handler.rs @@ -128,7 +128,7 @@ impl Handler { pub(crate) fn new( interval: Duration, remote_peer_id: PeerId, - public_key: KeyType, + local_key: KeyType, protocol_version: String, agent_version: String, observed_addr: Multiaddr, @@ -144,7 +144,7 @@ impl Handler { trigger_next_identify: Delay::new(Duration::ZERO), exchanged_one_periodic_identify: false, interval, - local_key: public_key, + local_key, protocol_version, agent_version, observed_addr, diff --git a/protocols/identify/src/protocol.rs b/protocols/identify/src/protocol.rs index a4547301128..ad0b5c48620 100644 --- a/protocols/identify/src/protocol.rs +++ b/protocols/identify/src/protocol.rs @@ -171,7 +171,7 @@ where fn parse_listen_addrs(listen_addrs: Vec>) -> Vec { listen_addrs .into_iter() - .filter_map(|bytes| match Multiaddr::try_from(bytes.to_vec()) { + .filter_map(|bytes| match Multiaddr::try_from(bytes) { Ok(a) => Some(a), Err(e) => { tracing::debug!("Unable to parse multiaddr: {e:?}"); @@ -184,7 +184,7 @@ fn parse_listen_addrs(listen_addrs: Vec>) -> Vec { fn parse_protocols(protocols: Vec) -> Vec { protocols .into_iter() - .filter_map(|p| match StreamProtocol::try_from_owned(p.to_string()) { + .filter_map(|p| match StreamProtocol::try_from_owned(p) { Ok(p) => Some(p), Err(e) => { tracing::debug!("Received invalid protocol from peer: {e}"); @@ -205,7 +205,7 @@ fn parse_public_key(public_key: Option>) -> Option { } fn parse_observed_addr(observed_addr: Option>) -> Option { - observed_addr.and_then(|bytes| match Multiaddr::try_from(bytes.to_vec()) { + observed_addr.and_then(|bytes| match Multiaddr::try_from(bytes) { Ok(a) => Some(a), Err(e) => { tracing::debug!("Unable to parse observed multiaddr: {e:?}"); @@ -248,8 +248,8 @@ impl TryFrom for PushInfo { fn try_from(msg: proto::Identify) -> Result { let info = PushInfo { public_key: parse_public_key(msg.publicKey), - protocol_version: msg.protocolVersion.map(|v| v.to_string()), - agent_version: msg.agentVersion.map(|v| v.to_string()), + protocol_version: msg.protocolVersion, + agent_version: msg.agentVersion, listen_addrs: parse_listen_addrs(msg.listenAddrs), protocols: parse_protocols(msg.protocols), observed_addr: parse_observed_addr(msg.observedAddr), From 12b9a29e19588898f66525fe0e4f684c6e703432 Mon Sep 17 00:00:00 2001 From: drHuangMHT Date: Fri, 10 Jan 2025 12:26:31 +0800 Subject: [PATCH 05/20] rename symbols --- protocols/identify/src/behaviour.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 5acee4f4945..781df516240 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -178,11 +178,11 @@ impl Config { /// advertises the given protocol version and public key. /// The private key will be used to sign [`PeerRecord`](libp2p_core::PeerRecord) /// for verifiable address advertisement. - pub fn new_with_keypair(protocol_version: String, local_keypair: &Keypair) -> Self { + pub fn new_with_signed_peer_record(protocol_version: String, keypair: &Keypair) -> Self { Self { protocol_version, agent_version: format!("rust-libp2p/{}", env!("CARGO_PKG_VERSION")), - local_key: local_keypair.into(), + local_key: keypair.into(), interval: Duration::from_secs(5 * 60), push_listen_addr_updates: false, cache_size: 100, From d3d8ae6b9800f34238aa1eaaaebd0c4e11bfbe9c Mon Sep 17 00:00:00 2001 From: drHuangMHT Date: Fri, 10 Jan 2025 14:22:08 +0800 Subject: [PATCH 06/20] prefer addresses in signedPeerRecord --- core/src/peer_record.rs | 51 ++++++++++++++++-------------- protocols/identify/src/protocol.rs | 23 +++++++++++--- 2 files changed, 46 insertions(+), 28 deletions(-) diff --git a/core/src/peer_record.rs b/core/src/peer_record.rs index 9c6b7f73f05..ac7c1dd19c9 100644 --- a/core/src/peer_record.rs +++ b/core/src/peer_record.rs @@ -1,11 +1,11 @@ -use libp2p_identity::{Keypair, PeerId, SigningError}; +use libp2p_identity::{Keypair, PeerId, PublicKey, SigningError}; use quick_protobuf::{BytesReader, Writer}; use web_time::SystemTime; use crate::{proto, signed_envelope, signed_envelope::SignedEnvelope, DecodeError, Multiaddr}; -const PAYLOAD_TYPE: &str = "/libp2p/routing-state-record"; -const DOMAIN_SEP: &str = "libp2p-routing-state"; +pub const PAYLOAD_TYPE: &str = "/libp2p/routing-state-record"; +pub const DOMAIN_SEP: &str = "libp2p-routing-state"; /// Represents a peer routing record. /// @@ -30,26 +30,7 @@ impl PeerRecord { /// If this function succeeds, the [`SignedEnvelope`] contained a peer record with a valid /// signature and can hence be considered authenticated. pub fn from_signed_envelope(envelope: SignedEnvelope) -> Result { - use quick_protobuf::MessageRead; - - let (payload, signing_key) = - envelope.payload_and_signing_key(String::from(DOMAIN_SEP), PAYLOAD_TYPE.as_bytes())?; - let mut reader = BytesReader::from_bytes(payload); - let record = proto::PeerRecord::from_reader(&mut reader, payload).map_err(DecodeError)?; - - let peer_id = PeerId::from_bytes(&record.peer_id)?; - - if peer_id != signing_key.to_peer_id() { - return Err(FromEnvelopeError::MismatchedSignature); - } - - let seq = record.seq; - let addresses = record - .addresses - .into_iter() - .map(|a| a.multiaddr.to_vec().try_into()) - .collect::, _>>()?; - + let (_, peer_id, seq, addresses) = Self::try_deserialize_signed_envelope(&envelope)?; Ok(Self { peer_id, seq, @@ -126,6 +107,30 @@ impl PeerRecord { pub fn addresses(&self) -> &[Multiaddr] { self.addresses.as_slice() } + + pub fn try_deserialize_signed_envelope( + envelope: &SignedEnvelope, + ) -> Result<(&PublicKey, PeerId, u64, Vec), FromEnvelopeError> { + use quick_protobuf::MessageRead; + + let (payload, signing_key) = + envelope.payload_and_signing_key(String::from(DOMAIN_SEP), PAYLOAD_TYPE.as_bytes())?; + let mut reader = BytesReader::from_bytes(payload); + let record = proto::PeerRecord::from_reader(&mut reader, payload).map_err(DecodeError)?; + + let peer_id = PeerId::from_bytes(&record.peer_id)?; + + if peer_id != signing_key.to_peer_id() { + return Err(FromEnvelopeError::MismatchedSignature); + } + + let addresses = record + .addresses + .into_iter() + .map(|a| a.multiaddr.to_vec().try_into()) + .collect::, _>>()?; + Ok((signing_key, peer_id, record.seq, addresses)) + } } #[derive(thiserror::Error, Debug)] diff --git a/protocols/identify/src/protocol.rs b/protocols/identify/src/protocol.rs index ad0b5c48620..69e14412225 100644 --- a/protocols/identify/src/protocol.rs +++ b/protocols/identify/src/protocol.rs @@ -22,7 +22,7 @@ use std::io; use asynchronous_codec::{FramedRead, FramedWrite}; use futures::prelude::*; -use libp2p_core::{multiaddr, Multiaddr, SignedEnvelope}; +use libp2p_core::{multiaddr, Multiaddr, PeerRecord, SignedEnvelope}; use libp2p_identity as identity; use libp2p_identity::PublicKey; use libp2p_swarm::StreamProtocol; @@ -226,16 +226,29 @@ impl TryFrom for Info { } }; + let signed_peer_record = msg + .signedPeerRecord + .and_then(|b| SignedEnvelope::from_protobuf_encoding(b.as_ref()).ok()); + + // When signedPeerRecord contains valid addresses, ignore addresses in listenAddrs. + // When signedPeerRecord is invalid or signed by others, ignore the signedPeerRecord(set to `None`). + let (signed_peer_record, listen_addrs) = signed_peer_record + .as_ref() + .and_then(|envelope| PeerRecord::try_deserialize_signed_envelope(&envelope).ok()) + .and_then(|(envelope_public_key, _, _, addresses)| { + (*envelope_public_key == public_key).then_some(addresses) + }) + .map(|addrs| (signed_peer_record, addrs)) + .unwrap_or_else(|| (None, parse_listen_addrs(msg.listenAddrs))); + let info = Info { public_key, protocol_version: msg.protocolVersion.unwrap_or_default(), agent_version: msg.agentVersion.unwrap_or_default(), - listen_addrs: parse_listen_addrs(msg.listenAddrs), + listen_addrs, protocols: parse_protocols(msg.protocols), observed_addr: parse_observed_addr(msg.observedAddr).unwrap_or(Multiaddr::empty()), - signed_peer_record: msg - .signedPeerRecord - .and_then(|b| SignedEnvelope::from_protobuf_encoding(b.as_ref()).ok()), + signed_peer_record, }; Ok(info) From 59151b6dbdb3ded365f39d96fc4aa88a3df41a2a Mon Sep 17 00:00:00 2001 From: drHuangMHT Date: Sat, 11 Jan 2025 10:06:26 +0800 Subject: [PATCH 07/20] rename symbols --- protocols/identify/src/behaviour.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 781df516240..79014a96eb2 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -162,11 +162,11 @@ impl Config { /// Creates a new configuration for the identify [`Behaviour`] that /// advertises the given protocol version and public key. /// Use [`new_with_keypair`](Config::new_with_keypair) for `signedPeerRecord` support. - pub fn new(protocol_version: String, public_key: PublicKey) -> Self { + pub fn new(protocol_version: String, local_public_key: PublicKey) -> Self { Self { protocol_version, agent_version: format!("rust-libp2p/{}", env!("CARGO_PKG_VERSION")), - local_key: public_key.into(), + local_key: local_public_key.into(), interval: Duration::from_secs(5 * 60), push_listen_addr_updates: false, cache_size: 100, @@ -178,11 +178,11 @@ impl Config { /// advertises the given protocol version and public key. /// The private key will be used to sign [`PeerRecord`](libp2p_core::PeerRecord) /// for verifiable address advertisement. - pub fn new_with_signed_peer_record(protocol_version: String, keypair: &Keypair) -> Self { + pub fn new_with_signed_peer_record(protocol_version: String, local_keypair: &Keypair) -> Self { Self { protocol_version, agent_version: format!("rust-libp2p/{}", env!("CARGO_PKG_VERSION")), - local_key: keypair.into(), + local_key: local_keypair.into(), interval: Duration::from_secs(5 * 60), push_listen_addr_updates: false, cache_size: 100, From 9b6a139f4af545176f69e01b5bf3fb51d9690eac Mon Sep 17 00:00:00 2001 From: drHuangMHT Date: Sat, 11 Jan 2025 11:42:57 +0800 Subject: [PATCH 08/20] lint and fmt --- protocols/identify/src/protocol.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/protocols/identify/src/protocol.rs b/protocols/identify/src/protocol.rs index 69e14412225..e3354b5b02a 100644 --- a/protocols/identify/src/protocol.rs +++ b/protocols/identify/src/protocol.rs @@ -230,11 +230,12 @@ impl TryFrom for Info { .signedPeerRecord .and_then(|b| SignedEnvelope::from_protobuf_encoding(b.as_ref()).ok()); - // When signedPeerRecord contains valid addresses, ignore addresses in listenAddrs. - // When signedPeerRecord is invalid or signed by others, ignore the signedPeerRecord(set to `None`). + // When signedPeerRecord contains valid addresses, ignore addresses in listenAddrs. + // When signedPeerRecord is invalid or signed by others, ignore the signedPeerRecord(set to + // `None`). let (signed_peer_record, listen_addrs) = signed_peer_record .as_ref() - .and_then(|envelope| PeerRecord::try_deserialize_signed_envelope(&envelope).ok()) + .and_then(|envelope| PeerRecord::try_deserialize_signed_envelope(envelope).ok()) .and_then(|(envelope_public_key, _, _, addresses)| { (*envelope_public_key == public_key).then_some(addresses) }) From e0e4d9c4a124793946ffc86248ff7f3e7b4ac62b Mon Sep 17 00:00:00 2001 From: drHuangMHT Date: Thu, 13 Feb 2025 22:15:14 +0800 Subject: [PATCH 09/20] rename identifiers --- protocols/identify/src/protocol.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/protocols/identify/src/protocol.rs b/protocols/identify/src/protocol.rs index e3354b5b02a..52af252c155 100644 --- a/protocols/identify/src/protocol.rs +++ b/protocols/identify/src/protocol.rs @@ -218,7 +218,7 @@ impl TryFrom for Info { type Error = UpgradeError; fn try_from(msg: proto::Identify) -> Result { - let public_key = { + let identify_public_key = { match parse_public_key(msg.publicKey) { Some(key) => key, // This will always produce a DecodingError if the public key is missing. @@ -226,30 +226,29 @@ impl TryFrom for Info { } }; - let signed_peer_record = msg + let signed_envelope = msg .signedPeerRecord .and_then(|b| SignedEnvelope::from_protobuf_encoding(b.as_ref()).ok()); // When signedPeerRecord contains valid addresses, ignore addresses in listenAddrs. - // When signedPeerRecord is invalid or signed by others, ignore the signedPeerRecord(set to - // `None`). - let (signed_peer_record, listen_addrs) = signed_peer_record + // When signedPeerRecord is invalid or signed by others, ignore the signedPeerRecord(set to `None`). + let (signed_envelope, listen_addrs) = signed_envelope .as_ref() .and_then(|envelope| PeerRecord::try_deserialize_signed_envelope(envelope).ok()) .and_then(|(envelope_public_key, _, _, addresses)| { - (*envelope_public_key == public_key).then_some(addresses) + (*envelope_public_key == identify_public_key).then_some(addresses) }) - .map(|addrs| (signed_peer_record, addrs)) + .map(|addrs| (signed_envelope, addrs)) .unwrap_or_else(|| (None, parse_listen_addrs(msg.listenAddrs))); let info = Info { - public_key, + public_key: identify_public_key, protocol_version: msg.protocolVersion.unwrap_or_default(), agent_version: msg.agentVersion.unwrap_or_default(), listen_addrs, protocols: parse_protocols(msg.protocols), observed_addr: parse_observed_addr(msg.observedAddr).unwrap_or(Multiaddr::empty()), - signed_peer_record, + signed_peer_record: signed_envelope, }; Ok(info) From 92a49a5bb4d7790b4e542abd830782d4197c0d92 Mon Sep 17 00:00:00 2001 From: drHuangMHT Date: Sun, 16 Feb 2025 18:20:35 +0800 Subject: [PATCH 10/20] reduce enum variant size with Box --- protocols/identify/src/behaviour.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 79014a96eb2..786caaaffd0 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -692,26 +692,26 @@ impl PeerCache { } #[derive(Debug, Clone)] -#[allow(clippy::large_enum_variant)] pub(crate) enum KeyType { // With public key only the behaviour will not // be able to produce a `SignedEnvelope`. - PublicKey(PublicKey), + // Reduce enum size with heap allocated `Box` + PublicKey(Box), Keypair { - keypair: Keypair, - public_key: PublicKey, + keypair: Box, + public_key: Box, }, } impl From for KeyType { fn from(value: PublicKey) -> Self { - Self::PublicKey(value.clone()) + Self::PublicKey(value.clone().into()) } } impl From<&Keypair> for KeyType { fn from(value: &Keypair) -> Self { Self::Keypair { - public_key: value.public(), - keypair: value.clone(), + public_key: value.public().into(), + keypair: value.clone().into(), } } } From b35cbd31b5e655f23b7a64782639f808f4b4caa4 Mon Sep 17 00:00:00 2001 From: drHuangMHT Date: Sun, 16 Feb 2025 18:28:41 +0800 Subject: [PATCH 11/20] simplify envelope deserialization --- protocols/identify/src/protocol.rs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/protocols/identify/src/protocol.rs b/protocols/identify/src/protocol.rs index 52af252c155..028d6bbe3bf 100644 --- a/protocols/identify/src/protocol.rs +++ b/protocols/identify/src/protocol.rs @@ -226,19 +226,17 @@ impl TryFrom for Info { } }; - let signed_envelope = msg - .signedPeerRecord - .and_then(|b| SignedEnvelope::from_protobuf_encoding(b.as_ref()).ok()); - // When signedPeerRecord contains valid addresses, ignore addresses in listenAddrs. - // When signedPeerRecord is invalid or signed by others, ignore the signedPeerRecord(set to `None`). - let (signed_envelope, listen_addrs) = signed_envelope - .as_ref() - .and_then(|envelope| PeerRecord::try_deserialize_signed_envelope(envelope).ok()) - .and_then(|(envelope_public_key, _, _, addresses)| { - (*envelope_public_key == identify_public_key).then_some(addresses) + // When signedPeerRecord is invalid or signed by others, ignore the signedPeerRecord(set to + // `None`). + let (signed_envelope, listen_addrs) = msg + .signedPeerRecord + .and_then(|b| { + let envelope = SignedEnvelope::from_protobuf_encoding(b.as_ref()).ok()?; + let (envelope_public_key, _, _, addresses) = + PeerRecord::try_deserialize_signed_envelope(&envelope).ok()?; + (*envelope_public_key == identify_public_key).then_some((Some(envelope), addresses)) }) - .map(|addrs| (signed_envelope, addrs)) .unwrap_or_else(|| (None, parse_listen_addrs(msg.listenAddrs))); let info = Info { From f29c58d5c7a4bd8c8835b2b6e0b0bb2c7b5e0ca6 Mon Sep 17 00:00:00 2001 From: drHuangMHT Date: Sun, 16 Feb 2025 18:40:54 +0800 Subject: [PATCH 12/20] document try_deserialize_signed_envelope --- core/src/peer_record.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/src/peer_record.rs b/core/src/peer_record.rs index ac7c1dd19c9..19c7a968270 100644 --- a/core/src/peer_record.rs +++ b/core/src/peer_record.rs @@ -108,6 +108,13 @@ impl PeerRecord { self.addresses.as_slice() } + /// Utility method for deserializing an [`SignedEnvelope`] using + /// [`PeerRecord`]-specific [domain separation](https://github.com/libp2p/specs/blob/master/RFC/0003-routing-records.md#signed-envelope-domain) + /// and [payload type](https://github.com/libp2p/specs/blob/master/RFC/0003-routing-records.md#signed-envelope-payload-type). + /// Useful for extracting the address only. + /// Returns `Ok((envelope_public_key, envelope_signer_id, sequence_number, signed_addresses))` + /// when the envelope is valid. + /// Will fail when the source of the addresses doesn't match signer of the envelope. pub fn try_deserialize_signed_envelope( envelope: &SignedEnvelope, ) -> Result<(&PublicKey, PeerId, u64, Vec), FromEnvelopeError> { From ec8f31b074e8405eca3ece3fe2d1dcf17566aa7c Mon Sep 17 00:00:00 2001 From: drHuangMHT Date: Sun, 16 Feb 2025 22:36:05 +0800 Subject: [PATCH 13/20] CI lint --- core/CHANGELOG.md | 7 +++++++ core/src/peer_record.rs | 6 +++--- protocols/identify/CHANGELOG.md | 5 +++++ protocols/identify/src/behaviour.rs | 3 ++- protocols/identify/src/protocol.rs | 1 + 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index 898031c006e..7ede3cc0b69 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.43.1 + +- Add `libp2p::core::peer_record::PeerRecord::try_deserialize_signed_peer_record` + utility method for deserializing `SignedEnvelope` without creating an instance of + `PeerRecord`. + See [PR 5785](https://github.com/libp2p/rust-libp2p/pull/5785) + ## 0.43.0 - Added `libp2p::core::util::unreachable` that is a drop-in replacement of `void::unreachable`. diff --git a/core/src/peer_record.rs b/core/src/peer_record.rs index 19c7a968270..363141345bf 100644 --- a/core/src/peer_record.rs +++ b/core/src/peer_record.rs @@ -110,10 +110,10 @@ impl PeerRecord { /// Utility method for deserializing an [`SignedEnvelope`] using /// [`PeerRecord`]-specific [domain separation](https://github.com/libp2p/specs/blob/master/RFC/0003-routing-records.md#signed-envelope-domain) - /// and [payload type](https://github.com/libp2p/specs/blob/master/RFC/0003-routing-records.md#signed-envelope-payload-type). + /// and [payload type](https://github.com/libp2p/specs/blob/master/RFC/0003-routing-records.md#signed-envelope-payload-type). /// Useful for extracting the address only. - /// Returns `Ok((envelope_public_key, envelope_signer_id, sequence_number, signed_addresses))` - /// when the envelope is valid. + /// Returns `Ok((envelope_public_key, envelope_signer_id, sequence_number, signed_addresses))` + /// when the envelope is valid. /// Will fail when the source of the addresses doesn't match signer of the envelope. pub fn try_deserialize_signed_envelope( envelope: &SignedEnvelope, diff --git a/protocols/identify/CHANGELOG.md b/protocols/identify/CHANGELOG.md index 720dd66f721..4c73e22a748 100644 --- a/protocols/identify/CHANGELOG.md +++ b/protocols/identify/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.46.1 + +- Implement optional `signedPeerRecord` support for identify messages. + See [PR 5785](https://github.com/libp2p/rust-libp2p/pull/5785) + ## 0.46.0 - Add `hide_listen_addrs` option to prevent leaking (local) listen addresses. diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 786caaaffd0..80df4d5c35c 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -161,7 +161,8 @@ pub struct Config { impl Config { /// Creates a new configuration for the identify [`Behaviour`] that /// advertises the given protocol version and public key. - /// Use [`new_with_keypair`](Config::new_with_keypair) for `signedPeerRecord` support. + /// Use [`new_with_signed_peer_record`](Config::new_with_signed_peer_record) for + /// `signedPeerRecord` support. pub fn new(protocol_version: String, local_public_key: PublicKey) -> Self { Self { protocol_version, diff --git a/protocols/identify/src/protocol.rs b/protocols/identify/src/protocol.rs index 028d6bbe3bf..43837faa012 100644 --- a/protocols/identify/src/protocol.rs +++ b/protocols/identify/src/protocol.rs @@ -53,6 +53,7 @@ pub struct Info { pub protocols: Vec, /// Address observed by or for the remote. pub observed_addr: Multiaddr, + /// Verifiable addresses of the peer. pub signed_peer_record: Option, } From c73d37a70bce1572407d73e71cab3c7ee107b96e Mon Sep 17 00:00:00 2001 From: drHuangMHT Date: Thu, 20 Feb 2025 11:00:22 +0800 Subject: [PATCH 14/20] dedup constructor, reference count KeyType --- protocols/identify/src/behaviour.rs | 35 +++++++++++++---------------- protocols/identify/src/handler.rs | 10 ++++----- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 80df4d5c35c..da0d4a510f5 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -21,6 +21,7 @@ use std::{ collections::{hash_map::Entry, HashMap, HashSet, VecDeque}, num::NonZeroUsize, + sync::Arc, task::{Context, Poll}, time::Duration, }; @@ -122,7 +123,7 @@ pub struct Config { /// The key of the local node. Only the public key will be report on the wire. /// The behaviour will not produce [`PeerRecord`](libp2p_core::PeerRecord) when /// supplied with a public key. - local_key: KeyType, + local_key: Arc, /// Name and version of the local peer implementation, similar to the /// `User-Agent` header in the HTTP protocol. /// @@ -164,15 +165,7 @@ impl Config { /// Use [`new_with_signed_peer_record`](Config::new_with_signed_peer_record) for /// `signedPeerRecord` support. pub fn new(protocol_version: String, local_public_key: PublicKey) -> Self { - Self { - protocol_version, - agent_version: format!("rust-libp2p/{}", env!("CARGO_PKG_VERSION")), - local_key: local_public_key.into(), - interval: Duration::from_secs(5 * 60), - push_listen_addr_updates: false, - cache_size: 100, - hide_listen_addrs: false, - } + Self::new_with_key(protocol_version, local_public_key.into()) } /// Creates a new configuration for the identify [`Behaviour`] that @@ -180,10 +173,14 @@ impl Config { /// The private key will be used to sign [`PeerRecord`](libp2p_core::PeerRecord) /// for verifiable address advertisement. pub fn new_with_signed_peer_record(protocol_version: String, local_keypair: &Keypair) -> Self { + Self::new_with_key(protocol_version, local_keypair.into()) + } + + fn new_with_key(protocol_version: String, key_type: KeyType) -> Self { Self { protocol_version, agent_version: format!("rust-libp2p/{}", env!("CARGO_PKG_VERSION")), - local_key: local_keypair.into(), + local_key: Arc::new(key_type), interval: Duration::from_secs(5 * 60), push_listen_addr_updates: false, cache_size: 100, @@ -693,26 +690,24 @@ impl PeerCache { } #[derive(Debug, Clone)] +#[allow(clippy::large_enum_variant)] pub(crate) enum KeyType { - // With public key only the behaviour will not - // be able to produce a `SignedEnvelope`. - // Reduce enum size with heap allocated `Box` - PublicKey(Box), + PublicKey(PublicKey), Keypair { - keypair: Box, - public_key: Box, + keypair: Keypair, + public_key: PublicKey, }, } impl From for KeyType { fn from(value: PublicKey) -> Self { - Self::PublicKey(value.clone().into()) + Self::PublicKey(value) } } impl From<&Keypair> for KeyType { fn from(value: &Keypair) -> Self { Self::Keypair { - public_key: value.public().into(), - keypair: value.clone().into(), + public_key: value.public(), + keypair: value.clone(), } } } diff --git a/protocols/identify/src/handler.rs b/protocols/identify/src/handler.rs index c40242a5786..52a570a86ac 100644 --- a/protocols/identify/src/handler.rs +++ b/protocols/identify/src/handler.rs @@ -19,9 +19,7 @@ // DEALINGS IN THE SOFTWARE. use std::{ - collections::HashSet, - task::{Context, Poll}, - time::Duration, + collections::HashSet, sync::Arc, task::{Context, Poll}, time::Duration }; use either::Either; @@ -81,7 +79,7 @@ pub struct Handler { interval: Duration, /// The key of the local peer. - local_key: KeyType, + local_key: Arc, /// Application-specific version of the protocol family used by the peer, /// e.g. `ipfs/1.0.0` or `polkadot/1.0.0`. @@ -128,7 +126,7 @@ impl Handler { pub(crate) fn new( interval: Duration, remote_peer_id: PeerId, - local_key: KeyType, + local_key: Arc, protocol_version: String, agent_version: String, observed_addr: Multiaddr, @@ -226,7 +224,7 @@ impl Handler { } fn build_info(&mut self) -> Info { - let signed_envelope = match &self.local_key { + let signed_envelope = match self.local_key.as_ref() { KeyType::PublicKey(_) => None, KeyType::Keypair { keypair, .. } => libp2p_core::PeerRecord::new( keypair, From 7cbb3f2b224a3be2be64071ab51c82418af9031c Mon Sep 17 00:00:00 2001 From: drHuangMHT Date: Fri, 21 Feb 2025 09:53:47 +0800 Subject: [PATCH 15/20] doc and fmt lint --- protocols/identify/src/behaviour.rs | 4 ++-- protocols/identify/src/handler.rs | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index da0d4a510f5..5c7eb3292e1 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -121,8 +121,8 @@ pub struct Config { /// e.g. `ipfs/1.0.0` or `polkadot/1.0.0`. protocol_version: String, /// The key of the local node. Only the public key will be report on the wire. - /// The behaviour will not produce [`PeerRecord`](libp2p_core::PeerRecord) when - /// supplied with a public key. + /// The behaviour will send signed [`PeerRecord`](libp2p_core::PeerRecord) in + /// its identify message only when supplied with a keypair. local_key: Arc, /// Name and version of the local peer implementation, similar to the /// `User-Agent` header in the HTTP protocol. diff --git a/protocols/identify/src/handler.rs b/protocols/identify/src/handler.rs index 52a570a86ac..c2e31ae95f6 100644 --- a/protocols/identify/src/handler.rs +++ b/protocols/identify/src/handler.rs @@ -19,7 +19,10 @@ // DEALINGS IN THE SOFTWARE. use std::{ - collections::HashSet, sync::Arc, task::{Context, Poll}, time::Duration + collections::HashSet, + sync::Arc, + task::{Context, Poll}, + time::Duration, }; use either::Either; From c013293de066209784215fca3ec34b6bdd7bebba Mon Sep 17 00:00:00 2001 From: drHuangMHT Date: Fri, 21 Feb 2025 11:11:05 +0800 Subject: [PATCH 16/20] opaque type on new_with_key --- protocols/identify/src/behaviour.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 5c7eb3292e1..d23828af05f 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -165,7 +165,7 @@ impl Config { /// Use [`new_with_signed_peer_record`](Config::new_with_signed_peer_record) for /// `signedPeerRecord` support. pub fn new(protocol_version: String, local_public_key: PublicKey) -> Self { - Self::new_with_key(protocol_version, local_public_key.into()) + Self::new_with_key(protocol_version, local_public_key) } /// Creates a new configuration for the identify [`Behaviour`] that @@ -173,14 +173,14 @@ impl Config { /// The private key will be used to sign [`PeerRecord`](libp2p_core::PeerRecord) /// for verifiable address advertisement. pub fn new_with_signed_peer_record(protocol_version: String, local_keypair: &Keypair) -> Self { - Self::new_with_key(protocol_version, local_keypair.into()) + Self::new_with_key(protocol_version, local_keypair) } - fn new_with_key(protocol_version: String, key_type: KeyType) -> Self { + fn new_with_key(protocol_version: String, key: impl Into) -> Self { Self { protocol_version, agent_version: format!("rust-libp2p/{}", env!("CARGO_PKG_VERSION")), - local_key: Arc::new(key_type), + local_key: Arc::new(key.into()), interval: Duration::from_secs(5 * 60), push_listen_addr_updates: false, cache_size: 100, From 54aed27f7f0cf0dddafa1244ac1ce3b0d9e62d1d Mon Sep 17 00:00:00 2001 From: drHuangMHT Date: Fri, 21 Feb 2025 11:24:55 +0800 Subject: [PATCH 17/20] changelog and manifest --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- core/CHANGELOG.md | 2 +- core/Cargo.toml | 2 +- core/src/peer_record.rs | 4 ++-- protocols/identify/CHANGELOG.md | 2 +- protocols/identify/Cargo.toml | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b917d0a96e8..4bbafe38abc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2760,7 +2760,7 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.43.0" +version = "0.43.1" dependencies = [ "either", "fnv", @@ -2887,7 +2887,7 @@ dependencies = [ [[package]] name = "libp2p-identify" -version = "0.46.0" +version = "0.47.0" dependencies = [ "asynchronous-codec", "either", diff --git a/Cargo.toml b/Cargo.toml index 0d1880eb2b1..40b899a9d7d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,7 +81,7 @@ libp2p-dcutr = { version = "0.13.0", path = "protocols/dcutr" } libp2p-dns = { version = "0.43.0", path = "transports/dns" } libp2p-floodsub = { version = "0.46.1", path = "protocols/floodsub" } libp2p-gossipsub = { version = "0.48.1", path = "protocols/gossipsub" } -libp2p-identify = { version = "0.46.0", path = "protocols/identify" } +libp2p-identify = { version = "0.47.0", path = "protocols/identify" } libp2p-identity = { version = "0.2.10" } libp2p-kad = { version = "0.47.0", path = "protocols/kad" } libp2p-mdns = { version = "0.47.0", path = "protocols/mdns" } diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index 7ede3cc0b69..d46f439da41 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -1,6 +1,6 @@ ## 0.43.1 -- Add `libp2p::core::peer_record::PeerRecord::try_deserialize_signed_peer_record` +- Add `libp2p_core::peer_record::PeerRecord::try_deserialize_signed_peer_record` utility method for deserializing `SignedEnvelope` without creating an instance of `PeerRecord`. See [PR 5785](https://github.com/libp2p/rust-libp2p/pull/5785) diff --git a/core/Cargo.toml b/core/Cargo.toml index 5e84c6f0435..c2befa37568 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -3,7 +3,7 @@ name = "libp2p-core" edition = "2021" rust-version = { workspace = true } description = "Core traits and structs of libp2p" -version = "0.43.0" +version = "0.43.1" authors = ["Parity Technologies "] license = "MIT" repository = "https://github.com/libp2p/rust-libp2p" diff --git a/core/src/peer_record.rs b/core/src/peer_record.rs index 363141345bf..5d83af1072f 100644 --- a/core/src/peer_record.rs +++ b/core/src/peer_record.rs @@ -4,8 +4,8 @@ use web_time::SystemTime; use crate::{proto, signed_envelope, signed_envelope::SignedEnvelope, DecodeError, Multiaddr}; -pub const PAYLOAD_TYPE: &str = "/libp2p/routing-state-record"; -pub const DOMAIN_SEP: &str = "libp2p-routing-state"; +const PAYLOAD_TYPE: &str = "/libp2p/routing-state-record"; +const DOMAIN_SEP: &str = "libp2p-routing-state"; /// Represents a peer routing record. /// diff --git a/protocols/identify/CHANGELOG.md b/protocols/identify/CHANGELOG.md index 4c73e22a748..b70f5bc2383 100644 --- a/protocols/identify/CHANGELOG.md +++ b/protocols/identify/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.46.1 +## 0.47.0 - Implement optional `signedPeerRecord` support for identify messages. See [PR 5785](https://github.com/libp2p/rust-libp2p/pull/5785) diff --git a/protocols/identify/Cargo.toml b/protocols/identify/Cargo.toml index 07730626f42..2546ceed0e1 100644 --- a/protocols/identify/Cargo.toml +++ b/protocols/identify/Cargo.toml @@ -3,7 +3,7 @@ name = "libp2p-identify" edition = "2021" rust-version = { workspace = true } description = "Nodes identification protocol for libp2p" -version = "0.46.0" +version = "0.47.0" authors = ["Parity Technologies "] license = "MIT" repository = "https://github.com/libp2p/rust-libp2p" From cd70cb941615d903d6d74b9ab910855940575dc7 Mon Sep 17 00:00:00 2001 From: drHuangMHT Date: Fri, 21 Feb 2025 12:17:01 +0800 Subject: [PATCH 18/20] workspace manifest --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 40b899a9d7d..c6e2c51736d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,7 +76,7 @@ libp2p = { version = "0.55.1", path = "libp2p" } libp2p-allow-block-list = { version = "0.5.0", path = "misc/allow-block-list" } libp2p-autonat = { version = "0.14.1", path = "protocols/autonat" } libp2p-connection-limits = { version = "0.5.1", path = "misc/connection-limits" } -libp2p-core = { version = "0.43.0", path = "core" } +libp2p-core = { version = "0.43.1", path = "core" } libp2p-dcutr = { version = "0.13.0", path = "protocols/dcutr" } libp2p-dns = { version = "0.43.0", path = "transports/dns" } libp2p-floodsub = { version = "0.46.1", path = "protocols/floodsub" } From c5db8731b8708fec27e82e90296fed40900d882d Mon Sep 17 00:00:00 2001 From: drHuangMHT Date: Fri, 28 Feb 2025 09:35:46 +0800 Subject: [PATCH 19/20] fix definition link, simplify record parsing --- core/src/peer_record.rs | 54 ++++++++----------- .../identify/src/generated/structs.proto | 5 +- protocols/identify/src/protocol.rs | 12 +++-- 3 files changed, 31 insertions(+), 40 deletions(-) diff --git a/core/src/peer_record.rs b/core/src/peer_record.rs index 5d83af1072f..9c6b7f73f05 100644 --- a/core/src/peer_record.rs +++ b/core/src/peer_record.rs @@ -1,4 +1,4 @@ -use libp2p_identity::{Keypair, PeerId, PublicKey, SigningError}; +use libp2p_identity::{Keypair, PeerId, SigningError}; use quick_protobuf::{BytesReader, Writer}; use web_time::SystemTime; @@ -30,7 +30,26 @@ impl PeerRecord { /// If this function succeeds, the [`SignedEnvelope`] contained a peer record with a valid /// signature and can hence be considered authenticated. pub fn from_signed_envelope(envelope: SignedEnvelope) -> Result { - let (_, peer_id, seq, addresses) = Self::try_deserialize_signed_envelope(&envelope)?; + use quick_protobuf::MessageRead; + + let (payload, signing_key) = + envelope.payload_and_signing_key(String::from(DOMAIN_SEP), PAYLOAD_TYPE.as_bytes())?; + let mut reader = BytesReader::from_bytes(payload); + let record = proto::PeerRecord::from_reader(&mut reader, payload).map_err(DecodeError)?; + + let peer_id = PeerId::from_bytes(&record.peer_id)?; + + if peer_id != signing_key.to_peer_id() { + return Err(FromEnvelopeError::MismatchedSignature); + } + + let seq = record.seq; + let addresses = record + .addresses + .into_iter() + .map(|a| a.multiaddr.to_vec().try_into()) + .collect::, _>>()?; + Ok(Self { peer_id, seq, @@ -107,37 +126,6 @@ impl PeerRecord { pub fn addresses(&self) -> &[Multiaddr] { self.addresses.as_slice() } - - /// Utility method for deserializing an [`SignedEnvelope`] using - /// [`PeerRecord`]-specific [domain separation](https://github.com/libp2p/specs/blob/master/RFC/0003-routing-records.md#signed-envelope-domain) - /// and [payload type](https://github.com/libp2p/specs/blob/master/RFC/0003-routing-records.md#signed-envelope-payload-type). - /// Useful for extracting the address only. - /// Returns `Ok((envelope_public_key, envelope_signer_id, sequence_number, signed_addresses))` - /// when the envelope is valid. - /// Will fail when the source of the addresses doesn't match signer of the envelope. - pub fn try_deserialize_signed_envelope( - envelope: &SignedEnvelope, - ) -> Result<(&PublicKey, PeerId, u64, Vec), FromEnvelopeError> { - use quick_protobuf::MessageRead; - - let (payload, signing_key) = - envelope.payload_and_signing_key(String::from(DOMAIN_SEP), PAYLOAD_TYPE.as_bytes())?; - let mut reader = BytesReader::from_bytes(payload); - let record = proto::PeerRecord::from_reader(&mut reader, payload).map_err(DecodeError)?; - - let peer_id = PeerId::from_bytes(&record.peer_id)?; - - if peer_id != signing_key.to_peer_id() { - return Err(FromEnvelopeError::MismatchedSignature); - } - - let addresses = record - .addresses - .into_iter() - .map(|a| a.multiaddr.to_vec().try_into()) - .collect::, _>>()?; - Ok((signing_key, peer_id, record.seq, addresses)) - } } #[derive(thiserror::Error, Debug)] diff --git a/protocols/identify/src/generated/structs.proto b/protocols/identify/src/generated/structs.proto index c9df399294c..d9891e27153 100644 --- a/protocols/identify/src/generated/structs.proto +++ b/protocols/identify/src/generated/structs.proto @@ -28,7 +28,8 @@ message Identify { // signedPeerRecord contains a serialized SignedEnvelope containing a PeerRecord, // signed by the sending node. It contains the same addresses as the listenAddrs field, but // in a form that lets us share authenticated addrs with other peers. - // see github.com/libp2p/go-libp2p/core/record/pb/envelope.proto and - // github.com/libp2p/go-libp2p/core/peer/pb/peer_record.proto for message definitions. + // see https://github.com/libp2p/rust-libp2p/blob/8ac5b5aac5f5c25a85f1065e292deeaf58290189/core/src/generated/envelope.proto#L12 + // and https://github.com/libp2p/rust-libp2p/blob/8ac5b5aac5f5c25a85f1065e292deeaf58290189/core/src/generated/peer_record.proto#L11 + // for message definitions. optional bytes signedPeerRecord = 8; } diff --git a/protocols/identify/src/protocol.rs b/protocols/identify/src/protocol.rs index 43837faa012..0fb4e32d357 100644 --- a/protocols/identify/src/protocol.rs +++ b/protocols/identify/src/protocol.rs @@ -230,15 +230,17 @@ impl TryFrom for Info { // When signedPeerRecord contains valid addresses, ignore addresses in listenAddrs. // When signedPeerRecord is invalid or signed by others, ignore the signedPeerRecord(set to // `None`). - let (signed_envelope, listen_addrs) = msg + let (listen_addrs, signed_envelope) = msg .signedPeerRecord .and_then(|b| { let envelope = SignedEnvelope::from_protobuf_encoding(b.as_ref()).ok()?; - let (envelope_public_key, _, _, addresses) = - PeerRecord::try_deserialize_signed_envelope(&envelope).ok()?; - (*envelope_public_key == identify_public_key).then_some((Some(envelope), addresses)) + let peer_record = PeerRecord::from_signed_envelope(envelope).ok()?; + (peer_record.peer_id() == identify_public_key.to_peer_id()).then_some(( + peer_record.addresses().to_vec(), + Some(peer_record.into_signed_envelope()), + )) }) - .unwrap_or_else(|| (None, parse_listen_addrs(msg.listenAddrs))); + .unwrap_or_else(|| (parse_listen_addrs(msg.listenAddrs), None)); let info = Info { public_key: identify_public_key, From b882ad5cd48af917383d96007e83497a402de91c Mon Sep 17 00:00:00 2001 From: drHuangMHT Date: Fri, 28 Feb 2025 09:41:26 +0800 Subject: [PATCH 20/20] revert core version bump --- Cargo.lock | 2 +- Cargo.toml | 2 +- core/CHANGELOG.md | 7 ------- core/Cargo.toml | 2 +- 4 files changed, 3 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ad8a9492ed3..bea5f26ae2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2772,7 +2772,7 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.43.1" +version = "0.43.0" dependencies = [ "either", "fnv", diff --git a/Cargo.toml b/Cargo.toml index 83e765fd567..7b46dcbd0bd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,7 +76,7 @@ libp2p = { version = "0.55.1", path = "libp2p" } libp2p-allow-block-list = { version = "0.5.0", path = "misc/allow-block-list" } libp2p-autonat = { version = "0.14.1", path = "protocols/autonat" } libp2p-connection-limits = { version = "0.5.1", path = "misc/connection-limits" } -libp2p-core = { version = "0.43.1", path = "core" } +libp2p-core = { version = "0.43.0", path = "core" } libp2p-dcutr = { version = "0.13.0", path = "protocols/dcutr" } libp2p-dns = { version = "0.43.0", path = "transports/dns" } libp2p-floodsub = { version = "0.46.1", path = "protocols/floodsub" } diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index d46f439da41..898031c006e 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -1,10 +1,3 @@ -## 0.43.1 - -- Add `libp2p_core::peer_record::PeerRecord::try_deserialize_signed_peer_record` - utility method for deserializing `SignedEnvelope` without creating an instance of - `PeerRecord`. - See [PR 5785](https://github.com/libp2p/rust-libp2p/pull/5785) - ## 0.43.0 - Added `libp2p::core::util::unreachable` that is a drop-in replacement of `void::unreachable`. diff --git a/core/Cargo.toml b/core/Cargo.toml index c2befa37568..5e84c6f0435 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -3,7 +3,7 @@ name = "libp2p-core" edition = "2021" rust-version = { workspace = true } description = "Core traits and structs of libp2p" -version = "0.43.1" +version = "0.43.0" authors = ["Parity Technologies "] license = "MIT" repository = "https://github.com/libp2p/rust-libp2p"