diff --git a/mithril-common/src/fake_data.rs b/mithril-common/src/fake_data.rs index 38607d767e5..8a97c76c45c 100644 --- a/mithril-common/src/fake_data.rs +++ b/mithril-common/src/fake_data.rs @@ -1,5 +1,6 @@ #![allow(dead_code)] +use crate::digesters::DigesterResult; use std::time::{SystemTime, UNIX_EPOCH}; use crate::entities; @@ -26,6 +27,14 @@ pub fn digest(beacon: &entities::Beacon) -> Vec { .to_vec() } +/// Fake DigesterResult +pub fn digester_result(digest: &str) -> DigesterResult { + DigesterResult { + digest: digest.to_string(), + last_immutable_file_number: 0, + } +} + /// Fake ProtocolParameters pub fn protocol_parameters() -> entities::ProtocolParameters { let k = 5; diff --git a/mithril-signer/src/runtime.rs b/mithril-signer/src/runtime.rs index a70e86793ae..008b4b9f801 100644 --- a/mithril-signer/src/runtime.rs +++ b/mithril-signer/src/runtime.rs @@ -7,7 +7,7 @@ use tokio::time::sleep; use crate::certificate_handler::CertificateHandlerError; use crate::single_signer::SingleSignerError; use mithril_common::crypto_helper::{key_encode_hex, Bytes}; -use mithril_common::digesters::Digester; +use mithril_common::digesters::{Digester, DigesterError}; use mithril_common::entities::{self, Beacon, CertificatePending, SignerWithStake}; use mithril_common::fake_data; @@ -33,6 +33,8 @@ pub enum RuntimeError { RegisterSignerFailed(String), #[error("codec error:`{0}`")] Codec(String), + #[error("digest computation failed: `{0}`")] + Digester(#[from] DigesterError), } impl Runtime { @@ -66,12 +68,12 @@ impl Runtime { .retrieve_pending_certificate() .await? { - let message = fake_data::digest(&pending_certificate.beacon); - self.register_to_aggregator_if_needed().await?; if self.should_register_signature(&pending_certificate.beacon) { - self.register_signature(message, pending_certificate) + let message = self.digester.compute_digest()?; + info!("Signing digest"; "digester_result" => #?message); + self.register_signature(message.digest.into_bytes(), pending_certificate) .await?; } } @@ -81,8 +83,19 @@ impl Runtime { fn should_register_signature(&self, new_beacon: &Beacon) -> bool { match &self.current_beacon { - None => true, - Some(beacon) => beacon != new_beacon, + None => { + info!("Unknown beacon, signatures will be registered ..."); + true + } + Some(beacon) => { + if beacon != new_beacon { + info!("The beacon changed, signatures will be registered ..."); + true + } else { + info!("Signatures already registered for this beacon"); + false + } + } } } @@ -263,13 +276,16 @@ mod tests { .return_once(move || party_id); mock_single_signer .expect_get_protocol_initializer() - .return_once(move || Some(protocol_initializer.clone())); + .return_once(move || Some(protocol_initializer)); mock_single_signer .expect_get_is_registered() .return_once(|| false); mock_single_signer .expect_update_is_registered() .return_once(move |_| Ok(())); + mock_digester + .expect_compute_digest() + .return_once(|| Ok(fake_data::digester_result("digest"))); let mut signer = Runtime::new( Box::new(mock_certificate_handler), @@ -321,6 +337,9 @@ mod tests { mock_single_signer .expect_get_protocol_initializer() .return_once(move || Some(protocol_initializer.clone())); + mock_digester + .expect_compute_digest() + .return_once(|| Ok(fake_data::digester_result("digest"))); let mut signer = Runtime::new( Box::new(mock_certificate_handler), @@ -364,6 +383,9 @@ mod tests { mock_single_signer .expect_update_is_registered() .return_once(move |_| Ok(())); + mock_digester + .expect_compute_digest() + .return_once(|| Ok(fake_data::digester_result("digest"))); let mut signer = Runtime::new( Box::new(mock_certificate_handler), @@ -391,6 +413,9 @@ mod tests { mock_single_signer .expect_get_protocol_initializer() .return_once(move || None); + mock_digester + .expect_compute_digest() + .return_once(|| Ok(fake_data::digester_result("digest"))); let mut signer = Runtime::new( Box::new(mock_certificate_handler), @@ -414,7 +439,7 @@ mod tests { let pending_certificate = fake_data::certificate_pending(); let mut mock_certificate_handler = MockCertificateHandler::new(); let mut mock_single_signer = MockSingleSigner::new(); - let mut mock_digester = MockDigesterImpl::new(); + let mock_digester = MockDigesterImpl::new(); mock_certificate_handler .expect_retrieve_pending_certificate() .return_once(|| Ok(Some(pending_certificate))); @@ -452,4 +477,37 @@ mod tests { signer.run().await.unwrap_err().to_string() ); } + + #[tokio::test] + async fn signer_fails_if_digest_computation_fails() { + let mut mock_certificate_handler = MockCertificateHandler::new(); + let mut mock_single_signer = MockSingleSigner::new(); + let mut mock_digester = MockDigesterImpl::new(); + let pending_certificate = fake_data::certificate_pending(); + mock_certificate_handler + .expect_retrieve_pending_certificate() + .return_once(|| Ok(Some(pending_certificate))); + mock_single_signer + .expect_compute_single_signatures() + .never(); + mock_single_signer + .expect_get_is_registered() + .return_once(|| false); + mock_single_signer + .expect_get_protocol_initializer() + .return_once(move || None); + mock_digester + .expect_compute_digest() + .return_once(|| Err(DigesterError::NotEnoughImmutable())); + + let mut signer = Runtime::new( + Box::new(mock_certificate_handler), + Box::new(mock_single_signer), + Box::new(mock_digester), + ); + assert_eq!( + RuntimeError::Digester(DigesterError::NotEnoughImmutable()).to_string(), + signer.run().await.unwrap_err().to_string() + ); + } } diff --git a/mithril-test-lab/mithril-end-to-end/src/Mithril/Signer.hs b/mithril-test-lab/mithril-end-to-end/src/Mithril/Signer.hs index add2b70bec2..608d2b253e9 100644 --- a/mithril-test-lab/mithril-end-to-end/src/Mithril/Signer.hs +++ b/mithril-test-lab/mithril-end-to-end/src/Mithril/Signer.hs @@ -56,7 +56,8 @@ signerProcess cwd aggregatorEndpoint = do [ ("AGGREGATOR_ENDPOINT", toString aggregatorEndpoint), ("NETWORK", "testnet"), ("PARTY_ID", "0"), - ("RUN_INTERVAL", "2") + ("RUN_INTERVAL", "2"), + ("DB_DIRECTORY", "db") ] <> baseEnv diff --git a/mithril-test-lab/mithril-end-to-end/test/Test/EndToEndSpec.hs b/mithril-test-lab/mithril-end-to-end/test/Test/EndToEndSpec.hs index 0ec6ee4d422..c1df8577fde 100644 --- a/mithril-test-lab/mithril-end-to-end/test/Test/EndToEndSpec.hs +++ b/mithril-test-lab/mithril-end-to-end/test/Test/EndToEndSpec.hs @@ -62,7 +62,7 @@ spec = -- Start aggregator service on some random port withAggregator (takeDirectory nodeSocket) (contramap AggregatorLog tr) $ \aggregator@Aggregator {aggregatorPort} -> do waitForAggregator aggregatorPort - withSigner tmp (contramap SignerLog tr) aggregatorPort node $ \signer -> do + withSigner (takeDirectory nodeSocket) (contramap SignerLog tr) aggregatorPort node $ \signer -> do digest <- assertNodeIsProducingSnapshot tr node aggregatorPort assertSignerIsSigningSnapshot signer aggregatorPort digest assertClientCanVerifySnapshot tmp aggregator digest