Skip to content

Commit cbf035d

Browse files
authored
Merge pull request #906 from input-output-hk/jpraynaud/869-use-artifact-builder-service-aggregator
Use Artifact Builder Service in aggregator
2 parents c5ca321 + ff2d661 commit cbf035d

File tree

18 files changed

+237
-302
lines changed

18 files changed

+237
-302
lines changed

Cargo.lock

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mithril-aggregator/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mithril-aggregator"
3-
version = "0.3.14"
3+
version = "0.3.15"
44
description = "A Mithril Aggregator server"
55
authors = { workspace = true }
66
edition = { workspace = true }
@@ -23,6 +23,7 @@ semver = "1.0.16"
2323
serde = { version = "1.0", features = ["derive"] }
2424
serde_json = "1.0"
2525
serde_yaml = "0.9.10"
26+
sha2 = "0.10.2"
2627
slog = { version = "2.7.0", features = ["max_level_trace", "release_max_level_debug"] }
2728
slog-async = "2.7.0"
2829
slog-bunyan = "2.4.0"

mithril-aggregator/src/artifact_builder/artifact_builder_service.rs

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use async_trait::async_trait;
2+
use chrono::Utc;
23

34
use std::sync::Arc;
45

@@ -8,7 +9,10 @@ use mithril_common::{
89
StdResult,
910
};
1011

11-
use crate::artifact_builder::ArtifactBuilder;
12+
use crate::{
13+
artifact_builder::ArtifactBuilder,
14+
database::provider::{SignedEntityRecord, SignedEntityStorer},
15+
};
1216

1317
use super::MithrilStakeDistribution;
1418

@@ -19,40 +23,39 @@ use mockall::automock;
1923
#[cfg_attr(test, automock)]
2024
#[async_trait]
2125
pub trait ArtifactBuilderService: Send + Sync {
22-
/// Compute artifact from signed entity type
23-
async fn compute_artifact(
26+
/// Create artifact for a signed entity type and a certificate
27+
async fn create_artifact(
2428
&self,
2529
signed_entity_type: SignedEntityType,
2630
certificate: &Certificate,
27-
) -> StdResult<Arc<dyn Artifact>>;
31+
) -> StdResult<()>;
2832
}
2933

3034
/// Mithril ArtifactBuilder Service
3135
pub struct MithrilArtifactBuilderService {
36+
signed_entity_storer: Arc<dyn SignedEntityStorer>,
3237
mithril_stake_distribution_artifact_builder:
3338
Arc<dyn ArtifactBuilder<Epoch, MithrilStakeDistribution>>,
3439
cardano_immutable_files_full_artifact_builder: Arc<dyn ArtifactBuilder<Beacon, Snapshot>>,
3540
}
3641

3742
impl MithrilArtifactBuilderService {
3843
/// MithrilArtifactBuilderService factory
39-
#[allow(dead_code)]
4044
pub fn new(
45+
signed_entity_storer: Arc<dyn SignedEntityStorer>,
4146
mithril_stake_distribution_artifact_builder: Arc<
4247
dyn ArtifactBuilder<Epoch, MithrilStakeDistribution>,
4348
>,
4449
cardano_immutable_files_full_artifact_builder: Arc<dyn ArtifactBuilder<Beacon, Snapshot>>,
4550
) -> Self {
4651
Self {
52+
signed_entity_storer,
4753
mithril_stake_distribution_artifact_builder,
4854
cardano_immutable_files_full_artifact_builder,
4955
}
5056
}
51-
}
5257

53-
#[async_trait]
54-
impl ArtifactBuilderService for MithrilArtifactBuilderService {
55-
#[allow(dead_code)]
58+
/// Compute artifact from signed entity type
5659
async fn compute_artifact(
5760
&self,
5861
signed_entity_type: SignedEntityType,
@@ -74,20 +77,51 @@ impl ArtifactBuilderService for MithrilArtifactBuilderService {
7477
}
7578
}
7679

80+
#[async_trait]
81+
impl ArtifactBuilderService for MithrilArtifactBuilderService {
82+
async fn create_artifact(
83+
&self,
84+
signed_entity_type: SignedEntityType,
85+
certificate: &Certificate,
86+
) -> StdResult<()> {
87+
let artifact = self
88+
.compute_artifact(signed_entity_type.clone(), certificate)
89+
.await?;
90+
let signed_entity = SignedEntityRecord {
91+
signed_entity_id: artifact.get_id(),
92+
signed_entity_type,
93+
certificate_id: certificate.hash.clone(),
94+
artifact: serde_json::to_string(&artifact)?,
95+
created_at: format!("{:?}", Utc::now()),
96+
};
97+
98+
self.signed_entity_storer
99+
.store_signed_entity(&signed_entity)
100+
.await?;
101+
102+
Ok(())
103+
}
104+
}
105+
77106
#[cfg(test)]
78107
mod tests {
79108
use mithril_common::{entities::Epoch, test_utils::fake_data};
80109

81110
use super::*;
82111

83-
use crate::artifact_builder::MockArtifactBuilder;
112+
use crate::{
113+
artifact_builder::MockArtifactBuilder, database::provider::MockSignedEntityStorer,
114+
};
84115

85116
#[tokio::test]
86117
async fn build_mithril_stake_distribution_artifact_when_given_mithril_stake_distribution_entity_type(
87118
) {
88119
let signers_with_stake = fake_data::signers_with_stakes(5);
89120
let mithril_stake_distribution_expected = MithrilStakeDistribution::new(signers_with_stake);
90121
let mithril_stake_distribution_clone = mithril_stake_distribution_expected.clone();
122+
123+
let mock_signed_entity_storer = MockSignedEntityStorer::new();
124+
91125
let mut mock_mithril_stake_distribution_artifact_builder =
92126
MockArtifactBuilder::<Epoch, MithrilStakeDistribution>::new();
93127
mock_mithril_stake_distribution_artifact_builder
@@ -99,6 +133,7 @@ mod tests {
99133
MockArtifactBuilder::<Beacon, Snapshot>::new();
100134

101135
let artifact_builder_service = MithrilArtifactBuilderService::new(
136+
Arc::new(mock_signed_entity_storer),
102137
Arc::new(mock_mithril_stake_distribution_artifact_builder),
103138
Arc::new(mock_cardano_immutable_files_full_artifact_builder),
104139
);
@@ -121,6 +156,9 @@ mod tests {
121156
async fn build_snapshot_artifact_when_given_cardano_immutable_files_full_entity_type() {
122157
let snapshot_expected = fake_data::snapshots(1).first().unwrap().to_owned();
123158
let snapshot_expected_clone = snapshot_expected.clone();
159+
160+
let mock_signed_entity_storer = MockSignedEntityStorer::new();
161+
124162
let mock_mithril_stake_distribution_artifact_builder =
125163
MockArtifactBuilder::<Epoch, MithrilStakeDistribution>::new();
126164

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

134172
let artifact_builder_service = MithrilArtifactBuilderService::new(
173+
Arc::new(mock_signed_entity_storer),
135174
Arc::new(mock_mithril_stake_distribution_artifact_builder),
136175
Arc::new(mock_cardano_immutable_files_full_artifact_builder),
137176
);

mithril-aggregator/src/artifact_builder/dummy_artifact.rs

Lines changed: 0 additions & 58 deletions
This file was deleted.

mithril-aggregator/src/artifact_builder/mithril_stake_distribution.rs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use async_trait::async_trait;
22
use serde::{Deserialize, Serialize};
3+
use sha2::{Digest, Sha256};
34
use std::sync::Arc;
45
use tokio::sync::RwLock;
56

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

2022
impl MithrilStakeDistribution {
2123
/// MithrilStakeDistribution artifact factory
2224
pub fn new(signers_with_stake: Vec<SignerWithStake>) -> Self {
23-
Self { signers_with_stake }
25+
let mut signers_with_stake_sorted = signers_with_stake;
26+
signers_with_stake_sorted.sort();
27+
let mut mithril_stake_distribution = Self {
28+
signers_with_stake: signers_with_stake_sorted,
29+
hash: "".to_string(),
30+
};
31+
mithril_stake_distribution.hash = mithril_stake_distribution.compute_hash();
32+
mithril_stake_distribution
33+
}
34+
35+
fn compute_hash(&self) -> String {
36+
let mut hasher = Sha256::new();
37+
for signer_with_stake in &self.signers_with_stake {
38+
hasher.update(signer_with_stake.compute_hash().as_bytes());
39+
}
40+
hex::encode(hasher.finalize())
2441
}
2542
}
2643

2744
#[typetag::serde]
28-
impl Artifact for MithrilStakeDistribution {}
45+
impl Artifact for MithrilStakeDistribution {
46+
fn get_id(&self) -> String {
47+
self.hash.clone()
48+
}
49+
}
2950

3051
/// A [MithrilStakeDistributionArtifact] builder
3152
pub struct MithrilStakeDistributionArtifactBuilder {
@@ -79,4 +100,24 @@ mod tests {
79100
let artifact_expected = MithrilStakeDistribution::new(signers_with_stake);
80101
assert_eq!(artifact_expected, artifact);
81102
}
103+
104+
#[test]
105+
fn sort_given_signers_when_created() {
106+
let signers_with_stake = fake_data::signers_with_stakes(5);
107+
108+
assert_eq!(
109+
MithrilStakeDistribution::new(signers_with_stake.clone()),
110+
MithrilStakeDistribution::new(signers_with_stake.into_iter().rev().collect())
111+
);
112+
}
113+
114+
#[test]
115+
fn hash_value_doesnt_change_if_signers_order_change() {
116+
let signers_with_stake = fake_data::signers_with_stakes(5);
117+
118+
let sd = MithrilStakeDistribution::new(signers_with_stake.clone());
119+
let sd2 = MithrilStakeDistribution::new(signers_with_stake.into_iter().rev().collect());
120+
121+
assert_eq!(sd.hash, sd2.hash);
122+
}
82123
}

mithril-aggregator/src/artifact_builder/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22
33
mod artifact_builder_service;
44
mod cardano_immutable_files_full;
5-
mod dummy_artifact;
65
mod interface;
76
mod mithril_stake_distribution;
87

98
pub use artifact_builder_service::*;
109
pub use cardano_immutable_files_full::*;
11-
pub use dummy_artifact::*;
1210
pub use interface::*;
1311
pub use mithril_stake_distribution::*;

mithril-aggregator/src/database/migration.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,16 @@ drop table single_signature_legacy;
290290
alter table open_message drop column message;
291291
alter table open_message add column protocol_message json not null;
292292
alter table open_message add column is_certified bool not null default false;
293+
"#,
294+
),
295+
// Migration 11
296+
// Alter `signed_entity` table
297+
SqlMigration::new(
298+
11,
299+
r#"
300+
alter table signed_entity add column artifact json not null;
301+
update signed_entity set artifact = entity;
302+
alter table signed_entity drop column entity;
293303
"#,
294304
),
295305
]

mithril-aggregator/src/database/provider/open_message.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ type StdResult<T> = Result<T, StdError>;
2323
/// An open message is a message open for signatures. Every signer may send a
2424
/// single signature for this message from which a multi signature will be
2525
/// generated if possible.
26-
#[allow(dead_code)]
2726
#[derive(Debug, Clone, PartialEq, Eq)]
2827
pub struct OpenMessageRecord {
2928
/// OpenMessage unique identifier

0 commit comments

Comments
 (0)