mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-04-25 19:02:13 +00:00
Remove Send/Sync/'static requirements in identify (#649)
This commit is contained in:
parent
37994b34e7
commit
2c1807b646
@ -67,6 +67,7 @@
|
|||||||
|
|
||||||
extern crate bytes;
|
extern crate bytes;
|
||||||
extern crate fnv;
|
extern crate fnv;
|
||||||
|
#[macro_use]
|
||||||
extern crate futures;
|
extern crate futures;
|
||||||
extern crate libp2p_peerstore;
|
extern crate libp2p_peerstore;
|
||||||
extern crate libp2p_core;
|
extern crate libp2p_core;
|
||||||
@ -87,7 +88,7 @@ pub use self::listen_layer::IdentifyListen;
|
|||||||
pub use self::periodic_id_handler::{PeriodicIdentification, PeriodicIdentificationEvent};
|
pub use self::periodic_id_handler::{PeriodicIdentification, PeriodicIdentificationEvent};
|
||||||
pub use self::periodic_id_layer::{PeriodicIdentifyBehaviour, PeriodicIdentifyBehaviourEvent};
|
pub use self::periodic_id_layer::{PeriodicIdentifyBehaviour, PeriodicIdentifyBehaviourEvent};
|
||||||
pub use self::protocol::{IdentifyInfo, RemoteInfo};
|
pub use self::protocol::{IdentifyInfo, RemoteInfo};
|
||||||
pub use self::protocol::{IdentifyProtocolConfig, IdentifySender};
|
pub use self::protocol::{IdentifyProtocolConfig, IdentifySender, IdentifySenderFuture};
|
||||||
|
|
||||||
mod id_transport;
|
mod id_transport;
|
||||||
mod listen_handler;
|
mod listen_handler;
|
||||||
|
@ -55,7 +55,7 @@ impl<TSubstream> IdentifyListenHandler<TSubstream> {
|
|||||||
|
|
||||||
impl<TSubstream> ProtocolsHandler for IdentifyListenHandler<TSubstream>
|
impl<TSubstream> ProtocolsHandler for IdentifyListenHandler<TSubstream>
|
||||||
where
|
where
|
||||||
TSubstream: AsyncRead + AsyncWrite + Send + Sync + 'static, // TODO: remove useless bounds
|
TSubstream: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
type InEvent = Void;
|
type InEvent = Void;
|
||||||
type OutEvent = IdentifySender<TSubstream>;
|
type OutEvent = IdentifySender<TSubstream>;
|
||||||
|
@ -22,10 +22,10 @@ use futures::prelude::*;
|
|||||||
use libp2p_core::nodes::{ConnectedPoint, NetworkBehaviour, NetworkBehaviourAction};
|
use libp2p_core::nodes::{ConnectedPoint, NetworkBehaviour, NetworkBehaviourAction};
|
||||||
use libp2p_core::{protocols_handler::ProtocolsHandler, Multiaddr, PeerId};
|
use libp2p_core::{protocols_handler::ProtocolsHandler, Multiaddr, PeerId};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::{collections::HashMap, io, marker::PhantomData};
|
use std::collections::HashMap;
|
||||||
use tokio_io::{AsyncRead, AsyncWrite};
|
use tokio_io::{AsyncRead, AsyncWrite};
|
||||||
use void::Void;
|
use void::Void;
|
||||||
use {IdentifyListenHandler, IdentifyInfo};
|
use {IdentifyListenHandler, IdentifyInfo, IdentifySenderFuture};
|
||||||
|
|
||||||
/// Network behaviour that automatically identifies nodes periodically, and returns information
|
/// Network behaviour that automatically identifies nodes periodically, and returns information
|
||||||
/// about them.
|
/// about them.
|
||||||
@ -35,9 +35,7 @@ pub struct IdentifyListen<TSubstream> {
|
|||||||
/// For each peer we're connected to, the observed address to send back to it.
|
/// For each peer we're connected to, the observed address to send back to it.
|
||||||
observed_addresses: HashMap<PeerId, Multiaddr>,
|
observed_addresses: HashMap<PeerId, Multiaddr>,
|
||||||
/// List of futures that send back information back to remotes.
|
/// List of futures that send back information back to remotes.
|
||||||
futures: SmallVec<[Box<Future<Item = (), Error = io::Error> + Send>; 4]>,
|
futures: SmallVec<[IdentifySenderFuture<TSubstream>; 4]>,
|
||||||
/// Marker to pin the generics.
|
|
||||||
marker: PhantomData<TSubstream>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TSubstream> IdentifyListen<TSubstream> {
|
impl<TSubstream> IdentifyListen<TSubstream> {
|
||||||
@ -47,7 +45,6 @@ impl<TSubstream> IdentifyListen<TSubstream> {
|
|||||||
send_back_info: info,
|
send_back_info: info,
|
||||||
observed_addresses: HashMap::new(),
|
observed_addresses: HashMap::new(),
|
||||||
futures: SmallVec::new(),
|
futures: SmallVec::new(),
|
||||||
marker: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +63,7 @@ impl<TSubstream> IdentifyListen<TSubstream> {
|
|||||||
|
|
||||||
impl<TSubstream> NetworkBehaviour for IdentifyListen<TSubstream>
|
impl<TSubstream> NetworkBehaviour for IdentifyListen<TSubstream>
|
||||||
where
|
where
|
||||||
TSubstream: AsyncRead + AsyncWrite + Send + Sync + 'static,
|
TSubstream: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
type ProtocolsHandler = IdentifyListenHandler<TSubstream>;
|
type ProtocolsHandler = IdentifyListenHandler<TSubstream>;
|
||||||
type OutEvent = Void;
|
type OutEvent = Void;
|
||||||
|
@ -77,7 +77,7 @@ impl<TSubstream> PeriodicIdentification<TSubstream> {
|
|||||||
|
|
||||||
impl<TSubstream> ProtocolsHandler for PeriodicIdentification<TSubstream>
|
impl<TSubstream> ProtocolsHandler for PeriodicIdentification<TSubstream>
|
||||||
where
|
where
|
||||||
TSubstream: AsyncRead + AsyncWrite + Send + Sync + 'static, // TODO: remove useless bounds
|
TSubstream: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
type InEvent = Void;
|
type InEvent = Void;
|
||||||
type OutEvent = PeriodicIdentificationEvent;
|
type OutEvent = PeriodicIdentificationEvent;
|
||||||
|
@ -46,7 +46,7 @@ impl<TSubstream> PeriodicIdentifyBehaviour<TSubstream> {
|
|||||||
|
|
||||||
impl<TSubstream> NetworkBehaviour for PeriodicIdentifyBehaviour<TSubstream>
|
impl<TSubstream> NetworkBehaviour for PeriodicIdentifyBehaviour<TSubstream>
|
||||||
where
|
where
|
||||||
TSubstream: AsyncRead + AsyncWrite + Send + Sync + 'static,
|
TSubstream: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
type ProtocolsHandler = PeriodicIdentification<TSubstream>;
|
type ProtocolsHandler = PeriodicIdentification<TSubstream>;
|
||||||
type OutEvent = PeriodicIdentifyBehaviourEvent;
|
type OutEvent = PeriodicIdentifyBehaviourEvent;
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
use bytes::{Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
use futures::{future::{self, FutureResult}, Future, Sink, Stream};
|
use futures::{future::{self, FutureResult}, Async, AsyncSink, Future, Poll, Sink, Stream};
|
||||||
use libp2p_core::{
|
use libp2p_core::{
|
||||||
Multiaddr, PublicKey,
|
Multiaddr, PublicKey,
|
||||||
upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo}
|
upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo}
|
||||||
@ -54,15 +54,10 @@ pub struct IdentifySender<T> {
|
|||||||
inner: Framed<T, codec::UviBytes<Vec<u8>>>,
|
inner: Framed<T, codec::UviBytes<Vec<u8>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> IdentifySender<T>
|
impl<T> IdentifySender<T> where T: AsyncWrite {
|
||||||
where
|
|
||||||
T: AsyncWrite + Send + 'a,
|
|
||||||
{
|
|
||||||
/// Sends back information to the client. Returns a future that is signalled whenever the
|
/// Sends back information to the client. Returns a future that is signalled whenever the
|
||||||
/// info have been sent.
|
/// info have been sent.
|
||||||
pub fn send(self, info: IdentifyInfo, observed_addr: &Multiaddr)
|
pub fn send(self, info: IdentifyInfo, observed_addr: &Multiaddr) -> IdentifySenderFuture<T> {
|
||||||
-> Box<Future<Item = (), Error = IoError> + Send + 'a>
|
|
||||||
{
|
|
||||||
debug!("Sending identify info to client");
|
debug!("Sending identify info to client");
|
||||||
trace!("Sending: {:?}", info);
|
trace!("Sending: {:?}", info);
|
||||||
|
|
||||||
@ -83,8 +78,42 @@ where
|
|||||||
.write_to_bytes()
|
.write_to_bytes()
|
||||||
.expect("writing protobuf failed; should never happen");
|
.expect("writing protobuf failed; should never happen");
|
||||||
|
|
||||||
let future = self.inner.send(bytes).map(|_| ());
|
IdentifySenderFuture {
|
||||||
Box::new(future) as Box<_>
|
inner: self.inner,
|
||||||
|
item: Some(bytes),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Future returned by `IdentifySender::send()`. Must be processed to the end in order to send
|
||||||
|
/// the information to the remote.
|
||||||
|
// Note: we don't use a `futures::sink::Sink` because it requires `T` to implement `Sink`, which
|
||||||
|
// means that we would require `T: AsyncWrite` in this struct definition. This requirement
|
||||||
|
// would then propagate everywhere.
|
||||||
|
#[must_use = "futures do nothing unless polled"]
|
||||||
|
pub struct IdentifySenderFuture<T> {
|
||||||
|
/// The Sink where to send the data.
|
||||||
|
inner: Framed<T, codec::UviBytes<Vec<u8>>>,
|
||||||
|
/// Bytes to send, or `None` if we've already sent them.
|
||||||
|
item: Option<Vec<u8>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Future for IdentifySenderFuture<T>
|
||||||
|
where T: AsyncWrite
|
||||||
|
{
|
||||||
|
type Item = ();
|
||||||
|
type Error = IoError;
|
||||||
|
|
||||||
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
|
if let Some(item) = self.item.take() {
|
||||||
|
if let AsyncSink::NotReady(item) = self.inner.start_send(item)? {
|
||||||
|
self.item = Some(item);
|
||||||
|
return Ok(Async::NotReady);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try_ready!(self.inner.poll_complete());
|
||||||
|
Ok(Async::Ready(()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +147,7 @@ impl UpgradeInfo for IdentifyProtocolConfig {
|
|||||||
|
|
||||||
impl<C> InboundUpgrade<C> for IdentifyProtocolConfig
|
impl<C> InboundUpgrade<C> for IdentifyProtocolConfig
|
||||||
where
|
where
|
||||||
C: AsyncRead + AsyncWrite + Send + 'static,
|
C: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
type Output = IdentifySender<C>;
|
type Output = IdentifySender<C>;
|
||||||
type Error = IoError;
|
type Error = IoError;
|
||||||
@ -134,41 +163,57 @@ where
|
|||||||
|
|
||||||
impl<C> OutboundUpgrade<C> for IdentifyProtocolConfig
|
impl<C> OutboundUpgrade<C> for IdentifyProtocolConfig
|
||||||
where
|
where
|
||||||
C: AsyncRead + AsyncWrite + Send + 'static,
|
C: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
type Output = RemoteInfo;
|
type Output = RemoteInfo;
|
||||||
type Error = IoError;
|
type Error = IoError;
|
||||||
type Future = Box<dyn Future<Item=Self::Output, Error=IoError> + Send>;
|
type Future = IdentifyOutboundFuture<C>;
|
||||||
|
|
||||||
fn upgrade_outbound(self, socket: C, _: ()) -> Self::Future {
|
fn upgrade_outbound(self, socket: C, _: ()) -> Self::Future {
|
||||||
let socket = Framed::new(socket, codec::UviBytes::<BytesMut>::default());
|
IdentifyOutboundFuture {
|
||||||
let future = socket
|
inner: Framed::new(socket, codec::UviBytes::<BytesMut>::default()),
|
||||||
.into_future()
|
}
|
||||||
.map(|(msg, _)| msg)
|
}
|
||||||
.map_err(|(err, _)| err)
|
}
|
||||||
.and_then(|msg| {
|
|
||||||
debug!("Received identify message");
|
/// Future returned by `OutboundUpgrade::upgrade_outbound`.
|
||||||
if let Some(msg) = msg {
|
pub struct IdentifyOutboundFuture<T> {
|
||||||
let (info, observed_addr) = match parse_proto_msg(msg) {
|
inner: Framed<T, codec::UviBytes<BytesMut>>,
|
||||||
Ok(v) => v,
|
}
|
||||||
Err(err) => {
|
|
||||||
debug!("Failed to parse protobuf message; error = {:?}", err);
|
impl<T> Future for IdentifyOutboundFuture<T>
|
||||||
return Err(err.into());
|
where T: AsyncRead
|
||||||
}
|
{
|
||||||
};
|
type Item = RemoteInfo;
|
||||||
trace!("Remote observes us as {:?}", observed_addr);
|
type Error = IoError;
|
||||||
trace!("Information received: {:?}", info);
|
|
||||||
Ok(RemoteInfo {
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
info,
|
let msg = match try_ready!(self.inner.poll()) {
|
||||||
observed_addr: observed_addr.clone(),
|
Some(i) => i,
|
||||||
_priv: ()
|
None => {
|
||||||
})
|
debug!("Identify protocol stream closed before receiving info");
|
||||||
} else {
|
return Err(IoErrorKind::InvalidData.into());
|
||||||
debug!("Identify protocol stream closed before receiving info");
|
}
|
||||||
Err(IoErrorKind::InvalidData.into())
|
};
|
||||||
}
|
|
||||||
});
|
debug!("Received identify message");
|
||||||
Box::new(future) as Box<_>
|
|
||||||
|
let (info, observed_addr) = match parse_proto_msg(msg) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(err) => {
|
||||||
|
debug!("Failed to parse protobuf message; error = {:?}", err);
|
||||||
|
return Err(err.into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
trace!("Remote observes us as {:?}", observed_addr);
|
||||||
|
trace!("Information received: {:?}", info);
|
||||||
|
|
||||||
|
Ok(Async::Ready(RemoteInfo {
|
||||||
|
info,
|
||||||
|
observed_addr: observed_addr.clone(),
|
||||||
|
_priv: ()
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user