From 6a93497c8fa9ee288624517c400d954b29468fb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= Date: Tue, 28 Feb 2023 13:58:01 +0200 Subject: [PATCH] Extend public key submission in case no dealer registered (#3106) --- .../coconut-dkg/src/dealers/transactions.rs | 4 +- .../coconut-dkg/src/dealings/transactions.rs | 2 + .../src/epoch_state/transactions.rs | 38 +++++++++++++------ .../coconut-dkg/src/support/tests/helpers.rs | 22 ++++++++++- .../verification_key_shares/transactions.rs | 6 ++- 5 files changed, 56 insertions(+), 16 deletions(-) diff --git a/contracts/coconut-dkg/src/dealers/transactions.rs b/contracts/coconut-dkg/src/dealers/transactions.rs index 0c2d0b4241..9a4197dd8d 100644 --- a/contracts/coconut-dkg/src/dealers/transactions.rs +++ b/contracts/coconut-dkg/src/dealers/transactions.rs @@ -80,7 +80,7 @@ pub(crate) mod tests { use crate::epoch_state::transactions::advance_epoch_state; use crate::support::tests::fixtures::dealer_details_fixture; use crate::support::tests::helpers; - use crate::support::tests::helpers::GROUP_MEMBERS; + use crate::support::tests::helpers::{add_fixture_dealer, GROUP_MEMBERS}; use coconut_dkg_common::types::{InitialReplacementData, TimeConfiguration}; use cosmwasm_std::testing::{mock_env, mock_info}; use cw4::Member; @@ -147,6 +147,8 @@ pub(crate) mod tests { .block .time .plus_seconds(TimeConfiguration::default().public_key_submission_time_secs); + + add_fixture_dealer(deps.as_mut()); advance_epoch_state(deps.as_mut(), env).unwrap(); let ret = try_add_dealer( diff --git a/contracts/coconut-dkg/src/dealings/transactions.rs b/contracts/coconut-dkg/src/dealings/transactions.rs index 3f6a797775..b9220cff9e 100644 --- a/contracts/coconut-dkg/src/dealings/transactions.rs +++ b/contracts/coconut-dkg/src/dealings/transactions.rs @@ -53,6 +53,7 @@ pub(crate) mod tests { use crate::epoch_state::transactions::advance_epoch_state; use crate::support::tests::fixtures::{dealer_details_fixture, dealing_bytes_fixture}; use crate::support::tests::helpers; + use crate::support::tests::helpers::add_fixture_dealer; use coconut_dkg_common::dealer::DealerDetails; use coconut_dkg_common::types::{InitialReplacementData, TimeConfiguration}; use cosmwasm_std::testing::{mock_env, mock_info}; @@ -80,6 +81,7 @@ pub(crate) mod tests { .block .time .plus_seconds(TimeConfiguration::default().public_key_submission_time_secs); + add_fixture_dealer(deps.as_mut()); advance_epoch_state(deps.as_mut(), env).unwrap(); let ret = try_commit_dealings(deps.as_mut(), info.clone(), dealing_bytes.clone(), false) diff --git a/contracts/coconut-dkg/src/epoch_state/transactions.rs b/contracts/coconut-dkg/src/epoch_state/transactions.rs index 414ba2344c..3a812f6437 100644 --- a/contracts/coconut-dkg/src/epoch_state/transactions.rs +++ b/contracts/coconut-dkg/src/epoch_state/transactions.rs @@ -89,23 +89,29 @@ pub(crate) fn advance_epoch_state(deps: DepsMut<'_>, env: Env) -> Result, _>>()?; - // note: ceiling in integer division can be achieved via q = (x + y - 1) / y; - let threshold = (2 * current_dealers.len() as u64 + 3 - 1) / 3; - THRESHOLD.save(deps.storage, &threshold)?; - if !resharing { - let replacement_data = InitialReplacementData { - initial_dealers: current_dealers, - initial_height: None, - }; - INITIAL_REPLACEMENT_DATA.save(deps.storage, &replacement_data)?; + if current_dealers.is_empty() { + // If no dealer registered yet, we just stay in the same state until there's at least one + new_state = current_epoch.state; + } else { + // note: ceiling in integer division can be achieved via q = (x + y - 1) / y; + let threshold = (2 * current_dealers.len() as u64 + 3 - 1) / 3; + THRESHOLD.save(deps.storage, &threshold)?; + if !resharing { + let replacement_data = InitialReplacementData { + initial_dealers: current_dealers, + initial_height: None, + }; + INITIAL_REPLACEMENT_DATA.save(deps.storage, &replacement_data)?; + } } - } + }; Epoch::new( - state, + new_state, current_epoch.epoch_id, current_epoch.time_configuration, env.block.time, @@ -392,6 +398,14 @@ pub(crate) mod tests { EarlyEpochStateAdvancement(1) ); + env.block.time = env.block.time.plus_seconds(1); + advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + assert_eq!( + epoch.state, + EpochState::PublicKeySubmission { resharing: false } + ); + // setup dealer details let all_details: [_; 4] = std::array::from_fn(|i| dealer_details_fixture(i as u64 + 1)); for details in all_details.iter() { @@ -404,7 +418,7 @@ pub(crate) mod tests { .may_load(&deps.storage) .unwrap() .is_none()); - env.block.time = env.block.time.plus_seconds(1); + env.block.time = env.block.time.plus_seconds(epoch.time_configuration.public_key_submission_time_secs); advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); assert_eq!( diff --git a/contracts/coconut-dkg/src/support/tests/helpers.rs b/contracts/coconut-dkg/src/support/tests/helpers.rs index 2b8dd56115..b806dd4989 100644 --- a/contracts/coconut-dkg/src/support/tests/helpers.rs +++ b/contracts/coconut-dkg/src/support/tests/helpers.rs @@ -2,11 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 use crate::contract::instantiate; +use crate::dealers::storage::current_dealers; use coconut_dkg_common::msg::InstantiateMsg; +use coconut_dkg_common::types::DealerDetails; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info, MockApi, MockQuerier}; use cosmwasm_std::{ - from_binary, to_binary, ContractResult, Empty, MemoryStorage, OwnedDeps, QuerierResult, - SystemResult, WasmQuery, + from_binary, to_binary, Addr, ContractResult, DepsMut, Empty, MemoryStorage, OwnedDeps, + QuerierResult, SystemResult, WasmQuery, }; use cw4::{Cw4QueryMsg, Member, MemberListResponse, MemberResponse}; use lazy_static::lazy_static; @@ -22,6 +24,22 @@ lazy_static! { pub static ref GROUP_MEMBERS: Mutex> = Mutex::new(vec![]); } +pub fn add_fixture_dealer(deps: DepsMut<'_>) { + let owner = Addr::unchecked("owner"); + current_dealers() + .save( + deps.storage, + &owner, + &DealerDetails { + address: owner.clone(), + bte_public_key_with_proof: String::new(), + announce_address: String::new(), + assigned_index: 100, + }, + ) + .unwrap(); +} + fn querier_handler(query: &WasmQuery) -> QuerierResult { let bin = match query { WasmQuery::Smart { contract_addr, msg } => { diff --git a/contracts/coconut-dkg/src/verification_key_shares/transactions.rs b/contracts/coconut-dkg/src/verification_key_shares/transactions.rs index f7b2e80844..2d6002a003 100644 --- a/contracts/coconut-dkg/src/verification_key_shares/transactions.rs +++ b/contracts/coconut-dkg/src/verification_key_shares/transactions.rs @@ -91,7 +91,7 @@ mod tests { use super::*; use crate::epoch_state::transactions::advance_epoch_state; use crate::support::tests::helpers; - use crate::support::tests::helpers::MULTISIG_CONTRACT; + use crate::support::tests::helpers::{add_fixture_dealer, MULTISIG_CONTRACT}; use coconut_dkg_common::dealer::DealerDetails; use coconut_dkg_common::types::{EpochState, TimeConfiguration}; use cosmwasm_std::testing::{mock_env, mock_info}; @@ -104,6 +104,7 @@ mod tests { let info = mock_info("requester", &[]); let share = "share".to_string(); + add_fixture_dealer(deps.as_mut()); env.block.time = env .block .time @@ -171,6 +172,7 @@ mod tests { .to_string() } ); + add_fixture_dealer(deps.as_mut()); env.block.time = env .block .time @@ -247,6 +249,7 @@ mod tests { } ); + add_fixture_dealer(deps.as_mut()); env.block.time = env .block .time @@ -292,6 +295,7 @@ mod tests { let share = "share".to_string(); let multisig_info = mock_info(MULTISIG_CONTRACT, &[]); + add_fixture_dealer(deps.as_mut()); env.block.time = env .block .time