Feature/dkg rerun tests (#2875)
* Some contract unit tests * Hook for group queries * Test epoch advancement * Use separate process for tests using group global var
This commit is contained in:
committed by
GitHub
parent
404473c128
commit
f1d0bd0bf4
@@ -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" }
|
||||
group-contract-common = { path = "../../common/cosmwasm-smart-contracts/group-contract" }
|
||||
lazy_static = "1.4"
|
||||
rusty-fork = "0.3"
|
||||
@@ -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() {
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Vec<Member>> = 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<MemoryStorage, MockApi, MockQuerier<Empty>> {
|
||||
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),
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user