Skip to content

Commit ab9d05b

Browse files
authored
Merge pull request #877 from input-output-hk/jpraynaud/873-fix-verification-key-discrepancy
Fix Signer Registration Discrepancy
2 parents e262899 + e1cd99d commit ab9d05b

File tree

18 files changed

+280
-56
lines changed

18 files changed

+280
-56
lines changed

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mithril-aggregator/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mithril-aggregator"
3-
version = "0.3.1"
3+
version = "0.3.2"
44
description = "A Mithril Aggregator server"
55
authors = { workspace = true }
66
edition = { workspace = true }

mithril-aggregator/src/http_server/routes/signer_routes.rs

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,25 @@ mod handlers {
5454
"⇄ HTTP SERVER: register_signer/{:?}",
5555
register_signer_message
5656
);
57+
58+
let registration_epoch = match register_signer_message.epoch {
59+
Some(epoch) => epoch,
60+
None => match signer_registerer.get_current_round().await {
61+
Some(round) => round.epoch,
62+
None => {
63+
let err = SignerRegistrationError::RegistrationRoundNotYetOpened;
64+
warn!("register_signer::error"; "error" => ?err);
65+
return Ok(reply::internal_server_error(err.to_string()));
66+
}
67+
},
68+
};
69+
5770
let signer = FromRegisterSignerAdapter::adapt(register_signer_message);
5871
let mut headers: Vec<(&str, &str)> = match signer_node_version.as_ref() {
5972
Some(version) => vec![("signer-node-version", version)],
6073
None => Vec::new(),
6174
};
75+
6276
let epoch_str = match beacon_provider.get_current_beacon().await {
6377
Ok(beacon) => format!("{}", beacon.epoch),
6478
Err(e) => {
@@ -67,11 +81,14 @@ mod handlers {
6781
String::new()
6882
}
6983
};
70-
7184
if !epoch_str.is_empty() {
7285
headers.push(("epoch", epoch_str.as_str()));
7386
}
74-
match signer_registerer.register_signer(&signer).await {
87+
88+
match signer_registerer
89+
.register_signer(registration_epoch, &signer)
90+
.await
91+
{
7592
Ok(signer_with_stake) => {
7693
let _ = event_transmitter.send_event_message(
7794
"HTTP::signer_register",
@@ -147,7 +164,10 @@ mod tests {
147164
let mut mock_signer_registerer = MockSignerRegisterer::new();
148165
mock_signer_registerer
149166
.expect_register_signer()
150-
.return_once(|_| Ok(signer_with_stake));
167+
.return_once(|_, _| Ok(signer_with_stake));
168+
mock_signer_registerer
169+
.expect_get_current_round()
170+
.return_once(|| None);
151171
let (mut dependency_manager, _) = initialize_dependencies().await;
152172
dependency_manager.signer_registerer = Arc::new(mock_signer_registerer);
153173

@@ -179,7 +199,10 @@ mod tests {
179199
let mut mock_signer_registerer = MockSignerRegisterer::new();
180200
mock_signer_registerer
181201
.expect_register_signer()
182-
.return_once(|_| Err(SignerRegistrationError::ExistingSigner(signer_with_stake)));
202+
.return_once(|_, _| Err(SignerRegistrationError::ExistingSigner(signer_with_stake)));
203+
mock_signer_registerer
204+
.expect_get_current_round()
205+
.return_once(|| None);
183206
let (mut dependency_manager, _) = initialize_dependencies().await;
184207
dependency_manager.signer_registerer = Arc::new(mock_signer_registerer);
185208

@@ -210,11 +233,14 @@ mod tests {
210233
let mut mock_signer_registerer = MockSignerRegisterer::new();
211234
mock_signer_registerer
212235
.expect_register_signer()
213-
.return_once(|_| {
236+
.return_once(|_, _| {
214237
Err(SignerRegistrationError::FailedSignerRegistration(
215238
ProtocolRegistrationError::OpCertInvalid,
216239
))
217240
});
241+
mock_signer_registerer
242+
.expect_get_current_round()
243+
.return_once(|| None);
218244
let (mut dependency_manager, _) = initialize_dependencies().await;
219245
dependency_manager.signer_registerer = Arc::new(mock_signer_registerer);
220246

@@ -245,11 +271,14 @@ mod tests {
245271
let mut mock_signer_registerer = MockSignerRegisterer::new();
246272
mock_signer_registerer
247273
.expect_register_signer()
248-
.return_once(|_| {
274+
.return_once(|_, _| {
249275
Err(SignerRegistrationError::ChainObserver(
250276
"an error occurred".to_string(),
251277
))
252278
});
279+
mock_signer_registerer
280+
.expect_get_current_round()
281+
.return_once(|| None);
253282
let (mut dependency_manager, _) = initialize_dependencies().await;
254283
dependency_manager.signer_registerer = Arc::new(mock_signer_registerer);
255284

mithril-aggregator/src/signer_registerer.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ pub enum SignerRegistrationError {
2424
#[error("a signer registration round has not yet to be opened")]
2525
RegistrationRoundNotYetOpened,
2626

27+
/// Registration round for unexpected epoch
28+
#[error("unexpected signer registration round epoch: current_round_epoch: {current_round_epoch}, received_epoch: {received_epoch}")]
29+
RegistrationRoundUnexpectedEpoch {
30+
/// Epoch of the current round
31+
current_round_epoch: Epoch,
32+
/// Epoch of the received signer registration
33+
received_epoch: Epoch,
34+
},
35+
2736
/// Codec error.
2837
#[error("codec error: '{0}'")]
2938
Codec(String),
@@ -52,7 +61,9 @@ pub enum SignerRegistrationError {
5261
/// Represents the information needed to handle a signer registration round
5362
#[derive(Debug, Clone, PartialEq, Eq)]
5463
pub struct SignerRegistrationRound {
55-
epoch: Epoch,
64+
/// Registration round epoch
65+
pub epoch: Epoch,
66+
5667
stake_distribution: StakeDistribution,
5768
}
5869

@@ -73,8 +84,12 @@ pub trait SignerRegisterer: Sync + Send {
7384
/// Register a signer
7485
async fn register_signer(
7586
&self,
87+
epoch: Epoch,
7688
signer: &Signer,
7789
) -> Result<SignerWithStake, SignerRegistrationError>;
90+
91+
/// Get current open round if exists
92+
async fn get_current_round(&self) -> Option<SignerRegistrationRound>;
7893
}
7994

8095
/// Trait to open a signer registration round
@@ -171,12 +186,19 @@ impl SignerRegistrationRoundOpener for MithrilSignerRegisterer {
171186
impl SignerRegisterer for MithrilSignerRegisterer {
172187
async fn register_signer(
173188
&self,
189+
epoch: Epoch,
174190
signer: &Signer,
175191
) -> Result<SignerWithStake, SignerRegistrationError> {
176192
let registration_round = self.current_round.read().await;
177193
let registration_round = registration_round
178194
.as_ref()
179195
.ok_or(SignerRegistrationError::RegistrationRoundNotYetOpened)?;
196+
if registration_round.epoch != epoch {
197+
return Err(SignerRegistrationError::RegistrationRoundUnexpectedEpoch {
198+
current_round_epoch: registration_round.epoch,
199+
received_epoch: epoch,
200+
});
201+
}
180202

181203
let mut key_registration = ProtocolKeyRegistration::init(
182204
&registration_round
@@ -245,6 +267,10 @@ impl SignerRegisterer for MithrilSignerRegisterer {
245267
None => Ok(signer_save),
246268
}
247269
}
270+
271+
async fn get_current_round(&self) -> Option<SignerRegistrationRound> {
272+
self.current_round.read().await.as_ref().cloned()
273+
}
248274
}
249275

250276
#[cfg(test)]
@@ -293,7 +319,7 @@ mod tests {
293319
.expect("signer registration round opening should not fail");
294320

295321
signer_registerer
296-
.register_signer(&signer_to_register)
322+
.register_signer(registration_epoch, &signer_to_register)
297323
.await
298324
.expect("signer registration should not fail");
299325

@@ -342,7 +368,7 @@ mod tests {
342368
.expect("signer registration round opening should not fail");
343369

344370
signer_registerer
345-
.register_signer(&signer_to_register)
371+
.register_signer(registration_epoch, &signer_to_register)
346372
.await
347373
.expect("signer registration should not fail");
348374

@@ -373,11 +399,12 @@ mod tests {
373399
verification_key_store.clone(),
374400
Arc::new(signer_recorder),
375401
);
402+
let registration_epoch = Epoch(1);
376403
let fixture = MithrilFixtureBuilder::default().with_signers(5).build();
377404
let signer_to_register: Signer = fixture.signers()[0].to_owned();
378405

379406
signer_registerer
380-
.register_signer(&signer_to_register)
407+
.register_signer(registration_epoch, &signer_to_register)
381408
.await
382409
.expect_err("signer registration should fail if no round opened");
383410
}

mithril-aggregator/tests/certificate_chain.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ async fn certificate_chain() {
193193
current_epoch = tester.increase_epoch().await.unwrap();
194194
tester.increase_immutable_number().await.unwrap();
195195
cycle!(tester, "ready");
196+
tester.register_signers(&signers).await.unwrap();
196197
cycle!(tester, "signing");
197198

198199
let signed_entity_type = tester
@@ -214,6 +215,7 @@ async fn certificate_chain() {
214215
tester.increase_epoch().await.unwrap();
215216
tester.increase_immutable_number().await.unwrap();
216217
cycle!(tester, "ready");
218+
tester.register_signers(&signers).await.unwrap();
217219
cycle!(tester, "signing");
218220
let signed_entity_type = tester
219221
.open_message_observer

mithril-aggregator/tests/test_extensions/runtime_tester.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use tokio::sync::mpsc::UnboundedReceiver;
1313
use crate::test_extensions::open_message_observer::OpenMessageObserver;
1414
use mithril_aggregator::{
1515
AggregatorRuntime, Configuration, DumbSnapshotUploader, DumbSnapshotter,
16-
ProtocolParametersStorer, SignerRegisterer,
16+
ProtocolParametersStorer, SignerRegisterer, SignerRegistrationError,
1717
};
1818
use mithril_common::crypto_helper::{ProtocolClerk, ProtocolGenesisSigner};
1919
use mithril_common::digesters::DumbImmutableFileObserver;
@@ -248,14 +248,27 @@ impl RuntimeTester {
248248

249249
/// Register the given signers in the registerer
250250
pub async fn register_signers(&mut self, signers: &[SignerFixture]) -> Result<(), String> {
251+
let registration_epoch = self
252+
.chain_observer
253+
.current_beacon
254+
.read()
255+
.await
256+
.as_ref()
257+
.unwrap()
258+
.epoch
259+
.offset_to_recording_epoch();
260+
let signer_registerer = self.deps_builder.get_mithril_registerer().await.unwrap();
251261
for signer_with_stake in signers.iter().map(|f| &f.signer_with_stake) {
252-
self.deps_builder
253-
.get_mithril_registerer()
262+
match signer_registerer
263+
.register_signer(registration_epoch, &signer_with_stake.to_owned().into())
254264
.await
255-
.unwrap()
256-
.register_signer(&signer_with_stake.to_owned().into())
257-
.await
258-
.map_err(|e| format!("Registering a signer should not fail: {e:?}"))?;
265+
{
266+
Ok(_) => {}
267+
Err(SignerRegistrationError::ExistingSigner(_)) => {}
268+
Err(e) => {
269+
return Err(format!("Registering a signer should not fail: {e:?}"));
270+
}
271+
}
259272
}
260273

261274
Ok(())

mithril-common/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mithril-common"
3-
version = "0.2.41"
3+
version = "0.2.42"
44
authors = { workspace = true }
55
edition = { workspace = true }
66
documentation = { workspace = true }

mithril-common/src/era/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,9 @@ mod supported_era;
88
pub use era_checker::EraChecker;
99
pub use era_reader::*;
1010
pub use supported_era::*;
11+
12+
/// Macro used to mark the code that should be cleaned up when the new era is activated
13+
#[macro_export]
14+
macro_rules! era_deprecate {
15+
( $comment:literal ) => {};
16+
}

mithril-common/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub mod crypto_helper;
1818
pub mod database;
1919
pub mod digesters;
2020
pub mod entities;
21+
#[macro_use]
2122
pub mod era;
2223
pub mod messages;
2324
pub mod signable_builder;

mithril-common/src/messages/register_signature.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use serde::{Deserialize, Serialize};
22

33
use crate::entities::{HexEncodedSingleSignature, LotteryIndex, PartyId, SignedEntityType};
44

5+
era_deprecate!("make signed_entity_type of RegisterSignatureMessage not optional");
56
/// Message structure to register single signature.
67
#[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize)]
78
pub struct RegisterSignatureMessage {

0 commit comments

Comments
 (0)