everscale_network/rldp/mod.rs
1//! ## RLDP - Reliable Large Datagram Protocol
2//!
3//! A reliable arbitrary-size datagram protocol built upon the ADNL, called RLDP, is used instead
4//! of a TCP-like protocol. This reliable datagram protocol can be employed, for instance,
5//! to send RPC queries to remote hosts and receive answers from them.
6//!
7//! TODO
8
9use std::sync::Arc;
10
11use anyhow::Result;
12use frunk_core::hlist::{HCons, HList, IntoTuple2, Selector};
13use frunk_core::indices::{Here, There};
14
15pub(crate) use decoder::RaptorQDecoder;
16pub(crate) use encoder::RaptorQEncoder;
17pub use node::{Node, NodeMetrics, NodeOptions};
18
19use crate::adnl;
20use crate::subscriber::QuerySubscriber;
21use crate::util::{DeferredInitialization, NetworkBuilder};
22
23pub(crate) mod compression;
24mod decoder;
25mod encoder;
26mod incoming_transfer;
27mod node;
28mod outgoing_transfer;
29mod transfers_cache;
30
31pub(crate) type Deferred = Result<(Arc<adnl::Node>, Vec<Arc<dyn QuerySubscriber>>, NodeOptions)>;
32
33impl DeferredInitialization for Deferred {
34 type Initialized = Arc<Node>;
35
36 fn initialize(self) -> Result<Self::Initialized> {
37 let (adnl, subscribers, options) = self?;
38 Node::new(adnl, subscribers, options)
39 }
40}
41
42impl<L, A, R> NetworkBuilder<L, (A, R)>
43where
44 L: HList + Selector<adnl::Deferred, A>,
45 HCons<Deferred, L>: IntoTuple2,
46{
47 /// Creates RLDP network layer
48 ///
49 /// See [`with_rldp_ext`] if you need an RLDP node with additional subscribers
50 ///
51 /// [`with_rldp_ext`]: fn@crate::util::NetworkBuilder::with_rldp_ext
52 ///
53 /// # Examples
54 ///
55 /// ```
56 /// # use anyhow::Result;
57 /// # use everscale_network::{adnl, rldp, NetworkBuilder};
58 /// #[tokio::main]
59 /// async fn main() -> Result<()> {
60 /// let keystore = adnl::Keystore::builder()
61 /// .with_tagged_key([0; 32], 0)?
62 /// .build();
63 ///
64 /// let adnl_options = adnl::NodeOptions::default();
65 /// let rldp_options = rldp::NodeOptions::default();
66 ///
67 /// let (adnl, rldp) = NetworkBuilder::with_adnl("127.0.0.1:10000", keystore, adnl_options)
68 /// .with_rldp(rldp_options)
69 /// .build()?;
70 /// Ok(())
71 /// }
72 /// ```
73 #[allow(clippy::type_complexity)]
74 pub fn with_rldp(
75 self,
76 options: NodeOptions,
77 ) -> NetworkBuilder<HCons<Deferred, L>, (There<A>, Here)> {
78 self.with_rldp_ext(options, Vec::new())
79 }
80
81 /// Creates RLDP network layer with additional RLDP query subscribers
82 ///
83 /// # Examples
84 ///
85 /// ```
86 /// # use std::borrow::Cow;
87 /// # use std::sync::Arc;
88 /// # use anyhow::Result;
89 /// # use everscale_network::{
90 /// # adnl, rldp, NetworkBuilder, QueryConsumingResult, QuerySubscriber, SubscriberContext,
91 /// # };
92 /// struct LoggerSubscriber;
93 ///
94 /// #[async_trait::async_trait]
95 /// impl QuerySubscriber for LoggerSubscriber {
96 /// async fn try_consume_query<'a>(
97 /// &self,
98 /// ctx: SubscriberContext<'a>,
99 /// constructor: u32,
100 /// query: Cow<'a, [u8]>,
101 /// ) -> Result<QueryConsumingResult<'a>> {
102 /// println!("received {constructor}");
103 /// Ok(QueryConsumingResult::Rejected(query))
104 /// }
105 /// }
106 ///
107 /// #[tokio::main]
108 /// async fn main() -> Result<()> {
109 /// let keystore = adnl::Keystore::builder()
110 /// .with_tagged_key([0; 32], 0)?
111 /// .build();
112 ///
113 /// let adnl_options = adnl::NodeOptions::default();
114 /// let rldp_options = rldp::NodeOptions::default();
115 ///
116 /// let subscriber = Arc::new(LoggerSubscriber);
117 ///
118 /// let (adnl, rldp) = NetworkBuilder::with_adnl("127.0.0.1:10000", keystore, adnl_options)
119 /// .with_rldp_ext(rldp_options, vec![subscriber])
120 /// .build()?;
121 /// Ok(())
122 /// }
123 /// ```
124 #[allow(clippy::type_complexity)]
125 pub fn with_rldp_ext(
126 self,
127 options: NodeOptions,
128 subscribers: Vec<Arc<dyn QuerySubscriber>>,
129 ) -> NetworkBuilder<HCons<Deferred, L>, (There<A>, Here)> {
130 let deferred = match self.0.get() {
131 Ok(adnl) => Ok((adnl.clone(), subscribers, options)),
132 Err(_) => Err(anyhow::anyhow!("ADNL was not initialized")),
133 };
134 NetworkBuilder(self.0.prepend(deferred), Default::default())
135 }
136}