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

Query Response Constructors #1766

Merged
merged 6 commits into from
Jul 15, 2023
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
37 changes: 35 additions & 2 deletions packages/std/src/query/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ pub struct SupplyResponse {
pub amount: Coin,
}

#[cfg(feature = "cosmwasm_1_1")]
impl_response_constructor!(SupplyResponse, amount: Coin);

#[cfg(feature = "cosmwasm_1_1")]
impl QueryResponseType for SupplyResponse {}

Expand All @@ -55,6 +58,8 @@ pub struct BalanceResponse {
pub amount: Coin,
}

impl_response_constructor!(BalanceResponse, amount: Coin);
Copy link
Member

Choose a reason for hiding this comment

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

Great. This also brings up #1767


impl QueryResponseType for BalanceResponse {}

#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, JsonSchema)]
Expand All @@ -64,22 +69,27 @@ pub struct AllBalanceResponse {
pub amount: Vec<Coin>,
}

impl_response_constructor!(AllBalanceResponse, amount: Vec<Coin>);

impl QueryResponseType for AllBalanceResponse {}

#[cfg(feature = "cosmwasm_1_3")]
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, JsonSchema)]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub struct DenomMetadataResponse {
/// The metadata for the queried denom.
pub metadata: DenomMetadata,
}

#[cfg(feature = "cosmwasm_1_3")]
impl_response_constructor!(DenomMetadataResponse, metadata: DenomMetadata);

#[cfg(feature = "cosmwasm_1_3")]
impl QueryResponseType for DenomMetadataResponse {}

#[cfg(feature = "cosmwasm_1_3")]
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, JsonSchema)]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub struct AllDenomMetadataResponse {
Expand All @@ -88,5 +98,28 @@ pub struct AllDenomMetadataResponse {
pub next_key: Option<Binary>,
}

#[cfg(feature = "cosmwasm_1_3")]
impl_response_constructor!(
AllDenomMetadataResponse,
metadata: Vec<DenomMetadata>,
next_key: Option<Binary>
);

#[cfg(feature = "cosmwasm_1_3")]
impl QueryResponseType for AllDenomMetadataResponse {}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn private_constructor_works() {
let response = AllBalanceResponse::new(vec![Coin::new(1234, "uatom")]);
assert_eq!(
response,
AllBalanceResponse {
amount: vec![Coin::new(1234, "uatom")]
}
);
}
}
8 changes: 6 additions & 2 deletions packages/std/src/query/distribution.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use crate::Addr;

use super::query_response::QueryResponseType;

#[non_exhaustive]
Expand All @@ -12,11 +14,13 @@ pub enum DistributionQuery {
}

// https://github.com/cosmos/cosmos-sdk/blob/4f6f6c00021f4b5ee486bbb71ae2071a8ceb47c9/x/distribution/types/query.pb.go#L832-L835
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, JsonSchema)]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub struct DelegatorWithdrawAddressResponse {
pub withdraw_address: String,
pub withdraw_address: Addr,
}

impl_response_constructor!(DelegatorWithdrawAddressResponse, withdraw_address: Addr);

impl QueryResponseType for DelegatorWithdrawAddressResponse {}
6 changes: 6 additions & 0 deletions packages/std/src/query/ibc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,18 @@ pub struct PortIdResponse {
pub port_id: String,
}

impl_response_constructor!(PortIdResponse, port_id: String);

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct ListChannelsResponse {
pub channels: Vec<IbcChannel>,
}

impl_response_constructor!(ListChannelsResponse, channels: Vec<IbcChannel>);

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct ChannelResponse {
pub channel: Option<IbcChannel>,
}

impl_response_constructor!(ChannelResponse, channel: Option<IbcChannel>);
19 changes: 19 additions & 0 deletions packages/std/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@ use serde::{Deserialize, Serialize};
use crate::Binary;
use crate::Empty;

/// Implements a hidden constructor for query responses.
macro_rules! impl_response_constructor {
( $response:ty, $( $field: ident : $t: ty),* ) => {
impl $response {
/// Constructor for testing frameworks such as cw-multi-test.
/// This is required because query response types should be #[non_exhaustive].
/// As a contract developer you should not need this constructor since
/// query responses are constructed for you via deserialization.
///
/// Warning: This can change in breaking ways in minor versions.
#[doc(hidden)]
#[allow(dead_code)]
pub fn new($( $field: $t),*) -> Self {
Self { $( $field ),* }
}
}
};
}

mod bank;
mod distribution;
mod ibc;
Expand Down
4 changes: 3 additions & 1 deletion packages/std/src/query/query_response.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::fmt::Debug;

use serde::de::DeserializeOwned;

/// A marker trait for query response types.
Expand All @@ -13,4 +15,4 @@ use serde::de::DeserializeOwned;
/// - multi-test/cw-sdk: create a default instance and mutate the fields
///
/// This trait is crate-internal and can change any time.
pub(crate) trait QueryResponseType: Default + DeserializeOwned {}
pub(crate) trait QueryResponseType: DeserializeOwned + Debug + PartialEq + Clone {}
22 changes: 22 additions & 0 deletions packages/std/src/query/staking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use serde::{Deserialize, Serialize};

use crate::{Addr, Coin, Decimal};

use super::query_response::QueryResponseType;

#[non_exhaustive]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
Expand Down Expand Up @@ -40,13 +42,21 @@ pub struct BondedDenomResponse {
pub denom: String,
}

impl QueryResponseType for BondedDenomResponse {}

impl_response_constructor!(BondedDenomResponse, denom: String);

/// DelegationsResponse is data format returned from StakingRequest::AllDelegations query
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct AllDelegationsResponse {
pub delegations: Vec<Delegation>,
}

impl QueryResponseType for AllDelegationsResponse {}

impl_response_constructor!(AllDelegationsResponse, delegations: Vec<Delegation>);

/// Delegation is basic (cheap to query) data about a delegation.
///
/// Instances are created in the querier.
Expand Down Expand Up @@ -76,6 +86,10 @@ pub struct DelegationResponse {
pub delegation: Option<FullDelegation>,
}

impl QueryResponseType for DelegationResponse {}

impl_response_constructor!(DelegationResponse, delegation: Option<FullDelegation>);

/// FullDelegation is all the info on the delegation, some (like accumulated_reward and can_redelegate)
/// is expensive to query.
///
Expand All @@ -101,12 +115,20 @@ pub struct AllValidatorsResponse {
pub validators: Vec<Validator>,
}

impl QueryResponseType for AllValidatorsResponse {}

impl_response_constructor!(AllValidatorsResponse, validators: Vec<Validator>);

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

impl QueryResponseType for ValidatorResponse {}

impl_response_constructor!(ValidatorResponse, validator: Option<Validator>);

/// Instances are created in the querier.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct Validator {
Expand Down
8 changes: 8 additions & 0 deletions packages/std/src/query/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ pub struct CodeInfoResponse {
pub checksum: HexBinary,
}

#[cfg(feature = "cosmwasm_1_2")]
impl_response_constructor!(
CodeInfoResponse,
code_id: u64,
creator: String,
checksum: HexBinary
);

#[cfg(feature = "cosmwasm_1_2")]
impl QueryResponseType for CodeInfoResponse {}

Expand Down
10 changes: 5 additions & 5 deletions packages/std/src/testing/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -972,11 +972,11 @@ impl DistributionQuerier {
let contract_result: ContractResult<Binary> = match request {
DistributionQuery::DelegatorWithdrawAddress { delegator_address } => {
let res = DelegatorWithdrawAddressResponse {
withdraw_address: self
.withdraw_addresses
.get(delegator_address)
.unwrap_or(delegator_address)
.clone(),
withdraw_address: Addr::unchecked(
self.withdraw_addresses
.get(delegator_address)
.unwrap_or(delegator_address),
),
};
to_binary(&res).into()
}
Expand Down
2 changes: 1 addition & 1 deletion packages/std/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ impl<'a, C: CustomQuery> QuerierWrapper<'a, C> {
pub fn query_delegator_withdraw_address(
&self,
delegator: impl Into<String>,
) -> StdResult<String> {
) -> StdResult<Addr> {
let request = DistributionQuery::DelegatorWithdrawAddress {
delegator_address: delegator.into(),
}
Expand Down
Loading