1use std::{convert::Infallible, marker::PhantomData};
2
3use futures::{stream, Stream};
4use tower::{make::Shared, util::MapErr};
5use tracing::Span;
6
7use cuprate_wire::BasicNodeData;
8
9use crate::{
10 client::{handshaker::HandShaker, InternalPeerID},
11 AddressBook, BroadcastMessage, CoreSyncSvc, NetworkZone, ProtocolRequestHandlerMaker,
12 Transport,
13};
14
15mod dummy;
16pub use dummy::{DummyAddressBook, DummyCoreSyncSvc, DummyProtocolRequestHandler};
17
18#[derive(Debug, Clone)]
27pub struct HandshakerBuilder<
28 N: NetworkZone,
29 T: Transport<N>,
30 AdrBook = DummyAddressBook,
31 CSync = DummyCoreSyncSvc,
32 ProtoHdlrMkr = MapErr<Shared<DummyProtocolRequestHandler>, fn(Infallible) -> tower::BoxError>,
33 BrdcstStrmMkr = fn(
34 InternalPeerID<<N as NetworkZone>::Addr>,
35 ) -> stream::Pending<BroadcastMessage>,
36> {
37 address_book: AdrBook,
39 core_sync_svc: CSync,
41 protocol_request_svc_maker: ProtoHdlrMkr,
43 our_basic_node_data: BasicNodeData,
45 broadcast_stream_maker: BrdcstStrmMkr,
47 connection_parent_span: Option<Span>,
49
50 transport_client_config: T::ClientConfig,
52 _zone: PhantomData<N>,
54}
55
56impl<N: NetworkZone, T: Transport<N>> HandshakerBuilder<N, T> {
57 pub fn new(
59 our_basic_node_data: BasicNodeData,
60 transport_client_config: T::ClientConfig,
61 ) -> Self {
62 Self {
63 address_book: DummyAddressBook,
64 core_sync_svc: DummyCoreSyncSvc::static_mainnet_genesis(),
65 protocol_request_svc_maker: MapErr::new(
66 Shared::new(DummyProtocolRequestHandler),
67 tower::BoxError::from,
68 ),
69 our_basic_node_data,
70 broadcast_stream_maker: |_| stream::pending(),
71 connection_parent_span: None,
72 transport_client_config,
73 _zone: PhantomData,
74 }
75 }
76}
77
78impl<N: NetworkZone, T: Transport<N>, AdrBook, CSync, ProtoHdlr, BrdcstStrmMkr>
79 HandshakerBuilder<N, T, AdrBook, CSync, ProtoHdlr, BrdcstStrmMkr>
80{
81 pub fn with_address_book<NAdrBook>(
90 self,
91 new_address_book: NAdrBook,
92 ) -> HandshakerBuilder<N, T, NAdrBook, CSync, ProtoHdlr, BrdcstStrmMkr>
93 where
94 NAdrBook: AddressBook<N> + Clone,
95 {
96 let Self {
97 core_sync_svc,
98 protocol_request_svc_maker,
99 our_basic_node_data,
100 broadcast_stream_maker,
101 connection_parent_span,
102 transport_client_config,
103 ..
104 } = self;
105
106 HandshakerBuilder {
107 address_book: new_address_book,
108 core_sync_svc,
109 protocol_request_svc_maker,
110 our_basic_node_data,
111 broadcast_stream_maker,
112 connection_parent_span,
113 transport_client_config,
114 _zone: PhantomData,
115 }
116 }
117
118 pub fn with_core_sync_svc<NCSync>(
132 self,
133 new_core_sync_svc: NCSync,
134 ) -> HandshakerBuilder<N, T, AdrBook, NCSync, ProtoHdlr, BrdcstStrmMkr>
135 where
136 NCSync: CoreSyncSvc + Clone,
137 {
138 let Self {
139 address_book,
140 protocol_request_svc_maker,
141 our_basic_node_data,
142 broadcast_stream_maker,
143 connection_parent_span,
144 transport_client_config,
145 ..
146 } = self;
147
148 HandshakerBuilder {
149 address_book,
150 core_sync_svc: new_core_sync_svc,
151 protocol_request_svc_maker,
152 our_basic_node_data,
153 broadcast_stream_maker,
154 connection_parent_span,
155 transport_client_config,
156 _zone: PhantomData,
157 }
158 }
159
160 pub fn with_protocol_request_handler_maker<NProtoHdlrMkr>(
169 self,
170 new_protocol_request_svc_maker: NProtoHdlrMkr,
171 ) -> HandshakerBuilder<N, T, AdrBook, CSync, NProtoHdlrMkr, BrdcstStrmMkr>
172 where
173 NProtoHdlrMkr: ProtocolRequestHandlerMaker<N> + Clone,
174 {
175 let Self {
176 address_book,
177 core_sync_svc,
178 our_basic_node_data,
179 broadcast_stream_maker,
180 connection_parent_span,
181 transport_client_config,
182 ..
183 } = self;
184
185 HandshakerBuilder {
186 address_book,
187 core_sync_svc,
188 protocol_request_svc_maker: new_protocol_request_svc_maker,
189 our_basic_node_data,
190 broadcast_stream_maker,
191 connection_parent_span,
192 transport_client_config,
193 _zone: PhantomData,
194 }
195 }
196
197 pub fn with_broadcast_stream_maker<NBrdcstStrmMkr, BrdcstStrm>(
205 self,
206 new_broadcast_stream_maker: NBrdcstStrmMkr,
207 ) -> HandshakerBuilder<N, T, AdrBook, CSync, ProtoHdlr, NBrdcstStrmMkr>
208 where
209 BrdcstStrm: Stream<Item = BroadcastMessage> + Send + 'static,
210 NBrdcstStrmMkr: Fn(InternalPeerID<N::Addr>) -> BrdcstStrm + Clone + Send + 'static,
211 {
212 let Self {
213 address_book,
214 core_sync_svc,
215 protocol_request_svc_maker,
216 our_basic_node_data,
217 connection_parent_span,
218 transport_client_config,
219 ..
220 } = self;
221
222 HandshakerBuilder {
223 address_book,
224 core_sync_svc,
225 protocol_request_svc_maker,
226 our_basic_node_data,
227 broadcast_stream_maker: new_broadcast_stream_maker,
228 connection_parent_span,
229 transport_client_config,
230 _zone: PhantomData,
231 }
232 }
233
234 #[must_use]
240 pub fn with_connection_parent_span(self, connection_parent_span: Span) -> Self {
241 Self {
242 connection_parent_span: Some(connection_parent_span),
243 ..self
244 }
245 }
246
247 pub fn build(self) -> HandShaker<N, T, AdrBook, CSync, ProtoHdlr, BrdcstStrmMkr> {
249 HandShaker::new(
250 self.address_book,
251 self.core_sync_svc,
252 self.protocol_request_svc_maker,
253 self.broadcast_stream_maker,
254 self.our_basic_node_data,
255 self.connection_parent_span.unwrap_or(Span::none()),
256 self.transport_client_config,
257 )
258 }
259}