mithril_aggregator/services/signable_builder/
signable_seed_builder.rs
1use anyhow::Context;
7use async_trait::async_trait;
8use std::sync::Arc;
9use tokio::sync::RwLock;
10
11use mithril_common::{
12 entities::ProtocolMessagePartValue, signable_builder::SignableSeedBuilder, StdResult,
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_utils::{MithrilFixture, MithrilFixtureBuilder},
62 };
63
64 use crate::{entities::AggregatorEpochSettings, services::FakeEpochServiceBuilder};
65
66 use super::*;
67
68 fn build_signable_builder_service(
69 epoch: Epoch,
70 fixture: &MithrilFixture,
71 next_fixture: &MithrilFixture,
72 ) -> AggregatorSignableSeedBuilder {
73 let epoch_service = Arc::new(RwLock::new(
74 FakeEpochServiceBuilder {
75 current_epoch_settings: AggregatorEpochSettings {
76 protocol_parameters: fixture.protocol_parameters(),
77 ..AggregatorEpochSettings::dummy()
78 },
79 next_epoch_settings: AggregatorEpochSettings {
80 protocol_parameters: next_fixture.protocol_parameters(),
81 ..AggregatorEpochSettings::dummy()
82 },
83 signer_registration_epoch_settings: AggregatorEpochSettings {
84 protocol_parameters: next_fixture.protocol_parameters(),
85 ..AggregatorEpochSettings::dummy()
86 },
87 current_signers_with_stake: fixture.signers_with_stake(),
88 next_signers_with_stake: next_fixture.signers_with_stake(),
89 ..FakeEpochServiceBuilder::dummy(epoch)
90 }
91 .build(),
92 ));
93
94 AggregatorSignableSeedBuilder::new(epoch_service)
95 }
96
97 #[tokio::test]
98 async fn test_compute_next_aggregate_verification_key_protocol_message_value() {
99 let epoch = Epoch(5);
100 let fixture = MithrilFixtureBuilder::default().with_signers(5).build();
101 let next_fixture = MithrilFixtureBuilder::default().with_signers(4).build();
102 let signable_seed_builder = build_signable_builder_service(epoch, &fixture, &next_fixture);
103 let expected_next_aggregate_verification_key = next_fixture.compute_and_encode_avk();
104
105 let next_aggregate_verification_key = signable_seed_builder
106 .compute_next_aggregate_verification_key()
107 .await
108 .unwrap();
109
110 assert_eq!(
111 next_aggregate_verification_key,
112 expected_next_aggregate_verification_key
113 );
114 }
115
116 #[tokio::test]
117 async fn test_compute_next_protocol_parameters_protocol_message_value() {
118 let epoch = Epoch(5);
119 let fixture = MithrilFixtureBuilder::default().with_signers(5).build();
120 let next_fixture = MithrilFixtureBuilder::default().with_signers(4).build();
121 let signable_seed_builder = build_signable_builder_service(epoch, &fixture, &next_fixture);
122 let expected_next_protocol_parameters = next_fixture.protocol_parameters().compute_hash();
123
124 let next_protocol_parameters = signable_seed_builder
125 .compute_next_protocol_parameters()
126 .await
127 .unwrap();
128
129 assert_eq!(next_protocol_parameters, expected_next_protocol_parameters);
130 }
131
132 #[tokio::test]
133 async fn test_compute_current_epoch_protocol_message_value() {
134 let epoch = Epoch(5);
135 let fixture = MithrilFixtureBuilder::default().with_signers(5).build();
136 let next_fixture = MithrilFixtureBuilder::default().with_signers(4).build();
137 let signable_seed_builder = build_signable_builder_service(epoch, &fixture, &next_fixture);
138 let expected_current_epoch = epoch.to_string();
139
140 let current_epoch = signable_seed_builder.compute_current_epoch().await.unwrap();
141
142 assert_eq!(current_epoch, expected_current_epoch);
143 }
144}