Skip to content

Commit e7611c0

Browse files
committed
fix: no error during protocol message creation if SNARK AVK is missing
1 parent 1030e12 commit e7611c0

2 files changed

Lines changed: 99 additions & 19 deletions

File tree

mithril-aggregator/src/services/signable_builder/signable_seed_builder.rs

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,12 @@ impl SignableSeedBuilder for AggregatorSignableSeedBuilder {
5959
return Ok(None);
6060
}
6161

62-
let snark_avk = (*epoch_service)
62+
let Some(snark_avk) = (*epoch_service)
6363
.next_aggregate_verification_key()?
6464
.to_snark_aggregate_verification_key()
65-
.ok_or_else(|| {
66-
anyhow::anyhow!(
67-
"SNARK aggregate verification key is unavailable during Lagrange era"
68-
)
69-
})?;
65+
else {
66+
return Ok(None);
67+
};
7068
let next_aggregate_verification_key = ProtocolKey::new(snark_avk.to_owned())
7169
.to_bytes_hex()
7270
.with_context(|| "convert next snark avk to bytes hex failure")?;
@@ -98,7 +96,7 @@ impl SignableSeedBuilder for AggregatorSignableSeedBuilder {
9896
#[cfg(test)]
9997
mod tests {
10098
use mithril_common::{
101-
entities::{Epoch, SupportedEra},
99+
entities::{Epoch, SignerWithStake, SupportedEra},
102100
test::{
103101
builder::{MithrilFixture, MithrilFixtureBuilder},
104102
double::Dummy,
@@ -192,6 +190,48 @@ mod tests {
192190
);
193191
}
194192

193+
#[cfg(feature = "future_snark")]
194+
#[tokio::test]
195+
async fn compute_next_snark_avk_returns_none_when_snark_avk_unavailable_during_lagrange_era() {
196+
let epoch = Epoch(5);
197+
let fixture = MithrilFixtureBuilder::default().with_signers(5).build();
198+
let next_fixture = MithrilFixtureBuilder::default().with_signers(4).build();
199+
let next_signers_without_snark =
200+
SignerWithStake::strip_snark_fields(next_fixture.signers_with_stake());
201+
let epoch_service = Arc::new(RwLock::new(
202+
FakeEpochServiceBuilder {
203+
current_epoch_settings: AggregatorEpochSettings {
204+
protocol_parameters: fixture.protocol_parameters(),
205+
..AggregatorEpochSettings::dummy()
206+
},
207+
next_epoch_settings: AggregatorEpochSettings {
208+
protocol_parameters: next_fixture.protocol_parameters(),
209+
..AggregatorEpochSettings::dummy()
210+
},
211+
signer_registration_epoch_settings: AggregatorEpochSettings {
212+
protocol_parameters: next_fixture.protocol_parameters(),
213+
..AggregatorEpochSettings::dummy()
214+
},
215+
current_signers_with_stake: fixture.signers_with_stake(),
216+
next_signers_with_stake: next_signers_without_snark,
217+
mithril_era: SupportedEra::Lagrange,
218+
..FakeEpochServiceBuilder::dummy(epoch)
219+
}
220+
.build(),
221+
));
222+
let signable_seed_builder = AggregatorSignableSeedBuilder::new(epoch_service);
223+
224+
let result = signable_seed_builder
225+
.compute_next_aggregate_verification_key_for_snark()
226+
.await
227+
.unwrap();
228+
229+
assert!(
230+
result.is_none(),
231+
"SNARK AVK should not be computed when SNARK is not yet set up during Lagrange era"
232+
);
233+
}
234+
195235
#[cfg(feature = "future_snark")]
196236
#[tokio::test]
197237
async fn compute_next_snark_avk_returns_value_during_lagrange_era() {

mithril-signer/src/services/signable_builder/signable_seed_builder.rs

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ impl SignerSignableSeedBuilder {
6666
&self,
6767
protocol_initializer: ProtocolInitializer,
6868
signers_with_stake: &[SignerWithStake],
69-
) -> StdResult<String> {
69+
) -> StdResult<Option<String>> {
7070
let signer_builder = SignerBuilder::new(
7171
signers_with_stake,
7272
&protocol_initializer.get_protocol_parameters().into(),
@@ -76,19 +76,16 @@ impl SignerSignableSeedBuilder {
7676
)?;
7777

7878
let aggregate_verification_key = signer_builder.compute_aggregate_verification_key();
79-
let snark_avk = aggregate_verification_key
80-
.to_snark_aggregate_verification_key()
81-
.ok_or_else(|| {
82-
anyhow::anyhow!(
83-
"SNARK aggregate verification key is unavailable during Lagrange era"
84-
)
85-
})?;
79+
let Some(snark_avk) = aggregate_verification_key.to_snark_aggregate_verification_key()
80+
else {
81+
return Ok(None);
82+
};
8683
let snark_avk_encoded =
8784
ProtocolKey::new(snark_avk.to_owned()).to_bytes_hex().with_context(
8885
|| "SignerSignableSeedBuilder can not serialize SNARK aggregate verification key",
8986
)?;
9087

91-
Ok(snark_avk_encoded)
88+
Ok(Some(snark_avk_encoded))
9289
}
9390
}
9491

@@ -137,9 +134,8 @@ impl SignableSeedBuilder for SignerSignableSeedBuilder {
137134
)
138135
})?;
139136
let next_signers_with_stake = epoch_service.next_signers_with_stake().await?;
140-
let next_snark_aggregate_verification_key = Some(
141-
self.compute_encode_snark_avk(next_protocol_initializer, &next_signers_with_stake)?,
142-
);
137+
let next_snark_aggregate_verification_key =
138+
self.compute_encode_snark_avk(next_protocol_initializer, &next_signers_with_stake)?;
143139

144140
Ok(next_snark_aggregate_verification_key)
145141
}
@@ -342,6 +338,50 @@ mod tests {
342338
assert_eq!(result, Some(expected_snark_avk));
343339
}
344340

341+
#[tokio::test]
342+
async fn returns_none_when_snark_avk_unavailable_during_lagrange_era() {
343+
use mithril_common::entities::SignerWithStake;
344+
345+
let epoch = Epoch(5);
346+
let next_fixture = MithrilFixtureBuilder::default().with_signers(4).build();
347+
let protocol_initializer =
348+
next_fixture.signers_fixture()[0].protocol_initializer.clone();
349+
let next_signers_without_snark =
350+
SignerWithStake::strip_snark_fields(next_fixture.signers_with_stake());
351+
let mut mock_container = MockDependencyInjector::new();
352+
mock_container.mock_epoch_service =
353+
MockEpochServiceImpl::new_with_config(|mock_epoch_service| {
354+
mock_epoch_service
355+
.expect_mithril_era()
356+
.return_once(move || Ok(SupportedEra::Lagrange))
357+
.once();
358+
mock_epoch_service
359+
.expect_epoch_of_current_data()
360+
.return_once(move || Ok(epoch))
361+
.once();
362+
mock_epoch_service
363+
.expect_next_signers_with_stake()
364+
.return_once(move || Ok(next_signers_without_snark))
365+
.once();
366+
});
367+
mock_container
368+
.mock_protocol_initializer_store
369+
.expect_get_protocol_initializer()
370+
.return_once(move |_| Ok(Some(protocol_initializer)))
371+
.once();
372+
let signable_seed_builder = mock_container.build_signable_builder_service();
373+
374+
let result = signable_seed_builder
375+
.compute_next_aggregate_verification_key_for_snark()
376+
.await
377+
.unwrap();
378+
379+
assert!(
380+
result.is_none(),
381+
"SNARK AVK should not be computed when SNARK is not yet set up during Lagrange era"
382+
);
383+
}
384+
345385
#[tokio::test]
346386
async fn returns_none_during_pythagoras_era() {
347387
let mut mock_container = MockDependencyInjector::new();

0 commit comments

Comments
 (0)