mithril_cardano_node_internal_database/signable_builder/
cardano_database.rs1use std::path::{Path, PathBuf};
2use std::sync::Arc;
3
4use anyhow::Context;
5use async_trait::async_trait;
6use slog::{Logger, info};
7
8use mithril_common::{
9 StdResult,
10 entities::{CardanoDbBeacon, ProtocolMessage, ProtocolMessagePartKey},
11 logging::LoggerExtensions,
12 signable_builder::SignableBuilder,
13};
14
15use crate::digesters::ImmutableDigester;
16
17pub struct CardanoDatabaseSignableBuilder {
19 digester: Arc<dyn ImmutableDigester>,
20 logger: Logger,
21 dirpath: PathBuf,
22}
23
24impl CardanoDatabaseSignableBuilder {
25 pub fn new(digester: Arc<dyn ImmutableDigester>, dirpath: &Path, logger: Logger) -> Self {
27 Self {
28 digester,
29 logger: logger.new_with_component_name::<Self>(),
30 dirpath: dirpath.to_owned(),
31 }
32 }
33}
34
35#[async_trait]
36impl SignableBuilder<CardanoDbBeacon> for CardanoDatabaseSignableBuilder {
37 async fn compute_protocol_message(
38 &self,
39 beacon: CardanoDbBeacon,
40 ) -> StdResult<ProtocolMessage> {
41 let merkle_tree = self
42 .digester
43 .compute_merkle_tree(&self.dirpath, &beacon)
44 .await
45 .with_context(|| {
46 format!(
47 "Cardano Database Signable Builder can not compute merkle tree of '{}'",
48 &self.dirpath.display()
49 )
50 })?;
51
52 let merkle_root = merkle_tree.compute_root()?.to_hex();
53 info!(
54 self.logger,
55 "Computed Cardano database Merkle root = '{merkle_root}'"
56 );
57
58 let mut protocol_message = ProtocolMessage::new();
59 protocol_message.set_message_part(
60 ProtocolMessagePartKey::CardanoDatabaseMerkleRoot,
61 merkle_root,
62 );
63
64 Ok(protocol_message)
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use mithril_common::crypto_helper::{MKTree, MKTreeStoreInMemory};
71
72 use crate::test::TestLogger;
73 use crate::test::double::DumbImmutableDigester;
74
75 use super::*;
76
77 #[tokio::test]
78 async fn compute_signable() {
79 let digests = vec!["digest-1".to_string(), "digest-2".to_string()];
80 let digester = DumbImmutableDigester::default().with_merkle_tree(digests.clone());
81 let signable_builder = CardanoDatabaseSignableBuilder::new(
82 Arc::new(digester),
83 Path::new(""),
84 TestLogger::stdout(),
85 );
86
87 let protocol_message = signable_builder
88 .compute_protocol_message(CardanoDbBeacon::default())
89 .await
90 .unwrap();
91
92 let expected_mktree: MKTree<MKTreeStoreInMemory> = MKTree::new(&digests).unwrap();
93 let mut expected_message = ProtocolMessage::new();
94 expected_message.set_message_part(
95 ProtocolMessagePartKey::CardanoDatabaseMerkleRoot,
96 expected_mktree.compute_root().unwrap().to_hex(),
97 );
98 assert_eq!(expected_message, protocol_message);
99 }
100}