mithril_cardano_node_internal_database/test/double/
immutable_digester.rs1use std::{collections::BTreeMap, ops::RangeInclusive, path::Path};
2
3use async_trait::async_trait;
4use tokio::sync::RwLock;
5
6use mithril_common::{
7 crypto_helper::{MKTree, MKTreeStoreInMemory},
8 entities::{CardanoDbBeacon, ImmutableFileNumber},
9};
10
11use crate::digesters::{ComputedImmutablesDigests, ImmutableDigester, ImmutableDigesterError};
12use crate::entities::ImmutableFile;
13
14pub struct DumbImmutableDigester {
16 digest: RwLock<String>,
17 mktree_leaves: RwLock<Vec<String>>,
18 is_success: bool,
19}
20
21impl DumbImmutableDigester {
22 pub fn with_digest(mut self, new_digest: &str) -> Self {
24 self.digest = RwLock::new(new_digest.to_string());
25 self
26 }
27
28 pub fn with_merkle_tree(mut self, leaves: Vec<String>) -> Self {
30 self.mktree_leaves = RwLock::new(leaves);
31 self
32 }
33
34 pub async fn update_digest(&self, new_digest: String) {
36 let mut digest = self.digest.write().await;
37 *digest = new_digest;
38 }
39
40 pub async fn update_merkle_tree(&self, leaves: Vec<String>) {
42 let mut mktree_leaves = self.mktree_leaves.write().await;
43 *mktree_leaves = leaves;
44 }
45}
46
47impl Default for DumbImmutableDigester {
48 fn default() -> Self {
49 Self {
50 digest: RwLock::new(String::from("1234")),
51 mktree_leaves: RwLock::new(vec!["1".to_string(), "2".to_string(), "3".to_string()]),
52 is_success: true,
53 }
54 }
55}
56
57#[async_trait]
58impl ImmutableDigester for DumbImmutableDigester {
59 async fn compute_digest(
60 &self,
61 dirpath: &Path,
62 beacon: &CardanoDbBeacon,
63 ) -> Result<String, ImmutableDigesterError> {
64 if self.is_success {
65 Ok(self.digest.read().await.clone())
66 } else {
67 Err(ImmutableDigesterError::NotEnoughImmutable {
68 expected_number: beacon.immutable_file_number,
69 found_number: None,
70 db_dir: dirpath.to_owned(),
71 })
72 }
73 }
74
75 async fn compute_digests_for_range(
76 &self,
77 dirpath: &Path,
78 range: &RangeInclusive<ImmutableFileNumber>,
79 ) -> Result<ComputedImmutablesDigests, ImmutableDigesterError> {
80 if self.is_success {
81 let immutable_file_paths = range
82 .clone()
83 .flat_map(|immutable_file_number| {
84 vec![
85 Path::new(&format!("{immutable_file_number:0>5}.chunk")).to_path_buf(),
86 Path::new(&format!("{immutable_file_number:0>5}.primary")).to_path_buf(),
87 Path::new(&format!("{immutable_file_number:0>5}.secondary")).to_path_buf(),
88 ]
89 })
90 .collect::<Vec<_>>();
91 let digest = self.digest.read().await.clone();
92
93 Ok(ComputedImmutablesDigests::compute_immutables_digests(
94 BTreeMap::from_iter(immutable_file_paths.into_iter().map(|immutable_file_path| {
95 (
96 ImmutableFile::new(immutable_file_path).unwrap(),
97 Some(digest.clone()),
98 )
99 })),
100 slog::Logger::root(slog::Discard, slog::o!()),
101 )?)
102 } else {
103 Err(ImmutableDigesterError::NotEnoughImmutable {
104 expected_number: *range.end(),
105 found_number: None,
106 db_dir: dirpath.to_owned(),
107 })
108 }
109 }
110
111 async fn compute_merkle_tree(
112 &self,
113 dirpath: &Path,
114 beacon: &CardanoDbBeacon,
115 ) -> Result<MKTree<MKTreeStoreInMemory>, ImmutableDigesterError> {
116 if self.is_success {
117 let leaves = self.mktree_leaves.read().await;
118 Ok(MKTree::new(&leaves).unwrap())
119 } else {
120 Err(ImmutableDigesterError::NotEnoughImmutable {
121 expected_number: beacon.immutable_file_number,
122 found_number: None,
123 db_dir: dirpath.to_owned(),
124 })
125 }
126 }
127}