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