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

Do not validate validator addresses #183

Merged
merged 20 commits into from
Jun 19, 2024
Merged
Changes from 17 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
46 changes: 27 additions & 19 deletions src/staking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use cosmwasm_std::{
coin, ensure, ensure_eq, to_json_binary, Addr, AllDelegationsResponse, AllValidatorsResponse,
Api, BankMsg, Binary, BlockInfo, BondedDenomResponse, Coin, CustomMsg, CustomQuery, Decimal,
Delegation, DelegationResponse, DistributionMsg, Empty, Event, FullDelegation, Querier,
StakingMsg, StakingQuery, Storage, Timestamp, Uint128, Validator, ValidatorResponse,
StakingMsg, StakingQuery, StdResult, Storage, Timestamp, Uint128, Validator, ValidatorResponse,
};
use cw_storage_plus::{Deque, Item, Map};
use schemars::JsonSchema;
Expand Down Expand Up @@ -177,14 +177,14 @@ impl StakeKeeper {
/// Add a new validator available for staking
pub fn add_validator(
&self,
api: &dyn Api,
_api: &dyn Api,
storage: &mut dyn Storage,
block: &BlockInfo,
validator: Validator,
) -> AnyResult<()> {
let mut storage = prefixed(storage, NAMESPACE_STAKING);

let val_addr = api.addr_validate(&validator.address)?;
let val_addr = validate_valoper_address(&validator.address)?;
if VALIDATOR_MAP.may_load(&storage, &val_addr)?.is_some() {
bail!(
"Cannot add validator {}, since a validator with that address already exists",
Expand Down Expand Up @@ -288,7 +288,7 @@ impl StakeKeeper {
/// It saves the validator info and stakers, so make sure not to overwrite that.
/// Always call this to update rewards before changing anything that influences future rewards.
fn update_rewards(
api: &dyn Api,
_api: &dyn Api,
staking_storage: &mut dyn Storage,
block: &BlockInfo,
validator: &Addr,
Expand Down Expand Up @@ -320,7 +320,7 @@ impl StakeKeeper {

// update delegators
if !new_rewards.is_zero() {
let validator_addr = api.addr_validate(&validator_obj.address)?;
let validator_addr = validate_valoper_address(&validator_obj.address)?;
// update all delegators
for staker in validator_info.stakers.iter() {
STAKES.update(
Expand Down Expand Up @@ -644,7 +644,7 @@ impl Module for StakeKeeper {
let mut staking_storage = prefixed(storage, NAMESPACE_STAKING);
match msg {
StakingMsg::Delegate { validator, amount } => {
let validator = api.addr_validate(&validator)?;
let validator = validate_valoper_address(&validator)?;

// see https://github.com/cosmos/cosmos-sdk/blob/3c5387048f75d7e78b40c5b8d2421fdb8f5d973a/x/staking/types/msg.go#L202-L207
if amount.amount.is_zero() {
Expand Down Expand Up @@ -679,7 +679,7 @@ impl Module for StakeKeeper {
Ok(AppResponse { events, data: None })
}
StakingMsg::Undelegate { validator, amount } => {
let validator = api.addr_validate(&validator)?;
let validator = validate_valoper_address(&validator)?;
self.validate_denom(&staking_storage, &amount)?;

// see https://github.com/cosmos/cosmos-sdk/blob/3c5387048f75d7e78b40c5b8d2421fdb8f5d973a/x/staking/types/msg.go#L292-L297
Expand Down Expand Up @@ -719,8 +719,8 @@ impl Module for StakeKeeper {
dst_validator,
amount,
} => {
let src_validator = api.addr_validate(&src_validator)?;
let dst_validator = api.addr_validate(&dst_validator)?;
let src_validator = validate_valoper_address(&src_validator)?;
let dst_validator = validate_valoper_address(&dst_validator)?;
// see https://github.com/cosmos/cosmos-sdk/blob/v0.46.1/x/staking/keeper/msg_server.go#L316-L322
let events = vec![Event::new("redelegate")
.add_attribute("source_validator", &src_validator)
Expand Down Expand Up @@ -862,7 +862,7 @@ impl Module for StakeKeeper {
percentage,
} => {
let mut staking_storage = prefixed(storage, NAMESPACE_STAKING);
let validator = api.addr_validate(&validator)?;
let validator = validate_valoper_address(&validator)?;
self.validate_percentage(percentage)?;
self.slash(api, &mut staking_storage, block, &validator, percentage)?;
Ok(AppResponse::default())
Expand Down Expand Up @@ -956,7 +956,7 @@ impl Module for DistributionKeeper {
) -> AnyResult<AppResponse> {
match msg {
DistributionMsg::WithdrawDelegatorReward { validator } => {
let validator_addr = api.addr_validate(&validator)?;
let validator_addr = validate_valoper_address(&validator)?;

let rewards = self.remove_rewards(api, storage, block, &sender, &validator_addr)?;

Expand Down Expand Up @@ -1027,12 +1027,21 @@ impl Module for DistributionKeeper {
}
}

/// Utility function for validating validator's address.
///
/// Currently, we do not validate this address, because we do not have a place to store Bech32 prefix for validators.
/// In real-life blockchains, validator addresses have a different prefix than user addresses.
/// In case such a validation should be possible in the future, just place it inside this function.
fn validate_valoper_address(human: &str) -> StdResult<Addr> {
DariuszDepta marked this conversation as resolved.
Show resolved Hide resolved
Ok(Addr::unchecked(human))
}

#[cfg(test)]
mod test {
use super::*;
use crate::{
BankKeeper, FailingModule, GovFailingModule, IbcFailingModule, Router, StargateFailing,
WasmKeeper,
BankKeeper, FailingModule, GovFailingModule, IbcFailingModule, IntoBech32, Router,
StargateFailing, WasmKeeper,
};
use cosmwasm_std::{
coins, from_json,
Expand Down Expand Up @@ -1092,9 +1101,8 @@ mod test {
fn new(validator1: ValidatorProperties, validator2: ValidatorProperties) -> Self {
// Utility function for creating a validator's address,
// which has a different prefix from a user's address.
fn valoper_address(api: &MockApi, value: &str) -> Addr {
//TODO: this will be different in next PR, as requested in: https://github.com/CosmWasm/cw-multi-test/issues/173
api.addr_make(value)
fn valoper_address(value: &str) -> Addr {
value.into_bech32_with_prefix("cosmwasmvaloper")
}

// Utility function for creating a user's address,
Expand All @@ -1117,9 +1125,9 @@ mod test {
let mut storage = MockStorage::new();
let block = mock_env().block;

let validator_addr_1 = valoper_address(&api, "validator1");
let validator_addr_2 = valoper_address(&api, "validator2");
let validator_addr_3 = valoper_address(&api, "validator3");
let validator_addr_1 = valoper_address("validator1");
let validator_addr_2 = valoper_address("validator2");
let validator_addr_3 = valoper_address("validator3");

// configure basic staking parameters
router
Expand Down