Skip to content

Commit

Permalink
Merge pull request #879 from CosmWasm/query_validator
Browse files Browse the repository at this point in the history
Add single validator query
  • Loading branch information
webmaster128 authored Apr 15, 2021
2 parents afe6466 + d653b37 commit 5b63cf6
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 25 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,12 @@ and this project adheres to
- cosmwasm-std: Remove `StakingMsg::Withdraw` in favour of
`DistributionMsg::SetWithdrawAddress` and
`DistributionMsg::WithdrawDelegatorReward` ([#848]).
- cosmwasm-std: Rename `StakingQuery::Validators`, `ValidatorsResponse` and
`QuerierWrapper::query_validators` to `StakingQuery::AllValidators`,
`AllValidatorsResponse` and `QuerierWrapper.query_all_validators`. Add
`StakingQuery::Validator`, `ValidatorResponse` and
`QuerierWrapper::query_validator` to allow querying a single validator.
([#879])

[#696]: https://github.com/CosmWasm/cosmwasm/issues/696
[#697]: https://github.com/CosmWasm/cosmwasm/issues/697
Expand All @@ -186,6 +192,7 @@ and this project adheres to
[#871]: https://github.com/CosmWasm/cosmwasm/issues/871
[#861]: https://github.com/CosmWasm/cosmwasm/issues/861
[#848]: https://github.com/CosmWasm/cosmwasm/issues/848
[#879]: https://github.com/CosmWasm/cosmwasm/pull/879

### Deprecated

Expand Down
28 changes: 25 additions & 3 deletions contracts/reflect/schema/query_msg.json
Original file line number Diff line number Diff line change
Expand Up @@ -420,17 +420,39 @@
"additionalProperties": false
},
{
"description": "Returns all registered Validators on the system",
"description": "Returns all validators in the currently active validator set.\n\nThe query response type is `AllValidatorsResponse`.",
"type": "object",
"required": [
"validators"
"all_validators"
],
"properties": {
"validators": {
"all_validators": {
"type": "object"
}
},
"additionalProperties": false
},
{
"description": "Returns the validator at the given address. Returns None if the validator is not part of the currently active validator set.\n\nThe query response type is `ValidatorResponse`.",
"type": "object",
"required": [
"validator"
],
"properties": {
"validator": {
"type": "object",
"required": [
"address"
],
"properties": {
"address": {
"description": "The validator's address (e.g. (e.g. cosmosvaloper1...))",
"type": "string"
}
}
}
},
"additionalProperties": false
}
]
},
Expand Down
4 changes: 2 additions & 2 deletions contracts/staking/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ pub fn instantiate(
msg: InstantiateMsg,
) -> StdResult<Response> {
// ensure the validator is registered
let vals = deps.querier.query_validators()?;
if !vals.iter().any(|v| v.address == msg.validator) {
let validator = deps.querier.query_validator(msg.validator.clone())?;
if validator.is_none() {
return Err(StdError::generic_err(format!(
"{} is not in the current validator set",
msg.validator
Expand Down
4 changes: 2 additions & 2 deletions packages/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ pub use crate::query::{
};
#[cfg(feature = "staking")]
pub use crate::query::{
AllDelegationsResponse, BondedDenomResponse, Delegation, FullDelegation, StakingQuery,
Validator, ValidatorsResponse,
AllDelegationsResponse, AllValidatorsResponse, BondedDenomResponse, Delegation, FullDelegation,
StakingQuery, Validator, ValidatorResponse,
};
pub use crate::results::{
attr, wasm_execute, wasm_instantiate, Attribute, BankMsg, ContractResult, CosmosMsg, Empty,
Expand Down
72 changes: 65 additions & 7 deletions packages/std/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use crate::query::{
};
#[cfg(feature = "staking")]
use crate::query::{
AllDelegationsResponse, BondedDenomResponse, DelegationResponse, FullDelegation, StakingQuery,
Validator, ValidatorsResponse,
AllDelegationsResponse, AllValidatorsResponse, BondedDenomResponse, DelegationResponse,
FullDelegation, StakingQuery, Validator, ValidatorResponse,
};
use crate::results::{ContractResult, Empty, SystemResult};
use crate::serde::{from_slice, to_binary};
Expand Down Expand Up @@ -459,12 +459,21 @@ impl StakingQuerier {
};
to_binary(&res).into()
}
StakingQuery::Validators {} => {
let res = ValidatorsResponse {
StakingQuery::AllValidators {} => {
let res = AllValidatorsResponse {
validators: self.validators.clone(),
};
to_binary(&res).into()
}
StakingQuery::Validator { address } => {
let validator: Option<Validator> = self
.validators
.iter()
.find(|validator| validator.address == *address)
.cloned();
let res = ValidatorResponse { validator };
to_binary(&res).into()
}
StakingQuery::AllDelegations { delegator } => {
let delegations: Vec<_> = self
.delegations
Expand Down Expand Up @@ -874,7 +883,7 @@ mod tests {

#[cfg(feature = "staking")]
#[test]
fn staking_querier_validators() {
fn staking_querier_all_validators() {
let val1 = Validator {
address: String::from("validator-one"),
commission: Decimal::percent(1),
Expand All @@ -892,13 +901,62 @@ mod tests {

// one match
let raw = staking
.query(&StakingQuery::Validators {})
.query(&StakingQuery::AllValidators {})
.unwrap()
.unwrap();
let vals: ValidatorsResponse = from_binary(&raw).unwrap();
let vals: AllValidatorsResponse = from_binary(&raw).unwrap();
assert_eq!(vals.validators, vec![val1, val2]);
}

#[cfg(feature = "staking")]
#[test]
fn staking_querier_validator() {
let address1 = String::from("validator-one");
let address2 = String::from("validator-two");
let address_non_existent = String::from("wannabe-validator");

let val1 = Validator {
address: address1.clone(),
commission: Decimal::percent(1),
max_commission: Decimal::percent(3),
max_change_rate: Decimal::percent(1),
};
let val2 = Validator {
address: address2.clone(),
commission: Decimal::permille(15),
max_commission: Decimal::permille(40),
max_change_rate: Decimal::permille(5),
};

let staking = StakingQuerier::new("ustake", &[val1.clone(), val2.clone()], &[]);

// query 1
let raw = staking
.query(&StakingQuery::Validator { address: address1 })
.unwrap()
.unwrap();
let res: ValidatorResponse = from_binary(&raw).unwrap();
assert_eq!(res.validator, Some(val1));

// query 2
let raw = staking
.query(&StakingQuery::Validator { address: address2 })
.unwrap()
.unwrap();
let res: ValidatorResponse = from_binary(&raw).unwrap();
assert_eq!(res.validator, Some(val2));

// query non-existent
let raw = staking
.query(&StakingQuery::Validator {
address: address_non_existent,
})
.unwrap()
.unwrap();
let res: ValidatorResponse = from_binary(&raw).unwrap();
assert_eq!(res.validator, None);
}

#[cfg(feature = "staking")]
// gets delegators from query or panic
fn get_all_delegators<U: Into<String>>(
Expand Down
4 changes: 2 additions & 2 deletions packages/std/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ mod wasm;
pub use bank::{AllBalanceResponse, BalanceResponse, BankQuery};
#[cfg(feature = "staking")]
pub use staking::{
AllDelegationsResponse, BondedDenomResponse, Delegation, DelegationResponse, FullDelegation,
StakingQuery, Validator, ValidatorsResponse,
AllDelegationsResponse, AllValidatorsResponse, BondedDenomResponse, Delegation,
DelegationResponse, FullDelegation, StakingQuery, Validator, ValidatorResponse,
};
#[cfg(feature = "stargate")]
pub use stargate::StargateResponse;
Expand Down
24 changes: 20 additions & 4 deletions packages/std/src/query/staking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,18 @@ pub enum StakingQuery {
delegator: String,
validator: String,
},
/// Returns all registered Validators on the system
Validators {},
/// Returns all validators in the currently active validator set.
///
/// The query response type is `AllValidatorsResponse`.
AllValidators {},
/// Returns the validator at the given address. Returns None if the validator is
/// not part of the currently active validator set.
///
/// The query response type is `ValidatorResponse`.
Validator {
/// The validator's address (e.g. (e.g. cosmosvaloper1...))
address: String,
},
}

/// BondedDenomResponse is data format returned from StakingRequest::BondedDenom query
Expand Down Expand Up @@ -85,12 +95,18 @@ pub struct FullDelegation {
pub accumulated_rewards: Vec<Coin>,
}

/// ValidatorsResponse is data format returned from StakingRequest::Validators query
/// The data format returned from StakingRequest::AllValidators query
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct ValidatorsResponse {
pub struct AllValidatorsResponse {
pub validators: Vec<Validator>,
}

/// The data format returned from StakingRequest::Validator query
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct ValidatorResponse {
pub validator: Option<Validator>,
}

/// Instances are created in the querier.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct Validator {
Expand Down
20 changes: 15 additions & 5 deletions packages/std/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use crate::query::{
};
#[cfg(feature = "staking")]
use crate::query::{
AllDelegationsResponse, BondedDenomResponse, Delegation, DelegationResponse, FullDelegation,
StakingQuery, Validator, ValidatorsResponse,
AllDelegationsResponse, AllValidatorsResponse, BondedDenomResponse, Delegation,
DelegationResponse, FullDelegation, StakingQuery, Validator, ValidatorResponse,
};
use crate::results::{ContractResult, Empty, SystemResult};
use crate::serde::{from_binary, to_binary, to_vec};
Expand Down Expand Up @@ -261,12 +261,22 @@ impl<'a> QuerierWrapper<'a> {
}

#[cfg(feature = "staking")]
pub fn query_validators(&self) -> StdResult<Vec<Validator>> {
let request = StakingQuery::Validators {}.into();
let res: ValidatorsResponse = self.query(&request)?;
pub fn query_all_validators(&self) -> StdResult<Vec<Validator>> {
let request = StakingQuery::AllValidators {}.into();
let res: AllValidatorsResponse = self.query(&request)?;
Ok(res.validators)
}

#[cfg(feature = "staking")]
pub fn query_validator<U: Into<String>>(&self, address: U) -> StdResult<Option<Validator>> {
let request = StakingQuery::Validator {
address: address.into(),
}
.into();
let res: ValidatorResponse = self.query(&request)?;
Ok(res.validator)
}

#[cfg(feature = "staking")]
pub fn query_bonded_denom(&self) -> StdResult<String> {
let request = StakingQuery::BondedDenom {}.into();
Expand Down

0 comments on commit 5b63cf6

Please sign in to comment.