Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate a new PeerId for each connection #1255

Merged
merged 4 commits into from
Oct 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading