mithril_aggregator/artifact_builder/
cardano_transactions.rs

1use 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
17/// A [CardanoTransactionsArtifact] builder
18pub struct CardanoTransactionsArtifactBuilder {
19    prover_service: Arc<dyn ProverService>,
20}
21
22impl CardanoTransactionsArtifactBuilder {
23    /// CardanoTransactions artifact builder factory
24    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}