Skip to content

Commit

Permalink
Generate a new PeerId for each connection (#1255)
Browse files Browse the repository at this point in the history
* Generate a new PeerId for each connection

* CHANGELOG

* Expand CHANGELOG and typo

* Fix typo
  • Loading branch information
tomaka authored Oct 29, 2023
1 parent bb9487b commit 66aac10
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 121 deletions.
9 changes: 7 additions & 2 deletions full-node/src/network_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,9 @@ struct Inner {
>,

/// Identity of the local node.
noise_key: service::NoiseKey,

/// Identity of the local node. Can be derived from [`Inner::noise_key`].
local_peer_id: PeerId,

/// Service to use to report traces.
Expand Down Expand Up @@ -296,7 +299,6 @@ impl NetworkService {
let mut network = service::ChainNetwork::new(service::Config {
chains_capacity: config.chains.len(),
connections_capacity: 100, // TODO: ?
noise_key: config.noise_key,
handshake_timeout: Duration::from_secs(8),
randomness_seed: rand::random(),
});
Expand Down Expand Up @@ -347,7 +349,7 @@ impl NetworkService {
let foreground_shutdown = event_listener::Event::new();

let local_peer_id =
peer_id::PublicKey::Ed25519(*network.noise_key().libp2p_public_ed25519_key())
peer_id::PublicKey::Ed25519(*config.noise_key.libp2p_public_ed25519_key())
.into_peer_id();

// Initialize the inner network service.
Expand All @@ -362,6 +364,7 @@ impl NetworkService {
tasks_executor: config.tasks_executor,
log_callback: config.log_callback.clone(),
network,
noise_key: config.noise_key,
peering_strategy,
active_connections: hashbrown::HashMap::with_capacity_and_hasher(
100, // TODO: ?
Expand Down Expand Up @@ -1443,6 +1446,7 @@ async fn background_task(mut inner: Inner) {
Instant::now(),
service::SingleStreamHandshakeKind::MultistreamSelectNoiseYamux {
is_initiator: true,
noise_key: &inner.noise_key,
},
multiaddr.clone().into_vec(),
Some(peer_id.clone()),
Expand Down Expand Up @@ -1543,6 +1547,7 @@ async fn background_task(mut inner: Inner) {
when_accepted,
service::SingleStreamHandshakeKind::MultistreamSelectNoiseYamux {
is_initiator: false,
noise_key: &inner.noise_key,
},
multiaddr.clone().into_vec(),
None,
Expand Down
90 changes: 22 additions & 68 deletions lib/src/network/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ use rand_chacha::rand_core::{RngCore as _, SeedableRng as _};
pub use crate::libp2p::{
collection::{
ConnectionId, ConnectionToCoordinator, CoordinatorToConnection, InboundError,
MultiStreamConnectionTask, NotificationsOutErr, ReadWrite, RequestError,
SingleStreamConnectionTask, SubstreamId,
MultiStreamConnectionTask, MultiStreamHandshakeKind, NotificationsOutErr, ReadWrite,
RequestError, SingleStreamConnectionTask, SingleStreamHandshakeKind, SubstreamId,
},
connection::noise::{self, NoiseKey},
multiaddr::{self, Multiaddr},
Expand All @@ -119,11 +119,6 @@ pub struct Config {
/// This is a defensive measure against users passing a dummy seed instead of actual entropy.
pub randomness_seed: [u8; 32],

/// Key used for the encryption layer.
/// This is a Noise static key, according to the Noise specification.
/// Signed using the actual libp2p key.
pub noise_key: NoiseKey,

/// Amount of time after which a connection hathat ndshake is considered to have taken too long
/// and must be aborted.
pub handshake_timeout: Duration,
Expand Down Expand Up @@ -198,10 +193,6 @@ pub struct ChainNetwork<TChain, TNow> {
collection::SubstreamId,
)>,

/// See [`Config::noise_key`].
// TODO: make rotatable, see <https://github.com/smol-dot/smoldot/issues/44>
noise_key: NoiseKey,

/// Chains indexed by genesis hash and fork ID.
///
/// Contains the same number of entries as [`ChainNetwork::chains`]. The values are `usize`s
Expand Down Expand Up @@ -266,6 +257,10 @@ struct Chain<TChain> {
struct ConnectionInfo {
address: Vec<u8>,

/// Public key of the local node used for this connection.
/// This information can be requested by the remote.
ed25519_public_key: [u8; 32],

/// Identity of the remote. Can be either the expected or the actual identity.
///
/// `None` if unknown, which can only be the case if the connection is still in its handshake
Expand Down Expand Up @@ -408,15 +403,9 @@ where
config.chains_capacity,
Default::default(),
),
noise_key: config.noise_key,
}
}

/// Returns the Noise key originally passed as [`Config::noise_key`].
pub fn noise_key(&self) -> &NoiseKey {
&self.noise_key
}

/// Adds a chain to the list of chains that is handled by the [`ChainNetwork`].
///
/// It is not possible to add a chain if its protocol names would conflict with an existing
Expand Down Expand Up @@ -782,20 +771,19 @@ where
// TODO: do the max protocol name length better ; knowing that it can later change if a chain with a long forkId is added
let max_protocol_name_len = 256;
let substreams_capacity = 16; // TODO: ?
let ed25519_public_key = match handshake_kind {
SingleStreamHandshakeKind::MultistreamSelectNoiseYamux { noise_key, .. } => {
*noise_key.libp2p_public_ed25519_key()
}
};
let (id, task) = self.inner.insert_single_stream(
when_connection_start,
match handshake_kind {
SingleStreamHandshakeKind::MultistreamSelectNoiseYamux { is_initiator } => {
collection::SingleStreamHandshakeKind::MultistreamSelectNoiseYamux {
is_initiator,
noise_key: &self.noise_key,
}
}
},
handshake_kind,
substreams_capacity,
max_protocol_name_len,
ConnectionInfo {
address: remote_addr,
ed25519_public_key,
peer_id: expected_peer_id.clone(),
},
);
Expand Down Expand Up @@ -835,25 +823,20 @@ where
// TODO: do the max protocol name length better ; knowing that it can later change if a chain with a long forkId is added
let max_protocol_name_len = 256;
let substreams_capacity = 16; // TODO: ?
let ed25519_public_key = match handshake_kind {
MultiStreamHandshakeKind::WebRtc { noise_key, .. } => {
*noise_key.libp2p_public_ed25519_key()
}
};
let (id, task) = self.inner.insert_multi_stream(
when_connection_start,
match handshake_kind {
MultiStreamHandshakeKind::WebRtc {
is_initiator,
local_tls_certificate_multihash,
remote_tls_certificate_multihash,
} => collection::MultiStreamHandshakeKind::WebRtc {
is_initiator,
noise_key: &self.noise_key,
local_tls_certificate_multihash,
remote_tls_certificate_multihash,
},
},
handshake_kind,
substreams_capacity,
max_protocol_name_len,
ConnectionInfo {
address: remote_addr,
peer_id: expected_peer_id.clone(),
ed25519_public_key,
},
);
if let Some(expected_peer_id) = expected_peer_id {
Expand Down Expand Up @@ -2791,6 +2774,7 @@ where

let response = {
let observed_addr = &self.inner[substream_info.connection_id].address;
let ed25519_public_key = &self.inner[substream_info.connection_id].ed25519_public_key;

// TODO: all protocols
let supported_protocols = [protocol::ProtocolName::Ping].into_iter();
Expand All @@ -2802,7 +2786,7 @@ where
protocol::build_identify_response(protocol::IdentifyResponse {
protocol_version: "/substrate/1.0", // TODO: same value as in Substrate, see also https://github.com/paritytech/substrate/issues/14331
agent_version,
ed25519_public_key: *self.noise_key.libp2p_public_ed25519_key(),
ed25519_public_key: *ed25519_public_key,
listen_addrs: iter::empty(), // TODO:
observed_addr,
protocols: supported_protocols_names.iter().map(|p| &p[..]),
Expand Down Expand Up @@ -3438,36 +3422,6 @@ impl<TChain, TNow> ops::IndexMut<ChainId> for ChainNetwork<TChain, TNow> {
}
}

/// What kind of handshake to perform on the newly-added connection.
pub enum SingleStreamHandshakeKind {
/// Use the multistream-select protocol to negotiate the Noise encryption, then use the
/// multistream-select protocol to negotiate the Yamux multiplexing.
MultistreamSelectNoiseYamux {
/// Must be `true` if the connection has been initiated locally, or `false` if it has been
/// initiated by the remote.
is_initiator: bool,
},
}

/// What kind of handshake to perform on the newly-added connection.
pub enum MultiStreamHandshakeKind {
/// The connection is a WebRTC connection.
///
/// See <https://github.com/libp2p/specs/pull/412> for details.
///
/// The reading and writing side of substreams must never be closed. Substreams can only be
/// abruptly destroyed by either side.
WebRtc {
/// Must be `true` if the connection has been initiated locally, or `false` if it has been
/// initiated by the remote.
is_initiator: bool,
/// Multihash encoding of the TLS certificate used by the local node at the DTLS layer.
local_tls_certificate_multihash: Vec<u8>,
/// Multihash encoding of the TLS certificate used by the remote node at the DTLS layer.
remote_tls_certificate_multihash: Vec<u8>,
},
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum GossipKind {
ConsensusTransactions,
Expand Down
5 changes: 1 addition & 4 deletions light-base/src/json_rpc_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ use alloc::{
sync::Arc,
};
use core::num::NonZeroU32;
use smoldot::{chain_spec, json_rpc::service, libp2p::PeerId};
use smoldot::{chain_spec, json_rpc::service};

/// Configuration for [`service()`].
pub struct Config {
Expand Down Expand Up @@ -223,9 +223,6 @@ pub struct StartConfig<'a, TPlat: PlatformRef> {
/// Specification of the chain.
pub chain_spec: &'a chain_spec::ChainSpec,

/// Network identity of the node.
pub peer_id: &'a PeerId,

/// Value to return when the `system_name` RPC is called. Should be set to the name of the
/// final executable.
pub system_name: String,
Expand Down
8 changes: 1 addition & 7 deletions light-base/src/json_rpc_service/background.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,6 @@ struct Background<TPlat: PlatformRef> {
chain_properties_json: String,
/// Whether the chain is a live network. Found in the chain specification.
chain_is_live: bool,
/// See [`StartConfig::peer_id`]. The only use for this field is to send the Base58 encoding of
/// the [`PeerId`]. Consequently, we store the conversion to Base58 ahead of time.
peer_id_base58: String,
/// Value to return when the `system_name` RPC is called.
system_name: String,
/// Value to return when the `system_version` RPC is called.
Expand Down Expand Up @@ -145,7 +142,6 @@ pub(super) fn start<TPlat: PlatformRef>(
chain_ty: config.chain_spec.chain_type().to_owned(),
chain_is_live: config.chain_spec.has_live_network(),
chain_properties_json: config.chain_spec.properties().to_owned(),
peer_id_base58: config.peer_id.to_base58(),
system_name: config.system_name.clone(),
system_version: config.system_version.clone(),
network_service: config.network_service.clone(),
Expand Down Expand Up @@ -428,9 +424,6 @@ impl<TPlat: PlatformRef> Background<TPlat> {
methods::MethodCall::system_localListenAddresses {} => {
self.system_local_listen_addresses(request).await;
}
methods::MethodCall::system_localPeerId {} => {
self.system_local_peer_id(request).await;
}
methods::MethodCall::system_name {} => {
self.system_name(request).await;
}
Expand Down Expand Up @@ -508,6 +501,7 @@ impl<TPlat: PlatformRef> Background<TPlat> {
| methods::MethodCall::state_queryStorage { .. }
| methods::MethodCall::system_addReservedPeer { .. }
| methods::MethodCall::system_dryRun { .. }
| methods::MethodCall::system_localPeerId { .. }
| methods::MethodCall::system_networkState { .. }
| methods::MethodCall::system_removeReservedPeer { .. }) => {
// TODO: implement the ones that make sense to implement ^
Expand Down
7 changes: 0 additions & 7 deletions light-base/src/json_rpc_service/background/getters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,6 @@ impl<TPlat: PlatformRef> Background<TPlat> {
request.respond(methods::Response::system_localListenAddresses(Vec::new()));
}

/// Handles a call to [`methods::MethodCall::system_localPeerId`].
pub(super) async fn system_local_peer_id(self: &Arc<Self>, request: service::RequestProcess) {
request.respond(methods::Response::system_localPeerId(
(&self.peer_id_base58).into(),
));
}

/// Handles a call to [`methods::MethodCall::system_name`].
pub(super) async fn system_name(self: &Arc<Self>, request: service::RequestProcess) {
request.respond(methods::Response::system_name((&self.system_name).into()));
Expand Down
Loading

0 comments on commit 66aac10

Please sign in to comment.