Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

valset: Add a feature to update min_weight and max_validators #45

Merged
merged 2 commits into from
Jan 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 45 additions & 4 deletions contracts/tgrade-valset/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use std::convert::TryInto;
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{
to_binary, Addr, Binary, BlockInfo, Decimal, Deps, DepsMut, Empty, Env, MessageInfo, Order,
Reply, StdResult, Timestamp, WasmMsg,
to_binary, Addr, Binary, BlockInfo, Decimal, Deps, DepsMut, Env, MessageInfo, Order, Reply,
StdError, StdResult, Timestamp, WasmMsg,
};

use cw2::set_contract_version;
Expand All @@ -24,7 +24,7 @@ use tg_utils::{ensure_from_older_version, JailingDuration, SlashMsg, ADMIN};
use crate::error::ContractError;
use crate::msg::{
EpochResponse, ExecuteMsg, InstantiateMsg, InstantiateResponse, JailingPeriod,
ListActiveValidatorsResponse, ListValidatorResponse, ListValidatorSlashingResponse,
ListActiveValidatorsResponse, ListValidatorResponse, ListValidatorSlashingResponse, MigrateMsg,
OperatorResponse, QueryMsg, RewardsDistribution, RewardsInstantiateMsg, ValidatorMetadata,
ValidatorResponse,
};
Expand Down Expand Up @@ -151,6 +151,11 @@ pub fn execute(
info,
admin.map(|admin| api.addr_validate(&admin)).transpose()?,
)?),
ExecuteMsg::UpdateConfig {
min_weight,
max_validators,
} => execute_update_config(deps, info, min_weight, max_validators),

ExecuteMsg::RegisterValidatorKey { pubkey, metadata } => {
execute_register_validator_key(deps, env, info, pubkey, metadata)
}
Expand All @@ -163,6 +168,31 @@ pub fn execute(
}
}

fn execute_update_config(
deps: DepsMut,
info: MessageInfo,
min_weight: Option<u64>,
max_validators: Option<u32>,
) -> Result<Response, ContractError> {
ADMIN.assert_admin(deps.as_ref(), &info.sender)?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good this is checked.


CONFIG.update::<_, StdError>(deps.storage, |mut cfg| {
if let Some(min_weight) = min_weight {
cfg.min_weight = min_weight;
}
if let Some(max_validators) = max_validators {
cfg.max_validators = max_validators;
}
Ok(cfg)
})?;

let res = Response::new()
.add_attribute("action", "update_config")
.add_attribute("operator", &info.sender);

Ok(res)
}

fn execute_register_validator_key(
deps: DepsMut,
_env: Env,
Expand Down Expand Up @@ -722,8 +752,19 @@ fn calculate_diff(
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(deps: DepsMut, _env: Env, _msg: Empty) -> Result<Response, ContractError> {
pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result<Response, ContractError> {
ensure_from_older_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;

CONFIG.update::<_, StdError>(deps.storage, |mut cfg| {
if let Some(min_weight) = msg.min_weight {
cfg.min_weight = min_weight;
}
if let Some(max_validators) = msg.max_validators {
cfg.max_validators = max_validators;
}
Ok(cfg)
})?;

Ok(Response::new())
}

Expand Down
12 changes: 12 additions & 0 deletions contracts/tgrade-valset/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,11 @@ pub enum ExecuteMsg {
UpdateAdmin {
admin: Option<String>,
},
/// Alter config values
UpdateConfig {
min_weight: Option<u64>,
max_validators: Option<u32>,
},
/// Links info.sender (operator) to this Tendermint consensus key.
/// The operator cannot re-register another key.
/// No two operators may have the same consensus_key.
Expand Down Expand Up @@ -416,6 +421,13 @@ pub struct InstantiateResponse {
pub rewards_contract: Addr,
}

#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)]
#[serde(rename_all = "snake_case")]
pub struct MigrateMsg {
pub min_weight: Option<u64>,
pub max_validators: Option<u32>,
}

#[cfg(test)]
mod test {
use super::*;
Expand Down
2 changes: 2 additions & 0 deletions contracts/tgrade-valset/src/multitest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ mod contract;
mod double_sign;
mod helpers;
mod jailing;
mod migration;
mod rewards_split;
mod slashing;
mod stake;
mod suite;
mod update_config;
29 changes: 29 additions & 0 deletions contracts/tgrade-valset/src/multitest/migration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use super::suite::SuiteBuilder;
use crate::msg::MigrateMsg;

#[test]
fn migration_can_alter_cfg() {
let mut suite = SuiteBuilder::new()
.with_max_validators(6)
.with_min_weight(3)
.build();
let admin = suite.admin().to_string();

let cfg = suite.config().unwrap();
assert_eq!(cfg.max_validators, 6);
assert_eq!(cfg.min_weight, 3);

suite
.migrate(
&admin,
&MigrateMsg {
min_weight: Some(5),
max_validators: Some(10),
},
)
.unwrap();

let cfg = suite.config().unwrap();
assert_eq!(cfg.max_validators, 10);
assert_eq!(cfg.min_weight, 5);
}
34 changes: 33 additions & 1 deletion contracts/tgrade-valset/src/multitest/suite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ pub fn contract_valset() -> Box<dyn Contract<TgradeMsg>> {
crate::contract::query,
)
.with_sudo(crate::contract::sudo)
.with_reply(crate::contract::reply);
.with_reply(crate::contract::reply)
.with_migrate(crate::contract::migrate);

Box::new(contract)
}
Expand Down Expand Up @@ -391,6 +392,7 @@ impl SuiteBuilder {

Suite {
app,
valset_code_id: valset_id,
valset,
membership,
distribution_contracts,
Expand All @@ -409,6 +411,8 @@ pub struct Suite {
/// Multitest app
#[derivative(Debug = "ignore")]
app: TgradeApp,
/// The code id of the valset contract
valset_code_id: u64,
/// tgrade-valset contract address
valset: Addr,
/// membership contract address
Expand Down Expand Up @@ -552,6 +556,23 @@ impl Suite {
)
}

pub fn update_config(
&mut self,
executor: &str,
min_weight: impl Into<Option<u64>>,
max_validators: impl Into<Option<u32>>,
) -> AnyResult<AppResponse> {
self.app.execute_contract(
Addr::unchecked(executor),
self.valset.clone(),
&ExecuteMsg::UpdateConfig {
min_weight: min_weight.into(),
max_validators: max_validators.into(),
},
&[],
)
}

pub fn slash(
&mut self,
executor: &str,
Expand Down Expand Up @@ -734,4 +755,15 @@ impl Suite {
&[],
)
}

/// Migrates the contract to the same version (same code id), but possibly changing
/// some cfg values via MigrateMsg.
pub fn migrate(&mut self, addr: &str, msg: &MigrateMsg) -> AnyResult<AppResponse> {
self.app.migrate_contract(
Addr::unchecked(addr),
self.valset.clone(),
msg,
self.valset_code_id,
)
}
}
57 changes: 57 additions & 0 deletions contracts/tgrade-valset/src/multitest/update_config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use cw_controllers::AdminError;

use crate::error::ContractError;

use super::suite::SuiteBuilder;

#[test]
fn update_cfg() {
let mut suite = SuiteBuilder::new()
.with_max_validators(6)
.with_min_weight(3)
.build();
let admin = suite.admin().to_string();

let cfg = suite.config().unwrap();
assert_eq!(cfg.max_validators, 6);
assert_eq!(cfg.min_weight, 3);

suite.update_config(&admin, Some(5), Some(10)).unwrap();

let cfg = suite.config().unwrap();
assert_eq!(cfg.max_validators, 10);
assert_eq!(cfg.min_weight, 5);
}

#[test]
fn none_values_do_not_alter_cfg() {
let mut suite = SuiteBuilder::new()
.with_max_validators(6)
.with_min_weight(3)
.build();
let admin = suite.admin().to_string();

let cfg = suite.config().unwrap();
assert_eq!(cfg.max_validators, 6);
assert_eq!(cfg.min_weight, 3);

suite.update_config(&admin, None, None).unwrap();

// Make sure the values haven't changed.
let cfg = suite.config().unwrap();
assert_eq!(cfg.max_validators, 6);
assert_eq!(cfg.min_weight, 3);
}

#[test]
fn non_admin_cannot_update_cfg() {
let mut suite = SuiteBuilder::new().build();

let err = suite
.update_config("random fella", Some(5), Some(10))
.unwrap_err();
assert_eq!(
ContractError::AdminError(AdminError::NotAdmin {}),
err.downcast().unwrap(),
);
}