On transport upgrades and the role of libp2p-core
#2829
Replies: 2 comments 4 replies
-
An open question to this would be how the encryption & authentication layer fits into this. At the moment this is also modeled via upgrades but contrary to multiplexing, this isn't enforced on the The fact that this is modeled with a tuple has always bugged me a bit and I think it is something that is quite hard to understand when one dives into the details of If |
Beta Was this translation helpful? Give feedback.
-
What would such new abstraction in @@ -225,6 +225,37 @@ pub trait Transport {
}
}
+pub trait MultiplexedTransport {
+ type Error: Error;
+ type ListenerUpgrade: Future<Output = Result<(PeerId, StreamMuxerBox), Self::Error>>;
+ type Dial: Future<Output = Result<(PeerId, StreamMuxerBox), Self::Error>>;
+
+ fn listen_on(&mut self, addr: Multiaddr) -> Result<ListenerId, TransportError<Self::Error>>;
+
+ fn remove_listener(&mut self, id: ListenerId) -> bool;
+
+ fn dial(&mut self, addr: Multiaddr) -> Result<Self::Dial, TransportError<Self::Error>>;
+
+ fn dial_as_listener(
+ &mut self,
+ addr: Multiaddr,
+ ) -> Result<Self::Dial, TransportError<Self::Error>>;
+
+ fn poll(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<TransportEvent<Self::ListenerUpgrade, Self::Error>>;
+
+ fn address_translation(&self, listen: &Multiaddr, observed: &Multiaddr) -> Option<Multiaddr>;
+}
+
+impl<T> MultiplexedTransport for T
+where
+ T: Transport<Output = (PeerId, StreamMuxerBox)>,
+{
+ // ...
+}
+
Agreed.
What would be an example where we could simplify QUIC or WebRTC in case we had
Agreed. To add to this, working with a tuple, instead of two separate types also makes referencing them in trait bounds difficult / impossible.
Independent of the direction of this effort, the above line should make it into our docs somewhere. Potentially extending the definition here rust-libp2p/src/tutorials/ping.rs Lines 125 to 127 in d92cab8 |
Beta Was this translation helpful? Give feedback.
-
With the introduction of QUIC and WebRTC, we are adding two transports to the codebase that offer native multiplexing. With TCP and other transports, we had upgrade a connection to a multiplexed one by putting yamux or mplex on top of an established connection. This upgrade mechanism doesn't really fit that well if a transport offers multiplexing capabilities out of the box.
Within our repository, the end consumer of
libp2p-core
- which hosts the abstractions ofTransport
,StreamMuxer
and upgrades - islibp2p-swarm
. ASwarm
only works with aTransport
that has been "upgraded" to support multiplexing becauseSwarm
offers substreams as a communication abstraction to its users:NetworkBehaviour
s.Both of these points indicate that the interface of
libp2p-core
is actually sub-optimal.Swarm
does not need to know thatTransport
andStreamMuxer
are different interfaces / technologies. The ideal interface for aSwarm
is the combination of both.Transport
and the ability to open/manage substreams.I'd like to open a discussion and gather ideas for a new interface exposed by
libp2p-core
. To avoid confusion with existing naming, I am going to name itMultiplexedTransport
but really the name does not matter. The hierarchy would look something like this:Most importantly,
libp2p-swarm
would only deal with theMultiplexedTransport
interface.ComposedTransport
would act as an adapter for combining technologies such as TCP and Yamux to fulfill the required interface.I think this design would have a number of benefits:
libp2p-core
by itself could form a more useful abstraction for other libraries and act as general-purpose networking layerVery curious to hear people's opinions on this idea!
Beta Was this translation helpful? Give feedback.
All reactions