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, PeerSyncCallback},
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 on_peer_sync: Option<PeerSyncCallback>,
51
52 transport_client_config: T::ClientConfig,
54 _zone: PhantomData<N>,
56}
57
58impl<N: NetworkZone, T: Transport<N>> HandshakerBuilder<N, T> {
59 pub fn new(
61 our_basic_node_data: BasicNodeData,
62 transport_client_config: T::ClientConfig,
63 ) -> Self {
64 Self {
65 address_book: DummyAddressBook,
66 core_sync_svc: DummyCoreSyncSvc::static_mainnet_genesis(),
67 protocol_request_svc_maker: MapErr::new(
68 Shared::new(DummyProtocolRequestHandler),
69 tower::BoxError::from,
70 ),
71 our_basic_node_data,
72 broadcast_stream_maker: |_| stream::pending(),
73 connection_parent_span: None,
74 on_peer_sync: None,
75 transport_client_config,
76 _zone: PhantomData,
77 }
78 }
79}
80
81impl<N: NetworkZone, T: Transport<N>, AdrBook, CSync, ProtoHdlr, BrdcstStrmMkr>
82 HandshakerBuilder<N, T, AdrBook, CSync, ProtoHdlr, BrdcstStrmMkr>
83{
84 pub fn with_address_book<NAdrBook>(
93 self,
94 new_address_book: NAdrBook,
95 ) -> HandshakerBuilder<N, T, NAdrBook, CSync, ProtoHdlr, BrdcstStrmMkr>
96 where
97 NAdrBook: AddressBook<N> + Clone,
98 {
99 let Self {
100 core_sync_svc,
101 protocol_request_svc_maker,
102 our_basic_node_data,
103 broadcast_stream_maker,
104 connection_parent_span,
105 on_peer_sync,
106 transport_client_config,
107 ..
108 } = self;
109
110 HandshakerBuilder {
111 address_book: new_address_book,
112 core_sync_svc,
113 protocol_request_svc_maker,
114 our_basic_node_data,
115 broadcast_stream_maker,
116 connection_parent_span,
117 on_peer_sync,
118 transport_client_config,
119 _zone: PhantomData,
120 }
121 }
122
123 pub fn with_core_sync_svc<NCSync>(
137 self,
138 new_core_sync_svc: NCSync,
139 ) -> HandshakerBuilder<N, T, AdrBook, NCSync, ProtoHdlr, BrdcstStrmMkr>
140 where
141 NCSync: CoreSyncSvc + Clone,
142 {
143 let Self {
144 address_book,
145 protocol_request_svc_maker,
146 our_basic_node_data,
147 broadcast_stream_maker,
148 connection_parent_span,
149 on_peer_sync,
150 transport_client_config,
151 ..
152 } = self;
153
154 HandshakerBuilder {
155 address_book,
156 core_sync_svc: new_core_sync_svc,
157 protocol_request_svc_maker,
158 our_basic_node_data,
159 broadcast_stream_maker,
160 connection_parent_span,
161 on_peer_sync,
162 transport_client_config,
163 _zone: PhantomData,
164 }
165 }
166
167 pub fn with_protocol_request_handler_maker<NProtoHdlrMkr>(
176 self,
177 new_protocol_request_svc_maker: NProtoHdlrMkr,
178 ) -> HandshakerBuilder<N, T, AdrBook, CSync, NProtoHdlrMkr, BrdcstStrmMkr>
179 where
180 NProtoHdlrMkr: ProtocolRequestHandlerMaker<N> + Clone,
181 {
182 let Self {
183 address_book,
184 core_sync_svc,
185 our_basic_node_data,
186 broadcast_stream_maker,
187 connection_parent_span,
188 on_peer_sync,
189 transport_client_config,
190 ..
191 } = self;
192
193 HandshakerBuilder {
194 address_book,
195 core_sync_svc,
196 protocol_request_svc_maker: new_protocol_request_svc_maker,
197 our_basic_node_data,
198 broadcast_stream_maker,
199 connection_parent_span,
200 on_peer_sync,
201 transport_client_config,
202 _zone: PhantomData,
203 }
204 }
205
206 pub fn with_broadcast_stream_maker<NBrdcstStrmMkr, BrdcstStrm>(
214 self,
215 new_broadcast_stream_maker: NBrdcstStrmMkr,
216 ) -> HandshakerBuilder<N, T, AdrBook, CSync, ProtoHdlr, NBrdcstStrmMkr>
217 where
218 BrdcstStrm: Stream<Item = BroadcastMessage> + Send + 'static,
219 NBrdcstStrmMkr: Fn(InternalPeerID<N::Addr>) -> BrdcstStrm + Clone + Send + 'static,
220 {
221 let Self {
222 address_book,
223 core_sync_svc,
224 protocol_request_svc_maker,
225 our_basic_node_data,
226 connection_parent_span,
227 on_peer_sync,
228 transport_client_config,
229 ..
230 } = self;
231
232 HandshakerBuilder {
233 address_book,
234 core_sync_svc,
235 protocol_request_svc_maker,
236 our_basic_node_data,
237 broadcast_stream_maker: new_broadcast_stream_maker,
238 connection_parent_span,
239 on_peer_sync,
240 transport_client_config,
241 _zone: PhantomData,
242 }
243 }
244
245 #[must_use]
251 pub fn with_peer_sync_callback(self, on_peer_sync: PeerSyncCallback) -> Self {
252 Self {
253 on_peer_sync: Some(on_peer_sync),
254 ..self
255 }
256 }
257
258 #[must_use]
264 pub fn with_connection_parent_span(self, connection_parent_span: Span) -> Self {
265 Self {
266 connection_parent_span: Some(connection_parent_span),
267 ..self
268 }
269 }
270
271 pub fn build(self) -> HandShaker<N, T, AdrBook, CSync, ProtoHdlr, BrdcstStrmMkr> {
273 HandShaker::new(
274 self.address_book,
275 self.core_sync_svc,
276 self.protocol_request_svc_maker,
277 self.broadcast_stream_maker,
278 self.our_basic_node_data,
279 self.connection_parent_span.unwrap_or(Span::none()),
280 self.on_peer_sync,
281 self.transport_client_config,
282 )
283 }
284}