[multistream-select] Fix panic with V1Lazy (regression) and more convenient transport boxing. (#1783)

* [multistream-select] Fix panic with V1Lazy and add integration tests.

Fixes a panic when using the `V1Lazy` negotiation protocol,
a regression introduced in https://github.com/libp2p/rust-libp2p/pull/1484.

Thereby adds integration tests for a transport upgrade with both
`V1` and `V1Lazy` to the `multistream-select` crate to prevent
future regressions.

* Cleanup.

* Update changelog.
This commit is contained in:
Roman Borschel
2020-10-07 11:10:54 +02:00
committed by GitHub
parent 2a5c1832a1
commit 3e31ea9337
13 changed files with 193 additions and 78 deletions

View File

@ -25,14 +25,13 @@
//! any desired protocols. The rest of the module defines combinators for
//! modifying a transport through composition with other transports or protocol upgrades.
use crate::ConnectedPoint;
use crate::{ConnectedPoint, ConnectionInfo, muxing::{StreamMuxer, StreamMuxerBox}};
use futures::prelude::*;
use multiaddr::Multiaddr;
use std::{error::Error, fmt};
use std::time::Duration;
pub mod and_then;
pub mod boxed;
pub mod choice;
pub mod dummy;
pub mod map;
@ -41,8 +40,10 @@ pub mod memory;
pub mod timeout;
pub mod upgrade;
mod boxed;
mod optional;
pub use self::boxed::Boxed;
pub use self::choice::OrTransport;
pub use self::memory::MemoryTransport;
pub use self::optional::OptionalTransport;
@ -128,14 +129,24 @@ pub trait Transport {
where
Self: Sized;
/// Turns the transport into an abstract boxed (i.e. heap-allocated) transport.
fn boxed(self) -> boxed::Boxed<Self::Output, Self::Error>
where Self: Sized + Clone + Send + Sync + 'static,
Self::Dial: Send + 'static,
Self::Listener: Send + 'static,
Self::ListenerUpgrade: Send + 'static,
/// Boxes an authenticated, multiplexed transport, including the
/// `StreamMuxer` and transport errors.
fn boxed<I, M>(self) -> boxed::Boxed<(I, StreamMuxerBox), std::io::Error>
where
Self: Transport<Output = (I, M)> + Sized + Clone + Send + Sync + 'static,
Self::Dial: Send + 'static,
Self::Listener: Send + 'static,
Self::ListenerUpgrade: Send + 'static,
Self::Error: Send + Sync,
I: ConnectionInfo,
M: StreamMuxer + Send + Sync + 'static,
M::Substream: Send + 'static,
M::OutboundSubstream: Send + 'static
{
boxed::boxed(self)
boxed::boxed(
self.map(|(i, m), _| (i, StreamMuxerBox::new(m)))
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e)))
}
/// Applies a function on the connections created by the transport.

View File

@ -24,7 +24,6 @@ use multiaddr::Multiaddr;
use std::{error, fmt, pin::Pin, sync::Arc};
/// See the `Transport::boxed` method.
#[inline]
pub fn boxed<T>(transport: T) -> Boxed<T::Output, T::Error>
where
T: Transport + Clone + Send + Sync + 'static,
@ -37,9 +36,14 @@ where
}
}
pub type Dial<O, E> = Pin<Box<dyn Future<Output = Result<O, E>> + Send>>;
pub type Listener<O, E> = Pin<Box<dyn Stream<Item = Result<ListenerEvent<ListenerUpgrade<O, E>, E>, E>> + Send>>;
pub type ListenerUpgrade<O, E> = Pin<Box<dyn Future<Output = Result<O, E>> + Send>>;
/// See the `Transport::boxed` method.
pub struct Boxed<O, E> {
inner: Arc<dyn Abstract<O, E> + Send + Sync>,
}
type Dial<O, E> = Pin<Box<dyn Future<Output = Result<O, E>> + Send>>;
type Listener<O, E> = Pin<Box<dyn Stream<Item = Result<ListenerEvent<ListenerUpgrade<O, E>, E>, E>> + Send>>;
type ListenerUpgrade<O, E> = Pin<Box<dyn Future<Output = Result<O, E>> + Send>>;
trait Abstract<O, E> {
fn listen_on(&self, addr: Multiaddr) -> Result<Listener<O, E>, TransportError<E>>;
@ -68,11 +72,6 @@ where
}
}
/// See the `Transport::boxed` method.
pub struct Boxed<O, E> {
inner: Arc<dyn Abstract<O, E> + Send + Sync>,
}
impl<O, E> fmt::Debug for Boxed<O, E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "BoxedTransport")