diff --git a/contracts/coconut-dkg/Cargo.toml b/contracts/coconut-dkg/Cargo.toml index 06a43598b1..7d3abea20b 100644 --- a/contracts/coconut-dkg/Cargo.toml +++ b/contracts/coconut-dkg/Cargo.toml @@ -24,4 +24,6 @@ thiserror = "1.0.23" [dev-dependencies] cw-multi-test = { version = "0.13.4" } cw4-group = { path = "../multisig/cw4-group" } -group-contract-common = { path = "../../common/cosmwasm-smart-contracts/group-contract" } \ No newline at end of file +group-contract-common = { path = "../../common/cosmwasm-smart-contracts/group-contract" } +lazy_static = "1.4" +rusty-fork = "0.3" \ No newline at end of file diff --git a/contracts/coconut-dkg/src/epoch_state/transactions.rs b/contracts/coconut-dkg/src/epoch_state/transactions.rs index 62d600b272..31e3916021 100644 --- a/contracts/coconut-dkg/src/epoch_state/transactions.rs +++ b/contracts/coconut-dkg/src/epoch_state/transactions.rs @@ -128,150 +128,376 @@ pub(crate) fn try_surpassed_threshold( pub(crate) mod tests { use super::*; use crate::error::ContractError::EarlyEpochStateAdvancement; - use crate::support::tests::helpers::init_contract; - use coconut_dkg_common::types::{DealerDetails, EpochState, TimeConfiguration}; + use crate::support::tests::fixtures::dealer_details_fixture; + use crate::support::tests::helpers::{init_contract, GROUP_MEMBERS}; + use coconut_dkg_common::types::{ + ContractSafeBytes, DealerDetails, EpochState, TimeConfiguration, + }; use cosmwasm_std::testing::mock_env; use cosmwasm_std::Addr; + use cw4::Member; + use rusty_fork::rusty_fork_test; - #[test] - fn advance_state() { - let mut deps = init_contract(); - let mut env = mock_env(); + // Because of the global variable handling group, we need individual process for each test + rusty_fork_test! { + #[test] + fn still_active() { + let mut deps = init_contract(); + { + let mut group = GROUP_MEMBERS.lock().unwrap(); - let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - assert_eq!(epoch.state, EpochState::PublicKeySubmission); - assert_eq!( - epoch.finish_timestamp, - env.block + group.push(Member { + addr: "owner1".to_string(), + weight: 10, + }); + group.push(Member { + addr: "owner2".to_string(), + weight: 10, + }); + group.push(Member { + addr: "owner3".to_string(), + weight: 10, + }); + } + assert_eq!(0, dealers_still_active(&deps.as_mut()).unwrap()); + for i in 0..3 as u64 { + let details = dealer_details_fixture(i + 1); + current_dealers() + .save(deps.as_mut().storage, &details.address, &details) + .unwrap(); + assert_eq!( + i as usize + 1, + dealers_still_active(&deps.as_mut()).unwrap() + ); + } + } + + #[test] + fn advance_state() { + let mut deps = init_contract(); + let mut env = mock_env(); + { + let mut group = GROUP_MEMBERS.lock().unwrap(); + + group.push(Member { + addr: "owner1".to_string(), + weight: 10, + }); + group.push(Member { + addr: "owner2".to_string(), + weight: 10, + }); + group.push(Member { + addr: "owner3".to_string(), + weight: 10, + }); + } + + let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + assert_eq!(epoch.state, EpochState::PublicKeySubmission); + assert_eq!( + epoch.finish_timestamp, + env.block + .time + .plus_seconds(epoch.time_configuration.public_key_submission_time_secs) + ); + + env.block.time = env + .block .time - .plus_seconds(epoch.time_configuration.public_key_submission_time_secs) - ); + .plus_seconds(epoch.time_configuration.public_key_submission_time_secs - 1); + assert_eq!( + advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), + EarlyEpochStateAdvancement(1) + ); - env.block.time = env - .block - .time - .plus_seconds(epoch.time_configuration.public_key_submission_time_secs - 1); - assert_eq!( - advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), - 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::DealingExchange); + assert_eq!( + epoch.finish_timestamp, + env.block + .time + .plus_seconds(epoch.time_configuration.dealing_exchange_time_secs) + ); - 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::DealingExchange); - assert_eq!( - epoch.finish_timestamp, - env.block + env.block.time = env + .block .time - .plus_seconds(epoch.time_configuration.dealing_exchange_time_secs) - ); + .plus_seconds(epoch.time_configuration.dealing_exchange_time_secs - 2); + assert_eq!( + advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), + EarlyEpochStateAdvancement(2) + ); - env.block.time = env - .block - .time - .plus_seconds(epoch.time_configuration.dealing_exchange_time_secs - 2); - assert_eq!( - advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), - EarlyEpochStateAdvancement(2) - ); + env.block.time = env.block.time.plus_seconds(3); + advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + assert_eq!(epoch.state, EpochState::VerificationKeySubmission); + assert_eq!( + epoch.finish_timestamp, + env.block.time.plus_seconds( + epoch + .time_configuration + .verification_key_submission_time_secs + ) + ); - env.block.time = env.block.time.plus_seconds(3); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); - let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - assert_eq!(epoch.state, EpochState::VerificationKeySubmission); - assert_eq!( - epoch.finish_timestamp, - env.block.time.plus_seconds( + env.block.time = env.block.time.plus_seconds( epoch .time_configuration .verification_key_submission_time_secs - ) - ); + - 2, + ); + assert_eq!( + advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), + EarlyEpochStateAdvancement(2) + ); - env.block.time = env.block.time.plus_seconds( - epoch - .time_configuration - .verification_key_submission_time_secs - - 2, - ); - assert_eq!( - advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), - EarlyEpochStateAdvancement(2) - ); + env.block.time = env.block.time.plus_seconds(3); + advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + assert_eq!(epoch.state, EpochState::VerificationKeyValidation); + assert_eq!( + epoch.finish_timestamp, + env.block.time.plus_seconds( + epoch + .time_configuration + .verification_key_validation_time_secs + ) + ); - env.block.time = env.block.time.plus_seconds(3); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); - let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - assert_eq!(epoch.state, EpochState::VerificationKeyValidation); - assert_eq!( - epoch.finish_timestamp, - env.block.time.plus_seconds( + env.block.time = env.block.time.plus_seconds( epoch .time_configuration .verification_key_validation_time_secs - ) - ); + - 3, + ); + assert_eq!( + advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), + EarlyEpochStateAdvancement(3) + ); - env.block.time = env.block.time.plus_seconds( - epoch - .time_configuration - .verification_key_validation_time_secs - - 3, - ); - assert_eq!( - advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), - EarlyEpochStateAdvancement(3) - ); + env.block.time = env.block.time.plus_seconds(3); + advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + assert_eq!(epoch.state, EpochState::VerificationKeyFinalization); + assert_eq!( + epoch.finish_timestamp, + env.block.time.plus_seconds( + epoch + .time_configuration + .verification_key_finalization_time_secs + ) + ); - env.block.time = env.block.time.plus_seconds(3); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); - let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - assert_eq!(epoch.state, EpochState::VerificationKeyFinalization); - assert_eq!( - epoch.finish_timestamp, - env.block.time.plus_seconds( - epoch - .time_configuration - .verification_key_finalization_time_secs - ) - ); - - env.block.time = env - .block - .time - .plus_seconds(TimeConfiguration::default().verification_key_finalization_time_secs - 1); - assert_eq!( - advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), - 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::InProgress); - assert_eq!( - epoch.finish_timestamp, - env.block + env.block.time = env + .block .time - .plus_seconds(epoch.time_configuration.in_progress_time_secs) + .plus_seconds(TimeConfiguration::default().verification_key_finalization_time_secs - 1); + assert_eq!( + advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), + 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::InProgress); + assert_eq!( + epoch.finish_timestamp, + env.block + .time + .plus_seconds(epoch.time_configuration.in_progress_time_secs) + ); + + env.block.time = env + .block + .time + .plus_seconds(epoch.time_configuration.in_progress_time_secs - 100); + assert_eq!( + advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), + EarlyEpochStateAdvancement(100) + ); + + env.block.time = env.block.time.plus_seconds(50); + assert_eq!( + advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), + EarlyEpochStateAdvancement(50) + ); + + // setup dealer details + let all_details: [_; 3] = std::array::from_fn(|i| dealer_details_fixture(i as u64 + 1)); + for details in all_details.iter() { + current_dealers() + .save(deps.as_mut().storage, &details.address, details) + .unwrap(); + } + + // Group hasn't changed, so we remain in the same epoch, with updated finish timestamp + env.block.time = env.block.time.plus_seconds(100); + let prev_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + let curr_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + let expected_epoch = Epoch::new( + EpochState::InProgress, + prev_epoch.epoch_id, + prev_epoch.time_configuration, + env.block.time, + ); + assert_eq!(curr_epoch, expected_epoch); + + // Group changed, slightly, so reset dkg state + *GROUP_MEMBERS.lock().unwrap().first_mut().unwrap() = Member { + addr: "owner4".to_string(), + weight: 10, + }; + env.block.time = env + .block + .time + .plus_seconds(epoch.time_configuration.in_progress_time_secs); + let prev_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + let curr_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + let expected_epoch = Epoch::new( + EpochState::default(), + prev_epoch.epoch_id + 1, + prev_epoch.time_configuration, + env.block.time, + ); + assert_eq!(curr_epoch, expected_epoch); + assert!(THRESHOLD.may_load(&deps.storage).unwrap().is_none()); + } + + + #[test] + fn surpass_threshold() { + let mut deps = init_contract(); + let mut env = mock_env(); + let time_configuration = TimeConfiguration::default(); + { + let mut group = GROUP_MEMBERS.lock().unwrap(); + + group.push(Member { + addr: "owner1".to_string(), + weight: 10, + }); + group.push(Member { + addr: "owner2".to_string(), + weight: 10, + }); + group.push(Member { + addr: "owner3".to_string(), + weight: 10, + }); + } + + let ret = try_surpassed_threshold(deps.as_mut(), env.clone()).unwrap_err(); + assert_eq!( + ret, + ContractError::IncorrectEpochState { + current_state: EpochState::default().to_string(), + expected_state: EpochState::InProgress.to_string() + } ); - env.block.time = env - .block - .time - .plus_seconds(epoch.time_configuration.in_progress_time_secs - 100); - assert_eq!( - advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), - EarlyEpochStateAdvancement(100) - ); + let all_details: [_; 3] = std::array::from_fn(|i| dealer_details_fixture(i as u64 + 1)); + for details in all_details.iter() { + current_dealers() + .save(deps.as_mut().storage, &details.address, details) + .unwrap(); + } - env.block.time = env.block.time.plus_seconds(50); + for times in [ + time_configuration.public_key_submission_time_secs, + time_configuration.dealing_exchange_time_secs, + time_configuration.verification_key_submission_time_secs, + time_configuration.verification_key_validation_time_secs, + time_configuration.verification_key_finalization_time_secs, + ] { + env.block.time = env.block.time.plus_seconds(times); + advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + } + let curr_epoch = CURRENT_EPOCH.load(&deps.storage).unwrap(); + assert_eq!(THRESHOLD.load(&deps.storage).unwrap(), 2); + + // epoch hasn't advanced as we are still in the threshold range + try_surpassed_threshold(deps.as_mut(), env.clone()).unwrap(); + assert_eq!(THRESHOLD.load(&deps.storage).unwrap(), 2); + assert_eq!(CURRENT_EPOCH.load(&deps.storage).unwrap(), curr_epoch); + + *GROUP_MEMBERS.lock().unwrap().first_mut().unwrap() = Member { + addr: "owner4".to_string(), + weight: 10, + }; + // epoch hasn't advanced as we are still in the threshold range + try_surpassed_threshold(deps.as_mut(), env.clone()).unwrap(); + assert_eq!(THRESHOLD.load(&deps.storage).unwrap(), 2); + assert_eq!(CURRENT_EPOCH.load(&deps.storage).unwrap(), curr_epoch); + + *GROUP_MEMBERS.lock().unwrap().last_mut().unwrap() = Member { + addr: "owner5".to_string(), + weight: 10, + }; + try_surpassed_threshold(deps.as_mut(), env.clone()).unwrap(); + assert!(THRESHOLD.may_load(&deps.storage).unwrap().is_none()); + let next_epoch = CURRENT_EPOCH.load(&deps.storage).unwrap(); assert_eq!( - advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), - EarlyEpochStateAdvancement(50) + next_epoch, + Epoch::new( + EpochState::default(), + curr_epoch.epoch_id + 1, + curr_epoch.time_configuration, + env.block.time, + ) ); } + } + + #[test] + fn reset_state() { + let mut deps = init_contract(); + let all_details: [_; 100] = std::array::from_fn(|i| dealer_details_fixture(i as u64)); + + THRESHOLD.save(deps.as_mut().storage, &42).unwrap(); + for details in all_details.iter() { + current_dealers() + .save(deps.as_mut().storage, &details.address, details) + .unwrap(); + for dealings in DEALINGS_BYTES { + dealings + .save( + deps.as_mut().storage, + &details.address, + &ContractSafeBytes(vec![1, 2, 3]), + ) + .unwrap(); + } + } + + reset_epoch_state(deps.as_mut().storage).unwrap(); + + assert!(THRESHOLD.may_load(&deps.storage).unwrap().is_none()); + for details in all_details { + for dealings in DEALINGS_BYTES { + assert!(dealings + .may_load(&deps.storage, &details.address) + .unwrap() + .is_none()); + } + assert!(current_dealers() + .may_load(deps.as_mut().storage, &details.address) + .unwrap() + .is_none()); + assert_eq!( + past_dealers() + .load(&deps.storage, &details.address) + .unwrap(), + details + ); + } + } #[test] fn verify_threshold() { diff --git a/contracts/coconut-dkg/src/support/tests/fixtures.rs b/contracts/coconut-dkg/src/support/tests/fixtures.rs index e2a3144a14..02a73b0ccf 100644 --- a/contracts/coconut-dkg/src/support/tests/fixtures.rs +++ b/contracts/coconut-dkg/src/support/tests/fixtures.rs @@ -8,13 +8,13 @@ use cosmwasm_std::Addr; pub const TEST_MIX_DENOM: &str = "unym"; -pub fn vk_share_fixture(index: u64) -> ContractVKShare { +pub fn vk_share_fixture(owner: &str, index: u64) -> ContractVKShare { ContractVKShare { share: format!("share{}", index), announce_address: format!("localhost:{}", index), node_index: index, - owner: Addr::unchecked(format!("owner{}", index)), - epoch_id: 0, + owner: Addr::unchecked(owner), + epoch_id: index, verified: index % 2 == 0, } } diff --git a/contracts/coconut-dkg/src/support/tests/helpers.rs b/contracts/coconut-dkg/src/support/tests/helpers.rs index 43b3819b08..d5451e1ee1 100644 --- a/contracts/coconut-dkg/src/support/tests/helpers.rs +++ b/contracts/coconut-dkg/src/support/tests/helpers.rs @@ -4,7 +4,13 @@ use crate::contract::instantiate; use coconut_dkg_common::msg::InstantiateMsg; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info, MockApi, MockQuerier}; -use cosmwasm_std::{Empty, MemoryStorage, OwnedDeps}; +use cosmwasm_std::{ + from_binary, to_binary, ContractResult, Empty, MemoryStorage, OwnedDeps, QuerierResult, + SystemResult, WasmQuery, +}; +use cw4::{Cw4QueryMsg, Member, MemberListResponse, MemberResponse}; +use lazy_static::lazy_static; +use std::sync::Mutex; use super::fixtures::TEST_MIX_DENOM; @@ -12,8 +18,42 @@ pub const ADMIN_ADDRESS: &str = "admin address"; pub const GROUP_CONTRACT: &str = "group contract address"; pub const MULTISIG_CONTRACT: &str = "multisig contract address"; +lazy_static! { + pub static ref GROUP_MEMBERS: Mutex> = Mutex::new(vec![]); +} + +fn querier_handler(query: &WasmQuery) -> QuerierResult { + let bin = match query { + WasmQuery::Smart { contract_addr, msg } => { + if contract_addr != GROUP_CONTRACT { + panic!("Not supported"); + } + match from_binary(msg) { + Ok(Cw4QueryMsg::Member { addr, .. }) => { + let weight = GROUP_MEMBERS.lock().unwrap().iter().find_map(|m| { + if m.addr == addr { + Some(m.weight) + } else { + None + } + }); + to_binary(&MemberResponse { weight }).unwrap() + } + Ok(Cw4QueryMsg::ListMembers { .. }) => { + let members = GROUP_MEMBERS.lock().unwrap().to_vec(); + to_binary(&MemberListResponse { members }).unwrap() + } + _ => panic!("Not supported"), + } + } + _ => panic!("Not supported"), + }; + SystemResult::Ok(ContractResult::Ok(bin)) +} + pub fn init_contract() -> OwnedDeps> { let mut deps = mock_dependencies(); + deps.querier.update_wasm(querier_handler); let msg = InstantiateMsg { group_addr: String::from(GROUP_CONTRACT), multisig_addr: String::from(MULTISIG_CONTRACT), diff --git a/contracts/coconut-dkg/src/verification_key_shares/queries.rs b/contracts/coconut-dkg/src/verification_key_shares/queries.rs index a3a02a0743..e3300330ea 100644 --- a/contracts/coconut-dkg/src/verification_key_shares/queries.rs +++ b/contracts/coconut-dkg/src/verification_key_shares/queries.rs @@ -52,6 +52,25 @@ pub(crate) mod tests { }; use cosmwasm_std::Addr; + #[test] + fn separate_epoch_ids() { + let mut deps = init_contract(); + let vk_share1 = vk_share_fixture("owner", 1); + let vk_share2 = vk_share_fixture("owner", 2); + let sender = Addr::unchecked("owner"); + vk_shares() + .save(&mut deps.storage, (&sender, 2), &vk_share2) + .unwrap(); + + let response = query_vk_shares_paged(deps.as_ref(), 1, None, None).unwrap(); + assert_eq!(0, response.shares.len()); + vk_shares() + .save(&mut deps.storage, (&sender, 1), &vk_share1) + .unwrap(); + let response = query_vk_shares_paged(deps.as_ref(), 1, None, None).unwrap(); + assert_eq!(1, response.shares.len()); + } + #[test] fn vk_shares_empty_on_init() { let deps = init_contract(); @@ -64,8 +83,9 @@ pub(crate) mod tests { let mut deps = init_contract(); let limit = 2; for n in 0..1000 { - let vk_share = vk_share_fixture(n); - let sender = Addr::unchecked(format!("owner{}", n)); + let owner = format!("owner{}", n); + let vk_share = vk_share_fixture(&owner, 0); + let sender = Addr::unchecked(owner); vk_shares() .save(&mut deps.storage, (&sender, 0), &vk_share) .unwrap(); @@ -79,8 +99,9 @@ pub(crate) mod tests { fn vk_shares_paged_retrieval_has_default_limit() { let mut deps = init_contract(); for n in 0..1000 { - let vk_share = vk_share_fixture(n); - let sender = Addr::unchecked(format!("owner{}", n)); + let owner = format!("owner{}", n); + let vk_share = vk_share_fixture(&owner, 0); + let sender = Addr::unchecked(owner); vk_shares() .save(&mut deps.storage, (&sender, 0), &vk_share) .unwrap(); @@ -99,8 +120,9 @@ pub(crate) mod tests { fn vk_shares_paged_retrieval_has_max_limit() { let mut deps = init_contract(); for n in 0..1000 { - let vk_share = vk_share_fixture(n); - let sender = Addr::unchecked(format!("owner{}", n)); + let owner = format!("owner{}", n); + let vk_share = vk_share_fixture(&owner, 0); + let sender = Addr::unchecked(owner); vk_shares() .save(&mut deps.storage, (&sender, 0), &vk_share) .unwrap(); @@ -120,8 +142,9 @@ pub(crate) mod tests { fn vk_shares_pagination_works() { let mut deps = init_contract(); - let vk_share = vk_share_fixture(1); - let sender = Addr::unchecked(format!("owner{}", 1)); + let owner = format!("owner{}", 1); + let vk_share = vk_share_fixture(&owner, 0); + let sender = Addr::unchecked(owner); vk_shares() .save(&mut deps.storage, (&sender, 0), &vk_share) .unwrap(); @@ -133,8 +156,9 @@ pub(crate) mod tests { assert_eq!(1, page1.shares.len()); // save another - let vk_share = vk_share_fixture(2); - let sender = Addr::unchecked(format!("owner{}", 2)); + let owner = format!("owner{}", 2); + let vk_share = vk_share_fixture(&owner, 0); + let sender = Addr::unchecked(owner); vk_shares() .save(&mut deps.storage, (&sender, 0), &vk_share) .unwrap(); @@ -143,8 +167,9 @@ pub(crate) mod tests { let page1 = query_vk_shares_paged(deps.as_ref(), 0, None, Option::from(per_page)).unwrap(); assert_eq!(2, page1.shares.len()); - let vk_share = vk_share_fixture(3); - let sender = Addr::unchecked(format!("owner{}", 3)); + let owner = format!("owner{}", 3); + let vk_share = vk_share_fixture(&owner, 0); + let sender = Addr::unchecked(owner); vk_shares() .save(&mut deps.storage, (&sender, 0), &vk_share) .unwrap(); @@ -165,8 +190,9 @@ pub(crate) mod tests { assert_eq!(1, page2.shares.len()); - let vk_share = vk_share_fixture(4); - let sender = Addr::unchecked(format!("owner{}", 4)); + let owner = format!("owner{}", 4); + let vk_share = vk_share_fixture(&owner, 0); + let sender = Addr::unchecked(owner); vk_shares() .save(&mut deps.storage, (&sender, 0), &vk_share) .unwrap(); diff --git a/contracts/coconut-dkg/src/verification_key_shares/transactions.rs b/contracts/coconut-dkg/src/verification_key_shares/transactions.rs index ef33f0b1a1..45bbe529d2 100644 --- a/contracts/coconut-dkg/src/verification_key_shares/transactions.rs +++ b/contracts/coconut-dkg/src/verification_key_shares/transactions.rs @@ -88,6 +88,51 @@ mod tests { use cosmwasm_std::testing::{mock_env, mock_info}; use cw_controllers::AdminError; + #[test] + fn current_epoch_id() { + let mut deps = helpers::init_contract(); + let mut env = mock_env(); + let info = mock_info("requester", &[]); + let share = "share".to_string(); + + env.block.time = env + .block + .time + .plus_seconds(TimeConfiguration::default().public_key_submission_time_secs); + advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + env.block.time = env + .block + .time + .plus_seconds(TimeConfiguration::default().dealing_exchange_time_secs); + advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + let dealer = Addr::unchecked("requester"); + let announce_address = String::from("localhost"); + let dealer_details = DealerDetails { + address: dealer.clone(), + bte_public_key_with_proof: String::new(), + announce_address: announce_address.clone(), + assigned_index: 1, + }; + dealers_storage::current_dealers() + .save(deps.as_mut().storage, &dealer, &dealer_details) + .unwrap(); + + try_commit_verification_key_share(deps.as_mut(), env.clone(), info.clone(), share.clone()) + .unwrap(); + let vk_share = vk_shares().load(&deps.storage, (&info.sender, 0)).unwrap(); + assert_eq!( + vk_share, + ContractVKShare { + share, + announce_address, + node_index: 1, + owner: dealer, + epoch_id: 0, + verified: false, + } + ); + } + #[test] fn commit_vk_share() { let mut deps = helpers::init_contract();