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