Skip to content

Commit 595cbe5

Browse files
authored
Merge pull request #2350 from input-output-hk/dlachaume/2329/document-client-incremental-cardano-db
Docs: update clients documentation for incremental Cardano DB
2 parents 86c1e4f + 382ac55 commit 595cbe5

File tree

5 files changed

+278
-33
lines changed

5 files changed

+278
-33
lines changed

docs/website/root/glossary.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ Below is a comprehensive list of definitions for some common terms used in the M
1010

1111
A beacon represents a point of the blockchain for which a [Mithril certificate](#certificate) is created. It embeds the [epoch](#epoch) of the [Cardano network](#cardano-network) that is targeted, and either the block number or the [immutable file number](#immutable-file-number).
1212

13+
## Cardano database
14+
15+
A Cardano database snapshot is a signed archive of the blockchain state that can be used by [Mithril clients](#mithril-client) to restore a [Cardano full node](#cardano-node). It is uniquely identified by its fingerprint or digest which is part of the message signed by the [Mithril network](#mithril-network).
16+
1317
## Cardano network
1418

1519
The Cardano network is a proof-of-stake blockchain platform that supports the ada cryptocurrency.
@@ -88,10 +92,6 @@ The Mithril multi-signature is an aggregate of [individual signatures](#individu
8892

8993
> More information is available on the [protocol page](./mithril/advanced/mithril-protocol/protocol.md).
9094
91-
## Snapshot
92-
93-
A Mithril snapshot is a signed archive of the blockchain state that can be used by [Mithril clients](#mithril-client) to restore a [Cardano full node](#cardano-node). It is uniquely identified by its fingerprint or digest which is part of the message signed by the [Mithril network](#mithril-network).
94-
9595
## Stake distribution
9696

9797
The Cardano stake distribution is the list of all the [stake pool operators'](#stake-pool-operator-spo) pool Id addresses and their associated share of the total stake of the [Cardano network](#cardano-network).

docs/website/root/manual/develop/nodes/mithril-client-library-wasm.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ Mithril client library WASM can be used by Javascript developers to use the Mith
1010

1111
It is responsible for handling the different types of data certified by Mithril and available through a Mithril aggregator:
1212

13-
- [**Snapshot**](../../../glossary.md#snapshot): list and get
14-
- [**Mithril stake distribution**](../../../glossary.md#stake-distribution): list and get
1513
- [**Cardano transaction**](../../../glossary.md#cardano-transaction): list and get snapshots, get proofs
1614
- [**Cardano stake distribution**](../../../glossary.md#stake-distribution): list, get and get by epoch
15+
- [**Cardano database**](../../../glossary.md#cardano-database): list and get
16+
- [**Mithril stake distribution**](../../../glossary.md#stake-distribution): list and get
1717
- [**Certificate**](../../../glossary.md#certificate): list, get, and chain validation.
1818

1919
:::

docs/website/root/manual/develop/nodes/mithril-client-library.md

Lines changed: 234 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ Mithril client library can be used by Rust developers to use the Mithril network
1010

1111
It is responsible for handling the different types of data certified by Mithril and available through a Mithril aggregator:
1212

13-
- [**Snapshot**](../../../glossary.md#snapshot): list, get, download the tarball, and record statistics
14-
- [**Mithril stake distribution**](../../../glossary.md#stake-distribution): list and get
1513
- [**Cardano transaction**](../../../glossary.md#cardano-transaction): list and get snapshots, get proofs
1614
- [**Cardano stake distribution**](../../../glossary.md#stake-distribution): list, get, and get by epoch
15+
- [**Cardano database**](../../../glossary.md#cardano-database): list, get, download the tarball, and record statistics
16+
- [**Mithril stake distribution**](../../../glossary.md#stake-distribution): list and get
1717
- [**Certificate**](../../../glossary.md#certificate): list, get, and chain validation.
1818

1919
:::
@@ -64,34 +64,168 @@ Mithril client is an asynchronous library. You will need a runtime to execute yo
6464

6565
## Using the Mithril client library
6666

67-
Below is a basic example of how to use most of the functions exposed by the Mithril client library:
67+
### Cardano transactions
68+
69+
Here is a basic example of the code targetting the `release-preprod` network aggregator:
70+
71+
```rust title="/src/main.rs"
72+
use mithril_client::{ClientBuilder, MessageBuilder, MithrilResult};
73+
74+
#[tokio::main]
75+
async fn main() -> MithrilResult<()> {
76+
const AGGREGATOR_ENDPOINT: &str =
77+
"https://aggregator.release-preprod.api.mithril.network/aggregator";
78+
const GENESIS_VERIFICATION_KEY: &str = "5b3132372c37332c3132342c3136312c362c3133372c3133312c3231332c3230372c3131372c3139382c38352c3137362c3139392c3136322c3234312c36382c3132332c3131392c3134352c31332c3233322c3234332c34392c3232392c322c3234392c3230352c3230352c33392c3233352c34345d";
79+
let client =
80+
ClientBuilder::aggregator(AGGREGATOR_ENDPOINT, GENESIS_VERIFICATION_KEY).build()?;
81+
82+
let transactions_hashes = [
83+
"f9b5221b3ead45d46c0ecae6bee18a0746c5694d0285281cca1b651bce5f49a5",
84+
"7769e8b78cc86890660ff5451c110b0a0d0413c8b8ebb17a64e017b4cd881777",
85+
];
86+
let cardano_transaction_proof = client
87+
.cardano_transaction()
88+
.get_proofs(&transactions_hashes)
89+
.await
90+
.unwrap();
91+
92+
let verified_transactions = cardano_transaction_proof.verify().unwrap();
93+
94+
let certificate = client
95+
.certificate()
96+
.verify_chain(&cardano_transaction_proof.certificate_hash)
97+
.await
98+
.unwrap();
99+
100+
let message = MessageBuilder::new()
101+
.compute_cardano_transactions_proofs_message(&certificate, &verified_transactions);
102+
assert!(certificate.match_message(&message));
103+
104+
println!(
105+
r###"Cardano transactions with hashes "'{}'" have been successfully certified by Mithril."###,
106+
verified_transactions.certified_transactions().join(","),
107+
);
108+
if !cardano_transaction_proof
109+
.non_certified_transactions
110+
.is_empty()
111+
{
112+
println!(
113+
r###"No proof could be computed for Cardano transactions with hashes "'{}'".
114+
115+
Mithril may not have signed those transactions yet, please try again later."###,
116+
cardano_transaction_proof
117+
.non_certified_transactions
118+
.join(","),
119+
);
120+
}
121+
122+
Ok(())
123+
}
124+
```
125+
126+
:::info
127+
128+
An full example is available in the [Mithril repository](https://github.com/input-output-hk/mithril/tree/main/examples/client-cardano-transaction/src/main.rs). To run it, execute the following command:
129+
130+
```bash
131+
cargo run -p client-cardano-transaction <TRANSACTIONS_HASHES>
132+
```
133+
134+
or directly from the example crate directory:
135+
136+
```bash
137+
cargo run
138+
```
139+
140+
:::
141+
142+
### Cardano stake distribution
143+
144+
Here is a basic example of the code targetting the `release-preprod` network aggregator:
145+
146+
```rust title="/src/main.rs"
147+
use mithril_client::{ClientBuilder, MessageBuilder, MithrilResult};
148+
149+
#[tokio::main]
150+
async fn main() -> MithrilResult<()> {
151+
const AGGREGATOR_ENDPOINT: &str =
152+
"https://aggregator.release-preprod.api.mithril.network/aggregator";
153+
const GENESIS_VERIFICATION_KEY: &str = "5b3132372c37332c3132342c3136312c362c3133372c3133312c3231332c3230372c3131372c3139382c38352c3137362c3139392c3136322c3234312c36382c3132332c3131392c3134352c31332c3233322c3234332c34392c3232392c322c3234392c3230352c3230352c33392c3233352c34345d";
154+
let client =
155+
ClientBuilder::aggregator(AGGREGATOR_ENDPOINT, GENESIS_VERIFICATION_KEY).build()?;
156+
157+
let cardano_stake_distributions = client.cardano_stake_distribution().list().await?;
158+
let last_epoch = cardano_stake_distributions.first().unwrap().epoch;
159+
160+
let cardano_stake_distribution = client
161+
.cardano_stake_distribution()
162+
.get_by_epoch(last_epoch)
163+
.await?
164+
.unwrap();
165+
166+
let certificate = client
167+
.certificate()
168+
.verify_chain(&cardano_stake_distribution.certificate_hash)
169+
.await?;
170+
171+
let message = MessageBuilder::new()
172+
.compute_cardano_stake_distribution_message(&certificate, &cardano_stake_distribution)?;
173+
174+
assert!(certificate.match_message(&message));
175+
176+
Ok(())
177+
}
178+
```
179+
180+
:::info
181+
182+
An full example is available in the [Mithril repository](https://github.com/input-output-hk/mithril/tree/main/examples/client-cardano-stake-distribution/src/main.rs). To run it, execute the following command:
183+
184+
```bash
185+
cargo run -p client-cardano-stake-distribution
186+
```
187+
188+
or directly from the example crate directory:
189+
190+
```bash
191+
cargo run
192+
```
193+
194+
:::
195+
196+
### Cardano database
197+
198+
Here is a basic example of the code targetting the `release-preprod` network aggregator:
68199

69200
```rust title="/src/main.rs"
70201
use mithril_client::{ClientBuilder, MessageBuilder};
71202
use std::path::Path;
72203

73204
#[tokio::main]
74205
async fn main() -> mithril_client::MithrilResult<()> {
75-
let client = ClientBuilder::aggregator("YOUR_AGGREGATOR_ENDPOINT", "YOUR_GENESIS_VERIFICATION_KEY").build()?;
76-
77-
let snapshots = client.snapshot().list().await?;
206+
const AGGREGATOR_ENDPOINT: &str =
207+
"https://aggregator.release-preprod.api.mithril.network/aggregator";
208+
const GENESIS_VERIFICATION_KEY: &str = "5b3132372c37332c3132342c3136312c362c3133372c3133312c3231332c3230372c3131372c3139382c38352c3137362c3139392c3136322c3234312c36382c3132332c3131392c3134352c31332c3233322c3234332c34392c3232392c322c3234392c3230352c3230352c33392c3233352c34345d";
209+
let client =
210+
ClientBuilder::aggregator(AGGREGATOR_ENDPOINT, GENESIS_VERIFICATION_KEY).build()?;
211+
let snapshots = client.cardano_database().list().await?;
78212

79213
let last_digest = snapshots.first().unwrap().digest.as_ref();
80-
let snapshot = client.snapshot().get(last_digest).await?.unwrap();
214+
let snapshot = client.cardano_database().get(last_digest).await?.unwrap();
81215

82216
let certificate = client
83217
.certificate()
84218
.verify_chain(&snapshot.certificate_hash)
85219
.await?;
86220

87221
// Note: the directory must already exist, and the user running this code must have read/write access to it.
88-
let target_directory = Path::new("YOUR_TARGET_DIRECTORY");
222+
let target_directory = Path::new(".");
89223
client
90-
.snapshot()
224+
.cardano_database()
91225
.download_unpack(&snapshot, target_directory)
92226
.await?;
93227

94-
if let Err(e) = client.snapshot().add_statistics(&snapshot).await {
228+
if let Err(e) = client.cardano_database().add_statistics(&snapshot).await {
95229
println!("Could not increment snapshot download statistics: {:?}", e);
96230
}
97231

@@ -108,10 +242,10 @@ async fn main() -> mithril_client::MithrilResult<()> {
108242

109243
Snapshot download and certificate chain validation can take quite some time, even with a fast computer and network. We have implemented a feedback mechanism for them; more details are available in the [feedback sub-module](https://mithril.network/rust-doc/mithril_client/feedback/index.html).
110244

111-
An example of implementation with the crate [indicatif](https://crates.io/crates/indicatif) is available in the [Mithril repository](https://github.com/input-output-hk/mithril/tree/main/examples/client-snapshot/src/main.rs). To run it, execute the following command:
245+
An example of implementation with the crate [indicatif](https://crates.io/crates/indicatif) is available in the [Mithril repository](https://github.com/input-output-hk/mithril/tree/main/examples/client-cardano-database/src/main.rs). To run it, execute the following command:
112246

113247
```bash
114-
cargo run -p client-snapshot
248+
cargo run -p client-cardano-database
115249
```
116250

117251
or directly from the example crate directory:
@@ -122,46 +256,122 @@ cargo run
122256

123257
:::
124258

125-
Here is a working example of the code using the configuration parameters of the `release-preprod` network:
259+
### Cardano database v2
260+
261+
:::danger
262+
263+
This feature is still unstable.
264+
265+
To use it, you need to add the `unstable` feature in your project's `Cargo.toml` file.
266+
267+
```
268+
mithril-client = { version = "0.11.X", features = ["fs", "unstable"] }
269+
```
270+
271+
:::
272+
273+
Below is a basic example using the new `CardanoDatabase` functions. Make sure the target aggregator signs `CardanoDatabase` incremental snapshot.
274+
275+
:::tip
276+
277+
You can verify that the aggregator signs **CardanoDatabase** by running the command below:
278+
279+
```bash
280+
wget -q -O - YOUR_AGGREGATOR_ENDPOINT | jq '.capabilities.signed_entity_types | contains(["CardanoDatabase"])'
281+
```
282+
283+
For example, with the aggregator on the `testing-preview` Mithril network:
284+
285+
```bash
286+
wget -q -O - https://aggregator.testing-preview.api.mithril.network/aggregator | jq '.capabilities.signed_entity_types | contains(["CardanoDatabase"])'
287+
```
288+
289+
:::
126290

127291
```rust title="/src/main.rs"
128-
use mithril_client::{ClientBuilder, MessageBuilder};
292+
use mithril_client::{
293+
cardano_database_client::{DownloadUnpackOptions, ImmutableFileRange},
294+
ClientBuilder, MessageBuilder,
295+
};
129296
use std::path::Path;
130297

131298
#[tokio::main]
132299
async fn main() -> mithril_client::MithrilResult<()> {
133-
let client = ClientBuilder::aggregator("https://aggregator.release-preprod.api.mithril.network/aggregator", "5b3132372c37332c3132342c3136312c362c3133372c3133312c3231332c3230372c3131372c3139382c38352c3137362c3139392c3136322c3234312c36382c3132332c3131392c3134352c31332c3233322c3234332c34392c3232392c322c3234392c3230352c3230352c33392c3233352c34345d").build()?;
300+
const AGGREGATOR_ENDPOINT: &str =
301+
"https://aggregator.testing-preview.api.mithril.network/aggregator";
302+
const GENESIS_VERIFICATION_KEY: &str = "5b3132372c37332c3132342c3136312c362c3133372c3133312c3231332c3230372c3131372c3139382c38352c3137362c3139392c3136322c3234312c36382c3132332c3131392c3134352c31332c3233322c3234332c34392c3232392c322c3234392c3230352c3230352c33392c3233352c34345d";
303+
let client =
304+
ClientBuilder::aggregator(AGGREGATOR_ENDPOINT, GENESIS_VERIFICATION_KEY).build()?;
134305

135-
let snapshots = client.snapshot().list().await?;
306+
let snapshots = client.cardano_database_v2().list().await?;
136307

137-
let last_digest = snapshots.first().unwrap().digest.as_ref();
138-
let snapshot = client.snapshot().get(last_digest).await?.unwrap();
308+
let latest_hash = snapshots.first().unwrap().hash.as_ref();
309+
let snapshot = client
310+
.cardano_database_v2()
311+
.get(latest_hash)
312+
.await?
313+
.unwrap();
139314

140315
let certificate = client
141316
.certificate()
142317
.verify_chain(&snapshot.certificate_hash)
143318
.await?;
144319

320+
let immutable_file_range = ImmutableFileRange::From(15000);
321+
let download_unpack_options = DownloadUnpackOptions {
322+
allow_override: true,
323+
include_ancillary: false,
324+
..DownloadUnpackOptions::default()
325+
};
326+
145327
// Note: the directory must already exist, and the user running this code must have read/write access to it.
146328
let target_directory = Path::new(".");
147329
client
148-
.snapshot()
149-
.download_unpack(&snapshot, target_directory)
330+
.cardano_database_v2()
331+
.download_unpack(
332+
&snapshot,
333+
&immutable_file_range,
334+
target_directory,
335+
download_unpack_options,
336+
)
150337
.await?;
151338

152-
if let Err(e) = client.snapshot().add_statistics(&snapshot).await {
153-
println!("Could not increment snapshot download statistics: {:?}", e);
154-
}
339+
let merkle_proof = client
340+
.cardano_database_v2()
341+
.compute_merkle_proof(
342+
&certificate,
343+
&snapshot,
344+
&immutable_file_range,
345+
target_directory,
346+
)
347+
.await?;
348+
merkle_proof.verify()?;
155349

156350
let message = MessageBuilder::new()
157-
.compute_snapshot_message(&certificate, target_directory)
351+
.compute_cardano_database_message(&certificate, &merkle_proof)
158352
.await?;
159353
assert!(certificate.match_message(&message));
160354

161355
Ok(())
162356
}
163357
```
164358

359+
:::info
360+
361+
An full example is available in the [Mithril repository](https://github.com/input-output-hk/mithril/tree/main/examples/client-cardano-database-v2/src/main.rs). To run it, execute the following command:
362+
363+
```bash
364+
cargo run -p client-cardano-database-v2
365+
```
366+
367+
or directly from the example crate directory:
368+
369+
```bash
370+
cargo run
371+
```
372+
373+
:::
374+
165375
:::tip
166376

167377
You can read the complete [developer documentation](https://mithril.network/rust-doc/mithril_client/index.html).

0 commit comments

Comments
 (0)