Skip to content

Commit fed370b

Browse files
committed
Remove multi-signature from multi-signer state
1 parent 9086b7c commit fed370b

File tree

6 files changed

+72
-82
lines changed

6 files changed

+72
-82
lines changed

mithril-aggregator/src/multi_signer.rs

Lines changed: 7 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,6 @@ pub trait MultiSigner: Sync + Send {
191191
signatures: &entities::SingleSignatures,
192192
) -> Result<(), ProtocolError>;
193193

194-
/// Retrieves a multi signature from a message
195-
async fn get_multi_signature(&self) -> Result<Option<ProtocolMultiSignature>, ProtocolError>;
196-
197194
/// Creates a multi signature from single signatures
198195
async fn create_multi_signature(
199196
&mut self,
@@ -211,9 +208,6 @@ pub struct MultiSignerImpl {
211208
/// Signing start datetime of current message
212209
current_initiated_at: Option<DateTime<Utc>>,
213210

214-
/// Created multi signature for message signed
215-
multi_signature: Option<ProtocolMultiSignature>,
216-
217211
/// Verification key store
218212
verification_key_store: Arc<VerificationKeyStore>,
219213

@@ -240,7 +234,6 @@ impl MultiSignerImpl {
240234
current_message: None,
241235
current_beacon: None,
242236
current_initiated_at: None,
243-
multi_signature: None,
244237
verification_key_store,
245238
stake_store,
246239
single_signature_store,
@@ -349,7 +342,6 @@ impl MultiSigner for MultiSignerImpl {
349342
) -> Result<(), ProtocolError> {
350343
debug!("Update current_message"; "protocol_message" => #?message, "signed message" => message.compute_hash().encode_hex::<String>());
351344

352-
self.multi_signature = None;
353345
self.current_initiated_at = Some(Utc::now());
354346
self.current_message = Some(message);
355347
Ok(())
@@ -602,12 +594,6 @@ impl MultiSigner for MultiSignerImpl {
602594
};
603595
}
604596

605-
/// Retrieves a multi signature from a message
606-
async fn get_multi_signature(&self) -> Result<Option<ProtocolMultiSignature>, ProtocolError> {
607-
debug!("Get multi signature");
608-
Ok(self.multi_signature.to_owned())
609-
}
610-
611597
/// Creates a multi signature from single signatures
612598
async fn create_multi_signature(
613599
&mut self,
@@ -649,10 +635,7 @@ impl MultiSigner for MultiSignerImpl {
649635
.ok_or_else(ProtocolError::UnavailableClerk)?;
650636

651637
match clerk.aggregate(&signatures, message.compute_hash().as_bytes()) {
652-
Ok(multi_signature) => {
653-
self.multi_signature = Some(multi_signature.clone());
654-
Ok(Some(multi_signature))
655-
}
638+
Ok(multi_signature) => Ok(Some(multi_signature)),
656639
Err(ProtocolAggregationError::NotEnoughSignatures(actual, expected)) => {
657640
warn!("Could not compute multi-signature: Not enough signatures. Got only {} out of {}.", actual, expected);
658641
Ok(None)
@@ -916,14 +899,10 @@ mod tests {
916899
);
917900

918901
// No signatures registered: multi-signer can't create the multi-signature
919-
multi_signer
920-
.create_multi_signature()
921-
.await
922-
.expect("create multi signature should not fail");
923902
assert!(multi_signer
924-
.get_multi_signature()
903+
.create_multi_signature()
925904
.await
926-
.expect("get multi signature should not fail")
905+
.expect("create multi signature should not fail")
927906
.is_none());
928907

929908
// Add some signatures but not enough to reach the quorum: multi-signer should not create the multi-signature
@@ -933,14 +912,10 @@ mod tests {
933912
.await
934913
.expect("register single signature should not fail");
935914
}
936-
multi_signer
937-
.create_multi_signature()
938-
.await
939-
.expect("create multi signature should not fail");
940915
assert!(multi_signer
941-
.get_multi_signature()
916+
.create_multi_signature()
942917
.await
943-
.expect("get multi signature should not fail")
918+
.expect("create multi signature should not fail")
944919
.is_none());
945920

946921
// Add the remaining signatures to reach the quorum: multi-signer should create a multi-signature
@@ -950,15 +925,11 @@ mod tests {
950925
.await
951926
.expect("register single signature should not fail");
952927
}
953-
multi_signer
954-
.create_multi_signature()
955-
.await
956-
.expect("create multi signature should not fail");
957928
assert!(
958929
multi_signer
959-
.get_multi_signature()
930+
.create_multi_signature()
960931
.await
961-
.expect("get multi signature should not fail")
932+
.expect("create multi signature should not fail")
962933
.is_some(),
963934
"no multi-signature were computed"
964935
);

mithril-aggregator/src/runtime/runner.rs

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use async_trait::async_trait;
22
use chrono::Utc;
3+
use mithril_common::crypto_helper::ProtocolMultiSignature;
34
use mithril_common::entities::Epoch;
45
use mithril_common::entities::PartyId;
56
use mithril_common::store::StakeStorer;
6-
use slog_scope::{debug, info, warn};
7+
use slog_scope::{debug, warn};
78

89
use mithril_common::crypto_helper::ProtocolStakeDistribution;
910
use mithril_common::entities::{
@@ -134,8 +135,10 @@ pub trait AggregatorRunnerTrait: Sync + Send {
134135
&self,
135136
) -> Result<Option<CertificatePending>, Box<dyn StdError + Sync + Send>>;
136137

137-
/// Check if the multisigner has issued a multi-signature.
138-
async fn is_multisig_created(&self) -> Result<bool, Box<dyn StdError + Sync + Send>>;
138+
/// Create multi-signature.
139+
async fn create_multi_signature(
140+
&self,
141+
) -> Result<Option<ProtocolMultiSignature>, Box<dyn StdError + Sync + Send>>;
139142

140143
/// Create an archive of the cardano node db directory naming it after the given beacon.
141144
///
@@ -157,6 +160,7 @@ pub trait AggregatorRunnerTrait: Sync + Send {
157160
async fn create_and_save_certificate(
158161
&self,
159162
working_certificate: &WorkingCertificate,
163+
multi_signature: ProtocolMultiSignature,
160164
) -> Result<Certificate, Box<dyn StdError + Sync + Send>>;
161165

162166
/// Create a snapshot and save it to the given locations.
@@ -546,25 +550,18 @@ impl AggregatorRunnerTrait for AggregatorRunner {
546550
Ok(certificate_pending)
547551
}
548552

549-
/// Is a multi-signature ready?
550-
/// Can we create a multi-signature.
551-
async fn is_multisig_created(&self) -> Result<bool, Box<dyn StdError + Sync + Send>> {
552-
debug!("RUNNER: check if we can create a multi-signature");
553-
let has_multisig = self
553+
async fn create_multi_signature(
554+
&self,
555+
) -> Result<Option<ProtocolMultiSignature>, Box<dyn StdError + Sync + Send>> {
556+
debug!("RUNNER: create multi-signature");
557+
558+
Ok(self
554559
.dependencies
555560
.multi_signer
556561
.write()
557562
.await
558563
.create_multi_signature()
559-
.await?
560-
.is_some();
561-
562-
if has_multisig {
563-
debug!(" > new multi-signature created");
564-
} else {
565-
info!(" > no multi-signature created");
566-
}
567-
Ok(has_multisig)
564+
.await?)
568565
}
569566

570567
async fn create_snapshot_archive(
@@ -633,10 +630,10 @@ impl AggregatorRunnerTrait for AggregatorRunner {
633630
async fn create_and_save_certificate(
634631
&self,
635632
working_certificate: &WorkingCertificate,
633+
multi_signature: ProtocolMultiSignature,
636634
) -> Result<Certificate, Box<dyn StdError + Sync + Send>> {
637635
debug!("RUNNER: create and save certificate");
638636
let certificate_store = self.dependencies.certificate_store.clone();
639-
let multisigner = self.dependencies.multi_signer.read().await;
640637
let signatures_party_ids: Vec<PartyId> = self
641638
.dependencies
642639
.single_signature_store
@@ -645,12 +642,6 @@ impl AggregatorRunnerTrait for AggregatorRunner {
645642
.unwrap_or_default()
646643
.into_keys()
647644
.collect::<Vec<_>>();
648-
let multi_signature = multisigner.get_multi_signature().await?.ok_or_else(|| {
649-
RunnerError::NoComputedMultiSignature(format!(
650-
"no multi signature generated for beacon {:?}",
651-
working_certificate.beacon
652-
))
653-
})?;
654645

655646
let certificate = MithrilCertificateCreator::create_certificate(
656647
working_certificate,
@@ -1183,6 +1174,7 @@ pub mod tests {
11831174
let first_certificate = certificate_chain[0].clone();
11841175
let multi_signature: ProtocolMultiSignature =
11851176
key_decode_hex(&first_certificate.multi_signature as &HexEncodedKey).unwrap();
1177+
let multi_signature_clone = multi_signature.clone();
11861178
let working_certificate = WorkingCertificate {
11871179
beacon: first_certificate.beacon.clone(),
11881180
signers: first_certificate.metadata.signers.clone(),
@@ -1193,16 +1185,13 @@ pub mod tests {
11931185
..WorkingCertificate::fake()
11941186
};
11951187
let (mut deps, config) = initialize_dependencies().await;
1196-
let mut mock_multi_signer = MockMultiSigner::new();
1197-
mock_multi_signer
1198-
.expect_get_multi_signature()
1199-
.return_once(move || Ok(Some(multi_signature)));
1188+
let mock_multi_signer = MockMultiSigner::new();
12001189
deps.multi_signer = Arc::new(RwLock::new(mock_multi_signer));
12011190
deps.init_state_from_chain(&certificate_chain, vec![]).await;
12021191
let runner = AggregatorRunner::new(config, Arc::new(deps));
12031192

12041193
let certificate = runner
1205-
.create_and_save_certificate(&working_certificate)
1194+
.create_and_save_certificate(&working_certificate, multi_signature_clone)
12061195
.await;
12071196
certificate.expect("a certificate should have been created and saved");
12081197
}

mithril-aggregator/src/runtime/state_machine.rs

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -215,14 +215,12 @@ impl AggregatorRuntime {
215215
.transition_from_signing_to_idle_new_beacon(state)
216216
.await?;
217217
self.state = AggregatorState::Idle(new_state);
218-
} else if self.runner.is_multisig_created().await? {
219-
info!("→ a multi-signature have been created, build a snapshot & a certificate and transitioning back to IDLE");
220-
let new_state = self
221-
.transition_from_signing_to_idle_multisignature(state)
222-
.await?;
223-
self.state = AggregatorState::Idle(new_state);
224218
} else {
225-
info!(" ⋅ not enough signature yet to aggregate a multi-signature, waiting…");
219+
let new_state = self
220+
.transition_from_signing_to_idle_multisignature(state)
221+
.await?;
222+
info!("→ a multi-signature have been created, build a snapshot & a certificate and transitioning back to IDLE");
223+
self.state = AggregatorState::Idle(new_state);
226224
}
227225
}
228226
}
@@ -270,6 +268,18 @@ impl AggregatorRuntime {
270268
state: SigningState,
271269
) -> Result<IdleState, RuntimeError> {
272270
trace!("launching transition from SIGNING to IDLE state");
271+
let multi_signature = self.runner.create_multi_signature().await?;
272+
273+
let multi_signature = if multi_signature.is_none() {
274+
return Err(RuntimeError::Critical {
275+
message: "not enough signature yet to aggregate a multi-signature, waiting…"
276+
.to_string(),
277+
nested_error: None,
278+
});
279+
} else {
280+
multi_signature.unwrap()
281+
};
282+
273283
self.runner.drop_pending_certificate().await?;
274284
let ongoing_snapshot = self
275285
.runner
@@ -281,7 +291,7 @@ impl AggregatorRuntime {
281291
.await?;
282292
let certificate = self
283293
.runner
284-
.create_and_save_certificate(&state.working_certificate)
294+
.create_and_save_certificate(&state.working_certificate, multi_signature)
285295
.await?;
286296
let _ = self
287297
.runner
@@ -349,6 +359,9 @@ mod tests {
349359
use super::super::runner::MockAggregatorRunner;
350360
use super::*;
351361

362+
use mithril_common::crypto_helper::tests_setup::setup_certificate_chain;
363+
use mithril_common::crypto_helper::{key_decode_hex, ProtocolMultiSignature};
364+
use mithril_common::entities::HexEncodedKey;
352365
use mithril_common::era::UnsupportedEraError;
353366
use mithril_common::test_utils::fake_data;
354367
use mockall::predicate;
@@ -632,30 +645,36 @@ mod tests {
632645
.once()
633646
.returning(|| Ok(fake_data::beacon()));
634647
runner
635-
.expect_is_multisig_created()
648+
.expect_create_multi_signature()
636649
.once()
637-
.returning(|| Ok(false));
650+
.returning(|| Ok(None));
638651
let state = SigningState {
639652
current_beacon: fake_data::beacon(),
640653
working_certificate: WorkingCertificate::fake(),
641654
};
642655
let mut runtime = init_runtime(Some(AggregatorState::Signing(state)), runner).await;
643-
runtime.cycle().await.unwrap();
656+
runtime
657+
.cycle()
658+
.await
659+
.expect_err("cycle should have returned an error");
644660

645661
assert_eq!("signing".to_string(), runtime.get_state());
646662
}
647663

648664
#[tokio::test]
649665
async fn signing_multisig_is_created() {
666+
let (certificate_chain, _) = setup_certificate_chain(5, 1);
667+
let first_certificate = certificate_chain[0].clone();
668+
let multi_signature: ProtocolMultiSignature =
669+
key_decode_hex(&first_certificate.multi_signature as &HexEncodedKey).unwrap();
650670
let mut runner = MockAggregatorRunner::new();
651671
runner
652672
.expect_get_beacon_from_chain()
653673
.once()
654674
.returning(|| Ok(fake_data::beacon()));
655675
runner
656-
.expect_is_multisig_created()
657-
.once()
658-
.returning(|| Ok(true));
676+
.expect_create_multi_signature()
677+
.return_once(move || Ok(Some(multi_signature)));
659678
runner
660679
.expect_drop_pending_certificate()
661680
.once()
@@ -676,7 +695,7 @@ mod tests {
676695
runner
677696
.expect_create_and_save_certificate()
678697
.once()
679-
.returning(|_| Ok(fake_data::certificate("whatever".to_string())));
698+
.returning(|_, _| Ok(fake_data::certificate("whatever".to_string())));
680699
runner
681700
.expect_create_and_save_snapshot()
682701
.once()

mithril-aggregator/tests/certificate_chain.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ async fn certificate_chain() {
5151
cycle!(tester, "ready");
5252
cycle!(tester, "signing");
5353
tester.register_signers(&signers).await.unwrap();
54-
cycle!(tester, "signing");
54+
cycle_err!(tester, "signing");
5555
tester.send_single_signatures(&signers).await.unwrap();
5656

5757
comment!("The state machine should have issued a multisignature");

mithril-aggregator/tests/create_certificate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ async fn create_certificate() {
4949

5050
comment!("register signers");
5151
tester.register_signers(&signers).await.unwrap();
52-
cycle!(tester, "signing");
52+
cycle_err!(tester, "signing");
5353

5454
comment!("change the immutable number to alter the beacon");
5555
tester.increase_immutable_number().await.unwrap();

mithril-aggregator/tests/test_extensions/runtime_tester.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,17 @@ macro_rules! cycle {
3131
}};
3232
}
3333

34+
#[macro_export]
35+
macro_rules! cycle_err {
36+
( $tester:expr, $expected_state:expr ) => {{
37+
$tester
38+
.cycle()
39+
.await
40+
.expect_err("cycle tick shoudl have returned an error");
41+
assert_eq!($expected_state, $tester.runtime.get_state());
42+
}};
43+
}
44+
3445
pub struct RuntimeTester {
3546
pub snapshot_uploader: Arc<DumbSnapshotUploader>,
3647
pub chain_observer: Arc<FakeObserver>,

0 commit comments

Comments
 (0)