Skip to content

Commit 8ab5440

Browse files
committed
Check all artifact types are produced in end to end test
1 parent 5c13964 commit 8ab5440

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

mithril-test-lab/mithril-end-to-end/src/end_to_end_spec.rs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ use crate::{attempt, Aggregator, Client, ClientCommand, Devnet, MithrilInfrastru
33
use mithril_common::chain_observer::{CardanoCliChainObserver, ChainObserver};
44
use mithril_common::digesters::ImmutableFile;
55
use mithril_common::entities::{Certificate, Epoch, EpochSettings, ProtocolParameters, Snapshot};
6+
use mithril_common::messages::{
7+
MithrilStakeDistributionListMessage, MithrilStakeDistributionMessage,
8+
};
69
use reqwest::StatusCode;
710
use slog_scope::{info, warn};
811
use std::error::Error;
@@ -70,6 +73,22 @@ impl Spec {
7073
)
7174
.await?;
7275

76+
// Verify that mithril stake distribution artifacts are produced and signed correctly
77+
let hash = assert_node_producing_mithril_stake_distribution(&aggregator_endpoint).await?;
78+
let certificate_hash = assert_signer_is_signing_mithril_stake_distribution(
79+
&aggregator_endpoint,
80+
&hash,
81+
target_epoch - 2,
82+
)
83+
.await?;
84+
assert_is_creating_certificate_with_enough_signers(
85+
&aggregator_endpoint,
86+
&certificate_hash,
87+
self.infrastructure.signers().len(),
88+
)
89+
.await?;
90+
91+
// Verify that snapshot artifacts are produced and signed correctly
7392
let digest = assert_node_producing_snapshot(&aggregator_endpoint).await?;
7493
let certificate_hash =
7594
assert_signer_is_signing_snapshot(&aggregator_endpoint, &digest, target_epoch - 2)
@@ -240,6 +259,79 @@ async fn update_protocol_parameters(aggregator: &mut Aggregator) -> Result<(), S
240259
Ok(())
241260
}
242261

262+
async fn assert_node_producing_mithril_stake_distribution(
263+
aggregator_endpoint: &str,
264+
) -> Result<String, String> {
265+
let url = format!("{aggregator_endpoint}/artifact/mithril-stake-distributions");
266+
info!("Waiting for the aggregator to produce a mithril stake distribution");
267+
268+
// todo: reduce the number of attempts if we can reduce the delay between two immutables
269+
match attempt!(45, Duration::from_millis(2000), {
270+
match reqwest::get(url.clone()).await {
271+
Ok(response) => match response.status() {
272+
StatusCode::OK => match response.json::<MithrilStakeDistributionListMessage>().await.as_deref() {
273+
Ok([stake_distribution, ..]) => Ok(Some(stake_distribution.hash.clone())),
274+
Ok(&[]) => Ok(None),
275+
Err(err) => Err(format!("Invalid mithril stake distribution body : {err}",)),
276+
},
277+
s => Err(format!("Unexpected status code from Aggregator: {s}")),
278+
},
279+
Err(err) => Err(format!("Request to `{url}` failed: {err}")),
280+
}
281+
}) {
282+
AttemptResult::Ok(hash) => {
283+
info!("Aggregator produced a mithril stake distribution"; "hash" => &hash);
284+
Ok(hash)
285+
}
286+
AttemptResult::Err(error) => Err(error),
287+
AttemptResult::Timeout() => Err(format!(
288+
"Timeout exhausted assert_node_producing_mithril_stake_distribution, no response from `{url}`"
289+
)),
290+
}
291+
}
292+
293+
async fn assert_signer_is_signing_mithril_stake_distribution(
294+
aggregator_endpoint: &str,
295+
hash: &str,
296+
expected_epoch_min: Epoch,
297+
) -> Result<String, String> {
298+
let url = format!("{aggregator_endpoint}/artifact/mithril-stake-distribution/{hash}");
299+
info!(
300+
"Asserting the aggregator is signing the mithril stake distribution message `{}` with an expected min epoch of `{}`",
301+
hash,
302+
expected_epoch_min
303+
);
304+
305+
match attempt!(10, Duration::from_millis(1000), {
306+
match reqwest::get(url.clone()).await {
307+
Ok(response) => match response.status() {
308+
StatusCode::OK => match response.json::<MithrilStakeDistributionMessage>().await {
309+
Ok(stake_distribution) => match stake_distribution.epoch {
310+
epoch if epoch >= expected_epoch_min => Ok(Some(stake_distribution)),
311+
epoch => Err(format!(
312+
"Minimum expected mithril stake distribution epoch not reached : {epoch} < {expected_epoch_min}"
313+
)),
314+
},
315+
Err(err) => Err(format!("Invalid mithril stake distribution body : {err}",)),
316+
},
317+
StatusCode::NOT_FOUND => Ok(None),
318+
s => Err(format!("Unexpected status code from Aggregator: {s}")),
319+
},
320+
Err(err) => Err(format!("Request to `{url}` failed: {err}")),
321+
}
322+
}) {
323+
AttemptResult::Ok(stake_distribution) => {
324+
// todo: assert that the mithril stake distribution is really signed
325+
info!("Signer signed a mithril stake distribution"; "certificate_hash" => &stake_distribution.certificate_hash);
326+
Ok(stake_distribution.certificate_hash)
327+
}
328+
AttemptResult::Err(error) => Err(error),
329+
AttemptResult::Timeout() => Err(format!(
330+
"Timeout exhausted assert_signer_is_signing_mithril_stake_distribution, no response from `{url}`"
331+
)),
332+
}
333+
}
334+
243335
async fn assert_node_producing_snapshot(aggregator_endpoint: &str) -> Result<String, String> {
244336
let url = format!("{aggregator_endpoint}/artifact/snapshots");
245337
info!("Waiting for the aggregator to produce a snapshot");

0 commit comments

Comments
 (0)