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