Skip to content

Commit 4044c13

Browse files
authored
Merge branch 'master' into dns-issue
2 parents 5fb486c + 09fa853 commit 4044c13

14 files changed

+219
-28
lines changed

Cargo.lock

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ libp2p-dcutr = { version = "0.13.0", path = "protocols/dcutr" }
8181
libp2p-dns = { version = "0.43.0", path = "transports/dns" }
8282
libp2p-floodsub = { version = "0.46.1", path = "protocols/floodsub" }
8383
libp2p-gossipsub = { version = "0.48.1", path = "protocols/gossipsub" }
84-
libp2p-identify = { version = "0.46.0", path = "protocols/identify" }
84+
libp2p-identify = { version = "0.47.0", path = "protocols/identify" }
8585
libp2p-identity = { version = "0.2.10" }
8686
libp2p-kad = { version = "0.47.0", path = "protocols/kad" }
8787
libp2p-mdns = { version = "0.47.0", path = "protocols/mdns" }
@@ -93,7 +93,7 @@ libp2p-perf = { version = "0.4.0", path = "protocols/perf" }
9393
libp2p-ping = { version = "0.46.0", path = "protocols/ping" }
9494
libp2p-plaintext = { version = "0.43.0", path = "transports/plaintext" }
9595
libp2p-pnet = { version = "0.26.0", path = "transports/pnet" }
96-
libp2p-quic = { version = "0.12.0", path = "transports/quic" }
96+
libp2p-quic = { version = "0.12.1", path = "transports/quic" }
9797
libp2p-relay = { version = "0.20.0", path = "protocols/relay" }
9898
libp2p-rendezvous = { version = "0.16.0", path = "protocols/rendezvous" }
9999
libp2p-request-response = { version = "0.28.1", path = "protocols/request-response" }

protocols/identify/CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 0.47.0
2+
3+
- Implement optional `signedPeerRecord` support for identify messages.
4+
See [PR 5785](https://github.com/libp2p/rust-libp2p/pull/5785)
5+
16
## 0.46.0
27

38
- Add `hide_listen_addrs` option to prevent leaking (local) listen addresses.

protocols/identify/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "libp2p-identify"
33
edition = "2021"
44
rust-version = { workspace = true }
55
description = "Nodes identification protocol for libp2p"
6-
version = "0.46.0"
6+
version = "0.47.0"
77
authors = ["Parity Technologies <[email protected]>"]
88
license = "MIT"
99
repository = "https://github.com/libp2p/rust-libp2p"

protocols/identify/src/behaviour.rs

+59-9
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,17 @@
2121
use std::{
2222
collections::{hash_map::Entry, HashMap, HashSet, VecDeque},
2323
num::NonZeroUsize,
24+
sync::Arc,
2425
task::{Context, Poll},
2526
time::Duration,
2627
};
2728

2829
use libp2p_core::{
29-
multiaddr, multiaddr::Protocol, transport::PortUse, ConnectedPoint, Endpoint, Multiaddr,
30+
multiaddr::{self, Protocol},
31+
transport::PortUse,
32+
ConnectedPoint, Endpoint, Multiaddr,
3033
};
31-
use libp2p_identity::{PeerId, PublicKey};
34+
use libp2p_identity::{Keypair, PeerId, PublicKey};
3235
use libp2p_swarm::{
3336
behaviour::{ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm},
3437
ConnectionDenied, ConnectionId, DialError, ExternalAddresses, ListenAddresses,
@@ -117,8 +120,10 @@ pub struct Config {
117120
/// Application-specific version of the protocol family used by the peer,
118121
/// e.g. `ipfs/1.0.0` or `polkadot/1.0.0`.
119122
protocol_version: String,
120-
/// The public key of the local node. To report on the wire.
121-
local_public_key: PublicKey,
123+
/// The key of the local node. Only the public key will be report on the wire.
124+
/// The behaviour will send signed [`PeerRecord`](libp2p_core::PeerRecord) in
125+
/// its identify message only when supplied with a keypair.
126+
local_key: Arc<KeyType>,
122127
/// Name and version of the local peer implementation, similar to the
123128
/// `User-Agent` header in the HTTP protocol.
124129
///
@@ -156,12 +161,26 @@ pub struct Config {
156161

157162
impl Config {
158163
/// Creates a new configuration for the identify [`Behaviour`] that
159-
/// advertises the given protocol version and public key.
164+
/// advertises the given protocol version and public key.
165+
/// Use [`new_with_signed_peer_record`](Config::new_with_signed_peer_record) for
166+
/// `signedPeerRecord` support.
160167
pub fn new(protocol_version: String, local_public_key: PublicKey) -> Self {
168+
Self::new_with_key(protocol_version, local_public_key)
169+
}
170+
171+
/// Creates a new configuration for the identify [`Behaviour`] that
172+
/// advertises the given protocol version and public key.
173+
/// The private key will be used to sign [`PeerRecord`](libp2p_core::PeerRecord)
174+
/// for verifiable address advertisement.
175+
pub fn new_with_signed_peer_record(protocol_version: String, local_keypair: &Keypair) -> Self {
176+
Self::new_with_key(protocol_version, local_keypair)
177+
}
178+
179+
fn new_with_key(protocol_version: String, key: impl Into<KeyType>) -> Self {
161180
Self {
162181
protocol_version,
163182
agent_version: format!("rust-libp2p/{}", env!("CARGO_PKG_VERSION")),
164-
local_public_key,
183+
local_key: Arc::new(key.into()),
165184
interval: Duration::from_secs(5 * 60),
166185
push_listen_addr_updates: false,
167186
cache_size: 100,
@@ -209,7 +228,7 @@ impl Config {
209228

210229
/// Get the local public key of the Config.
211230
pub fn local_public_key(&self) -> &PublicKey {
212-
&self.local_public_key
231+
self.local_key.public_key()
213232
}
214233

215234
/// Get the agent version of the Config.
@@ -380,7 +399,7 @@ impl NetworkBehaviour for Behaviour {
380399
Ok(Handler::new(
381400
self.config.interval,
382401
peer,
383-
self.config.local_public_key.clone(),
402+
self.config.local_key.clone(),
384403
self.config.protocol_version.clone(),
385404
self.config.agent_version.clone(),
386405
remote_addr.clone(),
@@ -413,7 +432,7 @@ impl NetworkBehaviour for Behaviour {
413432
Ok(Handler::new(
414433
self.config.interval,
415434
peer,
416-
self.config.local_public_key.clone(),
435+
self.config.local_key.clone(),
417436
self.config.protocol_version.clone(),
418437
self.config.agent_version.clone(),
419438
// TODO: This is weird? That is the public address we dialed,
@@ -670,6 +689,37 @@ impl PeerCache {
670689
}
671690
}
672691

692+
#[derive(Debug, Clone)]
693+
#[allow(clippy::large_enum_variant)]
694+
pub(crate) enum KeyType {
695+
PublicKey(PublicKey),
696+
Keypair {
697+
keypair: Keypair,
698+
public_key: PublicKey,
699+
},
700+
}
701+
impl From<PublicKey> for KeyType {
702+
fn from(value: PublicKey) -> Self {
703+
Self::PublicKey(value)
704+
}
705+
}
706+
impl From<&Keypair> for KeyType {
707+
fn from(value: &Keypair) -> Self {
708+
Self::Keypair {
709+
public_key: value.public(),
710+
keypair: value.clone(),
711+
}
712+
}
713+
}
714+
impl KeyType {
715+
pub(crate) fn public_key(&self) -> &PublicKey {
716+
match &self {
717+
KeyType::PublicKey(pubkey) => pubkey,
718+
KeyType::Keypair { public_key, .. } => public_key,
719+
}
720+
}
721+
}
722+
673723
#[cfg(test)]
674724
mod tests {
675725
use super::*;

protocols/identify/src/generated/structs.proto

+8
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,12 @@ message Identify {
2424
optional bytes observedAddr = 4;
2525

2626
repeated string protocols = 3;
27+
28+
// signedPeerRecord contains a serialized SignedEnvelope containing a PeerRecord,
29+
// signed by the sending node. It contains the same addresses as the listenAddrs field, but
30+
// in a form that lets us share authenticated addrs with other peers.
31+
// see https://github.com/libp2p/rust-libp2p/blob/8ac5b5aac5f5c25a85f1065e292deeaf58290189/core/src/generated/envelope.proto#L12
32+
// and https://github.com/libp2p/rust-libp2p/blob/8ac5b5aac5f5c25a85f1065e292deeaf58290189/core/src/generated/peer_record.proto#L11
33+
// for message definitions.
34+
optional bytes signedPeerRecord = 8;
2735
}

protocols/identify/src/generated/structs.rs

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub struct Identify {
2222
pub listenAddrs: Vec<Vec<u8>>,
2323
pub observedAddr: Option<Vec<u8>>,
2424
pub protocols: Vec<String>,
25+
pub signedPeerRecord: Option<Vec<u8>>,
2526
}
2627

2728
impl<'a> MessageRead<'a> for Identify {
@@ -35,6 +36,7 @@ impl<'a> MessageRead<'a> for Identify {
3536
Ok(18) => msg.listenAddrs.push(r.read_bytes(bytes)?.to_owned()),
3637
Ok(34) => msg.observedAddr = Some(r.read_bytes(bytes)?.to_owned()),
3738
Ok(26) => msg.protocols.push(r.read_string(bytes)?.to_owned()),
39+
Ok(66) => msg.signedPeerRecord = Some(r.read_bytes(bytes)?.to_owned()),
3840
Ok(t) => { r.read_unknown(bytes, t)?; }
3941
Err(e) => return Err(e),
4042
}
@@ -52,6 +54,7 @@ impl MessageWrite for Identify {
5254
+ self.listenAddrs.iter().map(|s| 1 + sizeof_len((s).len())).sum::<usize>()
5355
+ self.observedAddr.as_ref().map_or(0, |m| 1 + sizeof_len((m).len()))
5456
+ self.protocols.iter().map(|s| 1 + sizeof_len((s).len())).sum::<usize>()
57+
+ self.signedPeerRecord.as_ref().map_or(0, |m| 1 + sizeof_len((m).len()))
5558
}
5659

5760
fn write_message<W: WriterBackend>(&self, w: &mut Writer<W>) -> Result<()> {
@@ -61,6 +64,7 @@ impl MessageWrite for Identify {
6164
for s in &self.listenAddrs { w.write_with_tag(18, |w| w.write_bytes(&**s))?; }
6265
if let Some(ref s) = self.observedAddr { w.write_with_tag(34, |w| w.write_bytes(&**s))?; }
6366
for s in &self.protocols { w.write_with_tag(26, |w| w.write_string(&**s))?; }
67+
if let Some(ref s) = self.signedPeerRecord { w.write_with_tag(66, |w| w.write_bytes(&**s))?; }
6468
Ok(())
6569
}
6670
}

protocols/identify/src/handler.rs

+20-9
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
use std::{
2222
collections::HashSet,
23+
sync::Arc,
2324
task::{Context, Poll},
2425
time::Duration,
2526
};
@@ -32,7 +33,7 @@ use libp2p_core::{
3233
upgrade::{ReadyUpgrade, SelectUpgrade},
3334
Multiaddr,
3435
};
35-
use libp2p_identity::{PeerId, PublicKey};
36+
use libp2p_identity::PeerId;
3637
use libp2p_swarm::{
3738
handler::{
3839
ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound,
@@ -45,8 +46,8 @@ use smallvec::SmallVec;
4546
use tracing::Level;
4647

4748
use crate::{
48-
protocol,
49-
protocol::{Info, PushInfo, UpgradeError},
49+
behaviour::KeyType,
50+
protocol::{self, Info, PushInfo, UpgradeError},
5051
PROTOCOL_NAME, PUSH_PROTOCOL_NAME,
5152
};
5253

@@ -80,8 +81,8 @@ pub struct Handler {
8081
/// The interval of `trigger_next_identify`, i.e. the recurrent delay.
8182
interval: Duration,
8283

83-
/// The public key of the local peer.
84-
public_key: PublicKey,
84+
/// The key of the local peer.
85+
local_key: Arc<KeyType>,
8586

8687
/// Application-specific version of the protocol family used by the peer,
8788
/// e.g. `ipfs/1.0.0` or `polkadot/1.0.0`.
@@ -125,10 +126,10 @@ pub enum Event {
125126

126127
impl Handler {
127128
/// Creates a new `Handler`.
128-
pub fn new(
129+
pub(crate) fn new(
129130
interval: Duration,
130131
remote_peer_id: PeerId,
131-
public_key: PublicKey,
132+
local_key: Arc<KeyType>,
132133
protocol_version: String,
133134
agent_version: String,
134135
observed_addr: Multiaddr,
@@ -144,7 +145,7 @@ impl Handler {
144145
trigger_next_identify: Delay::new(Duration::ZERO),
145146
exchanged_one_periodic_identify: false,
146147
interval,
147-
public_key,
148+
local_key,
148149
protocol_version,
149150
agent_version,
150151
observed_addr,
@@ -226,13 +227,23 @@ impl Handler {
226227
}
227228

228229
fn build_info(&mut self) -> Info {
230+
let signed_envelope = match self.local_key.as_ref() {
231+
KeyType::PublicKey(_) => None,
232+
KeyType::Keypair { keypair, .. } => libp2p_core::PeerRecord::new(
233+
keypair,
234+
Vec::from_iter(self.external_addresses.iter().cloned()),
235+
)
236+
.ok()
237+
.map(|r| r.into_signed_envelope()),
238+
};
229239
Info {
230-
public_key: self.public_key.clone(),
240+
public_key: self.local_key.public_key().clone(),
231241
protocol_version: self.protocol_version.clone(),
232242
agent_version: self.agent_version.clone(),
233243
listen_addrs: Vec::from_iter(self.external_addresses.iter().cloned()),
234244
protocols: Vec::from_iter(self.local_supported_protocols.iter().cloned()),
235245
observed_addr: self.observed_addr.clone(),
246+
signed_peer_record: signed_envelope,
236247
}
237248
}
238249

0 commit comments

Comments
 (0)