Skip to content

Commit 9e5ab51

Browse files
authored
Merge pull request #887 from input-output-hk/jpraynaud/870-artifact-builder-mithril-stake-distribution
Mithril Stake Distribution Artifact builder in aggregator
2 parents 538e2e2 + d159daf commit 9e5ab51

File tree

9 files changed

+146
-67
lines changed

9 files changed

+146
-67
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mithril-aggregator/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mithril-aggregator"
3-
version = "0.3.7"
3+
version = "0.3.8"
44
description = "A Mithril Aggregator server"
55
authors = { workspace = true }
66
edition = { workspace = true }
Lines changed: 39 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,31 @@
11
use std::sync::Arc;
22

33
use mithril_common::{
4-
entities::{Certificate, SignedEntityType},
5-
signable_builder::{Artifact, DummyBeacon},
4+
entities::{Certificate, Epoch, SignedEntityType},
5+
signable_builder::Artifact,
66
StdResult,
77
};
88

9-
use crate::artifact_builder::{ArtifactBuilder, DummyArtifactBuilder};
9+
use crate::artifact_builder::ArtifactBuilder;
10+
11+
use super::MithrilStakeDistribution;
1012

1113
/// ArtifactBuilder Service
12-
// TODO: temporary implementation
1314
pub struct ArtifactBuilderService {
14-
dummy_artifact_builder: DummyArtifactBuilder,
15+
mithril_stake_distribution_artifact_builder:
16+
Arc<dyn ArtifactBuilder<Epoch, MithrilStakeDistribution>>,
1517
}
1618

1719
impl ArtifactBuilderService {
1820
/// ArtifactBuilderService factory
1921
#[allow(dead_code)]
20-
pub fn new(dummy_artifact_builder: DummyArtifactBuilder) -> Self {
22+
pub fn new(
23+
mithril_stake_distribution_artifact_builder: Arc<
24+
dyn ArtifactBuilder<Epoch, MithrilStakeDistribution>,
25+
>,
26+
) -> Self {
2127
Self {
22-
dummy_artifact_builder,
28+
mithril_stake_distribution_artifact_builder,
2329
}
2430
}
2531
}
@@ -33,20 +39,11 @@ impl ArtifactBuilderService {
3339
) -> StdResult<Arc<impl Artifact>> {
3440
let artifact = match signed_entity_type {
3541
SignedEntityType::MithrilStakeDistribution(e) => Arc::new(
36-
self.dummy_artifact_builder
37-
.compute_artifact(DummyBeacon { epoch: e }, certificate)
38-
.await?,
39-
),
40-
SignedEntityType::CardanoStakeDistribution(e) => Arc::new(
41-
self.dummy_artifact_builder
42-
.compute_artifact(DummyBeacon { epoch: e }, certificate)
43-
.await?,
44-
),
45-
SignedEntityType::CardanoImmutableFilesFull(b) => Arc::new(
46-
self.dummy_artifact_builder
47-
.compute_artifact(DummyBeacon { epoch: b.epoch }, certificate)
42+
self.mithril_stake_distribution_artifact_builder
43+
.compute_artifact(e, certificate)
4844
.await?,
4945
),
46+
_ => todo!(),
5047
};
5148

5249
Ok(artifact)
@@ -55,37 +52,36 @@ impl ArtifactBuilderService {
5552

5653
#[cfg(test)]
5754
mod tests {
58-
use mithril_common::entities::{Beacon, Epoch};
55+
use mithril_common::{entities::Epoch, test_utils::fake_data};
5956

6057
use super::*;
6158

62-
// TODO: temporary test
63-
#[tokio::test]
64-
async fn test_artifact_builder_service() {
65-
let dummy_artifact_builder = DummyArtifactBuilder::default();
66-
let artifact_builder_service = ArtifactBuilderService::new(dummy_artifact_builder);
67-
let certificate = Certificate::default();
59+
use crate::artifact_builder::MockArtifactBuilder;
6860

69-
let signed_entity_type_1 = SignedEntityType::MithrilStakeDistribution(Epoch(1));
70-
let artifact_1 = artifact_builder_service
71-
.compute_artifact(signed_entity_type_1, &certificate)
72-
.await
73-
.unwrap();
61+
#[tokio::test]
62+
async fn test_artifact_builder_service_mithril_stake_distribution() {
63+
let signers_with_stake = fake_data::signers_with_stakes(5);
64+
let mithril_stake_distribution_expected = MithrilStakeDistribution::new(signers_with_stake);
65+
let mithril_stake_distribution_clone = mithril_stake_distribution_expected.clone();
66+
let mut mock_mithril_stake_distribution_artifact_builder =
67+
MockArtifactBuilder::<Epoch, MithrilStakeDistribution>::new();
68+
mock_mithril_stake_distribution_artifact_builder
69+
.expect_compute_artifact()
70+
.once()
71+
.return_once(move |_, _| Ok(mithril_stake_distribution_clone));
7472

75-
let signed_entity_type_2 = SignedEntityType::CardanoStakeDistribution(Epoch(0));
76-
let artifact_2 = artifact_builder_service
77-
.compute_artifact(signed_entity_type_2, &certificate)
78-
.await
79-
.unwrap();
73+
let artifact_builder_service =
74+
ArtifactBuilderService::new(Arc::new(mock_mithril_stake_distribution_artifact_builder));
75+
let certificate = Certificate::default();
8076

81-
let signed_entity_type_3 = SignedEntityType::CardanoImmutableFilesFull(Beacon::default());
82-
let artifact_3 = artifact_builder_service
83-
.compute_artifact(signed_entity_type_3, &certificate)
77+
let signed_entity_type = SignedEntityType::MithrilStakeDistribution(Epoch(1));
78+
let artifact = artifact_builder_service
79+
.compute_artifact(signed_entity_type, &certificate)
8480
.await
8581
.unwrap();
86-
87-
assert_ne!(artifact_1, artifact_2);
88-
assert_ne!(artifact_1, artifact_3);
89-
assert_eq!(artifact_2, artifact_3);
82+
assert_eq!(
83+
serde_json::to_string(&mithril_stake_distribution_expected).unwrap(),
84+
serde_json::to_string(&artifact).unwrap()
85+
);
9086
}
9187
}

mithril-aggregator/src/artifact_builder/dummy_artifact.rs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::marker::PhantomData;
2-
31
use async_trait::async_trait;
42
use mithril_common::{
53
entities::Certificate,
@@ -12,24 +10,19 @@ use crate::artifact_builder::ArtifactBuilder;
1210

1311
/// Dummy artifact
1412
#[derive(Serialize, Deserialize, PartialEq, Debug)]
15-
pub struct DummyArtifact<'a> {
13+
pub struct DummyArtifact {
1614
message: String,
1715
beacon: DummyBeacon,
18-
phantom: PhantomData<&'a DummyBeacon>,
1916
}
2017

21-
impl<'a> DummyArtifact<'a> {
18+
impl DummyArtifact {
2219
/// Dummy artifact factory
2320
pub fn new(message: String, beacon: DummyBeacon) -> Self {
24-
Self {
25-
message,
26-
beacon,
27-
phantom: PhantomData,
28-
}
21+
Self { message, beacon }
2922
}
3023
}
3124

32-
impl<'a> Artifact<'a> for DummyArtifact<'a> {}
25+
impl Artifact for DummyArtifact {}
3326

3427
/// A [DummyArtifact] builder
3528
pub struct DummyArtifactBuilder {}
@@ -48,9 +41,9 @@ impl Default for DummyArtifactBuilder {
4841
}
4942

5043
#[async_trait]
51-
impl<'a> ArtifactBuilder<'a, DummyBeacon, DummyArtifact<'a>> for DummyArtifactBuilder {
44+
impl ArtifactBuilder<DummyBeacon, DummyArtifact> for DummyArtifactBuilder {
5245
async fn compute_artifact(
53-
&'a self,
46+
&self,
5447
beacon: DummyBeacon,
5548
certificate: &Certificate,
5649
) -> StdResult<DummyArtifact> {

mithril-aggregator/src/artifact_builder/interface.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,17 @@ use mithril_common::{
55
StdResult,
66
};
77

8+
#[cfg(test)]
9+
use mockall::automock;
10+
811
/// ArtifactBuilder is trait for building an artifact
12+
#[cfg_attr(test, automock)]
913
#[async_trait]
10-
pub trait ArtifactBuilder<'a, U, W>
14+
pub trait ArtifactBuilder<U, W>: Send + Sync
1115
where
1216
U: Beacon,
13-
W: Artifact<'a>,
17+
W: Artifact,
1418
{
1519
/// Compute an artifact
16-
async fn compute_artifact(&'a self, beacon: U, certificate: &Certificate) -> StdResult<W>;
20+
async fn compute_artifact(&self, beacon: U, certificate: &Certificate) -> StdResult<W>;
1721
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
use async_trait::async_trait;
2+
use serde::{Deserialize, Serialize};
3+
use std::sync::Arc;
4+
use tokio::sync::RwLock;
5+
6+
use super::ArtifactBuilder;
7+
use crate::MultiSigner;
8+
use mithril_common::{
9+
entities::{Certificate, Epoch, SignerWithStake},
10+
signable_builder::Artifact,
11+
StdResult,
12+
};
13+
14+
/// Mithril Stake Distribution
15+
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
16+
pub struct MithrilStakeDistribution {
17+
signers_with_stake: Vec<SignerWithStake>,
18+
}
19+
20+
impl MithrilStakeDistribution {
21+
/// MithrilStakeDistribution artifact factory
22+
pub fn new(signers_with_stake: Vec<SignerWithStake>) -> Self {
23+
Self { signers_with_stake }
24+
}
25+
}
26+
27+
impl Artifact for MithrilStakeDistribution {}
28+
29+
/// A [MithrilStakeDistributionArtifact] builder
30+
pub struct MithrilStakeDistributionArtifactBuilder {
31+
multi_signer: Arc<RwLock<dyn MultiSigner>>,
32+
}
33+
34+
impl MithrilStakeDistributionArtifactBuilder {
35+
/// MithrilStakeDistribution artifact builder factory
36+
pub fn new(multi_signer: Arc<RwLock<dyn MultiSigner>>) -> Self {
37+
Self { multi_signer }
38+
}
39+
}
40+
41+
#[async_trait]
42+
impl ArtifactBuilder<Epoch, MithrilStakeDistribution> for MithrilStakeDistributionArtifactBuilder {
43+
async fn compute_artifact(
44+
&self,
45+
_beacon: Epoch,
46+
_certificate: &Certificate,
47+
) -> StdResult<MithrilStakeDistribution> {
48+
let multi_signer = self.multi_signer.read().await;
49+
Ok(MithrilStakeDistribution::new(
50+
multi_signer.get_signers_with_stake().await?,
51+
))
52+
}
53+
}
54+
55+
#[cfg(test)]
56+
mod tests {
57+
use mithril_common::test_utils::fake_data;
58+
59+
use super::*;
60+
61+
use crate::multi_signer::MockMultiSigner;
62+
63+
#[tokio::test]
64+
async fn test_compute_artifact() {
65+
let signers_with_stake = fake_data::signers_with_stakes(5);
66+
let signers_with_stake_clone = signers_with_stake.clone();
67+
let certificate = fake_data::certificate("cert-123".to_string());
68+
let mut mock_multi_signer = MockMultiSigner::new();
69+
mock_multi_signer
70+
.expect_get_signers_with_stake()
71+
.return_once(move || Ok(signers_with_stake_clone));
72+
let mithril_stake_distribution_artifact_builder =
73+
MithrilStakeDistributionArtifactBuilder::new(Arc::new(RwLock::new(mock_multi_signer)));
74+
let artifact = mithril_stake_distribution_artifact_builder
75+
.compute_artifact(Epoch(1), &certificate)
76+
.await
77+
.unwrap();
78+
let artifact_expected = MithrilStakeDistribution::new(signers_with_stake);
79+
assert_eq!(artifact_expected, artifact);
80+
}
81+
}

mithril-aggregator/src/artifact_builder/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
mod artifact_builder_service;
44
mod dummy_artifact;
55
mod interface;
6+
mod mithril_stake_distribution;
67

78
pub use artifact_builder_service::*;
89
pub use dummy_artifact::*;
910
pub use interface::*;
11+
pub use mithril_stake_distribution::*;

mithril-aggregator/src/dependency_injection/builder.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use tokio::{
3232
use warp::Filter;
3333

3434
use crate::{
35-
artifact_builder::{ArtifactBuilderService, DummyArtifactBuilder},
35+
artifact_builder::{ArtifactBuilderService, MithrilStakeDistributionArtifactBuilder},
3636
certifier_service::{CertifierService, MithrilCertifierService},
3737
configuration::{ExecutionEnvironment, LIST_SNAPSHOTS_MAX_ITEMS},
3838
database::provider::{
@@ -897,9 +897,12 @@ impl DependenciesBuilder {
897897
}
898898

899899
async fn build_artifact_builder_service(&mut self) -> Result<Arc<ArtifactBuilderService>> {
900-
let dummy_artifact_builder = DummyArtifactBuilder::new();
901-
let artifact_builder_service =
902-
Arc::new(ArtifactBuilderService::new(dummy_artifact_builder));
900+
let multi_signer = self.get_multi_signer().await?;
901+
let mithril_stake_distribution_artifact_builder =
902+
Arc::new(MithrilStakeDistributionArtifactBuilder::new(multi_signer));
903+
let artifact_builder_service = Arc::new(ArtifactBuilderService::new(
904+
mithril_stake_distribution_artifact_builder,
905+
));
903906

904907
Ok(artifact_builder_service)
905908
}

mithril-common/src/signable_builder/interface.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use async_trait::async_trait;
2-
use serde::{Deserialize, Serialize};
2+
use serde::{de::DeserializeOwned, Serialize};
33
use std::fmt::Debug;
44

55
use crate::{entities::ProtocolMessage, StdResult};
@@ -14,7 +14,7 @@ pub trait Signable: Send + Sync {
1414
}
1515

1616
/// Artifact is a trait for types that represent signed artifacts
17-
pub trait Artifact<'a>: Serialize + Deserialize<'a> + PartialEq + Debug {}
17+
pub trait Artifact: Serialize + DeserializeOwned + PartialEq + Debug + Send + Sync {}
1818

1919
/// SignableBuilder is trait for building a signable for a beacon
2020
#[async_trait]

0 commit comments

Comments
 (0)