From a3f9ad780ee0da27deedcb8a3be518e018b96460 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Mon, 2 Jan 2023 14:52:36 +0100 Subject: [PATCH 1/5] Add QueryResponseType trait --- packages/std/src/query/bank.rs | 23 ++++++++++------------- packages/std/src/query/mod.rs | 1 + packages/std/src/query/query_response.rs | 16 ++++++++++++++++ packages/std/src/query/wasm.rs | 6 +++++- 4 files changed, 32 insertions(+), 14 deletions(-) create mode 100644 packages/std/src/query/query_response.rs diff --git a/packages/std/src/query/bank.rs b/packages/std/src/query/bank.rs index e53dbcc9b0..b3a43e11d5 100644 --- a/packages/std/src/query/bank.rs +++ b/packages/std/src/query/bank.rs @@ -3,6 +3,8 @@ use serde::{Deserialize, Serialize}; use crate::Coin; +use super::query_response::QueryResponseType; + #[non_exhaustive] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] @@ -22,7 +24,7 @@ pub enum BankQuery { } #[cfg(feature = "cosmwasm_1_1")] -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] #[non_exhaustive] pub struct SupplyResponse { @@ -32,18 +34,9 @@ pub struct SupplyResponse { } #[cfg(feature = "cosmwasm_1_1")] -impl SupplyResponse { - /// 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. - #[doc(hidden)] - pub fn new(amount: Coin) -> Self { - Self { amount } - } -} +impl QueryResponseType for SupplyResponse {} -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct BalanceResponse { /// Always returns a Coin with the requested denom. @@ -51,9 +44,13 @@ pub struct BalanceResponse { pub amount: Coin, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +impl QueryResponseType for BalanceResponse {} + +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct AllBalanceResponse { /// Returns all non-zero coins held by this account. pub amount: Vec, } + +impl QueryResponseType for AllBalanceResponse {} diff --git a/packages/std/src/query/mod.rs b/packages/std/src/query/mod.rs index 67a2fcdb0d..5ca17fe35b 100644 --- a/packages/std/src/query/mod.rs +++ b/packages/std/src/query/mod.rs @@ -7,6 +7,7 @@ use crate::Empty; mod bank; mod ibc; +mod query_response; mod staking; mod wasm; diff --git a/packages/std/src/query/query_response.rs b/packages/std/src/query/query_response.rs new file mode 100644 index 0000000000..dca2e766c9 --- /dev/null +++ b/packages/std/src/query/query_response.rs @@ -0,0 +1,16 @@ +use serde::de::DeserializeOwned; + +/// A marker trait for query response types. +/// +/// Those types have in common that they should be `#[non_exhaustive]` in order +/// to allow adding fields in a backwards compatible way. In contracts they are +/// only constructed through deserialization. We want to make it hard for +/// contract developers to construct those types themselves as this is most likely +/// not what they should do. +/// +/// In hosts they are constructed as follows: +/// - wasmvm: Go types with the same JSON layout +/// - 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 {} diff --git a/packages/std/src/query/wasm.rs b/packages/std/src/query/wasm.rs index fee0334635..09302d0563 100644 --- a/packages/std/src/query/wasm.rs +++ b/packages/std/src/query/wasm.rs @@ -3,6 +3,8 @@ use serde::{Deserialize, Serialize}; use crate::Binary; +use super::query_response::QueryResponseType; + #[non_exhaustive] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] @@ -27,7 +29,7 @@ pub enum WasmQuery { } #[non_exhaustive] -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq, Eq, JsonSchema)] pub struct ContractInfoResponse { pub code_id: u64, /// address that instantiated this contract @@ -40,6 +42,8 @@ pub struct ContractInfoResponse { pub ibc_port: Option, } +impl QueryResponseType for ContractInfoResponse {} + impl ContractInfoResponse { /// Constructor for testing frameworks such as cw-multi-test. /// This is required because query response types should be #[non_exhaustive]. From 34f78d3613d17d9b72cc49a24ded2354b9eacd68 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Mon, 2 Jan 2023 14:55:28 +0100 Subject: [PATCH 2/5] Adapt CHANGELOG entry and add follow-up PR link --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8b77d714d..451055879c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,8 @@ and this project adheres to - cosmwasm-std: Upgrade `serde-json-wasm` dependency to 0.5.0 which adds map support to `to_vec`/`to_binary` and friends. - cosmwasm-std: Implement `AsRef<[u8]>` for `Binary` and `HexBinary` ([#1550]). -- cosmwasm-std: Add constructor `SupplyResponse::new` ([#1552]). +- cosmwasm-std: Allow constructing `SupplyResponse` via a `Default` + implementation ([#1552], [#1560]). [#1436]: https://github.com/CosmWasm/cosmwasm/issues/1436 [#1437]: https://github.com/CosmWasm/cosmwasm/issues/1437 @@ -33,6 +34,7 @@ and this project adheres to [#1550]: https://github.com/CosmWasm/cosmwasm/issues/1550 [#1552]: https://github.com/CosmWasm/cosmwasm/pull/1552 [#1554]: https://github.com/CosmWasm/cosmwasm/pull/1554 +[#1560]: https://github.com/CosmWasm/cosmwasm/pull/1560 ### Changed From 54dc68c8b316699b8662c592079d21d5634268b5 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Mon, 2 Jan 2023 15:00:05 +0100 Subject: [PATCH 3/5] Improve doc string of ContractInfo --- contracts/reflect/schema/raw/query.json | 2 +- contracts/reflect/schema/reflect.json | 2 +- packages/std/src/query/wasm.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/reflect/schema/raw/query.json b/contracts/reflect/schema/raw/query.json index 04512e6f3f..914555088d 100644 --- a/contracts/reflect/schema/raw/query.json +++ b/contracts/reflect/schema/raw/query.json @@ -547,7 +547,7 @@ "additionalProperties": false }, { - "description": "returns a ContractInfoResponse with metadata on the contract from the runtime", + "description": "Returns a [`ContractInfoResponse`] with metadata on the contract from the runtime", "type": "object", "required": [ "contract_info" diff --git a/contracts/reflect/schema/reflect.json b/contracts/reflect/schema/reflect.json index ab4e2c0cc6..603c401cd4 100644 --- a/contracts/reflect/schema/reflect.json +++ b/contracts/reflect/schema/reflect.json @@ -1411,7 +1411,7 @@ "additionalProperties": false }, { - "description": "returns a ContractInfoResponse with metadata on the contract from the runtime", + "description": "Returns a [`ContractInfoResponse`] with metadata on the contract from the runtime", "type": "object", "required": [ "contract_info" diff --git a/packages/std/src/query/wasm.rs b/packages/std/src/query/wasm.rs index 09302d0563..6bd52dde91 100644 --- a/packages/std/src/query/wasm.rs +++ b/packages/std/src/query/wasm.rs @@ -24,7 +24,7 @@ pub enum WasmQuery { /// Key is the raw key used in the contracts Storage key: Binary, }, - /// returns a ContractInfoResponse with metadata on the contract from the runtime + /// Returns a [`ContractInfoResponse`] with metadata on the contract from the runtime ContractInfo { contract_addr: String }, } From 71b1f5e129b6fc391d8d06dbb5fabeab7aec7ef5 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Mon, 2 Jan 2023 15:00:17 +0100 Subject: [PATCH 4/5] Deprecate ContractInfoResponse::new --- packages/std/src/query/wasm.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/std/src/query/wasm.rs b/packages/std/src/query/wasm.rs index 6bd52dde91..153b35f51c 100644 --- a/packages/std/src/query/wasm.rs +++ b/packages/std/src/query/wasm.rs @@ -50,13 +50,13 @@ impl ContractInfoResponse { /// As a contract developer you should not need this constructor since /// query responses are constructed for you via deserialization. #[doc(hidden)] + #[deprecated( + note = "Use ContractInfoResponse::default() and mutate the fields you want to set." + )] pub fn new(code_id: u64, creator: impl Into) -> Self { - Self { - code_id, - creator: creator.into(), - admin: None, - pinned: false, - ibc_port: None, - } + let mut out = ContractInfoResponse::default(); + out.code_id = code_id; + out.creator = creator.into(); + out } } From 03f803d8e17fba3e9a5539caafbd3243e9f9b8fd Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Mon, 2 Jan 2023 16:15:16 +0100 Subject: [PATCH 5/5] Make clippy happy --- packages/std/src/query/wasm.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/std/src/query/wasm.rs b/packages/std/src/query/wasm.rs index 153b35f51c..2be597ae65 100644 --- a/packages/std/src/query/wasm.rs +++ b/packages/std/src/query/wasm.rs @@ -54,9 +54,10 @@ impl ContractInfoResponse { note = "Use ContractInfoResponse::default() and mutate the fields you want to set." )] pub fn new(code_id: u64, creator: impl Into) -> Self { - let mut out = ContractInfoResponse::default(); - out.code_id = code_id; - out.creator = creator.into(); - out + ContractInfoResponse { + code_id, + creator: creator.into(), + ..Default::default() + } } }