libp2p-next (#5278)

* Adapt to rust-libp2p#1440.

* Further adapt to libp2p/master.

* Update to libp2p-0.17

* Finishing touches.

* Remove stray TODO.

* Incorporate review feedback.

* Remove unused import.
This commit is contained in:
Roman Borschel
2020-04-08 09:23:21 +02:00
committed by GitHub
parent 1a9c0fee30
commit f8c8355ac7
26 changed files with 1049 additions and 681 deletions
File diff suppressed because it is too large Load Diff
@@ -143,7 +143,7 @@ impl IntoProtocolsHandler for NotifsHandlerProto {
}
/// Event that can be received by a `NotifsHandler`.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum NotifsHandlerIn {
/// The node should start using custom protocols.
Enable,
@@ -181,13 +181,18 @@ pub enum NotifsHandlerIn {
/// Event that can be emitted by a `NotifsHandler`.
#[derive(Debug)]
pub enum NotifsHandlerOut {
/// Opened the substreams with the remote.
Open,
/// The connection is open for custom protocols.
Open {
/// The endpoint of the connection that is open for custom protocols.
endpoint: ConnectedPoint,
},
/// Closed the substreams with the remote.
/// The connection is closed for custom protocols.
Closed {
/// Reason why the substream closed, for diagnostic purposes.
/// The reason for closing, for diagnostic purposes.
reason: Cow<'static, str>,
/// The endpoint of the connection that closed for custom protocols.
endpoint: ConnectedPoint,
},
/// Received a non-gossiping message on the legacy substream.
@@ -497,13 +502,13 @@ impl ProtocolsHandler for NotifsHandler {
protocol: protocol.map_upgrade(EitherUpgrade::B),
info: None,
}),
ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomProtocolOpen { .. }) =>
ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomProtocolOpen { endpoint, .. }) =>
return Poll::Ready(ProtocolsHandlerEvent::Custom(
NotifsHandlerOut::Open
NotifsHandlerOut::Open { endpoint }
)),
ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomProtocolClosed { reason }) =>
ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomProtocolClosed { endpoint, reason }) =>
return Poll::Ready(ProtocolsHandlerEvent::Custom(
NotifsHandlerOut::Closed { reason }
NotifsHandlerOut::Closed { endpoint, reason }
)),
ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomMessage { message }) =>
return Poll::Ready(ProtocolsHandlerEvent::Custom(
@@ -40,9 +40,8 @@ use std::{pin::Pin, task::{Context, Poll}};
/// it is turned into a `LegacyProtoHandler`. It then handles all communications that are specific
/// to Substrate on that single connection.
///
/// Note that there can be multiple instance of this struct simultaneously for same peer. However
/// if that happens, only one main instance can communicate with the outer layers of the code. In
/// other words, the outer layers of the code only ever see one handler.
/// Note that there can be multiple instance of this struct simultaneously for same peer,
/// if there are multiple established connections to the peer.
///
/// ## State of the handler
///
@@ -61,6 +60,7 @@ use std::{pin::Pin, task::{Context, Poll}};
/// these states. For example, if the handler reports a network misbehaviour, it will close the
/// substreams but it is the role of the user to send a `Disabled` event if it wants the connection
/// to close. Otherwise, the handler will try to reopen substreams.
///
/// The handler starts in the "Initializing" state and must be transitionned to Enabled or Disabled
/// as soon as possible.
///
@@ -111,7 +111,7 @@ impl IntoProtocolsHandler for LegacyProtoHandlerProto {
fn into_handler(self, remote_peer_id: &PeerId, connected_point: &ConnectedPoint) -> Self::Handler {
LegacyProtoHandler {
protocol: self.protocol,
endpoint: connected_point.to_endpoint(),
endpoint: connected_point.clone(),
remote_peer_id: remote_peer_id.clone(),
state: ProtocolState::Init {
substreams: SmallVec::new(),
@@ -136,7 +136,7 @@ pub struct LegacyProtoHandler {
/// Whether we are the connection dialer or listener. Used to determine who, between the local
/// node and the remote node, has priority.
endpoint: Endpoint,
endpoint: ConnectedPoint,
/// Queue of events to send to the outside.
///
@@ -218,12 +218,16 @@ pub enum LegacyProtoHandlerOut {
CustomProtocolOpen {
/// Version of the protocol that has been opened.
version: u8,
/// The connected endpoint.
endpoint: ConnectedPoint,
},
/// Closed a custom protocol with the remote.
CustomProtocolClosed {
/// Reason why the substream closed, for diagnostic purposes.
reason: Cow<'static, str>,
/// The connected endpoint.
endpoint: ConnectedPoint,
},
/// Receives a message on a custom protocol substream.
@@ -272,7 +276,7 @@ impl LegacyProtoHandler {
ProtocolState::Init { substreams: incoming, .. } => {
if incoming.is_empty() {
if let Endpoint::Dialer = self.endpoint {
if let ConnectedPoint::Dialer { .. } = self.endpoint {
self.events_queue.push(ProtocolsHandlerEvent::OutboundSubstreamRequest {
protocol: SubstreamProtocol::new(self.protocol.clone()),
info: (),
@@ -281,10 +285,10 @@ impl LegacyProtoHandler {
ProtocolState::Opening {
deadline: Delay::new(Duration::from_secs(60))
}
} else {
let event = LegacyProtoHandlerOut::CustomProtocolOpen {
version: incoming[0].protocol_version()
version: incoming[0].protocol_version(),
endpoint: self.endpoint.clone()
};
self.events_queue.push(ProtocolsHandlerEvent::Custom(event));
ProtocolState::Normal {
@@ -404,6 +408,7 @@ impl LegacyProtoHandler {
if substreams.is_empty() {
let event = LegacyProtoHandlerOut::CustomProtocolClosed {
reason: "All substreams have been closed by the remote".into(),
endpoint: self.endpoint.clone()
};
self.state = ProtocolState::Disabled {
shutdown: shutdown.into_iter().collect(),
@@ -416,6 +421,7 @@ impl LegacyProtoHandler {
if substreams.is_empty() {
let event = LegacyProtoHandlerOut::CustomProtocolClosed {
reason: format!("Error on the last substream: {:?}", err).into(),
endpoint: self.endpoint.clone()
};
self.state = ProtocolState::Disabled {
shutdown: shutdown.into_iter().collect(),
@@ -479,7 +485,8 @@ impl LegacyProtoHandler {
ProtocolState::Opening { .. } => {
let event = LegacyProtoHandlerOut::CustomProtocolOpen {
version: substream.protocol_version()
version: substream.protocol_version(),
endpoint: self.endpoint.clone()
};
self.events_queue.push(ProtocolsHandlerEvent::Custom(event));
ProtocolState::Normal {
@@ -72,7 +72,7 @@ pub struct NotifsInHandler {
}
/// Event that can be received by a `NotifsInHandler`.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum NotifsInHandlerIn {
/// Can be sent back as a response to an `OpenRequest`. Contains the status message to send
/// to the remote.
@@ -33,7 +33,7 @@ use libp2p::swarm::{
SubstreamProtocol,
NegotiatedSubstream,
};
use log::error;
use log::{debug, warn, error};
use prometheus_endpoint::Histogram;
use smallvec::SmallVec;
use std::{borrow::Cow, fmt, mem, pin::Pin, task::{Context, Poll}, time::Duration};
@@ -280,7 +280,7 @@ impl ProtocolsHandler for NotifsOutHandler {
// be recovered. When in doubt, let's drop the existing substream and
// open a new one.
if sub.close().now_or_never().is_none() {
log::warn!(
warn!(
target: "sub-libp2p",
"📞 Improperly closed outbound notifications substream"
);
@@ -293,16 +293,22 @@ impl ProtocolsHandler for NotifsOutHandler {
});
self.state = State::Opening { initial_message };
},
State::Opening { .. } | State::Refused | State::Open { .. } =>
error!("☎️ Tried to enable notifications handler that was already enabled"),
State::Poisoned => error!("☎️ Notifications handler in a poisoned state"),
st @ State::Opening { .. } | st @ State::Refused | st @ State::Open { .. } => {
debug!(target: "sub-libp2p",
"Tried to enable notifications handler that was already enabled");
self.state = st;
}
State::Poisoned => error!("Notifications handler in a poisoned state"),
}
}
NotifsOutHandlerIn::Disable => {
match mem::replace(&mut self.state, State::Poisoned) {
State::Disabled | State::DisabledOpen(_) | State::DisabledOpening =>
error!("☎️ Tried to disable notifications handler that was already disabled"),
st @ State::Disabled | st @ State::DisabledOpen(_) | st @ State::DisabledOpening => {
debug!(target: "sub-libp2p",
"Tried to disable notifications handler that was already disabled");
self.state = st;
}
State::Opening { .. } => self.state = State::DisabledOpening,
State::Refused => self.state = State::Disabled,
State::Open { substream, .. } => self.state = State::DisabledOpen(substream),
@@ -313,7 +319,7 @@ impl ProtocolsHandler for NotifsOutHandler {
NotifsOutHandlerIn::Send(msg) =>
if let State::Open { substream, .. } = &mut self.state {
if substream.push_message(msg).is_err() {
log::warn!(
warn!(
target: "sub-libp2p",
"📞 Notifications queue with peer {} is full, dropped message (protocol: {:?})",
self.peer_id,
@@ -325,7 +331,7 @@ impl ProtocolsHandler for NotifsOutHandler {
}
} else {
// This is an API misuse.
log::warn!(
warn!(
target: "sub-libp2p",
"📞 Tried to send a notification on a disabled handler"
);
@@ -18,7 +18,7 @@
use futures::{prelude::*, ready};
use codec::{Encode, Decode};
use libp2p::core::nodes::listeners::ListenerId;
use libp2p::core::connection::{ConnectionId, ListenerId};
use libp2p::core::ConnectedPoint;
use libp2p::swarm::{Swarm, ProtocolsHandler, IntoProtocolsHandler};
use libp2p::swarm::{PollParameters, NetworkBehaviour, NetworkBehaviourAction};
@@ -148,20 +148,29 @@ impl NetworkBehaviour for CustomProtoWithAddr {
list
}
fn inject_connected(&mut self, peer_id: PeerId, endpoint: ConnectedPoint) {
self.inner.inject_connected(peer_id, endpoint)
fn inject_connected(&mut self, peer_id: &PeerId) {
self.inner.inject_connected(peer_id)
}
fn inject_disconnected(&mut self, peer_id: &PeerId, endpoint: ConnectedPoint) {
self.inner.inject_disconnected(peer_id, endpoint)
fn inject_disconnected(&mut self, peer_id: &PeerId) {
self.inner.inject_disconnected(peer_id)
}
fn inject_node_event(
fn inject_connection_established(&mut self, peer_id: &PeerId, conn: &ConnectionId, endpoint: &ConnectedPoint) {
self.inner.inject_connection_established(peer_id, conn, endpoint)
}
fn inject_connection_closed(&mut self, peer_id: &PeerId, conn: &ConnectionId, endpoint: &ConnectedPoint) {
self.inner.inject_connection_closed(peer_id, conn, endpoint)
}
fn inject_event(
&mut self,
peer_id: PeerId,
connection: ConnectionId,
event: <<Self::ProtocolsHandler as IntoProtocolsHandler>::Handler as ProtocolsHandler>::OutEvent
) {
self.inner.inject_node_event(peer_id, event)
self.inner.inject_event(peer_id, connection, event)
}
fn poll(
@@ -177,10 +186,6 @@ impl NetworkBehaviour for CustomProtoWithAddr {
self.inner.poll(cx, params)
}
fn inject_replaced(&mut self, peer_id: PeerId, closed_endpoint: ConnectedPoint, new_endpoint: ConnectedPoint) {
self.inner.inject_replaced(peer_id, closed_endpoint, new_endpoint)
}
fn inject_addr_reach_failure(&mut self, peer_id: Option<&PeerId>, addr: &Multiaddr, error: &dyn std::error::Error) {
self.inner.inject_addr_reach_failure(peer_id, addr, error)
}
@@ -205,8 +210,8 @@ impl NetworkBehaviour for CustomProtoWithAddr {
self.inner.inject_listener_error(id, err);
}
fn inject_listener_closed(&mut self, id: ListenerId) {
self.inner.inject_listener_closed(id);
fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &io::Error>) {
self.inner.inject_listener_closed(id, reason);
}
}