Skip to content

Commit 7d4445c

Browse files
committed
feat(client-wasm): add list/get per epoch/latest/latest(-offset) for cdb and csd
1 parent e9a87bf commit 7d4445c

File tree

3 files changed

+245
-20
lines changed

3 files changed

+245
-20
lines changed

mithril-client-wasm/ci-test/index.js

Lines changed: 71 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,35 @@ if (aggregator_capabilities.includes("CardanoStakeDistribution")) {
201201
await run_test("get_cardano_stake_distribution_by_epoch", test_number, async () => {
202202
let epoch = BigInt(cardano_stake_distributions[0].epoch);
203203

204-
cardano_stake_distribution = await client.get_cardano_stake_distribution_by_epoch(epoch);
205-
console.log("cardano_stake_distribution by epoch", cardano_stake_distribution);
204+
let cardano_stake_distribution_by_epoch =
205+
await client.get_cardano_stake_distribution_by_epoch(epoch);
206+
console.log("cardano_stake_distribution by epoch", cardano_stake_distribution_by_epoch);
206207
});
207208

209+
test_number++;
210+
await run_test("get_cardano_stake_distribution_for_latest_epoch", test_number, async () => {
211+
let cardano_stake_distribution_for_latest_epoch =
212+
await client.get_cardano_stake_distribution_for_latest_epoch();
213+
console.log(
214+
"cardano_stake_distribution for latest epoch",
215+
cardano_stake_distribution_for_latest_epoch,
216+
);
217+
});
218+
219+
test_number++;
220+
await run_test(
221+
"get_cardano_stake_distribution_for_latest_epoch_with_offset",
222+
test_number,
223+
async () => {
224+
let cardano_stake_distribution_for_latest_epoch_with_offset =
225+
await client.get_cardano_stake_distribution_for_latest_epoch({ offset: 2 });
226+
console.log(
227+
"cardano_stake_distribution for latest epoch with offset",
228+
cardano_stake_distribution_for_latest_epoch_with_offset,
229+
);
230+
},
231+
);
232+
208233
let certificate;
209234
test_number++;
210235
await run_test("get_mithril_certificate", test_number, async () => {
@@ -240,24 +265,52 @@ if (aggregator_capabilities.includes("CardanoStakeDistribution")) {
240265
valid_cardano_stake_distribution_message,
241266
);
242267
});
268+
}
243269

244-
if (aggregator_capabilities.includes("CardanoDatabase")) {
245-
let cardano_database_snapshots;
246-
test_number++;
247-
await run_test("list_cardano_database_v2", test_number, async () => {
248-
cardano_database_snapshots = await client.list_cardano_database_v2();
249-
console.log("cardano_database_snapshots", cardano_database_snapshots);
250-
});
270+
if (aggregator_capabilities.includes("CardanoDatabase")) {
271+
let cardano_database_snapshots;
272+
test_number++;
273+
await run_test("list_cardano_database_v2", test_number, async () => {
274+
cardano_database_snapshots = await client.list_cardano_database_v2();
275+
console.log("cardano_database_snapshots", cardano_database_snapshots);
276+
});
251277

252-
let cardano_database_snapshot;
253-
test_number++;
254-
await run_test("get_cardano_database_v2", test_number, async () => {
255-
cardano_database_snapshot = await client.get_cardano_database_v2(
256-
cardano_database_snapshots[0].hash,
257-
);
258-
console.log("cardano_database_snapshot", cardano_database_snapshot);
259-
});
260-
}
278+
test_number++;
279+
await run_test("list_cardano_database_v2_per_epoch", test_number, async () => {
280+
let epoch = BigInt(cardano_database_snapshots[0].beacon.epoch);
281+
const cardano_database_snapshots_per_epoch =
282+
await client.list_cardano_database_v2_per_epoch(epoch);
283+
console.log("cardano_database_snapshots for epoch", cardano_database_snapshots_per_epoch);
284+
});
285+
286+
test_number++;
287+
await run_test("list_cardano_database_v2_for_latest_epoch", test_number, async () => {
288+
const cardano_database_snapshots_for_latest_epoch =
289+
await client.list_cardano_database_v2_for_latest_epoch();
290+
console.log(
291+
"cardano_database_snapshots for latest epoch",
292+
cardano_database_snapshots_for_latest_epoch,
293+
);
294+
});
295+
296+
test_number++;
297+
await run_test("list_cardano_database_v2_for_latest_epoch_with_offset", test_number, async () => {
298+
const cardano_database_snapshots_for_latest_epoch_with_offset =
299+
await client.list_cardano_database_v2_for_latest_epoch({ offset: 3 });
300+
console.log(
301+
"cardano_database_snapshots for latest epoch with offset",
302+
cardano_database_snapshots_for_latest_epoch_with_offset,
303+
);
304+
});
305+
306+
let cardano_database_snapshot;
307+
test_number++;
308+
await run_test("get_cardano_database_v2", test_number, async () => {
309+
cardano_database_snapshot = await client.get_cardano_database_v2(
310+
cardano_database_snapshots[0].hash,
311+
);
312+
console.log("cardano_database_snapshot", cardano_database_snapshot);
313+
});
261314
}
262315

263316
add_finished_div();

mithril-client-wasm/src/certificate_verification_cache.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ impl CachedCertificate {
4040
impl LocalStorageCertificateVerifierCache {
4141
/// `LocalStorageCertificateVerifierCache` factory
4242
pub fn new(cache_key_prefix_seed: &str, expiration_delay: TimeDelta) -> Self {
43-
const CACHE_KEY_BASE_PREFIX: &'static str = "certificate_cache";
43+
const CACHE_KEY_BASE_PREFIX: &str = "certificate_cache";
4444

4545
LocalStorageCertificateVerifierCache {
4646
cache_key_prefix: format!("{CACHE_KEY_BASE_PREFIX}_{cache_key_prefix_seed}_"),

mithril-client-wasm/src/client_wasm.rs

Lines changed: 173 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use async_trait::async_trait;
22
use chrono::TimeDelta;
3-
use serde::Serialize;
3+
use serde::{Deserialize, Serialize};
44
use std::sync::Arc;
55
use wasm_bindgen::prelude::*;
66

@@ -41,6 +41,24 @@ impl FeedbackReceiver for JSBroadcastChannelFeedbackReceiver {
4141
}
4242
}
4343

44+
/// Parameters that can be passed as a [JsValue] to methods that fetch data based on the latest epoch
45+
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
46+
struct LatestEpochOptions {
47+
pub offset: Option<u64>,
48+
}
49+
50+
impl LatestEpochOptions {
51+
fn parse_from_js_value(js_value: JsValue) -> Result<Self, JsValue> {
52+
let options = if js_value.is_object() {
53+
serde_wasm_bindgen::from_value(js_value)
54+
.map_err(|err| format!("Failed to parse options: {err:?}"))?
55+
} else {
56+
LatestEpochOptions::default()
57+
};
58+
Ok(options)
59+
}
60+
}
61+
4462
#[derive(Serialize)]
4563
struct MithrilEventWasm {
4664
#[serde(rename = "type")]
@@ -378,6 +396,7 @@ impl MithrilClient {
378396
}
379397

380398
/// Call the client to get a cardano stake distribution from an epoch
399+
///
381400
/// The epoch represents the epoch at the end of which the Cardano stake distribution is computed by the Cardano node
382401
#[wasm_bindgen]
383402
pub async fn get_cardano_stake_distribution_by_epoch(&self, epoch: u64) -> WasmResult {
@@ -394,6 +413,28 @@ impl MithrilClient {
394413
Ok(serde_wasm_bindgen::to_value(&result)?)
395414
}
396415

416+
/// Call the client to get a cardano stake distribution from an epoch
417+
#[wasm_bindgen]
418+
pub async fn get_cardano_stake_distribution_for_latest_epoch(
419+
&self,
420+
param: JsValue,
421+
) -> WasmResult {
422+
let options = LatestEpochOptions::parse_from_js_value(param)?;
423+
let client = self.client.cardano_stake_distribution();
424+
425+
let result = match options.offset {
426+
None => client.get_for_latest_epoch().await,
427+
Some(offset) => client.get_for_latest_epoch_with_offset(offset).await,
428+
}
429+
.map_err(|err| format!("{err:?}"))?
430+
.ok_or(JsValue::from_str(&format!(
431+
"No cardano stake distribution found for latest epoch{}",
432+
options.offset.map(|o| format!(" (offset: {o})")).unwrap_or_default()
433+
)))?;
434+
435+
Ok(serde_wasm_bindgen::to_value(&result)?)
436+
}
437+
397438
/// Call the client for the list of available cardano stake distributions
398439
#[wasm_bindgen]
399440
pub async fn list_cardano_stake_distributions(&self) -> WasmResult {
@@ -489,6 +530,43 @@ impl MithrilClient {
489530
Ok(serde_wasm_bindgen::to_value(&result)?)
490531
}
491532

533+
/// Call the client for the list of available cardano database snapshots for a given epoch
534+
///
535+
/// Warning: this function is unstable and may be modified in the future
536+
#[wasm_bindgen]
537+
pub async fn list_cardano_database_v2_per_epoch(&self, epoch: u64) -> WasmResult {
538+
self.guard_unstable()?;
539+
540+
let result = self
541+
.client
542+
.cardano_database_v2()
543+
.list_by_epoch(Epoch(epoch))
544+
.await
545+
.map_err(|err| format!("{err:?}"))?;
546+
547+
Ok(serde_wasm_bindgen::to_value(&result)?)
548+
}
549+
550+
/// Call the client for the list of available cardano database snapshots for the latest epoch
551+
///
552+
/// An optionnal offset can be provided
553+
///
554+
/// Warning: this function is unstable and may be modified in the future
555+
#[wasm_bindgen]
556+
pub async fn list_cardano_database_v2_for_latest_epoch(&self, param: JsValue) -> WasmResult {
557+
self.guard_unstable()?;
558+
let options = LatestEpochOptions::parse_from_js_value(param)?;
559+
let client = self.client.cardano_database_v2();
560+
561+
let result = match options.offset {
562+
None => client.list_for_latest_epoch().await,
563+
Some(offset) => client.list_for_latest_epoch_with_offset(offset).await,
564+
}
565+
.map_err(|err| format!("{err:?}"))?;
566+
567+
Ok(serde_wasm_bindgen::to_value(&result)?)
568+
}
569+
492570
/// `unstable` Reset the certificate verifier cache if enabled
493571
#[wasm_bindgen]
494572
pub async fn reset_certificate_verifier_cache(&self) -> Result<(), JsValue> {
@@ -915,6 +993,42 @@ mod tests {
915993
.expect_err("get_cardano_stake_distribution_by_epoch should fail");
916994
}
917995

996+
#[wasm_bindgen_test]
997+
async fn get_cardano_stake_distribution_for_latest_epoch_should_return_value_convertible_in_rust_type()
998+
{
999+
let latest_epoch = *test_data::cardano_stake_distribution_epochs().last().unwrap();
1000+
let csd_js_value = get_mithril_client_stable()
1001+
.get_cardano_stake_distribution_for_latest_epoch(JsValue::undefined())
1002+
.await
1003+
.expect("get_cardano_stake_distribution_by_epoch should not fail");
1004+
1005+
let csd = serde_wasm_bindgen::from_value::<CardanoStakeDistribution>(csd_js_value)
1006+
.expect("conversion should not fail");
1007+
1008+
assert_eq!(csd.epoch, latest_epoch);
1009+
}
1010+
1011+
#[wasm_bindgen_test]
1012+
async fn get_cardano_stake_distribution_for_latest_epoch_with_offset_should_return_value_convertible_in_rust_type()
1013+
{
1014+
let epoch = test_data::cardano_stake_distribution_epochs()
1015+
.into_iter()
1016+
.rev()
1017+
.nth(2)
1018+
.unwrap();
1019+
let csd_js_value = get_mithril_client_stable()
1020+
.get_cardano_stake_distribution_for_latest_epoch(
1021+
serde_wasm_bindgen::to_value(&LatestEpochOptions { offset: Some(2) }).unwrap(),
1022+
)
1023+
.await
1024+
.expect("get_cardano_stake_distribution_by_epoch should not fail");
1025+
1026+
let csd = serde_wasm_bindgen::from_value::<CardanoStakeDistribution>(csd_js_value)
1027+
.expect("conversion should not fail");
1028+
1029+
assert_eq!(csd.epoch, epoch);
1030+
}
1031+
9181032
#[wasm_bindgen_test]
9191033
async fn compute_cardano_stake_distribution_message_should_return_value_convertible_in_rust_type()
9201034
{
@@ -954,6 +1068,64 @@ mod tests {
9541068
);
9551069
}
9561070

1071+
#[wasm_bindgen_test]
1072+
async fn list_cardano_database_v2_per_epoch_should_return_value_convertible_in_rust_type() {
1073+
let cdb_list_js_value = get_mithril_client_unstable()
1074+
.list_cardano_database_v2_per_epoch(test_data::cardano_database_snapshot_epochs()[3])
1075+
.await
1076+
.expect("list_cardano_database_v2 should not fail");
1077+
let cdb_list = serde_wasm_bindgen::from_value::<Vec<CardanoDatabaseSnapshotListItem>>(
1078+
cdb_list_js_value,
1079+
)
1080+
.expect("conversion should not fail");
1081+
1082+
assert!(!cdb_list.is_empty());
1083+
assert_eq!(
1084+
cdb_list[0].beacon.epoch,
1085+
test_data::cardano_database_snapshot_epochs()[3]
1086+
);
1087+
}
1088+
1089+
#[wasm_bindgen_test]
1090+
async fn list_cardano_database_v2_for_latest_epoch_should_return_value_convertible_in_rust_type()
1091+
{
1092+
let latest_epoch = *test_data::cardano_database_snapshot_epochs().last().unwrap();
1093+
let cdb_list_js_value = get_mithril_client_unstable()
1094+
.list_cardano_database_v2_for_latest_epoch(JsValue::undefined())
1095+
.await
1096+
.expect("list_cardano_database_v2 should not fail");
1097+
let cdb_list = serde_wasm_bindgen::from_value::<Vec<CardanoDatabaseSnapshotListItem>>(
1098+
cdb_list_js_value,
1099+
)
1100+
.expect("conversion should not fail");
1101+
1102+
assert!(!cdb_list.is_empty());
1103+
assert_eq!(cdb_list[0].beacon.epoch, latest_epoch);
1104+
}
1105+
1106+
#[wasm_bindgen_test]
1107+
async fn list_cardano_database_v2_for_latest_epoch_with_offset_should_return_value_convertible_in_rust_type()
1108+
{
1109+
let epoch = test_data::cardano_database_snapshot_epochs()
1110+
.into_iter()
1111+
.rev()
1112+
.nth(3)
1113+
.unwrap();
1114+
let cdb_list_js_value = get_mithril_client_unstable()
1115+
.list_cardano_database_v2_for_latest_epoch(
1116+
serde_wasm_bindgen::to_value(&LatestEpochOptions { offset: Some(3) }).unwrap(),
1117+
)
1118+
.await
1119+
.expect("list_cardano_database_v2 should not fail");
1120+
let cdb_list = serde_wasm_bindgen::from_value::<Vec<CardanoDatabaseSnapshotListItem>>(
1121+
cdb_list_js_value,
1122+
)
1123+
.expect("conversion should not fail");
1124+
1125+
assert!(!cdb_list.is_empty());
1126+
assert_eq!(cdb_list[0].beacon.epoch, epoch);
1127+
}
1128+
9571129
#[wasm_bindgen_test]
9581130
async fn get_cardano_database_v2_should_return_value_convertible_in_rust_type() {
9591131
let cdb_js_value = get_mithril_client_unstable()

0 commit comments

Comments
 (0)