Skip to content

Commit b32461a

Browse files
committed
Common: Extract a Digester trait from the ImmutableDigester in order to mock it easily
1 parent ccfb864 commit b32461a

File tree

5 files changed

+87
-50
lines changed

5 files changed

+87
-50
lines changed

mithril-aggregator/src/runtime.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ use super::dependency::{BeaconStoreWrapper, MultiSignerWrapper, SnapshotStoreWra
22
use super::{BeaconStoreError, ProtocolError, SnapshotError, Snapshotter};
33

44
use mithril_common::crypto_helper::Bytes;
5+
use mithril_common::digesters::{Digester, DigesterError, ImmutableDigester};
56
use mithril_common::entities::Beacon;
67
use mithril_common::fake_data;
7-
use mithril_common::immutable_digester::{ImmutableDigester, ImmutableDigesterError};
88

99
use crate::snapshot_stores::SnapshotStoreError;
1010
use crate::snapshot_uploaders::{SnapshotLocation, SnapshotUploader};
@@ -30,8 +30,8 @@ pub enum RuntimeError {
3030
#[error("snapshotter error")]
3131
Snapshotter(#[from] SnapshotError),
3232

33-
#[error("immutable digester error")]
34-
ImmutableDigester(#[from] ImmutableDigesterError),
33+
#[error("digester error")]
34+
Digester(#[from] DigesterError),
3535

3636
#[error("snapshot store error")]
3737
SnapshotStore(#[from] SnapshotStoreError),
@@ -154,7 +154,7 @@ impl AggregatorRuntime {
154154
Err(err) => {
155155
let mut beacon_store = self.beacon_store.write().await;
156156
beacon_store.reset_current_beacon().await?;
157-
Err(RuntimeError::ImmutableDigester(err))
157+
Err(RuntimeError::Digester(err))
158158
}
159159
}
160160
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
use crate::entities::ImmutableFileNumber;
2+
use std::io;
3+
use thiserror::Error;
4+
5+
#[derive(Debug, Clone)]
6+
pub struct DigesterResult {
7+
/// The computed digest
8+
pub digest: String,
9+
10+
/// The number of the last immutable file used to compute the digest
11+
pub last_immutable_file_number: ImmutableFileNumber,
12+
}
13+
14+
#[derive(Error, Debug)]
15+
pub enum DigesterError {
16+
#[error("Immutable files listing failed: `{0}`")]
17+
ListImmutablesError(String),
18+
19+
#[error("At least two immutables chunk should exists")]
20+
NotEnoughImmutable(),
21+
22+
#[error("Digest computation failed:")]
23+
DigestComputationError(#[from] io::Error),
24+
}
25+
26+
/// A digester than can compute the digest used for mithril signatures
27+
///
28+
/// If you want to mock it using mockall:
29+
/// ```
30+
/// mod test {
31+
/// use mithril_common::digesters::{Digester, DigesterError, DigesterResult};
32+
/// use mockall::mock;
33+
///
34+
/// mock! {
35+
/// pub DigesterImpl { }
36+
/// impl Digester for DigesterImpl {
37+
/// fn compute_digest(&self) -> Result<DigesterResult, DigesterError>;
38+
/// }
39+
/// }
40+
///
41+
/// #[test]
42+
/// fn test_mock() {
43+
/// let mut mock = MockDigesterImpl::new();
44+
/// mock.expect_compute_digest()
45+
/// .return_once(|| Err(DigesterError::NotEnoughImmutable()));
46+
/// }
47+
/// }
48+
/// ```
49+
pub trait Digester {
50+
fn compute_digest(&self) -> Result<DigesterResult, DigesterError>;
51+
}

mithril-common/src/immutable_digester.rs renamed to mithril-common/src/digesters/immutable_digester.rs

Lines changed: 26 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::digesters::{Digester, DigesterError, DigesterResult};
12
use crate::entities::ImmutableFileNumber;
23

34
use sha2::{Digest, Sha256};
@@ -6,11 +7,10 @@ use std::ffi::OsStr;
67
use std::fs::File;
78
use std::io;
89
use std::path::{Path, PathBuf};
9-
use thiserror::Error;
1010

1111
use walkdir::WalkDir;
1212

13-
/// ImmutableDigester
13+
/// A digester working directly on a Cardano DB immutables files
1414
pub struct ImmutableDigester {
1515
/// A cardano node DB directory
1616
db_directory: PathBuf,
@@ -19,27 +19,6 @@ pub struct ImmutableDigester {
1919
logger: Logger,
2020
}
2121

22-
#[derive(Error, Debug)]
23-
pub enum ImmutableDigesterError {
24-
#[error("Immutable files listing failed: `{0}`")]
25-
ListImmutablesError(String),
26-
27-
#[error("At least two immutables chunk should exists")]
28-
NotEnoughImmutable(),
29-
30-
#[error("Digest computation failed:")]
31-
DigestComputationError(#[from] io::Error),
32-
}
33-
34-
#[derive(Debug)]
35-
pub struct ImmutableDigesterResult {
36-
/// The computed digest
37-
pub digest: String,
38-
39-
/// The number of the last immutable file used to compute the digest
40-
pub last_immutable_file_number: ImmutableFileNumber,
41-
}
42-
4322
impl ImmutableDigester {
4423
/// ImmutableDigester factory
4524
pub fn new(db_directory: PathBuf, logger: Logger) -> Self {
@@ -49,28 +28,6 @@ impl ImmutableDigester {
4928
}
5029
}
5130

52-
pub fn compute_digest(&self) -> Result<ImmutableDigesterResult, ImmutableDigesterError> {
53-
let immutables = ImmutableFile::list_in_dir(&*self.db_directory)
54-
.map_err(ImmutableDigesterError::ListImmutablesError)?;
55-
let last_immutable = immutables
56-
.last()
57-
.ok_or(ImmutableDigesterError::NotEnoughImmutable())?;
58-
59-
info!(self.logger, "#immutables: {}", immutables.len());
60-
61-
let hash = self
62-
.compute_hash(&immutables)
63-
.map_err(ImmutableDigesterError::DigestComputationError)?;
64-
let digest = hex::encode(hash);
65-
66-
debug!(self.logger, "#computed digest: {:?}", digest);
67-
68-
Ok(ImmutableDigesterResult {
69-
digest,
70-
last_immutable_file_number: last_immutable.number,
71-
})
72-
}
73-
7431
fn compute_hash(&self, entries: &[ImmutableFile]) -> Result<[u8; 32], io::Error> {
7532
let mut hasher = Sha256::new();
7633
let mut progress = Progress {
@@ -92,6 +49,30 @@ impl ImmutableDigester {
9249
}
9350
}
9451

52+
impl Digester for ImmutableDigester {
53+
fn compute_digest(&self) -> Result<DigesterResult, DigesterError> {
54+
let immutables = ImmutableFile::list_in_dir(&*self.db_directory)
55+
.map_err(DigesterError::ListImmutablesError)?;
56+
let last_immutable = immutables
57+
.last()
58+
.ok_or(DigesterError::NotEnoughImmutable())?;
59+
60+
info!(self.logger, "#immutables: {}", immutables.len());
61+
62+
let hash = self
63+
.compute_hash(&immutables)
64+
.map_err(DigesterError::DigestComputationError)?;
65+
let digest = hex::encode(hash);
66+
67+
debug!(self.logger, "#computed digest: {:?}", digest);
68+
69+
Ok(DigesterResult {
70+
digest,
71+
last_immutable_file_number: last_immutable.number,
72+
})
73+
}
74+
}
75+
9576
struct Progress {
9677
index: usize,
9778
total: usize,
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
mod digester;
2+
mod immutable_digester;
3+
4+
pub use digester::{Digester, DigesterError, DigesterResult};
5+
pub use immutable_digester::ImmutableDigester;

mithril-common/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
pub mod apispec;
22
pub mod crypto_helper;
3+
pub mod digesters;
34
pub mod entities;
45
pub mod fake_data;
5-
pub mod immutable_digester;

0 commit comments

Comments
 (0)