Skip to content

Commit

Permalink
Merge pull request #887 from input-output-hk/jpraynaud/870-artifact-b…
Browse files Browse the repository at this point in the history
…uilder-mithril-stake-distribution

Mithril Stake Distribution Artifact builder in aggregator
  • Loading branch information
jpraynaud authored May 2, 2023
2 parents 538e2e2 + d159daf commit 9e5ab51
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 67 deletions.
2 changes: 1 addition & 1 deletion 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 mithril-aggregator/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mithril-aggregator"
version = "0.3.7"
version = "0.3.8"
description = "A Mithril Aggregator server"
authors = { workspace = true }
edition = { workspace = true }
Expand Down
82 changes: 39 additions & 43 deletions mithril-aggregator/src/artifact_builder/artifact_builder_service.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
use std::sync::Arc;

use mithril_common::{
entities::{Certificate, SignedEntityType},
signable_builder::{Artifact, DummyBeacon},
entities::{Certificate, Epoch, SignedEntityType},
signable_builder::Artifact,
StdResult,
};

use crate::artifact_builder::{ArtifactBuilder, DummyArtifactBuilder};
use crate::artifact_builder::ArtifactBuilder;

use super::MithrilStakeDistribution;

/// ArtifactBuilder Service
// TODO: temporary implementation
pub struct ArtifactBuilderService {
dummy_artifact_builder: DummyArtifactBuilder,
mithril_stake_distribution_artifact_builder:
Arc<dyn ArtifactBuilder<Epoch, MithrilStakeDistribution>>,
}

impl ArtifactBuilderService {
/// ArtifactBuilderService factory
#[allow(dead_code)]
pub fn new(dummy_artifact_builder: DummyArtifactBuilder) -> Self {
pub fn new(
mithril_stake_distribution_artifact_builder: Arc<
dyn ArtifactBuilder<Epoch, MithrilStakeDistribution>,
>,
) -> Self {
Self {
dummy_artifact_builder,
mithril_stake_distribution_artifact_builder,
}
}
}
Expand All @@ -33,20 +39,11 @@ impl ArtifactBuilderService {
) -> StdResult<Arc<impl Artifact>> {
let artifact = match signed_entity_type {
SignedEntityType::MithrilStakeDistribution(e) => Arc::new(
self.dummy_artifact_builder
.compute_artifact(DummyBeacon { epoch: e }, certificate)
.await?,
),
SignedEntityType::CardanoStakeDistribution(e) => Arc::new(
self.dummy_artifact_builder
.compute_artifact(DummyBeacon { epoch: e }, certificate)
.await?,
),
SignedEntityType::CardanoImmutableFilesFull(b) => Arc::new(
self.dummy_artifact_builder
.compute_artifact(DummyBeacon { epoch: b.epoch }, certificate)
self.mithril_stake_distribution_artifact_builder
.compute_artifact(e, certificate)
.await?,
),
_ => todo!(),
};

Ok(artifact)
Expand All @@ -55,37 +52,36 @@ impl ArtifactBuilderService {

#[cfg(test)]
mod tests {
use mithril_common::entities::{Beacon, Epoch};
use mithril_common::{entities::Epoch, test_utils::fake_data};

use super::*;

// TODO: temporary test
#[tokio::test]
async fn test_artifact_builder_service() {
let dummy_artifact_builder = DummyArtifactBuilder::default();
let artifact_builder_service = ArtifactBuilderService::new(dummy_artifact_builder);
let certificate = Certificate::default();
use crate::artifact_builder::MockArtifactBuilder;

let signed_entity_type_1 = SignedEntityType::MithrilStakeDistribution(Epoch(1));
let artifact_1 = artifact_builder_service
.compute_artifact(signed_entity_type_1, &certificate)
.await
.unwrap();
#[tokio::test]
async fn test_artifact_builder_service_mithril_stake_distribution() {
let signers_with_stake = fake_data::signers_with_stakes(5);
let mithril_stake_distribution_expected = MithrilStakeDistribution::new(signers_with_stake);
let mithril_stake_distribution_clone = mithril_stake_distribution_expected.clone();
let mut mock_mithril_stake_distribution_artifact_builder =
MockArtifactBuilder::<Epoch, MithrilStakeDistribution>::new();
mock_mithril_stake_distribution_artifact_builder
.expect_compute_artifact()
.once()
.return_once(move |_, _| Ok(mithril_stake_distribution_clone));

let signed_entity_type_2 = SignedEntityType::CardanoStakeDistribution(Epoch(0));
let artifact_2 = artifact_builder_service
.compute_artifact(signed_entity_type_2, &certificate)
.await
.unwrap();
let artifact_builder_service =
ArtifactBuilderService::new(Arc::new(mock_mithril_stake_distribution_artifact_builder));
let certificate = Certificate::default();

let signed_entity_type_3 = SignedEntityType::CardanoImmutableFilesFull(Beacon::default());
let artifact_3 = artifact_builder_service
.compute_artifact(signed_entity_type_3, &certificate)
let signed_entity_type = SignedEntityType::MithrilStakeDistribution(Epoch(1));
let artifact = artifact_builder_service
.compute_artifact(signed_entity_type, &certificate)
.await
.unwrap();

assert_ne!(artifact_1, artifact_2);
assert_ne!(artifact_1, artifact_3);
assert_eq!(artifact_2, artifact_3);
assert_eq!(
serde_json::to_string(&mithril_stake_distribution_expected).unwrap(),
serde_json::to_string(&artifact).unwrap()
);
}
}
19 changes: 6 additions & 13 deletions mithril-aggregator/src/artifact_builder/dummy_artifact.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::marker::PhantomData;

use async_trait::async_trait;
use mithril_common::{
entities::Certificate,
Expand All @@ -12,24 +10,19 @@ use crate::artifact_builder::ArtifactBuilder;

/// Dummy artifact
#[derive(Serialize, Deserialize, PartialEq, Debug)]
pub struct DummyArtifact<'a> {
pub struct DummyArtifact {
message: String,
beacon: DummyBeacon,
phantom: PhantomData<&'a DummyBeacon>,
}

impl<'a> DummyArtifact<'a> {
impl DummyArtifact {
/// Dummy artifact factory
pub fn new(message: String, beacon: DummyBeacon) -> Self {
Self {
message,
beacon,
phantom: PhantomData,
}
Self { message, beacon }
}
}

impl<'a> Artifact<'a> for DummyArtifact<'a> {}
impl Artifact for DummyArtifact {}

/// A [DummyArtifact] builder
pub struct DummyArtifactBuilder {}
Expand All @@ -48,9 +41,9 @@ impl Default for DummyArtifactBuilder {
}

#[async_trait]
impl<'a> ArtifactBuilder<'a, DummyBeacon, DummyArtifact<'a>> for DummyArtifactBuilder {
impl ArtifactBuilder<DummyBeacon, DummyArtifact> for DummyArtifactBuilder {
async fn compute_artifact(
&'a self,
&self,
beacon: DummyBeacon,
certificate: &Certificate,
) -> StdResult<DummyArtifact> {
Expand Down
10 changes: 7 additions & 3 deletions mithril-aggregator/src/artifact_builder/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ use mithril_common::{
StdResult,
};

#[cfg(test)]
use mockall::automock;

/// ArtifactBuilder is trait for building an artifact
#[cfg_attr(test, automock)]
#[async_trait]
pub trait ArtifactBuilder<'a, U, W>
pub trait ArtifactBuilder<U, W>: Send + Sync
where
U: Beacon,
W: Artifact<'a>,
W: Artifact,
{
/// Compute an artifact
async fn compute_artifact(&'a self, beacon: U, certificate: &Certificate) -> StdResult<W>;
async fn compute_artifact(&self, beacon: U, certificate: &Certificate) -> StdResult<W>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use tokio::sync::RwLock;

use super::ArtifactBuilder;
use crate::MultiSigner;
use mithril_common::{
entities::{Certificate, Epoch, SignerWithStake},
signable_builder::Artifact,
StdResult,
};

/// Mithril Stake Distribution
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct MithrilStakeDistribution {
signers_with_stake: Vec<SignerWithStake>,
}

impl MithrilStakeDistribution {
/// MithrilStakeDistribution artifact factory
pub fn new(signers_with_stake: Vec<SignerWithStake>) -> Self {
Self { signers_with_stake }
}
}

impl Artifact for MithrilStakeDistribution {}

/// A [MithrilStakeDistributionArtifact] builder
pub struct MithrilStakeDistributionArtifactBuilder {
multi_signer: Arc<RwLock<dyn MultiSigner>>,
}

impl MithrilStakeDistributionArtifactBuilder {
/// MithrilStakeDistribution artifact builder factory
pub fn new(multi_signer: Arc<RwLock<dyn MultiSigner>>) -> Self {
Self { multi_signer }
}
}

#[async_trait]
impl ArtifactBuilder<Epoch, MithrilStakeDistribution> for MithrilStakeDistributionArtifactBuilder {
async fn compute_artifact(
&self,
_beacon: Epoch,
_certificate: &Certificate,
) -> StdResult<MithrilStakeDistribution> {
let multi_signer = self.multi_signer.read().await;
Ok(MithrilStakeDistribution::new(
multi_signer.get_signers_with_stake().await?,
))
}
}

#[cfg(test)]
mod tests {
use mithril_common::test_utils::fake_data;

use super::*;

use crate::multi_signer::MockMultiSigner;

#[tokio::test]
async fn test_compute_artifact() {
let signers_with_stake = fake_data::signers_with_stakes(5);
let signers_with_stake_clone = signers_with_stake.clone();
let certificate = fake_data::certificate("cert-123".to_string());
let mut mock_multi_signer = MockMultiSigner::new();
mock_multi_signer
.expect_get_signers_with_stake()
.return_once(move || Ok(signers_with_stake_clone));
let mithril_stake_distribution_artifact_builder =
MithrilStakeDistributionArtifactBuilder::new(Arc::new(RwLock::new(mock_multi_signer)));
let artifact = mithril_stake_distribution_artifact_builder
.compute_artifact(Epoch(1), &certificate)
.await
.unwrap();
let artifact_expected = MithrilStakeDistribution::new(signers_with_stake);
assert_eq!(artifact_expected, artifact);
}
}
2 changes: 2 additions & 0 deletions mithril-aggregator/src/artifact_builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
mod artifact_builder_service;
mod dummy_artifact;
mod interface;
mod mithril_stake_distribution;

pub use artifact_builder_service::*;
pub use dummy_artifact::*;
pub use interface::*;
pub use mithril_stake_distribution::*;
11 changes: 7 additions & 4 deletions mithril-aggregator/src/dependency_injection/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use tokio::{
use warp::Filter;

use crate::{
artifact_builder::{ArtifactBuilderService, DummyArtifactBuilder},
artifact_builder::{ArtifactBuilderService, MithrilStakeDistributionArtifactBuilder},
certifier_service::{CertifierService, MithrilCertifierService},
configuration::{ExecutionEnvironment, LIST_SNAPSHOTS_MAX_ITEMS},
database::provider::{
Expand Down Expand Up @@ -897,9 +897,12 @@ impl DependenciesBuilder {
}

async fn build_artifact_builder_service(&mut self) -> Result<Arc<ArtifactBuilderService>> {
let dummy_artifact_builder = DummyArtifactBuilder::new();
let artifact_builder_service =
Arc::new(ArtifactBuilderService::new(dummy_artifact_builder));
let multi_signer = self.get_multi_signer().await?;
let mithril_stake_distribution_artifact_builder =
Arc::new(MithrilStakeDistributionArtifactBuilder::new(multi_signer));
let artifact_builder_service = Arc::new(ArtifactBuilderService::new(
mithril_stake_distribution_artifact_builder,
));

Ok(artifact_builder_service)
}
Expand Down
4 changes: 2 additions & 2 deletions mithril-common/src/signable_builder/interface.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use serde::{de::DeserializeOwned, Serialize};
use std::fmt::Debug;

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

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

/// SignableBuilder is trait for building a signable for a beacon
#[async_trait]
Expand Down

0 comments on commit 9e5ab51

Please sign in to comment.