mithril_aggregator/artifact_builder/
cardano_transactions.rs1use std::sync::Arc;
2
3use anyhow::{anyhow, Context};
4use async_trait::async_trait;
5use mithril_common::{
6 entities::{
7 BlockNumber, CardanoTransactionsSnapshot, Certificate, ProtocolMessagePartKey,
8 SignedEntityType,
9 },
10 StdResult,
11};
12
13use crate::services::ProverService;
14
15use super::ArtifactBuilder;
16
17pub struct CardanoTransactionsArtifactBuilder {
19 prover_service: Arc<dyn ProverService>,
20}
21
22impl CardanoTransactionsArtifactBuilder {
23 pub fn new(prover_service: Arc<dyn ProverService>) -> Self {
25 Self { prover_service }
26 }
27}
28
29#[async_trait]
30impl ArtifactBuilder<BlockNumber, CardanoTransactionsSnapshot>
31 for CardanoTransactionsArtifactBuilder
32{
33 async fn compute_artifact(
34 &self,
35 beacon: BlockNumber,
36 certificate: &Certificate,
37 ) -> StdResult<CardanoTransactionsSnapshot> {
38 let merkle_root = certificate
39 .protocol_message
40 .get_message_part(&ProtocolMessagePartKey::CardanoTransactionsMerkleRoot)
41 .ok_or(anyhow!(
42 "Can not find CardanoTransactionsMerkleRoot protocol message part in certificate"
43 ))
44 .with_context(|| {
45 format!(
46 "Can not compute CardanoTransactionsSnapshot artifact for signed_entity: {:?}",
47 SignedEntityType::CardanoTransactions(certificate.epoch, beacon)
48 )
49 })?;
50 self.prover_service.compute_cache(beacon).await?;
51
52 Ok(CardanoTransactionsSnapshot::new(
53 merkle_root.to_string(),
54 beacon,
55 ))
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use mithril_common::{entities::ProtocolMessage, test_utils::fake_data};
62
63 use crate::services::MockProverService;
64
65 use super::*;
66
67 #[tokio::test]
68 async fn should_compute_valid_artifact_with_merkleroot() {
69 let mut mock_prover = MockProverService::new();
70 mock_prover.expect_compute_cache().returning(|_| Ok(()));
71 let cardano_transaction_artifact_builder =
72 CardanoTransactionsArtifactBuilder::new(Arc::new(mock_prover));
73
74 let certificate_with_merkle_root = {
75 let mut protocol_message = ProtocolMessage::new();
76 protocol_message.set_message_part(
77 ProtocolMessagePartKey::CardanoTransactionsMerkleRoot,
78 "merkleroot".to_string(),
79 );
80 Certificate {
81 protocol_message,
82 ..fake_data::certificate("certificate-123".to_string())
83 }
84 };
85 let beacon = BlockNumber(100);
86
87 let artifact = cardano_transaction_artifact_builder
88 .compute_artifact(beacon, &certificate_with_merkle_root)
89 .await
90 .unwrap();
91
92 assert_eq!(
93 CardanoTransactionsSnapshot::new("merkleroot".to_string(), beacon),
94 artifact
95 );
96 }
97
98 #[tokio::test]
99 async fn should_fail_to_compute_artifact_without_merkle_root() {
100 let mut mock_prover = MockProverService::new();
101 mock_prover.expect_compute_cache().returning(|_| Ok(()));
102 let cardano_transaction_artifact_builder =
103 CardanoTransactionsArtifactBuilder::new(Arc::new(mock_prover));
104
105 let certificate_without_merkle_root = Certificate {
106 protocol_message: ProtocolMessage::new(),
107 ..fake_data::certificate("certificate-123".to_string())
108 };
109 let beacon = BlockNumber(100);
110
111 cardano_transaction_artifact_builder
112 .compute_artifact(beacon, &certificate_without_merkle_root)
113 .await
114 .expect_err("The artifact building must fail since there is no CardanoTransactionsMerkleRoot part in its message.");
115 }
116}