diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/key_rotation.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/key_rotation.rs index a6f330d68e..90b6f7ac6b 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/key_rotation.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/key_rotation.rs @@ -7,12 +7,15 @@ use cosmwasm_schema::cw_serde; pub type KeyRotationId = u32; #[cw_serde] +#[derive(Copy)] +#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] pub struct KeyRotationState { /// Defines how long each key rotation is valid for (in terms of epochs) pub validity_epochs: u32, /// Records the initial epoch_id when the key rotation has been introduced (0 for fresh contracts). /// It is used for determining when rotation is meant to advance. + #[cfg_attr(feature = "utoipa", schema(value_type = u32))] pub initial_epoch_id: EpochId, } diff --git a/nym-api/nym-api-requests/src/models.rs b/nym-api/nym-api-requests/src/models.rs index d317817902..6d50550613 100644 --- a/nym-api/nym-api-requests/src/models.rs +++ b/nym-api/nym-api-requests/src/models.rs @@ -21,7 +21,7 @@ use nym_mixnet_contract_common::nym_node::Role; use nym_mixnet_contract_common::reward_params::{Performance, RewardingParams}; use nym_mixnet_contract_common::rewarding::RewardEstimate; use nym_mixnet_contract_common::{ - EpochId, GatewayBond, IdentityKey, Interval, MixNode, NodeId, Percent, + EpochId, GatewayBond, IdentityKey, Interval, KeyRotationState, MixNode, NodeId, Percent, }; use nym_network_defaults::{DEFAULT_MIX_LISTENING_PORT, DEFAULT_VERLOC_LISTENING_PORT}; use nym_node_requests::api::v1::authenticator::models::Authenticator; @@ -1381,6 +1381,21 @@ impl NodeRefreshBody { } } +#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, ToSchema)] +pub struct KeyRotationInfoResponse { + pub key_rotation_state: KeyRotationState, + + #[schema(value_type = u32)] + pub current_epoch_id: EpochId, + + #[serde(with = "time::serde::rfc3339")] + #[schemars(with = "String")] + #[schema(value_type = String)] + pub current_epoch_start: OffsetDateTime, + + pub epoch_duration: Duration, +} + #[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, ToSchema)] pub struct RewardedSetResponse { #[serde(default)] diff --git a/nym-api/src/nym_contract_cache/cache/data.rs b/nym-api/src/nym_contract_cache/cache/data.rs index ba2c7d9115..894d6511a6 100644 --- a/nym-api/src/nym_contract_cache/cache/data.rs +++ b/nym-api/src/nym_contract_cache/cache/data.rs @@ -6,8 +6,8 @@ use nym_api_requests::legacy::{LegacyGatewayBondWithId, LegacyMixNodeDetailsWith use nym_api_requests::models::ConfigScoreDataResponse; use nym_contracts_common::ContractBuildInformation; use nym_mixnet_contract_common::{ - ConfigScoreParams, HistoricalNymNodeVersionEntry, Interval, NodeId, NymNodeDetails, - RewardingParams, + ConfigScoreParams, HistoricalNymNodeVersionEntry, Interval, KeyRotationState, NodeId, + NymNodeDetails, RewardingParams, }; use nym_topology::CachedEpochRewardedSet; use nym_validator_client::nyxd::AccountId; @@ -46,6 +46,7 @@ pub(crate) struct ContractCacheData { pub(crate) config_score_data: Cache>, pub(crate) current_reward_params: Cache>, pub(crate) current_interval: Cache>, + pub(crate) key_rotation_state: Cache>, pub(crate) contracts_info: Cache, } @@ -64,6 +65,7 @@ impl ContractCacheData { current_reward_params: Cache::default(), contracts_info: Cache::default(), config_score_data: Default::default(), + key_rotation_state: Default::default(), } } } diff --git a/nym-api/src/nym_contract_cache/cache/mod.rs b/nym-api/src/nym_contract_cache/cache/mod.rs index 147fe60406..a1dc6064d2 100644 --- a/nym-api/src/nym_contract_cache/cache/mod.rs +++ b/nym-api/src/nym_contract_cache/cache/mod.rs @@ -334,6 +334,10 @@ impl NymContractCache { .unwrap_or_default() } + pub(crate) async fn get_key_rotation_state(&self) { + todo!() + } + pub(crate) async fn contract_details(&self) -> Cache { self.get_owned(|cache| cache.contracts_info.clone_cache()) .await diff --git a/nym-api/src/nym_contract_cache/handlers.rs b/nym-api/src/nym_contract_cache/handlers.rs index c40a64d8c4..98584d77ef 100644 --- a/nym-api/src/nym_contract_cache/handlers.rs +++ b/nym-api/src/nym_contract_cache/handlers.rs @@ -10,7 +10,7 @@ use crate::support::legacy_helpers::{to_legacy_gateway, to_legacy_mixnode}; use axum::extract::{Query, State}; use axum::Router; use nym_api_requests::legacy::LegacyMixNodeDetailsWithLayer; -use nym_api_requests::models::MixNodeBondAnnotated; +use nym_api_requests::models::{KeyRotationInfoResponse, MixNodeBondAnnotated}; use nym_http_api_common::{FormattedResponse, OutputParams}; use nym_mixnet_contract_common::reward_params::Performance; use nym_mixnet_contract_common::{reward_params::RewardingParams, GatewayBond, Interval, NodeId}; @@ -49,6 +49,10 @@ pub(crate) fn nym_contract_cache_routes() -> Router { axum::routing::get(get_interval_reward_params), ) .route("/epoch/current", axum::routing::get(get_current_epoch)) + .route( + "/epoch/key_rotation_info", + axum::routing::get(get_current_key_rotation_info), + ) } #[utoipa::path( @@ -513,3 +517,21 @@ async fn get_current_epoch( .to_owned(), ) } + +// +#[utoipa::path( + tag = "contract-cache", + get, + path = "/epoch/key_rotation_info", + context_path = "/v1/epoch", + responses( + (status = 200, body = Option) + ) +)] +async fn get_current_key_rotation_info( + State(state): State, +) -> Json { + let contract_cache = state.nym_contract_cache(); + let current_interval = contract_cache.current_interval().await; + todo!() +}