From 627334cfe2e7fa45c41fce47e797458ba405cb5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 16 Feb 2024 17:16:39 +0000 Subject: [PATCH] added dkg contract query to check if state can be advanced --- .../nyxd/contract_traits/dkg_query_client.rs | 8 ++++- .../coconut-dkg/src/msg.rs | 5 ++- .../coconut-dkg/src/types.rs | 16 ++++++++++ contracts/coconut-dkg/src/contract.rs | 7 +++-- .../coconut-dkg/src/epoch_state/queries.rs | 31 +++++++++++++++++-- 5 files changed, 61 insertions(+), 6 deletions(-) diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs index 33ae58bc42..dcf6590457 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs @@ -8,7 +8,7 @@ use crate::nyxd::CosmWasmClient; use async_trait::async_trait; use cosmrs::AccountId; use cosmwasm_std::Addr; -use nym_coconut_dkg_common::types::{ChunkIndex, NodeIndex}; +use nym_coconut_dkg_common::types::{ChunkIndex, NodeIndex, StateAdvanceResponse}; use serde::Deserialize; use nym_coconut_dkg_common::dealer::RegisteredDealerDetails; @@ -40,6 +40,11 @@ pub trait DkgQueryClient { self.query_dkg_contract(request).await } + async fn can_advance_state(&self) -> Result { + let request = DkgQueryMsg::CanAdvanceState {}; + self.query_dkg_contract(request).await + } + async fn get_current_epoch_threshold(&self) -> Result, NyxdError> { let request = DkgQueryMsg::GetCurrentEpochThreshold {}; self.query_dkg_contract(request).await @@ -245,6 +250,7 @@ mod tests { match msg { DkgQueryMsg::GetState {} => client.get_state().ignore(), DkgQueryMsg::GetCurrentEpochState {} => client.get_current_epoch().ignore(), + DkgQueryMsg::CanAdvanceState {} => client.can_advance_state().ignore(), DkgQueryMsg::GetCurrentEpochThreshold {} => { client.get_current_epoch_threshold().ignore() } diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs index 8874bce5cb..4e2a155c3f 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs @@ -13,7 +13,7 @@ use cosmwasm_schema::cw_serde; use crate::{ dealer::{ DealerDetailsResponse, PagedDealerIndexResponse, PagedDealerResponse, - RegisteredDealerDetails, + RegisteredDealerDetails, StateAdvanceResponse, }, dealing::{ DealerDealingsStatusResponse, DealingChunkResponse, DealingChunkStatusResponse, @@ -87,6 +87,9 @@ pub enum QueryMsg { #[cfg_attr(feature = "schema", returns(u64))] GetCurrentEpochThreshold {}, + #[cfg_attr(feature = "schema", returns(StateAdvanceResponse))] + CanAdvanceState {}, + #[cfg_attr(feature = "schema", returns(RegisteredDealerDetails))] GetRegisteredDealer { dealer_address: String, diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs index 7ff34d682e..43192e9622 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs @@ -21,6 +21,22 @@ pub type DealingIndex = u32; pub type ChunkIndex = u16; pub type PartialContractDealingData = ContractSafeBytes; +#[cw_serde] +#[derive(Copy, Default)] +pub struct StateAdvanceResponse { + pub current_state: EpochState, + pub progress: StateProgress, + pub deadline: Option, + pub reached_deadline: bool, + pub is_complete: bool, +} + +impl StateAdvanceResponse { + pub fn can_advance(&self) -> bool { + self.reached_deadline || self.is_complete + } +} + #[cw_serde] #[derive(Copy)] pub struct TimeConfiguration { diff --git a/contracts/coconut-dkg/src/contract.rs b/contracts/coconut-dkg/src/contract.rs index b1926206c6..2d1e25d5e9 100644 --- a/contracts/coconut-dkg/src/contract.rs +++ b/contracts/coconut-dkg/src/contract.rs @@ -11,7 +11,9 @@ use crate::dealings::queries::{ query_dealing_metadata, query_dealing_status, }; use crate::dealings::transactions::{try_commit_dealings_chunk, try_submit_dealings_metadata}; -use crate::epoch_state::queries::{query_current_epoch, query_current_epoch_threshold}; +use crate::epoch_state::queries::{ + query_can_advance_state, query_current_epoch, query_current_epoch_threshold, +}; use crate::epoch_state::storage::CURRENT_EPOCH; use crate::epoch_state::transactions::{ try_advance_epoch_state, try_initiate_dkg, try_trigger_reset, try_trigger_resharing, @@ -123,10 +125,11 @@ pub fn execute( } #[entry_point] -pub fn query(deps: Deps<'_>, _env: Env, msg: QueryMsg) -> Result { +pub fn query(deps: Deps<'_>, env: Env, msg: QueryMsg) -> Result { let response = match msg { QueryMsg::GetState {} => to_binary(&query_state(deps.storage)?)?, QueryMsg::GetCurrentEpochState {} => to_binary(&query_current_epoch(deps.storage)?)?, + QueryMsg::CanAdvanceState {} => to_binary(&query_can_advance_state(deps.storage, env)?)?, QueryMsg::GetCurrentEpochThreshold {} => { to_binary(&query_current_epoch_threshold(deps.storage)?)? } diff --git a/contracts/coconut-dkg/src/epoch_state/queries.rs b/contracts/coconut-dkg/src/epoch_state/queries.rs index 9a748385bb..76ea8ac9d7 100644 --- a/contracts/coconut-dkg/src/epoch_state/queries.rs +++ b/contracts/coconut-dkg/src/epoch_state/queries.rs @@ -2,9 +2,36 @@ // SPDX-License-Identifier: Apache-2.0 use crate::epoch_state::storage::{CURRENT_EPOCH, THRESHOLD}; +use crate::epoch_state::utils::check_state_completion; use crate::error::ContractError; -use cosmwasm_std::Storage; -use nym_coconut_dkg_common::types::Epoch; +use cosmwasm_std::{Env, StdResult, Storage}; +use nym_coconut_dkg_common::types::{Epoch, EpochState, StateAdvanceResponse}; + +pub(crate) fn query_can_advance_state( + storage: &dyn Storage, + env: Env, +) -> Result { + let epoch = CURRENT_EPOCH.load(storage)?; + + if epoch.state == EpochState::WaitingInitialisation { + return Ok(StateAdvanceResponse::default()); + } + + let is_complete = check_state_completion(storage, &epoch)?; + let reached_deadline = if let Some(finish_timestamp) = epoch.deadline { + finish_timestamp <= env.block.time + } else { + false + }; + + Ok(StateAdvanceResponse { + current_state: epoch.state, + progress: epoch.state_progress, + deadline: epoch.deadline, + reached_deadline, + is_complete, + }) +} pub(crate) fn query_current_epoch(storage: &dyn Storage) -> Result { CURRENT_EPOCH