Skip to main content

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}