mithril_client/
lib.rs

1#![warn(missing_docs)]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3
4//! Define all the tooling necessary to manipulate Mithril certified types from a
5//! [Mithril Aggregator](https://mithril.network/rust-doc/mithril_aggregator/index.html).
6//!
7//! It handles the different types that can be queried to a Mithril aggregator:
8//!
9//! - [Cardano Database v1 (aka Snapshot)][snapshot_client]: list, get, download archive and record statistics.
10//! - [Cardano Database v2][cardano_database_client] list, get, download archive and record statistics.
11//! - [Cardano transactions][cardano_transaction_client] list & get snapshot, get proofs.
12//! - [Cardano stake distribution][cardano_stake_distribution_client] list, get and get by epoch.
13//! - [Mithril stake distribution][mithril_stake_distribution_client] list and get.
14//! - [Certificates][certificate_client] list, get, and chain validation.
15//!
16//! The [Client] aggregates the queries of all of those types.
17//!
18//! **NOTE:** Snapshot download and Certificate chain validation can take quite some time even with a fast
19//! computer and network.
20//! For those a feedback mechanism is available, more details on it in the [feedback] submodule.
21//!
22//! # Example
23//!
24//! Below is an example describing the usage of most of the library's functions together:
25//!
26//! **Note:** _Snapshot download and the compute snapshot message functions are available using crate feature_ **fs**.
27//!
28//! ```no_run
29//! # #[cfg(feature = "fs")]
30//! # async fn run() -> mithril_client::MithrilResult<()> {
31//! use mithril_client::{ClientBuilder, MessageBuilder};
32//! use std::path::Path;
33//!
34//! let client = ClientBuilder::aggregator("YOUR_AGGREGATOR_ENDPOINT", "YOUR_GENESIS_VERIFICATION_KEY").build()?;
35//!
36//! let snapshots = client.snapshot().list().await?;
37//!
38//! let last_digest = snapshots.first().unwrap().digest.as_ref();
39//! let snapshot = client.snapshot().get(last_digest).await?.unwrap();
40//!
41//! let certificate = client
42//!     .certificate()
43//!     .verify_chain(&snapshot.certificate_hash)
44//!     .await?;
45//!
46//! // Note: the directory must already exist, and the user running the binary must have read/write access to it.
47//! let target_directory = Path::new("/home/user/download/");
48//! client
49//!     .snapshot()
50//!     .download_unpack(&snapshot, &target_directory)
51//!     .await?;
52//!
53//! if let Err(e) = client.snapshot().add_statistics(&snapshot).await {
54//!     println!("Could not increment snapshot download statistics: {:?}", e);
55//! }
56//!
57//! let message = MessageBuilder::new()
58//!     .compute_snapshot_message(&certificate, &target_directory)
59//!     .await?;
60//!
61//! assert!(certificate.match_message(&message));
62//! #    Ok(())
63//! # }
64//! ```
65//!
66//! ## Optional Features
67//!
68//! The following are a list of [Cargo features](https://doc.rust-lang.org/stable/cargo/reference/manifest.html#the-features-section) that can be
69//! enabled or disabled:
70//!
71//! - **fs**: Enables file system related functionalities.
72//! - **unstable**: Enables experimental or in-development `mithril-client` features that may change.
73//! - **rug-backend** *(enabled by default)*: Enables usage of `rug` numerical backend in `mithril-stm` (dependency of `mithril-common`).
74//! - **num-integer-backend**: Enables usage of `num-integer` numerical backend in `mithril-stm` (dependency of `mithril-common`).
75//!
76//! To allow fine tuning of the http queries, the following [Reqwest](https://docs.rs/reqwest/latest/reqwest/#optional-features) features are re-exported:
77//! - **native-tls** *(enabled by default)*: Enables TLS functionality provided by `native-tls`.
78//! - **native-tls-vendored**: Enables the `vendored` feature of `native-tls`.
79//! - **native-tls-alpn**: Enables the `alpn` feature of `native-tls`.
80//! - **rustls-tls**: Enables TLS functionality provided by `rustls`.
81//!   Equivalent to `rustls-tls-webpki-roots`.
82//! - **rustls-tls-manual-roots**: Enables TLS functionality provided by `rustls`,
83//!   without setting any root certificates. Roots have to be specified manually.
84//! - **rustls-tls-webpki-roots**: Enables TLS functionality provided by `rustls`,
85//!   while using root certificates from the `webpki-roots` crate.
86//! - **rustls-tls-native-roots**: Enables TLS functionality provided by `rustls`,
87//!   while using root certificates from the `rustls-native-certs` crate.
88//! - **enable-http-compression** *(enabled by default)*: Enables compressed traffic with `reqwest`.
89
90macro_rules! cfg_fs {
91    ($($item:item)*) => {
92        $(
93            #[cfg(feature = "fs")]
94            #[cfg_attr(docsrs, doc(cfg(feature = "fs")))]
95            $item
96        )*
97    }
98}
99
100#[allow(unused_macros)]
101macro_rules! cfg_unstable {
102    ($($item:item)*) => {
103        $(
104            #[cfg(feature = "unstable")]
105            #[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
106            $item
107        )*
108    }
109}
110
111#[allow(unused_macros)]
112macro_rules! cfg_fs_unstable {
113    ($($item:item)*) => {
114        $(
115            #[cfg(all(feature = "unstable", feature = "fs"))]
116            #[cfg_attr(docsrs, doc(cfg(all(feature = "unstable", feature = "fs"))))]
117            $item
118        )*
119    }
120}
121
122pub mod aggregator_client;
123cfg_unstable! {
124    pub mod cardano_database_client;
125}
126pub mod cardano_stake_distribution_client;
127pub mod cardano_transaction_client;
128pub mod certificate_client;
129mod client;
130pub mod feedback;
131mod message;
132pub mod mithril_stake_distribution_client;
133pub mod snapshot_client;
134cfg_fs! {
135    pub mod file_downloader;
136}
137
138mod type_alias;
139mod utils;
140
141pub use client::*;
142pub use message::*;
143pub use type_alias::*;
144
145#[cfg(test)]
146pub(crate) mod test_utils {
147    use std::fs::File;
148    use std::io;
149    use std::sync::Arc;
150
151    use slog::{Drain, Logger};
152    use slog_async::Async;
153    use slog_term::{CompactFormat, PlainDecorator};
154
155    pub struct TestLogger;
156
157    #[allow(unused)]
158    impl TestLogger {
159        fn from_writer<W: io::Write + Send + 'static>(writer: W) -> Logger {
160            let decorator = PlainDecorator::new(writer);
161            let drain = CompactFormat::new(decorator).build().fuse();
162            let drain = Async::new(drain).build().fuse();
163            Logger::root(Arc::new(drain), slog::o!())
164        }
165
166        pub fn stdout() -> Logger {
167            Self::from_writer(slog_term::TestStdoutWriter)
168        }
169
170        pub fn file(filepath: &std::path::Path) -> Logger {
171            Self::from_writer(File::create(filepath).unwrap())
172        }
173    }
174}