libp2p/builder/phase/
quic.rs

1use super::*;
2use crate::SwarmBuilder;
3#[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))]
4use libp2p_core::muxing::StreamMuxer;
5#[cfg(any(
6    feature = "relay",
7    all(not(target_arch = "wasm32"), feature = "websocket")
8))]
9use libp2p_core::{InboundUpgrade, Negotiated, OutboundUpgrade, UpgradeInfo};
10use std::{marker::PhantomData, sync::Arc};
11
12pub struct QuicPhase<T> {
13    pub(crate) transport: T,
14}
15
16macro_rules! impl_quic_builder {
17    ($providerKebabCase:literal, $providerPascalCase:ty, $quic:ident) => {
18        #[cfg(all(not(target_arch = "wasm32"), feature = "quic", feature = $providerKebabCase))]
19        impl<T: AuthenticatedMultiplexedTransport> SwarmBuilder<$providerPascalCase, QuicPhase<T>> {
20            pub fn with_quic(
21                self,
22            ) -> SwarmBuilder<
23                $providerPascalCase,
24                OtherTransportPhase<impl AuthenticatedMultiplexedTransport>,
25            > {
26                self.with_quic_config(std::convert::identity)
27            }
28
29            pub fn with_quic_config(
30                self,
31                constructor: impl FnOnce(libp2p_quic::Config) -> libp2p_quic::Config,
32            ) -> SwarmBuilder<
33                $providerPascalCase,
34                OtherTransportPhase<impl AuthenticatedMultiplexedTransport>,
35            > {
36                SwarmBuilder {
37                    phase: OtherTransportPhase {
38                        transport: self
39                            .phase
40                            .transport
41                            .or_transport(
42                                libp2p_quic::$quic::Transport::new(constructor(
43                                    libp2p_quic::Config::new(&self.keypair),
44                                ))
45                                .map(|(peer_id, muxer), _| {
46                                    (peer_id, libp2p_core::muxing::StreamMuxerBox::new(muxer))
47                                }),
48                            )
49                            .map(|either, _| either.into_inner()),
50                    },
51                    keypair: self.keypair,
52                    phantom: PhantomData,
53                }
54            }
55        }
56    };
57}
58
59impl_quic_builder!("async-std", AsyncStd, async_std);
60impl_quic_builder!("tokio", super::provider::Tokio, tokio);
61
62impl<Provider, T> SwarmBuilder<Provider, QuicPhase<T>> {
63    pub(crate) fn without_quic(self) -> SwarmBuilder<Provider, OtherTransportPhase<T>> {
64        SwarmBuilder {
65            keypair: self.keypair,
66            phantom: PhantomData,
67            phase: OtherTransportPhase {
68                transport: self.phase.transport,
69            },
70        }
71    }
72}
73
74// Shortcuts
75impl<Provider, T: AuthenticatedMultiplexedTransport> SwarmBuilder<Provider, QuicPhase<T>> {
76    /// See [`SwarmBuilder::with_relay_client`].
77    #[cfg(feature = "relay")]
78    pub fn with_relay_client<SecUpgrade, SecStream, SecError, MuxUpgrade, MuxStream, MuxError>(
79        self,
80        security_upgrade: SecUpgrade,
81        multiplexer_upgrade: MuxUpgrade,
82    ) -> Result<
83        SwarmBuilder<
84            Provider,
85            BandwidthLoggingPhase<impl AuthenticatedMultiplexedTransport, libp2p_relay::client::Behaviour>,
86        >,
87        SecUpgrade::Error,
88        > where
89
90        SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static,
91        SecError: std::error::Error + Send + Sync + 'static,
92        SecUpgrade: IntoSecurityUpgrade<libp2p_relay::client::Connection>,
93        SecUpgrade::Upgrade: InboundUpgrade<Negotiated<libp2p_relay::client::Connection>, Output = (libp2p_identity::PeerId, SecStream), Error = SecError> + OutboundUpgrade<Negotiated<libp2p_relay::client::Connection>, Output = (libp2p_identity::PeerId, SecStream), Error = SecError> + Clone + Send + 'static,
94    <SecUpgrade::Upgrade as InboundUpgrade<Negotiated<libp2p_relay::client::Connection>>>::Future: Send,
95    <SecUpgrade::Upgrade as OutboundUpgrade<Negotiated<libp2p_relay::client::Connection>>>::Future: Send,
96    <<<SecUpgrade as IntoSecurityUpgrade<libp2p_relay::client::Connection>>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send,
97    <<SecUpgrade as IntoSecurityUpgrade<libp2p_relay::client::Connection>>::Upgrade as UpgradeInfo>::Info: Send,
98
99        MuxStream: libp2p_core::muxing::StreamMuxer + Send + 'static,
100        MuxStream::Substream: Send + 'static,
101        MuxStream::Error: Send + Sync + 'static,
102        MuxUpgrade: IntoMultiplexerUpgrade<SecStream>,
103        MuxUpgrade::Upgrade: InboundUpgrade<Negotiated<SecStream>, Output = MuxStream, Error = MuxError> + OutboundUpgrade<Negotiated<SecStream>, Output = MuxStream, Error = MuxError> + Clone + Send + 'static,
104    <MuxUpgrade::Upgrade as InboundUpgrade<Negotiated<SecStream>>>::Future: Send,
105    <MuxUpgrade::Upgrade as OutboundUpgrade<Negotiated<SecStream>>>::Future: Send,
106        MuxError: std::error::Error + Send + Sync + 'static,
107    <<<MuxUpgrade as IntoMultiplexerUpgrade<SecStream>>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send,
108    <<MuxUpgrade as IntoMultiplexerUpgrade<SecStream>>::Upgrade as UpgradeInfo>::Info: Send,
109    {
110        self.without_quic()
111            .without_any_other_transports()
112            .without_dns()
113            .without_websocket()
114            .with_relay_client(security_upgrade, multiplexer_upgrade)
115    }
116
117    pub fn with_other_transport<
118        Muxer: libp2p_core::muxing::StreamMuxer + Send + 'static,
119        OtherTransport: Transport<Output = (libp2p_identity::PeerId, Muxer)> + Send + Unpin + 'static,
120        R: TryIntoTransport<OtherTransport>,
121    >(
122        self,
123        constructor: impl FnOnce(&libp2p_identity::Keypair) -> R,
124    ) -> Result<
125        SwarmBuilder<Provider, OtherTransportPhase<impl AuthenticatedMultiplexedTransport>>,
126        R::Error,
127    >
128    where
129        <OtherTransport as Transport>::Error: Send + Sync + 'static,
130        <OtherTransport as Transport>::Dial: Send,
131        <OtherTransport as Transport>::ListenerUpgrade: Send,
132        <Muxer as libp2p_core::muxing::StreamMuxer>::Substream: Send,
133        <Muxer as libp2p_core::muxing::StreamMuxer>::Error: Send + Sync,
134    {
135        self.without_quic().with_other_transport(constructor)
136    }
137
138    pub fn with_behaviour<B, R: TryIntoBehaviour<B>>(
139        self,
140        constructor: impl FnOnce(&libp2p_identity::Keypair) -> R,
141    ) -> Result<SwarmBuilder<Provider, SwarmPhase<T, B>>, R::Error> {
142        self.without_quic()
143            .without_any_other_transports()
144            .without_dns()
145            .without_websocket()
146            .without_relay()
147            .with_behaviour(constructor)
148    }
149}
150#[cfg(all(not(target_arch = "wasm32"), feature = "async-std", feature = "dns"))]
151impl<T: AuthenticatedMultiplexedTransport> SwarmBuilder<super::provider::AsyncStd, QuicPhase<T>> {
152    pub async fn with_dns(
153        self,
154    ) -> Result<
155        SwarmBuilder<
156            super::provider::AsyncStd,
157            WebsocketPhase<impl AuthenticatedMultiplexedTransport>,
158        >,
159        std::io::Error,
160    > {
161        self.without_quic()
162            .without_any_other_transports()
163            .with_dns()
164            .await
165    }
166}
167#[cfg(all(not(target_arch = "wasm32"), feature = "tokio", feature = "dns"))]
168impl<T: AuthenticatedMultiplexedTransport> SwarmBuilder<super::provider::Tokio, QuicPhase<T>> {
169    pub fn with_dns(
170        self,
171    ) -> Result<
172        SwarmBuilder<
173            super::provider::Tokio,
174            WebsocketPhase<impl AuthenticatedMultiplexedTransport>,
175        >,
176        std::io::Error,
177    > {
178        self.without_quic()
179            .without_any_other_transports()
180            .with_dns()
181    }
182}
183macro_rules! impl_quic_phase_with_websocket {
184    ($providerKebabCase:literal, $providerPascalCase:ty, $websocketStream:ty) => {
185        #[cfg(all(feature = $providerKebabCase, not(target_arch = "wasm32"), feature = "websocket"))]
186        impl<T: AuthenticatedMultiplexedTransport> SwarmBuilder<$providerPascalCase, QuicPhase<T>> {
187            /// See [`SwarmBuilder::with_websocket`].
188            pub async fn with_websocket <
189                SecUpgrade,
190                SecStream,
191                SecError,
192                MuxUpgrade,
193                MuxStream,
194                MuxError,
195            > (
196                self,
197                security_upgrade: SecUpgrade,
198                multiplexer_upgrade: MuxUpgrade,
199            ) -> Result<
200                    SwarmBuilder<
201                        $providerPascalCase,
202                        RelayPhase<impl AuthenticatedMultiplexedTransport>,
203                    >,
204                    super::websocket::WebsocketError<SecUpgrade::Error>,
205                >
206            where
207                SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static,
208                SecError: std::error::Error + Send + Sync + 'static,
209                SecUpgrade: IntoSecurityUpgrade<$websocketStream>,
210                SecUpgrade::Upgrade: InboundUpgrade<Negotiated<$websocketStream>, Output = (libp2p_identity::PeerId, SecStream), Error = SecError> + OutboundUpgrade<Negotiated<$websocketStream>, Output = (libp2p_identity::PeerId, SecStream), Error = SecError> + Clone + Send + 'static,
211            <SecUpgrade::Upgrade as InboundUpgrade<Negotiated<$websocketStream>>>::Future: Send,
212            <SecUpgrade::Upgrade as OutboundUpgrade<Negotiated<$websocketStream>>>::Future: Send,
213            <<<SecUpgrade as IntoSecurityUpgrade<$websocketStream>>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send,
214            <<SecUpgrade as IntoSecurityUpgrade<$websocketStream>>::Upgrade as UpgradeInfo>::Info: Send,
215
216                MuxStream: StreamMuxer + Send + 'static,
217                MuxStream::Substream: Send + 'static,
218                MuxStream::Error: Send + Sync + 'static,
219                MuxUpgrade: IntoMultiplexerUpgrade<SecStream>,
220                MuxUpgrade::Upgrade: InboundUpgrade<Negotiated<SecStream>, Output = MuxStream, Error = MuxError> + OutboundUpgrade<Negotiated<SecStream>, Output = MuxStream, Error = MuxError> + Clone + Send + 'static,
221                <MuxUpgrade::Upgrade as InboundUpgrade<Negotiated<SecStream>>>::Future: Send,
222                <MuxUpgrade::Upgrade as OutboundUpgrade<Negotiated<SecStream>>>::Future: Send,
223                    MuxError: std::error::Error + Send + Sync + 'static,
224                <<<MuxUpgrade as IntoMultiplexerUpgrade<SecStream>>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send,
225                <<MuxUpgrade as IntoMultiplexerUpgrade<SecStream>>::Upgrade as UpgradeInfo>::Info: Send,
226            {
227                self.without_quic()
228                    .without_any_other_transports()
229                    .without_dns()
230                    .with_websocket(security_upgrade, multiplexer_upgrade)
231                    .await
232            }
233        }
234    }
235}
236impl_quic_phase_with_websocket!(
237    "async-std",
238    super::provider::AsyncStd,
239    rw_stream_sink::RwStreamSink<
240        libp2p_websocket::BytesConnection<libp2p_tcp::async_io::TcpStream>,
241    >
242);
243impl_quic_phase_with_websocket!(
244    "tokio",
245    super::provider::Tokio,
246    rw_stream_sink::RwStreamSink<libp2p_websocket::BytesConnection<libp2p_tcp::tokio::TcpStream>>
247);
248impl<Provider, T: AuthenticatedMultiplexedTransport> SwarmBuilder<Provider, QuicPhase<T>> {
249    pub fn with_bandwidth_logging(
250        self,
251    ) -> (
252        SwarmBuilder<
253            Provider,
254            BehaviourPhase<impl AuthenticatedMultiplexedTransport, NoRelayBehaviour>,
255        >,
256        Arc<crate::bandwidth::BandwidthSinks>,
257    ) {
258        self.without_quic()
259            .without_any_other_transports()
260            .without_dns()
261            .without_websocket()
262            .without_relay()
263            .with_bandwidth_logging()
264    }
265}