diff --git a/mithril-aggregator/src/http_server/routes/epoch_routes.rs b/mithril-aggregator/src/http_server/routes/epoch_routes.rs index d11e89c2f9a..eadd2bc3876 100644 --- a/mithril-aggregator/src/http_server/routes/epoch_routes.rs +++ b/mithril-aggregator/src/http_server/routes/epoch_routes.rs @@ -40,24 +40,31 @@ mod handlers { debug!("⇄ HTTP SERVER: epoch_settings"); match multi_signer.read().await.get_current_beacon().await { - Some(beacon) => match protocol_parameters_store - .get_protocol_parameters(beacon.epoch) - .await - { - Ok(Some(protocol_parameters)) => Ok(reply::json( - &EpochSettings { - epoch: beacon.epoch, - protocol_parameters, - }, - StatusCode::OK, - )), - Ok(None) => { + Some(beacon) => match ( + protocol_parameters_store + .get_protocol_parameters(beacon.epoch) + .await, + protocol_parameters_store + .get_protocol_parameters(beacon.epoch + 1) + .await, + ) { + (Ok(Some(protocol_parameters)), Ok(Some(next_protocol_parameters))) => { + Ok(reply::json( + &EpochSettings { + epoch: beacon.epoch, + protocol_parameters, + next_protocol_parameters, + }, + StatusCode::OK, + )) + } + (Ok(None), Ok(Some(_))) | (Ok(Some(_)), Ok(None)) | (Ok(None), Ok(None)) => { warn!("epoch_settings::could_not_retrieve_protocol_parameters"); Ok(reply::internal_server_error( "could_not_retrieve_protocol_parameters".to_string(), )) } - Err(err) => { + (Err(err), _) | (_, Err(err)) => { warn!("epoch_settings::error"; "error" => ?err); Ok(reply::internal_server_error(err.to_string())) } diff --git a/mithril-common/src/entities/epoch_settings.rs b/mithril-common/src/entities/epoch_settings.rs index 15c77123966..581d62ad67e 100644 --- a/mithril-common/src/entities/epoch_settings.rs +++ b/mithril-common/src/entities/epoch_settings.rs @@ -10,4 +10,8 @@ pub struct EpochSettings { /// Current Protocol parameters #[serde(rename = "protocol")] pub protocol_parameters: ProtocolParameters, + + /// Next Protocol parameters + #[serde(rename = "next_protocol")] + pub next_protocol_parameters: ProtocolParameters, } diff --git a/mithril-common/src/fake_data.rs b/mithril-common/src/fake_data.rs index dd1fc6c3e7d..ac0ac2d313a 100644 --- a/mithril-common/src/fake_data.rs +++ b/mithril-common/src/fake_data.rs @@ -38,11 +38,13 @@ pub fn epoch_settings() -> entities::EpochSettings { // Protocol parameters let protocol_parameters = protocol_parameters(); + let next_protocol_parameters = protocol_parameters.clone(); // Epoch settings entities::EpochSettings { epoch: beacon.epoch, protocol_parameters, + next_protocol_parameters, } } diff --git a/mithril-common/src/lib.rs b/mithril-common/src/lib.rs index 928a630e602..87e77023edf 100644 --- a/mithril-common/src/lib.rs +++ b/mithril-common/src/lib.rs @@ -42,4 +42,4 @@ pub const SIGNER_EPOCH_RECORDING_OFFSET: i64 = 1; /// this is the same as the one in openapi.yml file. /// If you want to update this version to reflect changes in the protocol, /// please also update the entry in the openapi.yml -pub const MITHRIL_API_VERSION: &str = "0.0.1"; +pub const MITHRIL_API_VERSION: &str = "0.1.0"; diff --git a/mithril-explorer/components/EpochSettings/index.js b/mithril-explorer/components/EpochSettings/index.js index 9c3b38d1c39..8516fa2b360 100644 --- a/mithril-explorer/components/EpochSettings/index.js +++ b/mithril-explorer/components/EpochSettings/index.js @@ -1,7 +1,7 @@ -import React, {useEffect, useState} from 'react'; -import {Card, ListGroup} from "react-bootstrap"; +import React, { useEffect, useState } from 'react'; +import { Card, ListGroup } from "react-bootstrap"; import RawJsonButton from "../RawJsonButton"; -import {useSelector} from "react-redux"; +import { useSelector } from "react-redux"; import ProtocolParameters from "../ProtocolParameters"; export default function EpochSettings(props) { @@ -36,7 +36,7 @@ export default function EpochSettings(props) {

Epoch Settings - +

@@ -46,7 +46,9 @@ export default function EpochSettings(props) { {epochSettings.epoch} Protocol Parameters - + + Next Protocol Parameters +
diff --git a/mithril-signer/src/runtime/state_machine.rs b/mithril-signer/src/runtime/state_machine.rs index f601d0fd069..96476d88c5b 100644 --- a/mithril-signer/src/runtime/state_machine.rs +++ b/mithril-signer/src/runtime/state_machine.rs @@ -215,7 +215,7 @@ impl StateMachine { let beacon = self.runner.get_current_beacon().await?; self.runner.update_stake_distribution(beacon.epoch).await?; self.runner - .register_signer_to_aggregator(beacon.epoch, &epoch_settings.protocol_parameters) + .register_signer_to_aggregator(beacon.epoch, &epoch_settings.next_protocol_parameters) .await?; Ok(RegisteredState { beacon }) @@ -304,6 +304,7 @@ mod tests { let epoch_settings = EpochSettings { epoch: Epoch(3), protocol_parameters: fake_data::protocol_parameters(), + next_protocol_parameters: fake_data::protocol_parameters(), }; let known_epoch = Epoch(4); runner diff --git a/mithril-test-lab/mithril-end-to-end/src/end_to_end_spec.rs b/mithril-test-lab/mithril-end-to-end/src/end_to_end_spec.rs index 5877d38db37..e8f53e86eaf 100644 --- a/mithril-test-lab/mithril-end-to-end/src/end_to_end_spec.rs +++ b/mithril-test-lab/mithril-end-to-end/src/end_to_end_spec.rs @@ -2,7 +2,7 @@ use crate::utils::AttemptResult; use crate::{attempt, Aggregator, Client, ClientCommand, Devnet, MithrilInfrastructure}; use mithril_common::chain_observer::{CardanoCliChainObserver, ChainObserver}; use mithril_common::digesters::ImmutableFile; -use mithril_common::entities::{Certificate, Epoch, EpochSettings, Snapshot}; +use mithril_common::entities::{Certificate, Epoch, EpochSettings, ProtocolParameters, Snapshot}; use reqwest::StatusCode; use slog_scope::{info, warn}; use std::error::Error; @@ -41,7 +41,7 @@ impl Spec { bootstrap_genesis_certificate(self.infrastructure.aggregator_mut()).await?; wait_for_epoch_settings(&aggregator_endpoint).await?; - // Wait 2 epochs before changing stake distribution, so that we use at least once original stake distribution + // Wait 2 epochs before changing stake distribution, so that we use at least one original stake distribution target_epoch += 2; wait_for_target_epoch( self.infrastructure.chain_observer(), @@ -51,12 +51,22 @@ impl Spec { .await?; delegate_stakes_to_pools(self.infrastructure.devnet()).await?; - // Wait 5 epochs after stake delegation, so that we make sure that we use new stake distribution a few times - target_epoch += 5; + // Wait 2 epochs before changing protocol parameters + target_epoch += 2; wait_for_target_epoch( self.infrastructure.chain_observer(), target_epoch, - "epoch after which the certificate chain will be long enough to catch most common troubles".to_string(), + "epoch after which the protocol parameters will change".to_string(), + ) + .await?; + update_protocol_parameters(self.infrastructure.aggregator_mut()).await?; + + // Wait 4 epochs after protocol parameters update, so that we make sure that we use new protocol parameters as well as new stake distribution a few times + target_epoch += 4; + wait_for_target_epoch( + self.infrastructure.chain_observer(), + target_epoch, + "epoch after which the certificate chain will be long enough to catch most common troubles with stake distribution and protocol parameters".to_string(), ) .await?; @@ -177,7 +187,7 @@ async fn wait_for_target_epoch( } }) { AttemptResult::Ok(_) => { - info!("Target epoch reached !"; "target_epoch" => ?target_epoch); + info!("Target epoch reached!"; "target_epoch" => ?target_epoch); Ok(()) } AttemptResult::Err(error) => Err(error), @@ -194,7 +204,7 @@ async fn bootstrap_genesis_certificate(aggregator: &mut Aggregator) -> Result<() info!("> stopping aggregator"); aggregator.stop().await?; - info!("> bootstrapping genesis using signers registered two epochs ago ..."); + info!("> bootstrapping genesis using signers registered two epochs ago..."); aggregator.bootstrap_genesis().await?; info!("> done, restarting aggregator"); aggregator.serve()?; @@ -210,6 +220,27 @@ async fn delegate_stakes_to_pools(devnet: &Devnet) -> Result<(), String> { Ok(()) } +async fn update_protocol_parameters(aggregator: &mut Aggregator) -> Result<(), String> { + info!("Update protocol parameters"); + + info!("> stopping aggregator"); + aggregator.stop().await?; + let protocol_parameters_new = ProtocolParameters { + k: 150, + m: 200, + phi_f: 0.95, + }; + info!( + "> updating protocol parameters to {:?}...", + protocol_parameters_new + ); + aggregator.set_protocol_parameters(&protocol_parameters_new); + info!("> done, restarting aggregator"); + aggregator.serve()?; + + Ok(()) +} + async fn assert_node_producing_snapshot(aggregator_endpoint: &str) -> Result { let url = format!("{}/snapshots", aggregator_endpoint); info!("Waiting for the aggregator to produce a snapshot"); diff --git a/mithril-test-lab/mithril-end-to-end/src/mithril/aggregator.rs b/mithril-test-lab/mithril-end-to-end/src/mithril/aggregator.rs index 9eeceaf474c..693bfe193f1 100644 --- a/mithril-test-lab/mithril-end-to-end/src/mithril/aggregator.rs +++ b/mithril-test-lab/mithril-end-to-end/src/mithril/aggregator.rs @@ -1,6 +1,7 @@ use crate::devnet::BftNode; use crate::utils::MithrilCommand; use crate::DEVNET_MAGIC_ID; +use mithril_common::entities; use std::collections::HashMap; use std::path::{Path, PathBuf}; use tokio::process::Child; @@ -25,9 +26,6 @@ impl Aggregator { let server_port_parameter = server_port.to_string(); let env = HashMap::from([ ("NETWORK", "devnet"), - ("PROTOCOL_PARAMETERS__K", "75"), - ("PROTOCOL_PARAMETERS__M", "100"), - ("PROTOCOL_PARAMETERS__PHI_F", "0.95"), ("RUN_INTERVAL", "800"), ("SERVER_IP", "0.0.0.0"), ("SERVER_PORT", &server_port_parameter), @@ -105,6 +103,21 @@ impl Aggregator { Ok(()) } + pub fn set_protocol_parameters(&mut self, protocol_parameters: &entities::ProtocolParameters) { + self.command.set_env_var( + "PROTOCOL_PARAMETERS__K", + &format!("{}", protocol_parameters.k), + ); + self.command.set_env_var( + "PROTOCOL_PARAMETERS__M", + &format!("{}", protocol_parameters.m), + ); + self.command.set_env_var( + "PROTOCOL_PARAMETERS__PHI_F", + &format!("{}", protocol_parameters.phi_f), + ); + } + pub async fn tail_logs(&self, number_of_line: u64) -> Result<(), String> { self.command.tail_logs(None, number_of_line).await } diff --git a/mithril-test-lab/mithril-end-to-end/src/mithril/infrastructure.rs b/mithril-test-lab/mithril-end-to-end/src/mithril/infrastructure.rs index 400102d8e06..2cb20079b12 100644 --- a/mithril-test-lab/mithril-end-to-end/src/mithril/infrastructure.rs +++ b/mithril-test-lab/mithril-end-to-end/src/mithril/infrastructure.rs @@ -1,5 +1,6 @@ use crate::{Aggregator, Client, Devnet, Signer, DEVNET_MAGIC_ID}; use mithril_common::chain_observer::{CardanoCliChainObserver, CardanoCliRunner}; +use mithril_common::entities::ProtocolParameters; use mithril_common::CardanoNetwork; use std::borrow::BorrowMut; use std::path::{Path, PathBuf}; @@ -35,6 +36,11 @@ impl MithrilInfrastructure { work_dir, bin_dir, )?; + aggregator.set_protocol_parameters(&ProtocolParameters { + k: 75, + m: 100, + phi_f: 0.95, + }); aggregator.serve()?; let mut signers: Vec = vec![]; diff --git a/mithril-test-lab/mithril-end-to-end/src/utils/mithril_command.rs b/mithril-test-lab/mithril-end-to-end/src/utils/mithril_command.rs index be0e8d52bf1..a28ea539cd3 100644 --- a/mithril-test-lab/mithril-end-to-end/src/utils/mithril_command.rs +++ b/mithril-test-lab/mithril-end-to-end/src/utils/mithril_command.rs @@ -56,6 +56,10 @@ impl MithrilCommand { self.log_path = self.work_dir.join(format!("{}.log", name)); } + pub fn set_env_var(&mut self, name: &str, value: &str) { + self.env_vars.insert(name.to_string(), value.to_string()); + } + pub fn start(&mut self, args: &[String]) -> Result { let args = [&self.default_args, args].concat(); diff --git a/openapi.yaml b/openapi.yaml index 4ae65287a63..0c13cc349ca 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -4,7 +4,7 @@ info: # `mithril-aggregator/src/http_server/mod.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.0.1 + version: 0.1.0 title: Mithril Aggregator Server description: | The REST API provided by a Mithril Aggregator Node in a Mithril network. @@ -28,7 +28,8 @@ paths: summary: Get current epoch settings description: | Returns the information related to the current epoch: - * protocol parameters for current epoch (to setup cryptography, allowing signers to register) + * protocol parameters for current epoch + * protocol parameters for next epoch (to setup cryptography, allowing signers to register) responses: "200": description: epoch settings found @@ -238,6 +239,7 @@ components: required: - epoch - protocol + - next_protocol properties: epoch: description: Cardano chain epoch number @@ -245,10 +247,13 @@ components: format: int64 protocol: $ref: "#/components/schemas/ProtocolParameters" + next_protocol: + $ref: "#/components/schemas/ProtocolParameters" example: { "epoch": 329, - "protocol": { "k": 857, "m": 6172, "phi_f": 0.2 } + "protocol": { "k": 857, "m": 6172, "phi_f": 0.2 }, + "next_protocol": { "k": 2422, "m": 20973, "phi_f": 0.2 } } ProtocolParameters: description: Protocol cryptographic parameters