From 1d90c078bf277126fb1fc415bc6dc9ab3b4f8e89 Mon Sep 17 00:00:00 2001 From: sotnikov-s Date: Tue, 15 Aug 2023 15:26:32 +0200 Subject: [PATCH] add migration handler+tests for voting registry v2 --- .../neutron-voting-registry/src/contract.rs | 24 +++++-- .../src/testing/tests.rs | 71 ++++++++++++++++++- 2 files changed, 88 insertions(+), 7 deletions(-) diff --git a/contracts/dao/voting/neutron-voting-registry/src/contract.rs b/contracts/dao/voting/neutron-voting-registry/src/contract.rs index adabcabc..993a1ef2 100644 --- a/contracts/dao/voting/neutron-voting-registry/src/contract.rs +++ b/contracts/dao/voting/neutron-voting-registry/src/contract.rs @@ -1,16 +1,17 @@ +use crate::error::ContractError; +use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, VotingVault}; +use crate::state::{Config, VotingVaultState, CONFIG, DAO, VAULT_STATES}; #[cfg(not(feature = "library"))] use cosmwasm_std::{ entry_point, to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, }; use cw2::set_contract_version; +use cw_storage_plus::Item; use cwd_interface::voting::{self, TotalPowerAtHeightResponse, VotingPowerAtHeightResponse}; use neutron_vault::msg::QueryMsg as VaultQueryMsg; - -use crate::error::ContractError; -use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, VotingVault}; -use crate::state::{Config, VotingVaultState, CONFIG, DAO, VAULT_STATES}; - +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; pub(crate) const CONTRACT_NAME: &str = "crates.io:neutron-voting-registry"; pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -305,6 +306,19 @@ pub fn query_dao(deps: Deps) -> StdResult { #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + // read the prev version config + #[derive(Serialize, Deserialize, JsonSchema)] + struct OldConfig { + pub owner: Addr, + pub voting_vaults: Vec, + } + let old_config: OldConfig = Item::new("config").load(deps.storage)?; + + // move vaults from old config to a dedicated Item + for vault in old_config.voting_vaults { + VAULT_STATES.save(deps.storage, vault, &VotingVaultState::Active, 1u64)?; + } + // Set contract to version to latest set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; Ok(Response::default()) diff --git a/contracts/dao/voting/neutron-voting-registry/src/testing/tests.rs b/contracts/dao/voting/neutron-voting-registry/src/testing/tests.rs index f6785b35..a84982b1 100644 --- a/contracts/dao/voting/neutron-voting-registry/src/testing/tests.rs +++ b/contracts/dao/voting/neutron-voting-registry/src/testing/tests.rs @@ -9,9 +9,12 @@ use crate::testing::mock_querier::{ }; use cosmwasm_std::testing::{mock_env, mock_info}; use cosmwasm_std::{from_binary, Addr, Deps, DepsMut, Env, MessageInfo, Response, Uint128}; +use cw_storage_plus::Item; use cwd_interface::voting::{ InfoResponse, TotalPowerAtHeightResponse, VotingPowerAtHeightResponse, }; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; const DAO_ADDR: &str = "dao"; const ADDR1: &str = "addr1"; @@ -792,13 +795,77 @@ fn test_vaults_activation_deactivation_wrong_switch() { } #[test] -pub fn test_migrate_update_version() { +pub fn test_migrate() { let mut deps = mock_dependencies(); + let env = mock_env(); + let migration_height = env.block.height; cw2::set_contract_version(&mut deps.storage, "my-contract", "old-version").unwrap(); - migrate(deps.as_mut(), mock_env(), MigrateMsg {}).unwrap(); + + // define and store the previous version of config + #[derive(Serialize, Deserialize, JsonSchema)] + struct OldConfig { + pub owner: Addr, + pub voting_vaults: Vec, + } + Item::new("config") + .save( + deps.as_mut().storage, + &OldConfig { + owner: Addr::unchecked(DAO_ADDR), + voting_vaults: vec![Addr::unchecked(MOCK_VAULT_1), Addr::unchecked(MOCK_VAULT_2)], + }, + ) + .unwrap(); + + migrate(deps.as_mut(), env.clone(), MigrateMsg {}).unwrap(); + let version = cw2::get_contract_version(&deps.storage).unwrap(); assert_eq!(version.version, CONTRACT_VERSION); assert_eq!(version.contract, CONTRACT_NAME); + assert_eq!( + get_voting_vaults(deps.as_ref(), env.clone(), Some(migration_height)), + vec![ + VotingVault { + address: String::from(MOCK_VAULT_1), + name: String::from(MOCK_VAULT_1_NAME), + description: String::from(MOCK_VAULT_1_DESC), + state: VotingVaultState::Active, + }, + VotingVault { + address: String::from(MOCK_VAULT_2), + name: String::from(MOCK_VAULT_2_NAME), + description: String::from(MOCK_VAULT_2_DESC), + state: VotingVaultState::Active, + } + ], + ); + assert_eq!( + get_total_voting_power(deps.as_ref(), env.clone(), Some(migration_height)).power, + Uint128::from(MOCK_VAULT_1_VP + MOCK_VAULT_2_VP), + ); + + // make sure vaults are active starting with the height next to the beginning of the chain + assert_eq!( + get_voting_vaults(deps.as_ref(), env.clone(), Some(2u64)), + vec![ + VotingVault { + address: String::from(MOCK_VAULT_1), + name: String::from(MOCK_VAULT_1_NAME), + description: String::from(MOCK_VAULT_1_DESC), + state: VotingVaultState::Active, + }, + VotingVault { + address: String::from(MOCK_VAULT_2), + name: String::from(MOCK_VAULT_2_NAME), + description: String::from(MOCK_VAULT_2_DESC), + state: VotingVaultState::Active, + } + ], + ); + assert_eq!( + get_total_voting_power(deps.as_ref(), env, Some(2u64)).power, + Uint128::from(MOCK_VAULT_1_VP + MOCK_VAULT_2_VP), + ); } fn get_voting_vaults(deps: Deps, env: Env, height: Option) -> Vec {