mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-14 02:12:33 +00:00
Add support for noise protocol (#873)
* Add noise support with fallback to secio * Add config parameter for noise support * Add secio/noise compatibility test * Cleanup * Remove config parameter for noise support * Modify test to work between a secio swarm and a noise libp2p service * Minor fixes
This commit is contained in:
@@ -7,11 +7,16 @@ use crate::{NetworkGlobals, Topic, TopicHash};
|
||||
use futures::prelude::*;
|
||||
use futures::Stream;
|
||||
use libp2p::core::{
|
||||
identity::Keypair, multiaddr::Multiaddr, muxing::StreamMuxerBox, nodes::Substream,
|
||||
transport::boxed::Boxed, ConnectedPoint,
|
||||
identity::Keypair,
|
||||
multiaddr::Multiaddr,
|
||||
muxing::StreamMuxerBox,
|
||||
nodes::Substream,
|
||||
transport::boxed::Boxed,
|
||||
upgrade::{InboundUpgradeExt, OutboundUpgradeExt},
|
||||
ConnectedPoint,
|
||||
};
|
||||
use libp2p::gossipsub::MessageId;
|
||||
use libp2p::{core, secio, swarm::NetworkBehaviour, PeerId, Swarm, Transport};
|
||||
use libp2p::{core, noise, secio, swarm::NetworkBehaviour, PeerId, Swarm, Transport};
|
||||
use slog::{crit, debug, error, info, trace, warn};
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
@@ -68,7 +73,7 @@ impl Service {
|
||||
let network_globals = Arc::new(NetworkGlobals::new(local_peer_id.clone()));
|
||||
|
||||
let mut swarm = {
|
||||
// Set up the transport - tcp/ws with secio and mplex/yamux
|
||||
// Set up the transport - tcp/ws with noise/secio and mplex/yamux
|
||||
let transport = build_transport(local_keypair.clone());
|
||||
// Lighthouse network behaviour
|
||||
let behaviour = Behaviour::new(&local_keypair, config, network_globals.clone(), &log)?;
|
||||
@@ -250,7 +255,7 @@ impl Stream for Service {
|
||||
}
|
||||
}
|
||||
|
||||
/// The implementation supports TCP/IP, WebSockets over TCP/IP, secio as the encryption layer, and
|
||||
/// The implementation supports TCP/IP, WebSockets over TCP/IP, noise/secio as the encryption layer, and
|
||||
/// mplex or yamux as the multiplexing layer.
|
||||
fn build_transport(local_private_key: Keypair) -> Boxed<(PeerId, StreamMuxerBox), Error> {
|
||||
// TODO: The Wire protocol currently doesn't specify encryption and this will need to be customised
|
||||
@@ -262,20 +267,51 @@ fn build_transport(local_private_key: Keypair) -> Boxed<(PeerId, StreamMuxerBox)
|
||||
let trans_clone = transport.clone();
|
||||
transport.or_transport(websocket::WsConfig::new(trans_clone))
|
||||
};
|
||||
transport
|
||||
.upgrade(core::upgrade::Version::V1)
|
||||
.authenticate(secio::SecioConfig::new(local_private_key))
|
||||
.multiplex(core::upgrade::SelectUpgrade::new(
|
||||
libp2p::yamux::Config::default(),
|
||||
libp2p::mplex::MplexConfig::new(),
|
||||
))
|
||||
.map(|(peer, muxer), _| (peer, core::muxing::StreamMuxerBox::new(muxer)))
|
||||
.timeout(Duration::from_secs(20))
|
||||
// Authentication
|
||||
let transport = transport
|
||||
.and_then(move |stream, endpoint| {
|
||||
let upgrade = core::upgrade::SelectUpgrade::new(
|
||||
generate_noise_config(&local_private_key),
|
||||
secio::SecioConfig::new(local_private_key),
|
||||
);
|
||||
core::upgrade::apply(stream, upgrade, endpoint, core::upgrade::Version::V1).and_then(
|
||||
move |out| {
|
||||
match out {
|
||||
// Noise was negotiated
|
||||
core::either::EitherOutput::First((remote_id, out)) => {
|
||||
Ok((core::either::EitherOutput::First(out), remote_id))
|
||||
}
|
||||
// Secio was negotiated
|
||||
core::either::EitherOutput::Second((remote_id, out)) => {
|
||||
Ok((core::either::EitherOutput::Second(out), remote_id))
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
})
|
||||
.timeout(Duration::from_secs(20));
|
||||
|
||||
// Multiplexing
|
||||
let transport = transport
|
||||
.and_then(move |(stream, peer_id), endpoint| {
|
||||
let peer_id2 = peer_id.clone();
|
||||
let upgrade = core::upgrade::SelectUpgrade::new(
|
||||
libp2p::yamux::Config::default(),
|
||||
libp2p::mplex::MplexConfig::new(),
|
||||
)
|
||||
.map_inbound(move |muxer| (peer_id, muxer))
|
||||
.map_outbound(move |muxer| (peer_id2, muxer));
|
||||
|
||||
core::upgrade::apply(stream, upgrade, endpoint, core::upgrade::Version::V1)
|
||||
.map(|(id, muxer)| (id, core::muxing::StreamMuxerBox::new(muxer)))
|
||||
})
|
||||
.timeout(Duration::from_secs(20))
|
||||
.map_err(|err| Error::new(ErrorKind::Other, err))
|
||||
.boxed()
|
||||
.boxed();
|
||||
transport
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Events that can be obtained from polling the Libp2p Service.
|
||||
pub enum Libp2pEvent {
|
||||
/// An RPC response request has been received on the swarm.
|
||||
@@ -363,3 +399,13 @@ fn load_private_key(config: &NetworkConfig, log: &slog::Logger) -> Keypair {
|
||||
}
|
||||
local_private_key
|
||||
}
|
||||
|
||||
/// Generate authenticated XX Noise config from identity keys
|
||||
fn generate_noise_config(
|
||||
identity_keypair: &Keypair,
|
||||
) -> noise::NoiseAuthenticated<noise::XX, noise::X25519, ()> {
|
||||
let static_dh_keys = noise::Keypair::<noise::X25519>::new()
|
||||
.into_authentic(identity_keypair)
|
||||
.expect("signing can fail only once during starting a node");
|
||||
noise::NoiseConfig::xx(static_dh_keys).into_authenticated()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user