mithril_aggregator/services/signable_builder/
signable_seed_builder.rs1use anyhow::Context;
7use async_trait::async_trait;
8use std::sync::Arc;
9use tokio::sync::RwLock;
10
11use mithril_common::{
12 StdResult, crypto_helper::ProtocolKey, entities::ProtocolMessagePartValue,
13 signable_builder::SignableSeedBuilder,
14};
15
16use crate::services::EpochService;
17
18pub struct AggregatorSignableSeedBuilder {
20 epoch_service: Arc<RwLock<dyn EpochService>>,
21}
22
23impl AggregatorSignableSeedBuilder {
24 pub fn new(epoch_service: Arc<RwLock<dyn EpochService>>) -> Self {
26 Self { epoch_service }
27 }
28}
29
30#[async_trait]
31impl SignableSeedBuilder for AggregatorSignableSeedBuilder {
32 async fn compute_next_aggregate_verification_key_for_concatenation(
33 &self,
34 ) -> StdResult<ProtocolMessagePartValue> {
35 let epoch_service = self.epoch_service.read().await;
36 let next_aggregate_verification_key = ProtocolKey::new(
37 (*epoch_service)
38 .next_aggregate_verification_key()?
39 .to_concatenation_aggregate_verification_key()
40 .to_owned(),
41 )
42 .to_json_hex()
43 .with_context(|| "convert next avk to json hex failure")?
44 .to_string();
45
46 Ok(next_aggregate_verification_key)
47 }
48
49 async fn compute_next_protocol_parameters(&self) -> StdResult<ProtocolMessagePartValue> {
50 let epoch_service = self.epoch_service.read().await;
51 let next_protocol_parameters = epoch_service.next_protocol_parameters()?.compute_hash();
52
53 Ok(next_protocol_parameters)
54 }
55
56 async fn compute_current_epoch(&self) -> StdResult<ProtocolMessagePartValue> {
57 let epoch_service = self.epoch_service.read().await;
58 let current_epoch = epoch_service.epoch_of_current_data()?.to_string();
59
60 Ok(current_epoch)
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use mithril_common::{
67 entities::Epoch,
68 test::{
69 builder::{MithrilFixture, MithrilFixtureBuilder},
70 double::Dummy,
71 },
72 };
73
74 use crate::{entities::AggregatorEpochSettings, services::FakeEpochServiceBuilder};
75
76 use super::*;
77
78 fn build_signable_builder_service(
79 epoch: Epoch,
80 fixture: &MithrilFixture,
81 next_fixture: &MithrilFixture,
82 ) -> AggregatorSignableSeedBuilder {
83 let epoch_service = Arc::new(RwLock::new(
84 FakeEpochServiceBuilder {
85 current_epoch_settings: AggregatorEpochSettings {
86 protocol_parameters: fixture.protocol_parameters(),
87 ..AggregatorEpochSettings::dummy()
88 },
89 next_epoch_settings: AggregatorEpochSettings {
90 protocol_parameters: next_fixture.protocol_parameters(),
91 ..AggregatorEpochSettings::dummy()
92 },
93 signer_registration_epoch_settings: AggregatorEpochSettings {
94 protocol_parameters: next_fixture.protocol_parameters(),
95 ..AggregatorEpochSettings::dummy()
96 },
97 current_signers_with_stake: fixture.signers_with_stake(),
98 next_signers_with_stake: next_fixture.signers_with_stake(),
99 ..FakeEpochServiceBuilder::dummy(epoch)
100 }
101 .build(),
102 ));
103
104 AggregatorSignableSeedBuilder::new(epoch_service)
105 }
106
107 #[tokio::test]
108 async fn test_compute_next_aggregate_verification_key_protocol_message_value() {
109 let epoch = Epoch(5);
110 let fixture = MithrilFixtureBuilder::default().with_signers(5).build();
111 let next_fixture = MithrilFixtureBuilder::default().with_signers(4).build();
112 let signable_seed_builder = build_signable_builder_service(epoch, &fixture, &next_fixture);
113 let expected_next_aggregate_verification_key =
114 next_fixture.compute_and_encode_concatenation_aggregate_verification_key();
115
116 let next_aggregate_verification_key = signable_seed_builder
117 .compute_next_aggregate_verification_key_for_concatenation()
118 .await
119 .unwrap();
120
121 assert_eq!(
122 next_aggregate_verification_key,
123 expected_next_aggregate_verification_key
124 );
125 }
126
127 #[tokio::test]
128 async fn test_compute_next_protocol_parameters_protocol_message_value() {
129 let epoch = Epoch(5);
130 let fixture = MithrilFixtureBuilder::default().with_signers(5).build();
131 let next_fixture = MithrilFixtureBuilder::default().with_signers(4).build();
132 let signable_seed_builder = build_signable_builder_service(epoch, &fixture, &next_fixture);
133 let expected_next_protocol_parameters = next_fixture.protocol_parameters().compute_hash();
134
135 let next_protocol_parameters = signable_seed_builder
136 .compute_next_protocol_parameters()
137 .await
138 .unwrap();
139
140 assert_eq!(next_protocol_parameters, expected_next_protocol_parameters);
141 }
142
143 #[tokio::test]
144 async fn test_compute_current_epoch_protocol_message_value() {
145 let epoch = Epoch(5);
146 let fixture = MithrilFixtureBuilder::default().with_signers(5).build();
147 let next_fixture = MithrilFixtureBuilder::default().with_signers(4).build();
148 let signable_seed_builder = build_signable_builder_service(epoch, &fixture, &next_fixture);
149 let expected_current_epoch = epoch.to_string();
150
151 let current_epoch = signable_seed_builder.compute_current_epoch().await.unwrap();
152
153 assert_eq!(current_epoch, expected_current_epoch);
154 }
155}