From 5b3bcbe57975f922f75a3599800007270e4a525d Mon Sep 17 00:00:00 2001 From: Damien Lachaume <135982616+dlachaume@users.noreply.github.com> Date: Tue, 17 Sep 2024 12:04:36 +0200 Subject: [PATCH 1/9] feat: add `current_cardano_transactions_signing_config` to `EpochSettingsMessage` - Add optional `current_cardano_transactions_signing_config` field, used only when 'CardanoTransactions' is activated by the aggregator. - Add retro compatibility test with the original 'EpochSettingsMessage' structure, identified as 'Legacy', and the previous 'EpochSettingsMessage', identified as 'Previous'. --- mithril-common/src/messages/epoch_settings.rs | 80 ++++++++++++++++++- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/mithril-common/src/messages/epoch_settings.rs b/mithril-common/src/messages/epoch_settings.rs index d7bc3247d59..d091f3bd64a 100644 --- a/mithril-common/src/messages/epoch_settings.rs +++ b/mithril-common/src/messages/epoch_settings.rs @@ -1,4 +1,4 @@ -use crate::entities::{Epoch, ProtocolParameters}; +use crate::entities::{CardanoTransactionsSigningConfig, Epoch, ProtocolParameters}; use crate::messages::SignerMessagePart; use serde::{Deserialize, Serialize}; @@ -21,6 +21,10 @@ pub struct EpochSettingsMessage { /// Signers that will be able to sign on the next epoch pub next_signers: Vec, + + /// Cardano transactions signing configuration for the current epoch + #[serde(skip_serializing_if = "Option::is_none")] + pub current_cardano_transactions_signing_config: Option, } impl EpochSettingsMessage { @@ -41,6 +45,7 @@ impl EpochSettingsMessage { }, current_signers: [SignerMessagePart::dummy()].to_vec(), next_signers: [SignerMessagePart::dummy()].to_vec(), + current_cardano_transactions_signing_config: None, } } } @@ -49,6 +54,8 @@ impl EpochSettingsMessage { #[cfg(test)] mod tests { + use crate::entities::BlockNumber; + use super::*; const ACTUAL_JSON: &str = r#"{ @@ -68,10 +75,28 @@ mod tests { "verification_key_signature":"signature_456", "operational_certificate":"certificate_456", "kes_period":45 - }] + }], + "current_cardano_transactions_signing_config": { + "security_parameter": 70, + "step": 20 + } }"#; + #[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] + pub struct EpochSettingsMessageLegacyVersion { + /// Current Epoch + pub epoch: Epoch, + + /// Current Protocol parameters + #[serde(rename = "protocol")] + pub protocol_parameters: ProtocolParameters, + + /// Next Protocol parameters + #[serde(rename = "next_protocol")] + pub next_protocol_parameters: ProtocolParameters, + } + #[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] pub struct EpochSettingsMessagePreviousVersion { /// Current Epoch @@ -84,6 +109,28 @@ mod tests { /// Next Protocol parameters #[serde(rename = "next_protocol")] pub next_protocol_parameters: ProtocolParameters, + + /// Current Signers + pub current_signers: Vec, + + /// Signers that will be able to sign on the next epoch + pub next_signers: Vec, + } + + fn golden_legacy_message() -> EpochSettingsMessageLegacyVersion { + EpochSettingsMessageLegacyVersion { + epoch: Epoch(10), + protocol_parameters: ProtocolParameters { + k: 5, + m: 100, + phi_f: 0.65, + }, + next_protocol_parameters: ProtocolParameters { + k: 50, + m: 1000, + phi_f: 0.65, + }, + } } fn golden_previous_message() -> EpochSettingsMessagePreviousVersion { @@ -99,6 +146,20 @@ mod tests { m: 1000, phi_f: 0.65, }, + current_signers: vec![SignerMessagePart { + party_id: "123".to_string(), + verification_key: "key_123".to_string(), + verification_key_signature: Some("signature_123".to_string()), + operational_certificate: Some("certificate_123".to_string()), + kes_period: Some(12), + }], + next_signers: vec![SignerMessagePart { + party_id: "456".to_string(), + verification_key: "key_456".to_string(), + verification_key_signature: Some("signature_456".to_string()), + operational_certificate: Some("certificate_456".to_string()), + kes_period: Some(45), + }], } } @@ -129,9 +190,24 @@ mod tests { operational_certificate: Some("certificate_456".to_string()), kes_period: Some(45), }], + current_cardano_transactions_signing_config: Some(CardanoTransactionsSigningConfig { + security_parameter: BlockNumber(70), + step: BlockNumber(20), + }), } } + // Test the backward compatibility with legacy structure. + #[test] + fn test_actual_json_deserialized_into_legacy_message() { + let json = ACTUAL_JSON; + let message: EpochSettingsMessageLegacyVersion = serde_json::from_str(json).expect( + "This JSON is expected to be successfully parsed into a EpochSettingsMessageLegacyVersion instance.", + ); + + assert_eq!(golden_legacy_message(), message); + } + // Test the backward compatibility with previous structure. #[test] fn test_actual_json_deserialized_into_previous_message() { From 694734a71c2f1893a38ea3aa8910889cc2f4feeb Mon Sep 17 00:00:00 2001 From: Damien Lachaume <135982616+dlachaume@users.noreply.github.com> Date: Tue, 17 Sep 2024 12:01:06 +0200 Subject: [PATCH 2/9] feat: update OpenAPI specification Add new `current_cardano_transactions_signing_config` field which is returned by the '/epoch-settings' route. --- openapi.yaml | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/openapi.yaml b/openapi.yaml index 9f96bd7080d..10bb702aa55 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -733,6 +733,25 @@ components: type: array items: $ref: "#/components/schemas/Signer" + current_cardano_transactions_signing_config: + description: | + Cardano transactions signing configuration for the current epoch + + Mandatory if `signed_entity_types` from the Aggregator configuration contains `CardanoTransactions`. + type: object + additionalProperties: false + required: + - security_parameter + - step + properties: + security_parameter: + description: Number of blocks to discard from the tip of the chain when importing Cardano transactions + type: integer + format: int64 + step: + description: Number of blocks between signature of Cardano transactions + type: integer + format: int64 example: { "epoch": 329, @@ -771,7 +790,9 @@ components: "operational_certificate": "2c38382c3138372c3233332c34302c37322c31362c36365d2c312c3132332c5b31362c3136392c3134312c3138332c32322c3137342c3131312c33322c36342c35322c2c3232382c37392c3137352c32395312c3838282c323030", "kes_period": 876 } - ] + ], + "current_cardano_transactions_signing_config": + { "security_parameter": 100, "step": 10 } } ProtocolParameters: From ee63b2b88cfdb826323554fd532800fab58018f4 Mon Sep 17 00:00:00 2001 From: Damien Lachaume <135982616+dlachaume@users.noreply.github.com> Date: Tue, 17 Sep 2024 12:26:32 +0200 Subject: [PATCH 3/9] feat: update `/epoch-routes` with `current_cardano_transactions_signing_config` --- .../src/http_server/routes/epoch_routes.rs | 131 ++++++++++++++++-- 1 file changed, 122 insertions(+), 9 deletions(-) diff --git a/mithril-aggregator/src/http_server/routes/epoch_routes.rs b/mithril-aggregator/src/http_server/routes/epoch_routes.rs index 019609458cc..f4e12bbb50f 100644 --- a/mithril-aggregator/src/http_server/routes/epoch_routes.rs +++ b/mithril-aggregator/src/http_server/routes/epoch_routes.rs @@ -15,25 +15,42 @@ fn epoch_settings( ) -> impl Filter + Clone { warp::path!("epoch-settings") .and(warp::get()) - .and(middlewares::with_epoch_service(dependency_manager)) + .and(middlewares::with_epoch_service(dependency_manager.clone())) + .and(middlewares::with_signed_entity_config( + dependency_manager.clone(), + )) + .and(middlewares::with_config(dependency_manager)) .and_then(handlers::epoch_settings) } mod handlers { - use crate::dependency_injection::EpochServiceWrapper; - use crate::http_server::routes::reply; - use mithril_common::messages::{EpochSettingsMessage, SignerMessagePart}; - use slog_scope::{debug, warn}; use std::convert::Infallible; + + use slog_scope::{debug, warn}; use warp::http::StatusCode; + use mithril_common::{ + entities::{SignedEntityConfig, SignedEntityTypeDiscriminants}, + messages::{EpochSettingsMessage, SignerMessagePart}, + }; + + use crate::http_server::routes::reply; + use crate::{dependency_injection::EpochServiceWrapper, Configuration}; + /// Epoch Settings pub async fn epoch_settings( epoch_service: EpochServiceWrapper, + signed_entity_config: SignedEntityConfig, + configuration: Configuration, ) -> Result { debug!("⇄ HTTP SERVER: epoch_settings"); let epoch_service = epoch_service.read().await; + let current_cardano_transactions_signing_config = signed_entity_config + .list_allowed_signed_entity_types_discriminants() + .contains(&SignedEntityTypeDiscriminants::CardanoTransactions) + .then_some(configuration.cardano_transactions_signing_config); + match ( epoch_service.epoch_of_current_data(), epoch_service.next_protocol_parameters(), @@ -54,6 +71,7 @@ mod handlers { next_protocol_parameters: next_protocol_parameters.clone(), current_signers: SignerMessagePart::from_signers(current_signers.to_vec()), next_signers: SignerMessagePart::from_signers(next_signers.to_vec()), + current_cardano_transactions_signing_config, }; Ok(reply::json(&epoch_settings_message, StatusCode::OK)) } @@ -71,15 +89,21 @@ mod handlers { #[cfg(test)] mod tests { - use mithril_common::{ - entities::Epoch, - test_utils::{apispec::APISpec, MithrilFixtureBuilder}, - }; + use std::collections::BTreeSet; + use serde_json::Value::Null; use tokio::sync::RwLock; use warp::http::{Method, StatusCode}; use warp::test::request; + use mithril_common::{ + entities::{ + BlockNumber, CardanoTransactionsSigningConfig, Epoch, SignedEntityTypeDiscriminants, + }, + messages::EpochSettingsMessage, + test_utils::{apispec::APISpec, MithrilFixtureBuilder}, + }; + use crate::http_server::SERVER_BASE_PATH; use crate::initialize_dependencies; use crate::services::FakeEpochService; @@ -126,6 +150,95 @@ mod tests { .unwrap(); } + #[tokio::test] + async fn test_epoch_settings_get_ok_with_cardano_transactions_enabled() { + let method = Method::GET.as_str(); + let path = "/epoch-settings"; + let mut dependency_manager = initialize_dependencies().await; + let fixture = MithrilFixtureBuilder::default().with_signers(5).build(); + let epoch_service = FakeEpochService::from_fixture(Epoch(5), &fixture); + dependency_manager.epoch_service = Arc::new(RwLock::new(epoch_service)); + dependency_manager + .signed_entity_config + .allowed_discriminants = + BTreeSet::from([SignedEntityTypeDiscriminants::CardanoTransactions]); + let signing_config = CardanoTransactionsSigningConfig { + security_parameter: BlockNumber(70), + step: BlockNumber(15), + }; + dependency_manager + .config + .cardano_transactions_signing_config = signing_config.clone(); + + let response = request() + .method(method) + .path(&format!("/{SERVER_BASE_PATH}{path}")) + .reply(&setup_router(Arc::new(dependency_manager))) + .await; + + let response_body: EpochSettingsMessage = serde_json::from_slice(response.body()).unwrap(); + + assert_eq!( + response_body.current_cardano_transactions_signing_config, + Some(signing_config) + ); + + APISpec::verify_conformity( + APISpec::get_all_spec_files(), + method, + path, + "application/json", + &Null, + &response, + &StatusCode::OK, + ) + .unwrap(); + } + + #[tokio::test] + async fn test_epoch_settings_get_ok_with_cardano_transactions_not_enabled() { + let method = Method::GET.as_str(); + let path = "/epoch-settings"; + let mut dependency_manager = initialize_dependencies().await; + let fixture = MithrilFixtureBuilder::default().with_signers(5).build(); + let epoch_service = FakeEpochService::from_fixture(Epoch(5), &fixture); + dependency_manager.epoch_service = Arc::new(RwLock::new(epoch_service)); + dependency_manager + .signed_entity_config + .allowed_discriminants = BTreeSet::new(); + let signing_config = CardanoTransactionsSigningConfig { + security_parameter: BlockNumber(70), + step: BlockNumber(15), + }; + dependency_manager + .config + .cardano_transactions_signing_config = signing_config.clone(); + + let response = request() + .method(method) + .path(&format!("/{SERVER_BASE_PATH}{path}")) + .reply(&setup_router(Arc::new(dependency_manager))) + .await; + + let response_body: EpochSettingsMessage = serde_json::from_slice(response.body()).unwrap(); + + assert_eq!( + response_body.current_cardano_transactions_signing_config, + None + ); + + APISpec::verify_conformity( + APISpec::get_all_spec_files(), + method, + path, + "application/json", + &Null, + &response, + &StatusCode::OK, + ) + .unwrap(); + } + #[tokio::test] async fn test_epoch_settings_get_ko_500() { let method = Method::GET.as_str(); From 44f93b32bb3835c64cbb39f025943e6cb0acba03 Mon Sep 17 00:00:00 2001 From: Damien Lachaume <135982616+dlachaume@users.noreply.github.com> Date: Tue, 17 Sep 2024 16:35:55 +0200 Subject: [PATCH 4/9] feat: store `current_cardano_transactions_signing_config` in signer epoch service --- mithril-common/src/entities/epoch_settings.rs | 5 +++- mithril-common/src/messages/epoch_settings.rs | 2 +- mithril-common/src/test_utils/fake_data.rs | 5 ++++ .../message_adapters/from_epoch_settings.rs | 2 ++ mithril-signer/src/runtime/runner.rs | 10 ++++++- mithril-signer/src/runtime/state_machine.rs | 1 + mithril-signer/src/services/epoch_service.rs | 28 +++++++++++++++++++ 7 files changed, 50 insertions(+), 3 deletions(-) diff --git a/mithril-common/src/entities/epoch_settings.rs b/mithril-common/src/entities/epoch_settings.rs index 955f80ac037..47572250f7e 100644 --- a/mithril-common/src/entities/epoch_settings.rs +++ b/mithril-common/src/entities/epoch_settings.rs @@ -1,4 +1,4 @@ -use crate::entities::{Epoch, ProtocolParameters}; +use crate::entities::{CardanoTransactionsSigningConfig, Epoch, ProtocolParameters}; use super::Signer; @@ -19,4 +19,7 @@ pub struct EpochSettings { /// Signers that will be able to sign on the next epoch pub next_signers: Vec, + + /// Cardano transactions signing configuration for the current epoch + pub current_cardano_transactions_signing_config: Option, } diff --git a/mithril-common/src/messages/epoch_settings.rs b/mithril-common/src/messages/epoch_settings.rs index d091f3bd64a..3967008b281 100644 --- a/mithril-common/src/messages/epoch_settings.rs +++ b/mithril-common/src/messages/epoch_settings.rs @@ -45,7 +45,7 @@ impl EpochSettingsMessage { }, current_signers: [SignerMessagePart::dummy()].to_vec(), next_signers: [SignerMessagePart::dummy()].to_vec(), - current_cardano_transactions_signing_config: None, + current_cardano_transactions_signing_config: Some(CardanoTransactionsSigningConfig::dummy()), } } } diff --git a/mithril-common/src/test_utils/fake_data.rs b/mithril-common/src/test_utils/fake_data.rs index f76b952be51..b556d577de9 100644 --- a/mithril-common/src/test_utils/fake_data.rs +++ b/mithril-common/src/test_utils/fake_data.rs @@ -66,6 +66,10 @@ pub fn epoch_settings() -> entities::EpochSettings { let current_signers = signers[1..3].to_vec(); let next_signers = signers[2..5].to_vec(); + // Cardano transactions signing configuration for the current epoch + let current_cardano_transactions_signing_config = + Some(entities::CardanoTransactionsSigningConfig::dummy()); + // Epoch settings entities::EpochSettings { epoch: beacon.epoch, @@ -73,6 +77,7 @@ pub fn epoch_settings() -> entities::EpochSettings { next_protocol_parameters, current_signers, next_signers, + current_cardano_transactions_signing_config, } } diff --git a/mithril-signer/src/message_adapters/from_epoch_settings.rs b/mithril-signer/src/message_adapters/from_epoch_settings.rs index 99059bb37de..e7fc8c7b34f 100644 --- a/mithril-signer/src/message_adapters/from_epoch_settings.rs +++ b/mithril-signer/src/message_adapters/from_epoch_settings.rs @@ -19,6 +19,8 @@ impl TryFromMessageAdapter for FromEpochSet .with_context(|| "'FromMessageAdapter' can not convert the current signers")?, next_signers: SignerMessagePart::try_into_signers(message.next_signers) .with_context(|| "'FromMessageAdapter' can not convert the next signers")?, + current_cardano_transactions_signing_config: message + .current_cardano_transactions_signing_config, }; Ok(epoch_settings) } diff --git a/mithril-signer/src/runtime/runner.rs b/mithril-signer/src/runtime/runner.rs index 17581540bb5..4eb5075560f 100644 --- a/mithril-signer/src/runtime/runner.rs +++ b/mithril-signer/src/runtime/runner.rs @@ -458,7 +458,10 @@ mod tests { MKMap, MKMapNode, MKTreeNode, MKTreeStoreInMemory, MKTreeStorer, ProtocolInitializer, }, digesters::{DumbImmutableDigester, DumbImmutableFileObserver}, - entities::{BlockNumber, BlockRange, CardanoDbBeacon, Epoch, ProtocolParameters}, + entities::{ + BlockNumber, BlockRange, CardanoDbBeacon, CardanoTransactionsSigningConfig, Epoch, + ProtocolParameters, + }, era::{adapters::EraReaderBootstrapAdapter, EraChecker, EraReader}, signable_builder::{ BlockRangeRootRetriever, CardanoImmutableFilesFullSignableBuilder, @@ -545,6 +548,11 @@ mod tests { async fn next_signers_with_stake(&self) -> StdResult> { Ok(vec![]) } + fn current_cardano_transactions_signing_config( + &self, + ) -> StdResult<&Option> { + Ok(&None) + } fn is_signer_included_in_current_stake_distribution( &self, diff --git a/mithril-signer/src/runtime/state_machine.rs b/mithril-signer/src/runtime/state_machine.rs index 624c84cfeed..a3ba5c9351a 100644 --- a/mithril-signer/src/runtime/state_machine.rs +++ b/mithril-signer/src/runtime/state_machine.rs @@ -548,6 +548,7 @@ mod tests { next_protocol_parameters: fake_data::protocol_parameters(), current_signers: vec![], next_signers: vec![], + current_cardano_transactions_signing_config: None, }; let known_epoch = Epoch(4); runner diff --git a/mithril-signer/src/services/epoch_service.rs b/mithril-signer/src/services/epoch_service.rs index d0e8e2c114a..5cc10e08956 100644 --- a/mithril-signer/src/services/epoch_service.rs +++ b/mithril-signer/src/services/epoch_service.rs @@ -2,6 +2,7 @@ use std::sync::Arc; use async_trait::async_trait; use mithril_common::crypto_helper::ProtocolInitializer; +use mithril_common::entities::CardanoTransactionsSigningConfig; use mithril_common::entities::Epoch; use mithril_common::entities::PartyId; use mithril_common::entities::ProtocolParameters; @@ -49,6 +50,11 @@ pub trait EpochService: Sync + Send { /// Get signers with stake for the next epoch async fn next_signers_with_stake(&self) -> StdResult>; + /// Get the cardano transactions signing configuration for the current epoch + fn current_cardano_transactions_signing_config( + &self, + ) -> StdResult<&Option>; + /// Check if a signer is included in the current stake distribution fn is_signer_included_in_current_stake_distribution( &self, @@ -62,6 +68,7 @@ struct EpochData { next_protocol_parameters: ProtocolParameters, current_signers: Vec, next_signers: Vec, + current_cardano_transactions_signing_config: Option, } /// Implementation of the [epoch service][EpochService]. @@ -138,6 +145,8 @@ impl EpochService for MithrilEpochService { next_protocol_parameters: epoch_settings.next_protocol_parameters, current_signers: epoch_settings.current_signers, next_signers: epoch_settings.next_signers, + current_cardano_transactions_signing_config: epoch_settings + .current_cardano_transactions_signing_config, }); Ok(()) @@ -177,6 +186,14 @@ impl EpochService for MithrilEpochService { .await } + fn current_cardano_transactions_signing_config( + &self, + ) -> StdResult<&Option> { + Ok(&self + .unwrap_data()? + .current_cardano_transactions_signing_config) + } + fn is_signer_included_in_current_stake_distribution( &self, party_id: PartyId, @@ -302,6 +319,9 @@ mod tests { assert!(service.next_signers().is_err()); assert!(service.current_signers_with_stake().await.is_err()); assert!(service.next_signers_with_stake().await.is_err()); + assert!(service + .current_cardano_transactions_signing_config() + .is_err()); } #[test] @@ -350,6 +370,14 @@ mod tests { epoch_settings.next_protocol_parameters, *service.next_protocol_parameters().unwrap() ); + + // Check current_cardano_transactions_signing_config + assert_eq!( + epoch_settings.current_cardano_transactions_signing_config, + *service + .current_cardano_transactions_signing_config() + .unwrap() + ) } #[tokio::test] From 48c511595d14f23378828b1f8104cd1cfb9fe4aa Mon Sep 17 00:00:00 2001 From: Damien Lachaume <135982616+dlachaume@users.noreply.github.com> Date: Thu, 19 Sep 2024 17:21:27 +0200 Subject: [PATCH 5/9] feat: add `next_cardano_transactions_signing_config` to `EpochSettingsMessage` and rename `current_cardano_transactions_signing_config` to `cardano_transactions_signing_config` - refactor backward compatibility tests with the latest OpenAPI version supported by each structure - update OpenAPI specifications with `next_cardano_transactions_signing_config` and refactor by extracting to a dedicated 'CardanoTransactionsSigningConfig' component - make the '/epoch-settings' HTTP route return the correct data --- .../src/http_server/routes/epoch_routes.rs | 6 +- mithril-common/src/messages/epoch_settings.rs | 55 ++++++++++++------- openapi.yaml | 51 ++++++++++------- 3 files changed, 69 insertions(+), 43 deletions(-) diff --git a/mithril-aggregator/src/http_server/routes/epoch_routes.rs b/mithril-aggregator/src/http_server/routes/epoch_routes.rs index f4e12bbb50f..146b4df9249 100644 --- a/mithril-aggregator/src/http_server/routes/epoch_routes.rs +++ b/mithril-aggregator/src/http_server/routes/epoch_routes.rs @@ -46,7 +46,7 @@ mod handlers { debug!("⇄ HTTP SERVER: epoch_settings"); let epoch_service = epoch_service.read().await; - let current_cardano_transactions_signing_config = signed_entity_config + let cardano_transactions_signing_config = signed_entity_config .list_allowed_signed_entity_types_discriminants() .contains(&SignedEntityTypeDiscriminants::CardanoTransactions) .then_some(configuration.cardano_transactions_signing_config); @@ -71,7 +71,9 @@ mod handlers { next_protocol_parameters: next_protocol_parameters.clone(), current_signers: SignerMessagePart::from_signers(current_signers.to_vec()), next_signers: SignerMessagePart::from_signers(next_signers.to_vec()), - current_cardano_transactions_signing_config, + cardano_transactions_signing_config: cardano_transactions_signing_config + .clone(), + next_cardano_transactions_signing_config: cardano_transactions_signing_config, }; Ok(reply::json(&epoch_settings_message, StatusCode::OK)) } diff --git a/mithril-common/src/messages/epoch_settings.rs b/mithril-common/src/messages/epoch_settings.rs index 3967008b281..197da16944c 100644 --- a/mithril-common/src/messages/epoch_settings.rs +++ b/mithril-common/src/messages/epoch_settings.rs @@ -24,7 +24,11 @@ pub struct EpochSettingsMessage { /// Cardano transactions signing configuration for the current epoch #[serde(skip_serializing_if = "Option::is_none")] - pub current_cardano_transactions_signing_config: Option, + pub cardano_transactions_signing_config: Option, + + /// Cardano transactions signing configuration for the next epoch + #[serde(skip_serializing_if = "Option::is_none")] + pub next_cardano_transactions_signing_config: Option, } impl EpochSettingsMessage { @@ -45,7 +49,8 @@ impl EpochSettingsMessage { }, current_signers: [SignerMessagePart::dummy()].to_vec(), next_signers: [SignerMessagePart::dummy()].to_vec(), - current_cardano_transactions_signing_config: Some(CardanoTransactionsSigningConfig::dummy()), + cardano_transactions_signing_config: Some(CardanoTransactionsSigningConfig::dummy()), + next_cardano_transactions_signing_config: Some(CardanoTransactionsSigningConfig::dummy()), } } } @@ -76,15 +81,20 @@ mod tests { "operational_certificate":"certificate_456", "kes_period":45 }], - "current_cardano_transactions_signing_config": { + "cardano_transactions_signing_config": { "security_parameter": 70, "step": 20 + }, + "next_cardano_transactions_signing_config": { + "security_parameter": 50, + "step": 10 } }"#; + // Supported structure until OpenAPI version 0.1.28. #[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] - pub struct EpochSettingsMessageLegacyVersion { + pub struct EpochSettingsMessageUntilV0_1_28 { /// Current Epoch pub epoch: Epoch, @@ -97,8 +107,9 @@ mod tests { pub next_protocol_parameters: ProtocolParameters, } + // Supported structure until OpenAPI version 0.1.29. #[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] - pub struct EpochSettingsMessagePreviousVersion { + pub struct EpochSettingsMessageUntilV0_1_29 { /// Current Epoch pub epoch: Epoch, @@ -117,8 +128,8 @@ mod tests { pub next_signers: Vec, } - fn golden_legacy_message() -> EpochSettingsMessageLegacyVersion { - EpochSettingsMessageLegacyVersion { + fn golden_message_until_open_api_0_1_28() -> EpochSettingsMessageUntilV0_1_28 { + EpochSettingsMessageUntilV0_1_28 { epoch: Epoch(10), protocol_parameters: ProtocolParameters { k: 5, @@ -133,8 +144,8 @@ mod tests { } } - fn golden_previous_message() -> EpochSettingsMessagePreviousVersion { - EpochSettingsMessagePreviousVersion { + fn golden_message_until_open_api_0_1_29() -> EpochSettingsMessageUntilV0_1_29 { + EpochSettingsMessageUntilV0_1_29 { epoch: Epoch(10), protocol_parameters: ProtocolParameters { k: 5, @@ -190,33 +201,37 @@ mod tests { operational_certificate: Some("certificate_456".to_string()), kes_period: Some(45), }], - current_cardano_transactions_signing_config: Some(CardanoTransactionsSigningConfig { + cardano_transactions_signing_config: Some(CardanoTransactionsSigningConfig { security_parameter: BlockNumber(70), step: BlockNumber(20), }), + next_cardano_transactions_signing_config: Some(CardanoTransactionsSigningConfig { + security_parameter: BlockNumber(50), + step: BlockNumber(10), + }), } } - // Test the backward compatibility with legacy structure. + // Test the backward compatibility with the structure supported until OpenAPI version 0.1.28. #[test] - fn test_actual_json_deserialized_into_legacy_message() { + fn test_actual_json_deserialized_into_message_supported_until_open_api_0_1_28() { let json = ACTUAL_JSON; - let message: EpochSettingsMessageLegacyVersion = serde_json::from_str(json).expect( - "This JSON is expected to be successfully parsed into a EpochSettingsMessageLegacyVersion instance.", + let message: EpochSettingsMessageUntilV0_1_28 = serde_json::from_str(json).expect( + "This JSON is expected to be successfully parsed into a EpochSettingsMessageUntilVersion0_1_28 instance.", ); - assert_eq!(golden_legacy_message(), message); + assert_eq!(golden_message_until_open_api_0_1_28(), message); } - // Test the backward compatibility with previous structure. + // Test the backward compatibility with the structure supported until OpenAPI version 0.1.29. #[test] - fn test_actual_json_deserialized_into_previous_message() { + fn test_actual_json_deserialized_into_message_supported_until_open_api_0_1_29() { let json = ACTUAL_JSON; - let message: EpochSettingsMessagePreviousVersion = serde_json::from_str(json).expect( - "This JSON is expected to be successfully parsed into a EpochSettingsMessagePreviousVersion instance.", + let message: EpochSettingsMessageUntilV0_1_29 = serde_json::from_str(json).expect( + "This JSON is expected to be successfully parsed into a EpochSettingsMessageUntilVersion0_1_29 instance.", ); - assert_eq!(golden_previous_message(), message); + assert_eq!(golden_message_until_open_api_0_1_29(), message); } // Test the compatibility with current structure. diff --git a/openapi.yaml b/openapi.yaml index 10bb702aa55..63b5e49d30a 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -55,6 +55,10 @@ paths: Returns the information related to the current epoch: * protocol parameters for current epoch * protocol parameters for next epoch (to setup cryptography, allowing signers to register) + * signers for current epoch + * signers for next epoch + * cardano transactions signing configuration for current epoch + * cardano transactions signing configuration for next epoch responses: "200": description: epoch settings found @@ -733,25 +737,10 @@ components: type: array items: $ref: "#/components/schemas/Signer" - current_cardano_transactions_signing_config: - description: | - Cardano transactions signing configuration for the current epoch - - Mandatory if `signed_entity_types` from the Aggregator configuration contains `CardanoTransactions`. - type: object - additionalProperties: false - required: - - security_parameter - - step - properties: - security_parameter: - description: Number of blocks to discard from the tip of the chain when importing Cardano transactions - type: integer - format: int64 - step: - description: Number of blocks between signature of Cardano transactions - type: integer - format: int64 + cardano_transactions_signing_config: + $ref: "#/components/schemas/CardanoTransactionsSigningConfig" + next_cardano_transactions_signing_config: + $ref: "#/components/schemas/CardanoTransactionsSigningConfig" example: { "epoch": 329, @@ -791,8 +780,10 @@ components: "kes_period": 876 } ], - "current_cardano_transactions_signing_config": - { "security_parameter": 100, "step": 10 } + "cardano_transactions_signing_config": + { "security_parameter": 100, "step": 10 }, + "next_cardano_transactions_signing_config": + { "security_parameter": 50, "step": 5 } } ProtocolParameters: @@ -818,6 +809,24 @@ components: format: double example: { "k": 857, "m": 6172, "phi_f": 0.2 } + CardanoTransactionsSigningConfig: + description: Cardano transactions signing configuration + type: object + additionalProperties: false + required: + - security_parameter + - step + properties: + security_parameter: + description: Number of blocks to discard from the tip of the chain when importing Cardano transactions + type: integer + format: int64 + step: + description: Number of blocks between signature of Cardano transactions + type: integer + format: int64 + example: { "security_parameter": 100, "step": 10 } + CardanoDbBeacon: description: A point in the Cardano chain at which a Mithril certificate of the Cardano Database should be produced type: object From d4330bbc2c584e07a0b2c22cf462b3f4a4140fe2 Mon Sep 17 00:00:00 2001 From: Damien Lachaume <135982616+dlachaume@users.noreply.github.com> Date: Thu, 19 Sep 2024 17:23:00 +0200 Subject: [PATCH 6/9] feat: adapt signer with the new message structure --- mithril-common/src/entities/epoch_settings.rs | 5 +- mithril-common/src/test_utils/fake_data.rs | 9 ++-- .../message_adapters/from_epoch_settings.rs | 5 +- mithril-signer/src/runtime/runner.rs | 7 ++- mithril-signer/src/runtime/state_machine.rs | 3 +- mithril-signer/src/services/epoch_service.rs | 47 ++++++++++++------- 6 files changed, 51 insertions(+), 25 deletions(-) diff --git a/mithril-common/src/entities/epoch_settings.rs b/mithril-common/src/entities/epoch_settings.rs index 47572250f7e..b46e7c80137 100644 --- a/mithril-common/src/entities/epoch_settings.rs +++ b/mithril-common/src/entities/epoch_settings.rs @@ -21,5 +21,8 @@ pub struct EpochSettings { pub next_signers: Vec, /// Cardano transactions signing configuration for the current epoch - pub current_cardano_transactions_signing_config: Option, + pub cardano_transactions_signing_config: Option, + + /// Cardano transactions signing configuration for the next epoch + pub next_cardano_transactions_signing_config: Option, } diff --git a/mithril-common/src/test_utils/fake_data.rs b/mithril-common/src/test_utils/fake_data.rs index b556d577de9..a4a409c1c9c 100644 --- a/mithril-common/src/test_utils/fake_data.rs +++ b/mithril-common/src/test_utils/fake_data.rs @@ -66,8 +66,10 @@ pub fn epoch_settings() -> entities::EpochSettings { let current_signers = signers[1..3].to_vec(); let next_signers = signers[2..5].to_vec(); - // Cardano transactions signing configuration for the current epoch - let current_cardano_transactions_signing_config = + // Cardano transactions signing configuration + let cardano_transactions_signing_config = + Some(entities::CardanoTransactionsSigningConfig::dummy()); + let next_cardano_transactions_signing_config = Some(entities::CardanoTransactionsSigningConfig::dummy()); // Epoch settings @@ -77,7 +79,8 @@ pub fn epoch_settings() -> entities::EpochSettings { next_protocol_parameters, current_signers, next_signers, - current_cardano_transactions_signing_config, + cardano_transactions_signing_config, + next_cardano_transactions_signing_config, } } diff --git a/mithril-signer/src/message_adapters/from_epoch_settings.rs b/mithril-signer/src/message_adapters/from_epoch_settings.rs index e7fc8c7b34f..5e04f973e20 100644 --- a/mithril-signer/src/message_adapters/from_epoch_settings.rs +++ b/mithril-signer/src/message_adapters/from_epoch_settings.rs @@ -19,8 +19,9 @@ impl TryFromMessageAdapter for FromEpochSet .with_context(|| "'FromMessageAdapter' can not convert the current signers")?, next_signers: SignerMessagePart::try_into_signers(message.next_signers) .with_context(|| "'FromMessageAdapter' can not convert the next signers")?, - current_cardano_transactions_signing_config: message - .current_cardano_transactions_signing_config, + cardano_transactions_signing_config: message.cardano_transactions_signing_config, + next_cardano_transactions_signing_config: message + .next_cardano_transactions_signing_config, }; Ok(epoch_settings) } diff --git a/mithril-signer/src/runtime/runner.rs b/mithril-signer/src/runtime/runner.rs index 4eb5075560f..2927a1b8378 100644 --- a/mithril-signer/src/runtime/runner.rs +++ b/mithril-signer/src/runtime/runner.rs @@ -548,7 +548,12 @@ mod tests { async fn next_signers_with_stake(&self) -> StdResult> { Ok(vec![]) } - fn current_cardano_transactions_signing_config( + fn cardano_transactions_signing_config( + &self, + ) -> StdResult<&Option> { + Ok(&None) + } + fn next_cardano_transactions_signing_config( &self, ) -> StdResult<&Option> { Ok(&None) diff --git a/mithril-signer/src/runtime/state_machine.rs b/mithril-signer/src/runtime/state_machine.rs index a3ba5c9351a..7e3147260c6 100644 --- a/mithril-signer/src/runtime/state_machine.rs +++ b/mithril-signer/src/runtime/state_machine.rs @@ -548,7 +548,8 @@ mod tests { next_protocol_parameters: fake_data::protocol_parameters(), current_signers: vec![], next_signers: vec![], - current_cardano_transactions_signing_config: None, + cardano_transactions_signing_config: None, + next_cardano_transactions_signing_config: None, }; let known_epoch = Epoch(4); runner diff --git a/mithril-signer/src/services/epoch_service.rs b/mithril-signer/src/services/epoch_service.rs index 5cc10e08956..efa9a9fe856 100644 --- a/mithril-signer/src/services/epoch_service.rs +++ b/mithril-signer/src/services/epoch_service.rs @@ -51,7 +51,12 @@ pub trait EpochService: Sync + Send { async fn next_signers_with_stake(&self) -> StdResult>; /// Get the cardano transactions signing configuration for the current epoch - fn current_cardano_transactions_signing_config( + fn cardano_transactions_signing_config( + &self, + ) -> StdResult<&Option>; + + /// Get the cardano transactions signing configuration for the next epoch + fn next_cardano_transactions_signing_config( &self, ) -> StdResult<&Option>; @@ -68,7 +73,8 @@ struct EpochData { next_protocol_parameters: ProtocolParameters, current_signers: Vec, next_signers: Vec, - current_cardano_transactions_signing_config: Option, + cardano_transactions_signing_config: Option, + next_cardano_transactions_signing_config: Option, } /// Implementation of the [epoch service][EpochService]. @@ -145,8 +151,9 @@ impl EpochService for MithrilEpochService { next_protocol_parameters: epoch_settings.next_protocol_parameters, current_signers: epoch_settings.current_signers, next_signers: epoch_settings.next_signers, - current_cardano_transactions_signing_config: epoch_settings - .current_cardano_transactions_signing_config, + cardano_transactions_signing_config: epoch_settings.cardano_transactions_signing_config, + next_cardano_transactions_signing_config: epoch_settings + .next_cardano_transactions_signing_config, }); Ok(()) @@ -186,12 +193,16 @@ impl EpochService for MithrilEpochService { .await } - fn current_cardano_transactions_signing_config( + fn cardano_transactions_signing_config( + &self, + ) -> StdResult<&Option> { + Ok(&self.unwrap_data()?.cardano_transactions_signing_config) + } + + fn next_cardano_transactions_signing_config( &self, ) -> StdResult<&Option> { - Ok(&self - .unwrap_data()? - .current_cardano_transactions_signing_config) + Ok(&self.unwrap_data()?.next_cardano_transactions_signing_config) } fn is_signer_included_in_current_stake_distribution( @@ -319,9 +330,8 @@ mod tests { assert!(service.next_signers().is_err()); assert!(service.current_signers_with_stake().await.is_err()); assert!(service.next_signers_with_stake().await.is_err()); - assert!(service - .current_cardano_transactions_signing_config() - .is_err()); + assert!(service.cardano_transactions_signing_config().is_err()); + assert!(service.next_cardano_transactions_signing_config().is_err()); } #[test] @@ -371,13 +381,16 @@ mod tests { *service.next_protocol_parameters().unwrap() ); - // Check current_cardano_transactions_signing_config + // Check cardano_transactions_signing_config assert_eq!( - epoch_settings.current_cardano_transactions_signing_config, - *service - .current_cardano_transactions_signing_config() - .unwrap() - ) + epoch_settings.cardano_transactions_signing_config, + *service.cardano_transactions_signing_config().unwrap() + ); + // Check next_cardano_transactions_signing_config + assert_eq!( + epoch_settings.next_cardano_transactions_signing_config, + *service.next_cardano_transactions_signing_config().unwrap() + ); } #[tokio::test] From 72766c9a7fa15427586fbbc4aae5104208b77b36 Mon Sep 17 00:00:00 2001 From: Damien Lachaume <135982616+dlachaume@users.noreply.github.com> Date: Thu, 19 Sep 2024 18:25:22 +0200 Subject: [PATCH 7/9] refactor: remove unnecessary dependencies, refactor 'epoch_settings' function by separating responsibilities MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sébastien Fauvel --- .../src/http_server/routes/epoch_routes.rs | 241 ++++++++---------- 1 file changed, 103 insertions(+), 138 deletions(-) diff --git a/mithril-aggregator/src/http_server/routes/epoch_routes.rs b/mithril-aggregator/src/http_server/routes/epoch_routes.rs index 146b4df9249..7aa6bbe93b3 100644 --- a/mithril-aggregator/src/http_server/routes/epoch_routes.rs +++ b/mithril-aggregator/src/http_server/routes/epoch_routes.rs @@ -1,8 +1,16 @@ -use crate::http_server::routes::middlewares; -use crate::DependencyContainer; use std::sync::Arc; use warp::Filter; +use mithril_common::{ + entities::{SignedEntityConfig, SignedEntityTypeDiscriminants}, + messages::{EpochSettingsMessage, SignerMessagePart}, + StdResult, +}; + +use crate::dependency_injection::EpochServiceWrapper; +use crate::http_server::routes::middlewares; +use crate::DependencyContainer; + pub fn routes( dependency_manager: Arc, ) -> impl Filter + Clone { @@ -16,93 +24,83 @@ fn epoch_settings( warp::path!("epoch-settings") .and(warp::get()) .and(middlewares::with_epoch_service(dependency_manager.clone())) - .and(middlewares::with_signed_entity_config( - dependency_manager.clone(), - )) - .and(middlewares::with_config(dependency_manager)) + .and(middlewares::with_signed_entity_config(dependency_manager)) .and_then(handlers::epoch_settings) } +async fn get_epoch_settings_message( + epoch_service: EpochServiceWrapper, + signed_entity_config: SignedEntityConfig, +) -> StdResult { + let epoch_service = epoch_service.read().await; + + let epoch = epoch_service.epoch_of_current_data()?; + let protocol_parameters = epoch_service.next_protocol_parameters()?.clone(); + let next_protocol_parameters = epoch_service.upcoming_protocol_parameters()?.clone(); + let current_signers = epoch_service.current_signers()?; + let next_signers = epoch_service.next_signers()?; + + let cardano_transactions_signing_config = signed_entity_config + .list_allowed_signed_entity_types_discriminants() + .contains(&SignedEntityTypeDiscriminants::CardanoTransactions) + .then_some(signed_entity_config.cardano_transactions_signing_config); + let next_cardano_transactions_signing_config = cardano_transactions_signing_config.clone(); + + let epoch_settings_message = EpochSettingsMessage { + epoch, + protocol_parameters, + next_protocol_parameters, + current_signers: SignerMessagePart::from_signers(current_signers.to_vec()), + next_signers: SignerMessagePart::from_signers(next_signers.to_vec()), + cardano_transactions_signing_config, + next_cardano_transactions_signing_config, + }; + + Ok(epoch_settings_message) +} + mod handlers { + use slog_scope::debug; use std::convert::Infallible; - - use slog_scope::{debug, warn}; use warp::http::StatusCode; - use mithril_common::{ - entities::{SignedEntityConfig, SignedEntityTypeDiscriminants}, - messages::{EpochSettingsMessage, SignerMessagePart}, - }; + use mithril_common::entities::SignedEntityConfig; + use crate::dependency_injection::EpochServiceWrapper; + use crate::http_server::routes::epoch_routes::get_epoch_settings_message; use crate::http_server::routes::reply; - use crate::{dependency_injection::EpochServiceWrapper, Configuration}; /// Epoch Settings pub async fn epoch_settings( epoch_service: EpochServiceWrapper, signed_entity_config: SignedEntityConfig, - configuration: Configuration, ) -> Result { debug!("⇄ HTTP SERVER: epoch_settings"); - let epoch_service = epoch_service.read().await; - - let cardano_transactions_signing_config = signed_entity_config - .list_allowed_signed_entity_types_discriminants() - .contains(&SignedEntityTypeDiscriminants::CardanoTransactions) - .then_some(configuration.cardano_transactions_signing_config); - - match ( - epoch_service.epoch_of_current_data(), - epoch_service.next_protocol_parameters(), - epoch_service.upcoming_protocol_parameters(), - epoch_service.current_signers(), - epoch_service.next_signers(), - ) { - ( - Ok(epoch), - Ok(protocol_parameters), - Ok(next_protocol_parameters), - Ok(current_signers), - Ok(next_signers), - ) => { - let epoch_settings_message = EpochSettingsMessage { - epoch, - protocol_parameters: protocol_parameters.clone(), - next_protocol_parameters: next_protocol_parameters.clone(), - current_signers: SignerMessagePart::from_signers(current_signers.to_vec()), - next_signers: SignerMessagePart::from_signers(next_signers.to_vec()), - cardano_transactions_signing_config: cardano_transactions_signing_config - .clone(), - next_cardano_transactions_signing_config: cardano_transactions_signing_config, - }; - Ok(reply::json(&epoch_settings_message, StatusCode::OK)) - } - (Err(err), _, _, _, _) - | (_, Err(err), _, _, _) - | (_, _, Err(err), _, _) - | (_, _, _, Err(err), _) - | (_, _, _, _, Err(err)) => { - warn!("epoch_settings::error"; "error" => ?err); - Ok(reply::server_error(err)) - } + let epoch_settings_message = + get_epoch_settings_message(epoch_service, signed_entity_config).await; + + match epoch_settings_message { + Ok(message) => Ok(reply::json(&message, StatusCode::OK)), + Err(err) => Ok(reply::server_error(err)), } } } #[cfg(test)] mod tests { - use std::collections::BTreeSet; - use serde_json::Value::Null; + use std::collections::BTreeSet; use tokio::sync::RwLock; - use warp::http::{Method, StatusCode}; - use warp::test::request; + use warp::{ + http::{Method, StatusCode}, + test::request, + }; use mithril_common::{ entities::{ - BlockNumber, CardanoTransactionsSigningConfig, Epoch, SignedEntityTypeDiscriminants, + BlockNumber, CardanoTransactionsSigningConfig, Epoch, SignedEntityConfig, + SignedEntityTypeDiscriminants, }, - messages::EpochSettingsMessage, test_utils::{apispec::APISpec, MithrilFixtureBuilder}, }; @@ -126,95 +124,69 @@ mod tests { } #[tokio::test] - async fn test_epoch_settings_get_ok() { - let method = Method::GET.as_str(); - let path = "/epoch-settings"; - let mut dependency_manager = initialize_dependencies().await; - let fixture = MithrilFixtureBuilder::default().with_signers(5).build(); - let epoch_service = FakeEpochService::from_fixture(Epoch(5), &fixture); - dependency_manager.epoch_service = Arc::new(RwLock::new(epoch_service)); + async fn get_epoch_settings_message_with_cardano_transactions_enabled() { + let fixture = MithrilFixtureBuilder::default().with_signers(3).build(); + let epoch_service = FakeEpochService::from_fixture(Epoch(4), &fixture); + let epoch_service = Arc::new(RwLock::new(epoch_service)); - let response = request() - .method(method) - .path(&format!("/{SERVER_BASE_PATH}{path}")) - .reply(&setup_router(Arc::new(dependency_manager))) - .await; + let cardano_transactions_signing_config = CardanoTransactionsSigningConfig { + security_parameter: BlockNumber(70), + step: BlockNumber(15), + }; + let signed_entity_config = SignedEntityConfig { + cardano_transactions_signing_config: cardano_transactions_signing_config.clone(), + allowed_discriminants: BTreeSet::from([ + SignedEntityTypeDiscriminants::CardanoTransactions, + ]), + ..SignedEntityConfig::dummy() + }; - APISpec::verify_conformity( - APISpec::get_all_spec_files(), - method, - path, - "application/json", - &Null, - &response, - &StatusCode::OK, - ) - .unwrap(); + let message = get_epoch_settings_message(epoch_service, signed_entity_config) + .await + .unwrap(); + + assert_eq!( + message.cardano_transactions_signing_config, + Some(cardano_transactions_signing_config.clone()) + ); + assert_eq!( + message.next_cardano_transactions_signing_config, + Some(cardano_transactions_signing_config) + ); } #[tokio::test] - async fn test_epoch_settings_get_ok_with_cardano_transactions_enabled() { - let method = Method::GET.as_str(); - let path = "/epoch-settings"; - let mut dependency_manager = initialize_dependencies().await; - let fixture = MithrilFixtureBuilder::default().with_signers(5).build(); - let epoch_service = FakeEpochService::from_fixture(Epoch(5), &fixture); - dependency_manager.epoch_service = Arc::new(RwLock::new(epoch_service)); - dependency_manager - .signed_entity_config - .allowed_discriminants = - BTreeSet::from([SignedEntityTypeDiscriminants::CardanoTransactions]); - let signing_config = CardanoTransactionsSigningConfig { + async fn get_epoch_settings_message_with_cardano_transactions_not_enabled() { + let fixture = MithrilFixtureBuilder::default().with_signers(3).build(); + let epoch_service = FakeEpochService::from_fixture(Epoch(4), &fixture); + let epoch_service = Arc::new(RwLock::new(epoch_service)); + + let cardano_transactions_signing_config = CardanoTransactionsSigningConfig { security_parameter: BlockNumber(70), step: BlockNumber(15), }; - dependency_manager - .config - .cardano_transactions_signing_config = signing_config.clone(); - - let response = request() - .method(method) - .path(&format!("/{SERVER_BASE_PATH}{path}")) - .reply(&setup_router(Arc::new(dependency_manager))) - .await; - - let response_body: EpochSettingsMessage = serde_json::from_slice(response.body()).unwrap(); + let signed_entity_config = SignedEntityConfig { + cardano_transactions_signing_config, + allowed_discriminants: BTreeSet::new(), + ..SignedEntityConfig::dummy() + }; - assert_eq!( - response_body.current_cardano_transactions_signing_config, - Some(signing_config) - ); + let message = get_epoch_settings_message(epoch_service, signed_entity_config) + .await + .unwrap(); - APISpec::verify_conformity( - APISpec::get_all_spec_files(), - method, - path, - "application/json", - &Null, - &response, - &StatusCode::OK, - ) - .unwrap(); + assert_eq!(message.cardano_transactions_signing_config, None); + assert_eq!(message.next_cardano_transactions_signing_config, None); } #[tokio::test] - async fn test_epoch_settings_get_ok_with_cardano_transactions_not_enabled() { + async fn test_epoch_settings_get_ok() { let method = Method::GET.as_str(); let path = "/epoch-settings"; let mut dependency_manager = initialize_dependencies().await; let fixture = MithrilFixtureBuilder::default().with_signers(5).build(); let epoch_service = FakeEpochService::from_fixture(Epoch(5), &fixture); dependency_manager.epoch_service = Arc::new(RwLock::new(epoch_service)); - dependency_manager - .signed_entity_config - .allowed_discriminants = BTreeSet::new(); - let signing_config = CardanoTransactionsSigningConfig { - security_parameter: BlockNumber(70), - step: BlockNumber(15), - }; - dependency_manager - .config - .cardano_transactions_signing_config = signing_config.clone(); let response = request() .method(method) @@ -222,13 +194,6 @@ mod tests { .reply(&setup_router(Arc::new(dependency_manager))) .await; - let response_body: EpochSettingsMessage = serde_json::from_slice(response.body()).unwrap(); - - assert_eq!( - response_body.current_cardano_transactions_signing_config, - None - ); - APISpec::verify_conformity( APISpec::get_all_spec_files(), method, From 45bed99d9935b738cb75c158063ecc67df774ff3 Mon Sep 17 00:00:00 2001 From: Damien Lachaume <135982616+dlachaume@users.noreply.github.com> Date: Fri, 20 Sep 2024 12:14:40 +0200 Subject: [PATCH 8/9] chore: reference the feature in the CHANGELOG --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 948ac003f61..794d3ab97d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,9 @@ As a minor extension, we have adopted a slightly different versioning convention - Optimizations of the state machine used by the signer to create individual signatures. -- Support for buffering of incoming single signatures by the aggregator if it can not aggregate them yet +- Support for buffering of incoming single signatures by the aggregator if it can not aggregate them yet. + +- Expose the Cardano transactions signing configuration for the current and upcoming epoch via the `/epoch-settings` route. - Crates versions: From 6e9fb44de3244c4e68145b04e18a3386d8ef9920 Mon Sep 17 00:00:00 2001 From: Damien Lachaume <135982616+dlachaume@users.noreply.github.com> Date: Fri, 20 Sep 2024 12:22:51 +0200 Subject: [PATCH 9/9] chore: bump crates versions and `openapi.yaml` version * mithril-aggregator from `0.5.64` to `0.5.65` * mithril-common from `0.4.52` to `0.4.53` * mithril-signer from `0.2.184` to `0.2.185` --- Cargo.lock | 6 +++--- mithril-aggregator/Cargo.toml | 2 +- mithril-common/Cargo.toml | 2 +- mithril-signer/Cargo.toml | 2 +- openapi.yaml | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 272a3ac21fa..dfe0bd5eac0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3403,7 +3403,7 @@ dependencies = [ [[package]] name = "mithril-aggregator" -version = "0.5.64" +version = "0.5.65" dependencies = [ "anyhow", "async-trait", @@ -3559,7 +3559,7 @@ dependencies = [ [[package]] name = "mithril-common" -version = "0.4.52" +version = "0.4.53" dependencies = [ "anyhow", "async-trait", @@ -3704,7 +3704,7 @@ dependencies = [ [[package]] name = "mithril-signer" -version = "0.2.184" +version = "0.2.185" dependencies = [ "anyhow", "async-trait", diff --git a/mithril-aggregator/Cargo.toml b/mithril-aggregator/Cargo.toml index 36489257b7a..0d011c61d3c 100644 --- a/mithril-aggregator/Cargo.toml +++ b/mithril-aggregator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mithril-aggregator" -version = "0.5.64" +version = "0.5.65" description = "A Mithril Aggregator server" authors = { workspace = true } edition = { workspace = true } diff --git a/mithril-common/Cargo.toml b/mithril-common/Cargo.toml index 0116e694bcf..247afa6eb35 100644 --- a/mithril-common/Cargo.toml +++ b/mithril-common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mithril-common" -version = "0.4.52" +version = "0.4.53" description = "Common types, interfaces, and utilities for Mithril nodes." authors = { workspace = true } edition = { workspace = true } diff --git a/mithril-signer/Cargo.toml b/mithril-signer/Cargo.toml index 6c43d149a72..3332d03edcf 100644 --- a/mithril-signer/Cargo.toml +++ b/mithril-signer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mithril-signer" -version = "0.2.184" +version = "0.2.185" description = "A Mithril Signer" authors = { workspace = true } edition = { workspace = true } diff --git a/openapi.yaml b/openapi.yaml index 63b5e49d30a..18977d53176 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -4,7 +4,7 @@ info: # `mithril-common/src/lib.rs` file. If you plan to update it # here to reflect changes in the API, please also update the constant in the # Rust file. - version: 0.1.30 + version: 0.1.31 title: Mithril Aggregator Server description: | The REST API provided by a Mithril Aggregator Node in a Mithril network.