Skip to content

Commit cd80429

Browse files
committed
feat: implement artifact builder for 'CardanoTransactions'
1 parent 786334d commit cd80429

File tree

7 files changed

+167
-5
lines changed

7 files changed

+167
-5
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
use async_trait::async_trait;
2+
3+
use super::ArtifactBuilder;
4+
use anyhow::{anyhow, Context};
5+
use mithril_common::{
6+
entities::{
7+
Beacon, CardanoTransactionsCommitment, Certificate, ProtocolMessagePartKey,
8+
SignedEntityType,
9+
},
10+
StdResult,
11+
};
12+
13+
/// A [CardanoTransactionsArtifact] builder
14+
pub struct CardanoTransactionsArtifactBuilder {}
15+
16+
impl CardanoTransactionsArtifactBuilder {
17+
/// CardanoTransactions artifact builder factory
18+
pub fn new() -> Self {
19+
Self {}
20+
}
21+
}
22+
23+
#[async_trait]
24+
impl ArtifactBuilder<Beacon, CardanoTransactionsCommitment> for CardanoTransactionsArtifactBuilder {
25+
async fn compute_artifact(
26+
&self,
27+
beacon: Beacon,
28+
certificate: &Certificate,
29+
) -> StdResult<CardanoTransactionsCommitment> {
30+
let merkle_root = certificate
31+
.protocol_message
32+
.get_message_part(&ProtocolMessagePartKey::CardanoTransactionsMerkleRoot)
33+
.ok_or(anyhow!(
34+
"Can not find CardanoTransactionsMerkleRoot protocol message part in certificate"
35+
))
36+
.with_context(|| {
37+
format!(
38+
"Can not compute CardanoTransactionsCommitment artifact for signed_entity: {:?}",
39+
SignedEntityType::CardanoTransactions(beacon)
40+
)
41+
})?;
42+
43+
Ok(CardanoTransactionsCommitment::new(merkle_root.to_string()))
44+
}
45+
}
46+
47+
#[cfg(test)]
48+
mod tests {
49+
use mithril_common::{entities::ProtocolMessage, test_utils::fake_data};
50+
51+
use super::*;
52+
53+
#[tokio::test]
54+
async fn should_compute_valid_artifact_with_merkleroot() {
55+
let certificate = {
56+
let mut certificate = fake_data::certificate("certificate-123".to_string());
57+
let mut message = ProtocolMessage::new();
58+
message.set_message_part(
59+
ProtocolMessagePartKey::CardanoTransactionsMerkleRoot,
60+
"merkleroot".to_string(),
61+
);
62+
certificate.protocol_message = message;
63+
certificate
64+
};
65+
66+
let cardano_transaction_artifact_builder = CardanoTransactionsArtifactBuilder::new();
67+
let artifact = cardano_transaction_artifact_builder
68+
.compute_artifact(Beacon::default(), &certificate)
69+
.await
70+
.unwrap();
71+
let artifact_expected = CardanoTransactionsCommitment::new("merkleroot".to_string());
72+
assert_eq!(artifact_expected, artifact);
73+
}
74+
75+
#[tokio::test]
76+
async fn should_fail_to_compute_artifact_without_merkle_root() {
77+
let certificate = {
78+
let mut certificate = fake_data::certificate("certificate-123".to_string());
79+
let message = ProtocolMessage::new();
80+
certificate.protocol_message = message;
81+
certificate
82+
};
83+
84+
let cardano_transaction_artifact_builder = CardanoTransactionsArtifactBuilder::new();
85+
cardano_transaction_artifact_builder
86+
.compute_artifact(Beacon::default(), &certificate)
87+
.await
88+
.expect_err("The artifact building must fail since there is no CardanoTransactionsMerkleRoot part in its message.");
89+
}
90+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
//! The module used for building artifact
22
mod cardano_immutable_files_full;
3+
mod cardano_transactions;
34
mod interface;
45
mod mithril_stake_distribution;
56

67
pub use cardano_immutable_files_full::*;
8+
pub use cardano_transactions::*;
79
pub use interface::*;
810
pub use mithril_stake_distribution::*;

mithril-aggregator/src/dependency_injection/builder.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ use mithril_common::{
4545

4646
use crate::{
4747
artifact_builder::{
48-
CardanoImmutableFilesFullArtifactBuilder, MithrilStakeDistributionArtifactBuilder,
48+
CardanoImmutableFilesFullArtifactBuilder, CardanoTransactionsArtifactBuilder,
49+
MithrilStakeDistributionArtifactBuilder,
4950
},
5051
configuration::ExecutionEnvironment,
5152
database::provider::{
@@ -977,10 +978,13 @@ impl DependenciesBuilder {
977978
snapshot_uploader,
978979
self.configuration.snapshot_compression_algorithm,
979980
));
981+
let cardano_transactions_artifact_builder =
982+
Arc::new(CardanoTransactionsArtifactBuilder::new());
980983
let signed_entity_service = Arc::new(MithrilSignedEntityService::new(
981984
signed_entity_storer,
982985
mithril_stake_distribution_artifact_builder,
983986
cardano_immutable_files_full_artifact_builder,
987+
cardano_transactions_artifact_builder,
984988
));
985989

986990
Ok(signed_entity_service)

mithril-aggregator/src/services/signed_entity.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use std::sync::Arc;
1010

1111
use mithril_common::{
1212
entities::{
13-
Beacon, Certificate, Epoch, MithrilStakeDistribution, SignedEntity, SignedEntityType,
14-
SignedEntityTypeDiscriminants, Snapshot,
13+
Beacon, CardanoTransactionsCommitment, Certificate, Epoch, MithrilStakeDistribution,
14+
SignedEntity, SignedEntityType, SignedEntityTypeDiscriminants, Snapshot,
1515
},
1616
signable_builder::Artifact,
1717
StdResult,
@@ -68,6 +68,8 @@ pub struct MithrilSignedEntityService {
6868
mithril_stake_distribution_artifact_builder:
6969
Arc<dyn ArtifactBuilder<Epoch, MithrilStakeDistribution>>,
7070
cardano_immutable_files_full_artifact_builder: Arc<dyn ArtifactBuilder<Beacon, Snapshot>>,
71+
cardano_transactions_artifact_builder:
72+
Arc<dyn ArtifactBuilder<Beacon, CardanoTransactionsCommitment>>,
7173
}
7274

7375
impl MithrilSignedEntityService {
@@ -78,11 +80,15 @@ impl MithrilSignedEntityService {
7880
dyn ArtifactBuilder<Epoch, MithrilStakeDistribution>,
7981
>,
8082
cardano_immutable_files_full_artifact_builder: Arc<dyn ArtifactBuilder<Beacon, Snapshot>>,
83+
cardano_transactions_artifact_builder: Arc<
84+
dyn ArtifactBuilder<Beacon, CardanoTransactionsCommitment>,
85+
>,
8186
) -> Self {
8287
Self {
8388
signed_entity_storer,
8489
mithril_stake_distribution_artifact_builder,
8590
cardano_immutable_files_full_artifact_builder,
91+
cardano_transactions_artifact_builder,
8692
}
8793
}
8894

@@ -114,7 +120,16 @@ impl MithrilSignedEntityService {
114120
})?,
115121
))),
116122
SignedEntityType::CardanoStakeDistribution(_) => todo!(),
117-
SignedEntityType::CardanoTransactions(_) => Ok(None),
123+
SignedEntityType::CardanoTransactions(beacon) => Ok(Some(Arc::new(
124+
self.cardano_transactions_artifact_builder
125+
.compute_artifact(beacon.clone(), certificate)
126+
.await
127+
.with_context(|| {
128+
format!(
129+
"Signed Entity Service can not compute artifact for entity type: '{signed_entity_type}'"
130+
)
131+
})?,
132+
))),
118133
}
119134
}
120135
}
@@ -302,11 +317,14 @@ mod tests {
302317

303318
let mock_cardano_immutable_files_full_artifact_builder =
304319
MockArtifactBuilder::<Beacon, Snapshot>::new();
320+
let mock_cardano_transactions_artifact_builder =
321+
MockArtifactBuilder::<Beacon, CardanoTransactionsCommitment>::new();
305322

306323
let artifact_builder_service = MithrilSignedEntityService::new(
307324
Arc::new(mock_signed_entity_storer),
308325
Arc::new(mock_mithril_stake_distribution_artifact_builder),
309326
Arc::new(mock_cardano_immutable_files_full_artifact_builder),
327+
Arc::new(mock_cardano_transactions_artifact_builder),
310328
);
311329
let certificate = fake_data::certificate("hash".to_string());
312330

@@ -355,11 +373,14 @@ mod tests {
355373
.expect_compute_artifact()
356374
.times(1)
357375
.return_once(move |_, _| Ok(snapshot_expected_clone));
376+
let mock_cardano_transactions_artifact_builder =
377+
MockArtifactBuilder::<Beacon, CardanoTransactionsCommitment>::new();
358378

359379
let artifact_builder_service = MithrilSignedEntityService::new(
360380
Arc::new(mock_signed_entity_storer),
361381
Arc::new(mock_mithril_stake_distribution_artifact_builder),
362382
Arc::new(mock_cardano_immutable_files_full_artifact_builder),
383+
Arc::new(mock_cardano_transactions_artifact_builder),
363384
);
364385
let certificate = fake_data::certificate("hash".to_string());
365386

@@ -392,11 +413,14 @@ mod tests {
392413
MockArtifactBuilder::<Epoch, MithrilStakeDistribution>::new();
393414
let mock_cardano_immutable_files_full_artifact_builder =
394415
MockArtifactBuilder::<Beacon, Snapshot>::new();
416+
let mock_cardano_transactions_artifact_builder =
417+
MockArtifactBuilder::<Beacon, CardanoTransactionsCommitment>::new();
395418

396419
let artifact_builder_service = MithrilSignedEntityService::new(
397420
Arc::new(mock_signed_entity_storer),
398421
Arc::new(mock_mithril_stake_distribution_artifact_builder),
399422
Arc::new(mock_cardano_immutable_files_full_artifact_builder),
423+
Arc::new(mock_cardano_transactions_artifact_builder),
400424
);
401425

402426
let certificate = fake_data::certificate("hash".to_string());
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use serde::{Deserialize, Serialize};
2+
3+
use crate::signable_builder::Artifact;
4+
5+
/// Commitment of a set of Cardano transactions
6+
#[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize)]
7+
pub struct CardanoTransactionsCommitment {
8+
merkle_root: String,
9+
}
10+
11+
impl CardanoTransactionsCommitment {
12+
/// Creates a new [CardanoTransactionsCommitment]
13+
pub fn new(merkle_root: String) -> Self {
14+
Self { merkle_root }
15+
}
16+
}
17+
18+
#[typetag::serde]
19+
impl Artifact for CardanoTransactionsCommitment {
20+
fn get_id(&self) -> String {
21+
self.merkle_root.clone()
22+
}
23+
}

mithril-common/src/entities/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
mod beacon;
44
mod cardano_network;
5+
mod cardano_transactions_commitment;
56
mod certificate;
67
mod certificate_metadata;
78
mod certificate_pending;
@@ -20,6 +21,7 @@ mod type_alias;
2021

2122
pub use beacon::{Beacon, BeaconComparison, BeaconComparisonError};
2223
pub use cardano_network::CardanoNetwork;
24+
pub use cardano_transactions_commitment::CardanoTransactionsCommitment;
2325
pub use certificate::{Certificate, CertificateSignature};
2426
pub use certificate_metadata::{CertificateMetadata, StakeDistributionParty};
2527
pub use certificate_pending::CertificatePending;

mithril-common/src/entities/signed_entity.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#[cfg(feature = "test_tools")]
22
use super::{Beacon, Epoch};
3-
use super::{MithrilStakeDistribution, SignedEntityType, Snapshot};
3+
use super::{CardanoTransactionsCommitment, MithrilStakeDistribution, SignedEntityType, Snapshot};
44
use crate::signable_builder::Artifact;
55
#[cfg(feature = "test_tools")]
66
use crate::test_utils::fake_data;
@@ -61,3 +61,20 @@ impl SignedEntity<MithrilStakeDistribution> {
6161
}
6262
}
6363
}
64+
65+
impl SignedEntity<CardanoTransactionsCommitment> {
66+
cfg_test_tools! {
67+
/// Create a dummy [SignedEntity] for [CardanoTransactionsCommitment] entity
68+
pub fn dummy() -> Self {
69+
SignedEntity {
70+
signed_entity_id: "snapshot-id-123".to_string(),
71+
signed_entity_type: SignedEntityType::CardanoTransactions(Beacon::default()),
72+
certificate_id: "certificate-hash-123".to_string(),
73+
artifact: CardanoTransactionsCommitment::new("mkroot123".to_string()),
74+
created_at: DateTime::parse_from_rfc3339("2023-01-19T13:43:05.618857482Z")
75+
.unwrap()
76+
.with_timezone(&Utc),
77+
}
78+
}
79+
}
80+
}

0 commit comments

Comments
 (0)