Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Feat: implement CardanoDatabase in mithril-client WASM #2258

Merged
merged 9 commits into from
Jan 29, 2025
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@ As a minor extension, we have adopted a slightly different versioning convention
- Implement the artifact immutable builder in the aggregator.
- Implement the artifact digest builder in the aggregator.
- Implement the client library for the the signed entity type `CardanoDatabase` (list snapshots and get snapshot detail).
- Implement the client library functions for the the signed entity type `CardanoDatabase` within the WASM library.

- Crates versions:

6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/client-wasm-nodejs/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/client-wasm-web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion internal/mithril-build-script/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mithril-build-script"
version = "0.2.15"
version = "0.2.16"
description = "A toolbox for Mithril crates build scripts"
authors = { workspace = true }
edition = { workspace = true }
19 changes: 19 additions & 0 deletions internal/mithril-build-script/src/fake_aggregator.rs
Original file line number Diff line number Diff line change
@@ -31,6 +31,9 @@ pub struct FakeAggregatorData {

csds_list: FileContent,
individual_csds: BTreeMap<ArtifactId, FileContent>,

cdbs_list: FileContent,
individual_cdbs: BTreeMap<ArtifactId, FileContent>,
}

impl FakeAggregatorData {
@@ -59,6 +62,9 @@ impl FakeAggregatorData {
"cardano-stake-distributions-list.json" => {
data.csds_list = file_content;
}
"cardano-databases-list.json" => {
data.cdbs_list = file_content;
}
"certificates-list.json" => {
data.certificates_list = file_content;
}
@@ -74,6 +80,9 @@ impl FakeAggregatorData {
"cardano-stake-distributions.json" => {
data.individual_csds = Self::read_artifacts_json_file(&entry.path());
}
"cardano-databases.json" => {
data.individual_cdbs = Self::read_artifacts_json_file(&entry.path());
}
"certificates.json" => {
data.individual_certificates = Self::read_artifacts_json_file(&entry.path());
}
@@ -110,6 +119,10 @@ impl FakeAggregatorData {
"csd_epochs",
BTreeSet::from_iter(extract_csd_epochs(&self.individual_csds)),
),
generate_ids_array(
"cdb_hashes",
BTreeSet::from_iter(self.individual_cdbs.keys().cloned()),
),
generate_ids_array(
"certificate_hashes",
BTreeSet::from_iter(self.individual_certificates.keys().cloned()),
@@ -157,6 +170,12 @@ impl FakeAggregatorData {
"certificate_hashes",
BTreeSet::from_iter(self.individual_certificates.keys().cloned()),
),
generate_ids_array(
"cdb_hashes",
BTreeSet::from_iter(self.individual_cdbs.keys().cloned()),
),
generate_artifact_getter("cdbs", self.individual_cdbs),
generate_list_getter("cdb_list", self.cdbs_list),
generate_artifact_getter("certificates", self.individual_certificates),
generate_list_getter("certificate_list", self.certificates_list),
generate_ids_array(
2 changes: 1 addition & 1 deletion mithril-client-wasm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mithril-client-wasm"
version = "0.7.5"
version = "0.7.6"
description = "Mithril client WASM"
authors = { workspace = true }
edition = { workspace = true }
20 changes: 18 additions & 2 deletions mithril-client-wasm/ci-test/README.md
Original file line number Diff line number Diff line change
@@ -15,13 +15,29 @@ cd mithril-client-wasm/
- Before running the tests, make sure to install the required dependencies. Use the following command:

```bash
make www-test-install
make ci-test-install
```

## Running the tests in the browser

Create an environment file with the following commands and your configuration:

```bash
echo "AGGREGATOR_ENDPOINT=**YOUR_AGGREGATOR_ENDPOINT**" > ci-test/.env
echo "GENESIS_VERIFICATION_KEY=**YOUR_GENESIS_VERIFICATION_KEY**" >> ci-test/.env
```

For example with the aggregator on `testing-preview` network:

```bash
echo "AGGREGATOR_ENDPOINT=https://aggregator.testing-preview.api.mithril.network/aggregator" > ci-test/.env
echo "GENESIS_VERIFICATION_KEY=$(curl -s https://raw.githubusercontent.com/input-output-hk/mithril/main/mithril-infra/configuration/testing-preview/genesis.vkey)" >> ci-test/.env
```

Then execute the command to run the tests:

```bash
make www-test-serve
make ci-test-serve
```

## Test Results Display
18 changes: 18 additions & 0 deletions mithril-client-wasm/ci-test/index.js
Original file line number Diff line number Diff line change
@@ -239,6 +239,24 @@ if (aggregator_capabilities.includes("CardanoStakeDistribution")) {
valid_cardano_stake_distribution_message,
);
});

if (aggregator_capabilities.includes("CardanoDatabase")) {
let cardano_database_snapshots;
test_number++;
await run_test("list_cardano_database_v2", test_number, async () => {
cardano_database_snapshots = await client.list_cardano_database_v2();
console.log("cardano_database_snapshots", cardano_database_snapshots);
});

let cardano_database_snapshot;
test_number++;
await run_test("get_cardano_database_v2", test_number, async () => {
cardano_database_snapshot = await client.get_cardano_database_v2(
cardano_database_snapshots[0].hash,
);
console.log("cardano_database_snapshot", cardano_database_snapshot);
});
}
}

add_finished_div();
6 changes: 3 additions & 3 deletions mithril-client-wasm/ci-test/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion mithril-client-wasm/ci-test/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "client-wasm-ci-test",
"version": "0.3.3",
"version": "0.3.4",
"private": true,
"scripts": {
"build": "webpack --config webpack.config.js",
2 changes: 1 addition & 1 deletion mithril-client-wasm/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@mithril-dev/mithril-client-wasm",
"version": "0.7.5",
"version": "0.7.6",
"description": "Mithril client WASM",
"license": "Apache-2.0",
"collaborators": [
112 changes: 91 additions & 21 deletions mithril-client-wasm/src/client_wasm.rs
Original file line number Diff line number Diff line change
@@ -15,15 +15,6 @@ use mithril_client::{
use crate::certificate_verification_cache::LocalStorageCertificateVerifierCache;
use crate::WasmResult;

macro_rules! allow_unstable_dead_code {
($($item:item)*) => {
$(
#[allow(dead_code)]
$item
)*
}
}

#[wasm_bindgen]
struct JSBroadcastChannelFeedbackReceiver {
channel: String,
@@ -427,17 +418,52 @@ impl MithrilClient {
}
}

allow_unstable_dead_code! {
// Unstable functions are only available when the unstable flag is set
// Unstable functions are only available when the unstable flag is set
#[wasm_bindgen]
impl MithrilClient {
fn guard_unstable(&self) -> Result<(), wasm_bindgen::JsValue> {
if !self.unstable {
return Err(JsValue::from_str("Unstable functions are not enabled. Set the 'unstable' client option field to 'true' to enable them."));
}

Ok(())
}

/// Call the client to get a cardano database snapshot from a hash
///
/// Warning: this function is unstable and may be modified in the future
#[wasm_bindgen]
impl MithrilClient {
fn guard_unstable(&self) -> Result<(), wasm_bindgen::JsValue> {
if !self.unstable {
return Err(JsValue::from_str("Unstable functions are not enabled. Set the 'unstable' client option field to 'true' to enable them."));
}
pub async fn get_cardano_database_v2(&self, hash: &str) -> WasmResult {
self.guard_unstable()?;

Ok(())
}
let result = self
.client
.cardano_database()
.get(hash)
.await
.map_err(|err| format!("{err:?}"))?
.ok_or(JsValue::from_str(&format!(
"No cardano database snapshot found for hash: '{hash}'"
)))?;

Ok(serde_wasm_bindgen::to_value(&result)?)
}

/// Call the client for the list of available cardano database snapshots
///
/// Warning: this function is unstable and may be modified in the future
#[wasm_bindgen]
pub async fn list_cardano_database_v2(&self) -> WasmResult {
self.guard_unstable()?;

let result = self
.client
.cardano_database()
.list()
.await
.map_err(|err| format!("{err:?}"))?;

Ok(serde_wasm_bindgen::to_value(&result)?)
}
}

@@ -447,9 +473,10 @@ mod tests {
use wasm_bindgen_test::*;

use mithril_client::{
common::ProtocolMessage, CardanoStakeDistribution, CardanoStakeDistributionListItem,
CardanoTransactionSnapshot, MithrilCertificateListItem, MithrilStakeDistribution,
MithrilStakeDistributionListItem, Snapshot, SnapshotListItem,
common::ProtocolMessage, CardanoDatabaseSnapshot, CardanoDatabaseSnapshotListItem,
CardanoStakeDistribution, CardanoStakeDistributionListItem, CardanoTransactionSnapshot,
MithrilCertificateListItem, MithrilStakeDistribution, MithrilStakeDistributionListItem,
Snapshot, SnapshotListItem,
};

use crate::test_data;
@@ -477,6 +504,11 @@ mod tests {
get_mithril_client(options)
}

fn get_mithril_client_unstable() -> MithrilClient {
let options = ClientOptions::new(None).with_unstable_features(true);
get_mithril_client(options)
}

#[cfg(not(feature = "test-node"))]
wasm_bindgen_test_configure!(run_in_browser);

@@ -847,4 +879,42 @@ mod tests {
serde_wasm_bindgen::from_value::<ProtocolMessage>(message_js_value)
.expect("conversion should not fail");
}

#[wasm_bindgen_test]
async fn list_cardano_database_v2_should_return_value_convertible_in_rust_type() {
let cdb_list_js_value = get_mithril_client_unstable()
.list_cardano_database_v2()
.await
.expect("list_cardano_database_v2 should not fail");
let cdb_list = serde_wasm_bindgen::from_value::<Vec<CardanoDatabaseSnapshotListItem>>(
cdb_list_js_value,
)
.expect("conversion should not fail");

assert_eq!(
cdb_list.len(),
// Aggregator return up to 20 items for a list route
test_data::cdb_hashes().len().min(20)
);
}

#[wasm_bindgen_test]
async fn get_cardano_database_v2_should_return_value_convertible_in_rust_type() {
let cdb_js_value = get_mithril_client_unstable()
.get_cardano_database_v2(test_data::cdb_hashes()[0])
.await
.expect("get_cardano_database_v2 should not fail");
let csd = serde_wasm_bindgen::from_value::<CardanoDatabaseSnapshot>(cdb_js_value)
.expect("conversion should not fail");

assert_eq!(csd.hash, test_data::cdb_hashes()[0]);
}

#[wasm_bindgen_test]
async fn get_cardano_database_v2_should_fail_with_unknown_hash() {
get_mithril_client_unstable()
.get_cardano_database_v2("whatever")
.await
.expect_err("get_cardano_database_v2 should fail");
}
}
2 changes: 1 addition & 1 deletion mithril-explorer/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion mithril-test-lab/mithril-aggregator-fake/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mithril-aggregator-fake"
version = "0.3.17"
version = "0.3.18"
description = "Mithril Fake Aggregator for client testing"
authors = { workspace = true }
documentation = { workspace = true }
Loading