Skip to content

Commit 8818621

Browse files
committed
Add MessageAdapter trait
Implement for Cardano Immutable Files Snapshot and Mithril Stake Distribution. Adapt artifact builder implementations.
1 parent 400090b commit 8818621

13 files changed

+301
-71
lines changed

mithril-aggregator/src/artifact_builder/artifact_builder_service.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use slog_scope::info;
44
use std::sync::Arc;
55

66
use mithril_common::{
7-
entities::{Beacon, Certificate, Epoch, SignedEntityType, Snapshot},
7+
entities::{Beacon, Certificate, Epoch, MithrilStakeDistribution, SignedEntityType, Snapshot},
88
signable_builder::Artifact,
99
StdResult,
1010
};
@@ -14,8 +14,6 @@ use crate::{
1414
database::provider::{SignedEntityRecord, SignedEntityStorer},
1515
};
1616

17-
use super::MithrilStakeDistribution;
18-
1917
#[cfg(test)]
2018
use mockall::automock;
2119

mithril-aggregator/src/artifact_builder/mithril_stake_distribution.rs

Lines changed: 1 addition & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,14 @@
11
use async_trait::async_trait;
2-
use serde::{Deserialize, Serialize};
3-
use sha2::{Digest, Sha256};
42
use std::sync::Arc;
53
use tokio::sync::RwLock;
64

75
use super::ArtifactBuilder;
86
use crate::MultiSigner;
97
use mithril_common::{
10-
entities::{Certificate, Epoch, SignerWithStake},
11-
signable_builder::Artifact,
8+
entities::{Certificate, Epoch, MithrilStakeDistribution},
129
StdResult,
1310
};
1411

15-
/// Mithril Stake Distribution
16-
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
17-
pub struct MithrilStakeDistribution {
18-
epoch: Epoch,
19-
signers_with_stake: Vec<SignerWithStake>,
20-
hash: String,
21-
}
22-
23-
impl MithrilStakeDistribution {
24-
/// MithrilStakeDistribution artifact factory
25-
pub fn new(epoch: Epoch, signers_with_stake: Vec<SignerWithStake>) -> Self {
26-
let mut signers_with_stake_sorted = signers_with_stake;
27-
signers_with_stake_sorted.sort();
28-
let mut mithril_stake_distribution = Self {
29-
epoch,
30-
signers_with_stake: signers_with_stake_sorted,
31-
hash: "".to_string(),
32-
};
33-
mithril_stake_distribution.hash = mithril_stake_distribution.compute_hash();
34-
mithril_stake_distribution
35-
}
36-
37-
fn compute_hash(&self) -> String {
38-
let mut hasher = Sha256::new();
39-
hasher.update(self.epoch.0.to_be_bytes());
40-
for signer_with_stake in &self.signers_with_stake {
41-
hasher.update(signer_with_stake.compute_hash().as_bytes());
42-
}
43-
hex::encode(hasher.finalize())
44-
}
45-
}
46-
47-
#[typetag::serde]
48-
impl Artifact for MithrilStakeDistribution {
49-
fn get_id(&self) -> String {
50-
self.hash.clone()
51-
}
52-
}
53-
54-
/// Mithril Stake Distribution Summary
55-
// TODO: This type should probably be listed in the common entities?
56-
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
57-
pub struct MithrilStakeDistributionSummary {
58-
epoch: Epoch,
59-
hash: String,
60-
}
61-
62-
impl From<MithrilStakeDistribution> for MithrilStakeDistributionSummary {
63-
fn from(other: MithrilStakeDistribution) -> Self {
64-
Self {
65-
epoch: other.epoch,
66-
hash: other.hash,
67-
}
68-
}
69-
}
70-
7112
/// A [MithrilStakeDistributionArtifact] builder
7213
pub struct MithrilStakeDistributionArtifactBuilder {
7314
multi_signer: Arc<RwLock<dyn MultiSigner>>,

mithril-aggregator/src/message_adapters/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@ mod from_register_signer;
33
mod to_certificate_message;
44
mod to_certificate_pending_message;
55
mod to_epoch_settings_message;
6+
mod to_mithril_stake_distribution_list_message;
7+
mod to_mithril_stake_distribution_message;
68
mod to_snapshot_list_message;
7-
mod to_snasphot_message;
9+
mod to_snapshot_message;
810

911
pub use from_register_signature::FromRegisterSingleSignatureAdapter;
1012
pub use from_register_signer::FromRegisterSignerAdapter;
1113
pub use to_certificate_message::ToCertificateMessageAdapter;
1214
pub use to_certificate_pending_message::ToCertificatePendingMessageAdapter;
1315
pub use to_epoch_settings_message::ToEpochSettingsMessageAdapter;
16+
pub use to_mithril_stake_distribution_list_message::ToMithrilStakeDistributionListMessageAdapter;
17+
pub use to_mithril_stake_distribution_message::ToMithrilStakeDistributionMessageAdapter;
1418
pub use to_snapshot_list_message::ToSnapshotListMessageAdapter;
15-
pub use to_snasphot_message::ToSnapshotMessageAdapter;
19+
pub use to_snapshot_message::ToSnapshotMessageAdapter;
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
use mithril_common::entities::MithrilStakeDistribution;
2+
use mithril_common::messages::{
3+
MessageAdapter, MithrilStakeDistributionListItemMessage, MithrilStakeDistributionListMessage,
4+
};
5+
6+
/// Adapter to convert a list of [MithrilStakeDistribution] to [MithrilStakeDistributionListMessage] instances
7+
pub struct ToMithrilStakeDistributionListMessageAdapter;
8+
9+
impl MessageAdapter<Vec<MithrilStakeDistribution>, MithrilStakeDistributionListMessage>
10+
for ToMithrilStakeDistributionListMessageAdapter
11+
{
12+
/// Method to trigger the conversion
13+
fn adapt(snapshots: Vec<MithrilStakeDistribution>) -> MithrilStakeDistributionListMessage {
14+
snapshots
15+
.into_iter()
16+
.map(
17+
|stake_distribution| MithrilStakeDistributionListItemMessage {
18+
epoch: stake_distribution.epoch,
19+
hash: stake_distribution.hash,
20+
},
21+
)
22+
.collect()
23+
}
24+
}
25+
26+
#[cfg(test)]
27+
mod tests {
28+
use mithril_common::{entities::Epoch, test_utils::fake_data::signers_with_stakes};
29+
30+
use super::*;
31+
32+
#[test]
33+
fn adapt_ok() {
34+
let mithril_stake_distribution = MithrilStakeDistribution {
35+
epoch: Epoch(1),
36+
signers_with_stake: signers_with_stakes(1),
37+
hash: "hash-123".to_string(),
38+
};
39+
let mithril_stake_distribution_list_message =
40+
ToMithrilStakeDistributionListMessageAdapter::adapt(vec![mithril_stake_distribution]);
41+
let mithril_stake_distribution_list_message_expected =
42+
vec![MithrilStakeDistributionListItemMessage {
43+
epoch: Epoch(1),
44+
hash: "hash-123".to_string(),
45+
}];
46+
47+
assert_eq!(
48+
mithril_stake_distribution_list_message_expected,
49+
mithril_stake_distribution_list_message
50+
);
51+
}
52+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use mithril_common::entities::MithrilStakeDistribution;
2+
use mithril_common::messages::{MessageAdapter, MithrilStakeDistributionMessage};
3+
4+
/// Adapter to convert [MithrilStakeDistribution] to [MithrilStakeDistributionMessage] instances
5+
pub struct ToMithrilStakeDistributionMessageAdapter;
6+
7+
impl MessageAdapter<MithrilStakeDistribution, MithrilStakeDistributionMessage>
8+
for ToMithrilStakeDistributionMessageAdapter
9+
{
10+
/// Method to trigger the conversion
11+
fn adapt(from: MithrilStakeDistribution) -> MithrilStakeDistributionMessage {
12+
MithrilStakeDistributionMessage {
13+
epoch: from.epoch,
14+
signers_with_stake: from.signers_with_stake,
15+
hash: from.hash,
16+
}
17+
}
18+
}
19+
20+
#[cfg(test)]
21+
mod tests {
22+
use mithril_common::{entities::Epoch, test_utils::fake_data};
23+
24+
use super::*;
25+
26+
#[test]
27+
fn adapt_ok() {
28+
let mithril_stake_distribution = MithrilStakeDistribution {
29+
epoch: Epoch(1),
30+
signers_with_stake: fake_data::signers_with_stakes(2),
31+
hash: "hash-123".to_string(),
32+
};
33+
let mithril_stake_distribution_message_expected = MithrilStakeDistributionMessage {
34+
epoch: Epoch(1),
35+
signers_with_stake: fake_data::signers_with_stakes(2),
36+
hash: "hash-123".to_string(),
37+
};
38+
let mithril_stake_distribution_message =
39+
ToMithrilStakeDistributionMessageAdapter::adapt(mithril_stake_distribution);
40+
41+
assert_eq!(
42+
mithril_stake_distribution_message_expected,
43+
mithril_stake_distribution_message
44+
);
45+
}
46+
}

mithril-aggregator/src/message_adapters/to_snapshot_list_message.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use mithril_common::entities::Snapshot;
2-
use mithril_common::messages::{SnapshotListItemMessage, SnapshotListMessage};
2+
use mithril_common::messages::{MessageAdapter, SnapshotListItemMessage, SnapshotListMessage};
33

44
/// Adapter to convert a list of [Snapshot] to [SnapshotListMessage] instances
55
pub struct ToSnapshotListMessageAdapter;
66

7-
impl ToSnapshotListMessageAdapter {
7+
impl MessageAdapter<Vec<Snapshot>, SnapshotListMessage> for ToSnapshotListMessageAdapter {
88
/// Method to trigger the conversion
9-
pub fn adapt(snapshots: Vec<Snapshot>) -> SnapshotListMessage {
9+
fn adapt(snapshots: Vec<Snapshot>) -> SnapshotListMessage {
1010
snapshots
1111
.into_iter()
1212
.map(|snapshot| SnapshotListItemMessage {

mithril-aggregator/src/message_adapters/to_snasphot_message.rs renamed to mithril-aggregator/src/message_adapters/to_snapshot_message.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use mithril_common::entities::Snapshot;
2-
use mithril_common::messages::SnapshotMessage;
2+
use mithril_common::messages::{MessageAdapter, SnapshotMessage};
33

44
/// Adapter to convert [Snapshot] to [SnapshotMessage] instances
55
pub struct ToSnapshotMessageAdapter;
66

7-
impl ToSnapshotMessageAdapter {
7+
impl MessageAdapter<Snapshot, SnapshotMessage> for ToSnapshotMessageAdapter {
88
/// Method to trigger the conversion
9-
pub fn adapt(snapshot: Snapshot) -> SnapshotMessage {
9+
fn adapt(snapshot: Snapshot) -> SnapshotMessage {
1010
SnapshotMessage {
1111
digest: snapshot.digest,
1212
beacon: snapshot.beacon,
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
use serde::{Deserialize, Serialize};
2+
use sha2::{Digest, Sha256};
3+
4+
use crate::{
5+
entities::{Epoch, SignerWithStake},
6+
signable_builder::Artifact,
7+
};
8+
9+
/// Mithril Stake Distribution
10+
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
11+
pub struct MithrilStakeDistribution {
12+
/// Epoch at which the Mithril Stake Distribution is created
13+
pub epoch: Epoch,
14+
15+
/// List of signers with stakes of the Mithril Stake Distribution
16+
pub signers_with_stake: Vec<SignerWithStake>,
17+
18+
/// Hash of the Mithril Stake Distribution (different from the AVK).
19+
pub hash: String,
20+
}
21+
22+
impl MithrilStakeDistribution {
23+
/// MithrilStakeDistribution artifact factory
24+
pub fn new(epoch: Epoch, signers_with_stake: Vec<SignerWithStake>) -> Self {
25+
let mut signers_with_stake_sorted = signers_with_stake;
26+
signers_with_stake_sorted.sort();
27+
let mut mithril_stake_distribution = Self {
28+
epoch,
29+
signers_with_stake: signers_with_stake_sorted,
30+
hash: "".to_string(),
31+
};
32+
mithril_stake_distribution.hash = mithril_stake_distribution.compute_hash();
33+
mithril_stake_distribution
34+
}
35+
36+
fn compute_hash(&self) -> String {
37+
let mut hasher = Sha256::new();
38+
hasher.update(self.epoch.0.to_be_bytes());
39+
for signer_with_stake in &self.signers_with_stake {
40+
hasher.update(signer_with_stake.compute_hash().as_bytes());
41+
}
42+
hex::encode(hasher.finalize())
43+
}
44+
}
45+
46+
#[typetag::serde]
47+
impl Artifact for MithrilStakeDistribution {
48+
fn get_id(&self) -> String {
49+
self.hash.clone()
50+
}
51+
}

mithril-common/src/entities/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod certificate_pending;
88
mod epoch;
99
mod epoch_settings;
1010
mod http_server_error;
11+
mod mithril_stake_distribution;
1112
mod protocol_message;
1213
mod protocol_parameters;
1314
mod signed_entity_type;
@@ -24,6 +25,7 @@ pub use certificate_pending::CertificatePending;
2425
pub use epoch::{Epoch, EpochError};
2526
pub use epoch_settings::EpochSettings;
2627
pub use http_server_error::{ClientError, InternalServerError};
28+
pub use mithril_stake_distribution::MithrilStakeDistribution;
2729
pub use protocol_message::{ProtocolMessage, ProtocolMessagePartKey, ProtocolMessagePartValue};
2830
pub use protocol_parameters::ProtocolParameters;
2931
pub use signed_entity_type::*;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
use serde::{Deserialize, Serialize};
2+
3+
/// Message adapter trait
4+
pub trait MessageAdapter<U, V: Serialize + for<'a> Deserialize<'a>> {
5+
/// Adapt entity to message
6+
fn adapt(from: U) -> V;
7+
}

0 commit comments

Comments
 (0)