Simplify trait bounds on NetworkBehaviour (#1405)

* Simplify trait bounds requirements

* More work

* Moar

* Finish

* Fix final tests

* More simplification

* Use separate traits for Inbound/Outbound

* Update gossipsub and remove warnings

* Add documentation to swarm

* Remove BoxSubstream

* Fix tests not compiling

* Fix stack overflow

* Address concerns

* For some reason my IDE ignored libp2p-kad
This commit is contained in:
Pierre Krieger
2020-02-07 16:29:30 +01:00
committed by GitHub
parent 69852a580b
commit 1eff4b9823
32 changed files with 580 additions and 652 deletions

View File

@ -22,10 +22,11 @@ use crate::behaviour::GossipsubRpc;
use crate::protocol::{GossipsubCodec, ProtocolConfig};
use futures::prelude::*;
use futures_codec::Framed;
use libp2p_core::upgrade::{InboundUpgrade, Negotiated, OutboundUpgrade};
use libp2p_core::upgrade::{InboundUpgrade, OutboundUpgrade};
use libp2p_swarm::protocols_handler::{
KeepAlive, ProtocolsHandler, ProtocolsHandlerEvent, ProtocolsHandlerUpgrErr, SubstreamProtocol,
};
use libp2p_swarm::NegotiatedSubstream;
use log::{debug, trace, warn};
use smallvec::SmallVec;
use std::{
@ -36,18 +37,15 @@ use std::{
};
/// Protocol Handler that manages a single long-lived substream with a peer.
pub struct GossipsubHandler<TSubstream>
where
TSubstream: AsyncRead + AsyncWrite,
{
pub struct GossipsubHandler {
/// Upgrade configuration for the gossipsub protocol.
listen_protocol: SubstreamProtocol<ProtocolConfig>,
/// The single long-lived outbound substream.
outbound_substream: Option<OutboundSubstreamState<TSubstream>>,
outbound_substream: Option<OutboundSubstreamState>,
/// The single long-lived inbound substream.
inbound_substream: Option<InboundSubstreamState<TSubstream>>,
inbound_substream: Option<InboundSubstreamState>,
/// Queue of values that we want to send to the remote.
send_queue: SmallVec<[GossipsubRpc; 16]>,
@ -57,39 +55,30 @@ where
}
/// State of the inbound substream, opened either by us or by the remote.
enum InboundSubstreamState<TSubstream>
where
TSubstream: AsyncRead + AsyncWrite,
{
enum InboundSubstreamState {
/// Waiting for a message from the remote. The idle state for an inbound substream.
WaitingInput(Framed<Negotiated<TSubstream>, GossipsubCodec>),
WaitingInput(Framed<NegotiatedSubstream, GossipsubCodec>),
/// The substream is being closed.
Closing(Framed<Negotiated<TSubstream>, GossipsubCodec>),
Closing(Framed<NegotiatedSubstream, GossipsubCodec>),
/// An error occurred during processing.
Poisoned,
}
/// State of the outbound substream, opened either by us or by the remote.
enum OutboundSubstreamState<TSubstream>
where
TSubstream: AsyncRead + AsyncWrite,
{
enum OutboundSubstreamState {
/// Waiting for the user to send a message. The idle state for an outbound substream.
WaitingOutput(Framed<Negotiated<TSubstream>, GossipsubCodec>),
WaitingOutput(Framed<NegotiatedSubstream, GossipsubCodec>),
/// Waiting to send a message to the remote.
PendingSend(Framed<Negotiated<TSubstream>, GossipsubCodec>, GossipsubRpc),
PendingSend(Framed<NegotiatedSubstream, GossipsubCodec>, GossipsubRpc),
/// Waiting to flush the substream so that the data arrives to the remote.
PendingFlush(Framed<Negotiated<TSubstream>, GossipsubCodec>),
PendingFlush(Framed<NegotiatedSubstream, GossipsubCodec>),
/// The substream is being closed. Used by either substream.
_Closing(Framed<Negotiated<TSubstream>, GossipsubCodec>),
_Closing(Framed<NegotiatedSubstream, GossipsubCodec>),
/// An error occurred during processing.
Poisoned,
}
impl<TSubstream> GossipsubHandler<TSubstream>
where
TSubstream: AsyncRead + AsyncWrite,
{
impl GossipsubHandler {
/// Builds a new `GossipsubHandler`.
pub fn new(protocol_id: impl Into<Cow<'static, [u8]>>, max_transmit_size: usize) -> Self {
GossipsubHandler {
@ -105,10 +94,7 @@ where
}
}
impl<TSubstream> Default for GossipsubHandler<TSubstream>
where
TSubstream: AsyncRead + AsyncWrite,
{
impl Default for GossipsubHandler {
fn default() -> Self {
GossipsubHandler {
listen_protocol: SubstreamProtocol::new(ProtocolConfig::default()),
@ -120,14 +106,10 @@ where
}
}
impl<TSubstream> ProtocolsHandler for GossipsubHandler<TSubstream>
where
TSubstream: AsyncRead + AsyncWrite + Unpin + Send + 'static,
{
impl ProtocolsHandler for GossipsubHandler {
type InEvent = GossipsubRpc;
type OutEvent = GossipsubRpc;
type Error = io::Error;
type Substream = TSubstream;
type InboundProtocol = ProtocolConfig;
type OutboundProtocol = ProtocolConfig;
type OutboundOpenInfo = GossipsubRpc;
@ -138,7 +120,7 @@ where
fn inject_fully_negotiated_inbound(
&mut self,
substream: <Self::InboundProtocol as InboundUpgrade<Negotiated<TSubstream>>>::Output,
substream: <Self::InboundProtocol as InboundUpgrade<NegotiatedSubstream>>::Output,
) {
// new inbound substream. Replace the current one, if it exists.
trace!("New inbound substream request");
@ -147,7 +129,7 @@ where
fn inject_fully_negotiated_outbound(
&mut self,
substream: <Self::OutboundProtocol as OutboundUpgrade<Negotiated<TSubstream>>>::Output,
substream: <Self::OutboundProtocol as OutboundUpgrade<NegotiatedSubstream>>::Output,
message: Self::OutboundOpenInfo,
) {
// Should never establish a new outbound substream if one already exists.
@ -169,7 +151,7 @@ where
&mut self,
_: Self::OutboundOpenInfo,
_: ProtocolsHandlerUpgrErr<
<Self::OutboundProtocol as OutboundUpgrade<Self::Substream>>::Error,
<Self::OutboundProtocol as OutboundUpgrade<NegotiatedSubstream>>::Error,
>,
) {
// Ignore upgrade errors for now.