Skip to content

Commit

Permalink
Merge pull request #906 from input-output-hk/jpraynaud/869-use-artifa…
Browse files Browse the repository at this point in the history
…ct-builder-service-aggregator

Use Artifact Builder Service in aggregator
  • Loading branch information
jpraynaud authored May 9, 2023
2 parents c5ca321 + ff2d661 commit cbf035d
Show file tree
Hide file tree
Showing 18 changed files with 237 additions and 302 deletions.
5 changes: 3 additions & 2 deletions Cargo.lock

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

3 changes: 2 additions & 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.14"
version = "0.3.15"
description = "A Mithril Aggregator server"
authors = { workspace = true }
edition = { workspace = true }
Expand All @@ -23,6 +23,7 @@ semver = "1.0.16"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_yaml = "0.9.10"
sha2 = "0.10.2"
slog = { version = "2.7.0", features = ["max_level_trace", "release_max_level_debug"] }
slog-async = "2.7.0"
slog-bunyan = "2.4.0"
Expand Down
59 changes: 49 additions & 10 deletions mithril-aggregator/src/artifact_builder/artifact_builder_service.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use async_trait::async_trait;
use chrono::Utc;

use std::sync::Arc;

Expand All @@ -8,7 +9,10 @@ use mithril_common::{
StdResult,
};

use crate::artifact_builder::ArtifactBuilder;
use crate::{
artifact_builder::ArtifactBuilder,
database::provider::{SignedEntityRecord, SignedEntityStorer},
};

use super::MithrilStakeDistribution;

Expand All @@ -19,40 +23,39 @@ use mockall::automock;
#[cfg_attr(test, automock)]
#[async_trait]
pub trait ArtifactBuilderService: Send + Sync {
/// Compute artifact from signed entity type
async fn compute_artifact(
/// Create artifact for a signed entity type and a certificate
async fn create_artifact(
&self,
signed_entity_type: SignedEntityType,
certificate: &Certificate,
) -> StdResult<Arc<dyn Artifact>>;
) -> StdResult<()>;
}

/// Mithril ArtifactBuilder Service
pub struct MithrilArtifactBuilderService {
signed_entity_storer: Arc<dyn SignedEntityStorer>,
mithril_stake_distribution_artifact_builder:
Arc<dyn ArtifactBuilder<Epoch, MithrilStakeDistribution>>,
cardano_immutable_files_full_artifact_builder: Arc<dyn ArtifactBuilder<Beacon, Snapshot>>,
}

impl MithrilArtifactBuilderService {
/// MithrilArtifactBuilderService factory
#[allow(dead_code)]
pub fn new(
signed_entity_storer: Arc<dyn SignedEntityStorer>,
mithril_stake_distribution_artifact_builder: Arc<
dyn ArtifactBuilder<Epoch, MithrilStakeDistribution>,
>,
cardano_immutable_files_full_artifact_builder: Arc<dyn ArtifactBuilder<Beacon, Snapshot>>,
) -> Self {
Self {
signed_entity_storer,
mithril_stake_distribution_artifact_builder,
cardano_immutable_files_full_artifact_builder,
}
}
}

#[async_trait]
impl ArtifactBuilderService for MithrilArtifactBuilderService {
#[allow(dead_code)]
/// Compute artifact from signed entity type
async fn compute_artifact(
&self,
signed_entity_type: SignedEntityType,
Expand All @@ -74,20 +77,51 @@ impl ArtifactBuilderService for MithrilArtifactBuilderService {
}
}

#[async_trait]
impl ArtifactBuilderService for MithrilArtifactBuilderService {
async fn create_artifact(
&self,
signed_entity_type: SignedEntityType,
certificate: &Certificate,
) -> StdResult<()> {
let artifact = self
.compute_artifact(signed_entity_type.clone(), certificate)
.await?;
let signed_entity = SignedEntityRecord {
signed_entity_id: artifact.get_id(),
signed_entity_type,
certificate_id: certificate.hash.clone(),
artifact: serde_json::to_string(&artifact)?,
created_at: format!("{:?}", Utc::now()),
};

self.signed_entity_storer
.store_signed_entity(&signed_entity)
.await?;

Ok(())
}
}

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

use super::*;

use crate::artifact_builder::MockArtifactBuilder;
use crate::{
artifact_builder::MockArtifactBuilder, database::provider::MockSignedEntityStorer,
};

#[tokio::test]
async fn build_mithril_stake_distribution_artifact_when_given_mithril_stake_distribution_entity_type(
) {
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 mock_signed_entity_storer = MockSignedEntityStorer::new();

let mut mock_mithril_stake_distribution_artifact_builder =
MockArtifactBuilder::<Epoch, MithrilStakeDistribution>::new();
mock_mithril_stake_distribution_artifact_builder
Expand All @@ -99,6 +133,7 @@ mod tests {
MockArtifactBuilder::<Beacon, Snapshot>::new();

let artifact_builder_service = MithrilArtifactBuilderService::new(
Arc::new(mock_signed_entity_storer),
Arc::new(mock_mithril_stake_distribution_artifact_builder),
Arc::new(mock_cardano_immutable_files_full_artifact_builder),
);
Expand All @@ -121,6 +156,9 @@ mod tests {
async fn build_snapshot_artifact_when_given_cardano_immutable_files_full_entity_type() {
let snapshot_expected = fake_data::snapshots(1).first().unwrap().to_owned();
let snapshot_expected_clone = snapshot_expected.clone();

let mock_signed_entity_storer = MockSignedEntityStorer::new();

let mock_mithril_stake_distribution_artifact_builder =
MockArtifactBuilder::<Epoch, MithrilStakeDistribution>::new();

Expand All @@ -132,6 +170,7 @@ mod tests {
.return_once(move |_, _| Ok(snapshot_expected_clone));

let artifact_builder_service = MithrilArtifactBuilderService::new(
Arc::new(mock_signed_entity_storer),
Arc::new(mock_mithril_stake_distribution_artifact_builder),
Arc::new(mock_cardano_immutable_files_full_artifact_builder),
);
Expand Down
58 changes: 0 additions & 58 deletions mithril-aggregator/src/artifact_builder/dummy_artifact.rs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use std::sync::Arc;
use tokio::sync::RwLock;

Expand All @@ -15,17 +16,37 @@ use mithril_common::{
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct MithrilStakeDistribution {
signers_with_stake: Vec<SignerWithStake>,
hash: String,
}

impl MithrilStakeDistribution {
/// MithrilStakeDistribution artifact factory
pub fn new(signers_with_stake: Vec<SignerWithStake>) -> Self {
Self { signers_with_stake }
let mut signers_with_stake_sorted = signers_with_stake;
signers_with_stake_sorted.sort();
let mut mithril_stake_distribution = Self {
signers_with_stake: signers_with_stake_sorted,
hash: "".to_string(),
};
mithril_stake_distribution.hash = mithril_stake_distribution.compute_hash();
mithril_stake_distribution
}

fn compute_hash(&self) -> String {
let mut hasher = Sha256::new();
for signer_with_stake in &self.signers_with_stake {
hasher.update(signer_with_stake.compute_hash().as_bytes());
}
hex::encode(hasher.finalize())
}
}

#[typetag::serde]
impl Artifact for MithrilStakeDistribution {}
impl Artifact for MithrilStakeDistribution {
fn get_id(&self) -> String {
self.hash.clone()
}
}

/// A [MithrilStakeDistributionArtifact] builder
pub struct MithrilStakeDistributionArtifactBuilder {
Expand Down Expand Up @@ -79,4 +100,24 @@ mod tests {
let artifact_expected = MithrilStakeDistribution::new(signers_with_stake);
assert_eq!(artifact_expected, artifact);
}

#[test]
fn sort_given_signers_when_created() {
let signers_with_stake = fake_data::signers_with_stakes(5);

assert_eq!(
MithrilStakeDistribution::new(signers_with_stake.clone()),
MithrilStakeDistribution::new(signers_with_stake.into_iter().rev().collect())
);
}

#[test]
fn hash_value_doesnt_change_if_signers_order_change() {
let signers_with_stake = fake_data::signers_with_stakes(5);

let sd = MithrilStakeDistribution::new(signers_with_stake.clone());
let sd2 = MithrilStakeDistribution::new(signers_with_stake.into_iter().rev().collect());

assert_eq!(sd.hash, sd2.hash);
}
}
2 changes: 0 additions & 2 deletions mithril-aggregator/src/artifact_builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@
mod artifact_builder_service;
mod cardano_immutable_files_full;
mod dummy_artifact;
mod interface;
mod mithril_stake_distribution;

pub use artifact_builder_service::*;
pub use cardano_immutable_files_full::*;
pub use dummy_artifact::*;
pub use interface::*;
pub use mithril_stake_distribution::*;
10 changes: 10 additions & 0 deletions mithril-aggregator/src/database/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,16 @@ drop table single_signature_legacy;
alter table open_message drop column message;
alter table open_message add column protocol_message json not null;
alter table open_message add column is_certified bool not null default false;
"#,
),
// Migration 11
// Alter `signed_entity` table
SqlMigration::new(
11,
r#"
alter table signed_entity add column artifact json not null;
update signed_entity set artifact = entity;
alter table signed_entity drop column entity;
"#,
),
]
Expand Down
1 change: 0 additions & 1 deletion mithril-aggregator/src/database/provider/open_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ type StdResult<T> = Result<T, StdError>;
/// An open message is a message open for signatures. Every signer may send a
/// single signature for this message from which a multi signature will be
/// generated if possible.
#[allow(dead_code)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OpenMessageRecord {
/// OpenMessage unique identifier
Expand Down
Loading

0 comments on commit cbf035d

Please sign in to comment.