From 1b931ca197c155902e91f6612475fe179d3cb96c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Wo=C5=BAniak?= Date: Thu, 10 Aug 2023 16:39:01 +0200 Subject: [PATCH 1/2] feat: Cast `deps` to empty --- Cargo.lock | 44 ++---- examples/Cargo.lock | 44 ++---- examples/contracts/cw1-subkeys/Cargo.toml | 2 +- examples/contracts/cw1-whitelist/Cargo.toml | 2 +- examples/contracts/cw20-base/Cargo.toml | 4 +- .../entry-points-overriding/Cargo.toml | 2 +- examples/interfaces/cw1/Cargo.toml | 2 +- .../interfaces/cw20-allowances/Cargo.toml | 2 +- examples/interfaces/cw20-marketing/Cargo.toml | 2 +- examples/interfaces/cw20-minting/Cargo.toml | 2 +- examples/interfaces/cw4/Cargo.toml | 2 +- sylvia-derive/src/message.rs | 23 ++- sylvia-derive/src/parser.rs | 47 +++++-- sylvia/Cargo.toml | 2 +- sylvia/src/into_deps.rs | 133 ------------------ sylvia/src/lib.rs | 1 - sylvia/tests/custom_query.rs | 50 +++++++ 17 files changed, 141 insertions(+), 223 deletions(-) delete mode 100644 sylvia/src/into_deps.rs diff --git a/Cargo.lock b/Cargo.lock index 21b1da90..f2fb4b2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,6 +61,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "845141a4fade3f790628b7daaaa298a25b204fb28907eb54febe5142db6ce653" + [[package]] name = "byteorder" version = "1.4.3" @@ -102,9 +108,9 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.2.1" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fecd74d3a0041114110d1260f77fcb644c5d2403549b37096c44f0e643a5177" +checksum = "871ce1d5a4b00ed1741f84b377eec19fadd81a904a227bc1e268d76539d26f5e" dependencies = [ "digest 0.10.6", "ed25519-zebra", @@ -115,9 +121,9 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.2.1" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5abeeb891e6d0098402e4d3d042f90451db52651d2fe14b170e69a1dd3e4115" +checksum = "7ce8b44b45a7c8c6d6f770cd0a51458c2445c7c15b6115e1d215fa35c77b305c" dependencies = [ "syn", ] @@ -148,11 +154,12 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.2.1" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5034c772c1369b160731aa00bb81f93733ab2884928edd8d588733d607ac5af4" +checksum = "da78abcf059181e8cb01e95e5003cf64fe95dde6c72b3fe37e5cabc75cdba32a" dependencies = [ "base64", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -163,7 +170,6 @@ dependencies = [ "serde-json-wasm", "sha2 0.10.6", "thiserror", - "uint", ] [[package]] @@ -175,12 +181,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - [[package]] name = "crypto-bigint" version = "0.4.9" @@ -815,12 +815,6 @@ dependencies = [ "der", ] -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "subtle" version = "2.4.1" @@ -924,18 +918,6 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - [[package]] name = "unicode-ident" version = "1.0.6" diff --git a/examples/Cargo.lock b/examples/Cargo.lock index f057d32a..4a897b66 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -67,6 +67,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "845141a4fade3f790628b7daaaa298a25b204fb28907eb54febe5142db6ce653" + [[package]] name = "bumpalo" version = "3.13.0" @@ -114,9 +120,9 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.2.6" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c0e41be7e6c7d7ab3c61cdc32fcfaa14f948491a401cbc1c74bb33b6f4b851" +checksum = "871ce1d5a4b00ed1741f84b377eec19fadd81a904a227bc1e268d76539d26f5e" dependencies = [ "digest 0.10.7", "ed25519-zebra", @@ -127,9 +133,9 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.2.6" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a7ee2798c92c00dd17bebb4210f81d5f647e5e92d847959b7977e0fd29a3500" +checksum = "7ce8b44b45a7c8c6d6f770cd0a51458c2445c7c15b6115e1d215fa35c77b305c" dependencies = [ "syn 1.0.109", ] @@ -160,11 +166,12 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.2.6" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d5fdfd112b070055f068fad079d490117c8e905a588b92a5a7c9276d029930" +checksum = "da78abcf059181e8cb01e95e5003cf64fe95dde6c72b3fe37e5cabc75cdba32a" dependencies = [ "base64", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -175,7 +182,6 @@ dependencies = [ "serde-json-wasm", "sha2 0.10.6", "thiserror", - "uint", ] [[package]] @@ -187,12 +193,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - [[package]] name = "crypto-bigint" version = "0.4.9" @@ -962,12 +962,6 @@ dependencies = [ "der", ] -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "subtle" version = "2.5.0" @@ -1074,18 +1068,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c52b4cb7830f995903b2fcff3f523d21efc1c11f6c1596dd544b7925a64ff56" -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - [[package]] name = "unicode-ident" version = "1.0.9" diff --git a/examples/contracts/cw1-subkeys/Cargo.toml b/examples/contracts/cw1-subkeys/Cargo.toml index fbf8398e..12dc5f70 100644 --- a/examples/contracts/cw1-subkeys/Cargo.toml +++ b/examples/contracts/cw1-subkeys/Cargo.toml @@ -13,7 +13,7 @@ tests = ["library", "cw-multi-test", "anyhow"] [dependencies] anyhow = { version = "1.0.68", optional = true } cosmwasm-schema = "1.2" -cosmwasm-std = { version = "1.2", features = ["staking"] } +cosmwasm-std = { version = "1.3", features = ["staking"] } cw-multi-test = { version = "0.16.2", optional = true } cw-storage-plus = "1.0" cw-utils = "1.0" diff --git a/examples/contracts/cw1-whitelist/Cargo.toml b/examples/contracts/cw1-whitelist/Cargo.toml index 6567b319..c307894e 100644 --- a/examples/contracts/cw1-whitelist/Cargo.toml +++ b/examples/contracts/cw1-whitelist/Cargo.toml @@ -17,7 +17,7 @@ tests = ["library", "cw-multi-test", "anyhow"] mt = ["sylvia/mt", "library"] [dependencies] -cosmwasm-std = { version = "1.2", features = ["staking"] } +cosmwasm-std = { version = "1.3", features = ["staking"] } cosmwasm-schema = "1.2" serde = { version = "1.0", default-features = false, features = ["derive"] } sylvia = { path = "../../../sylvia" } diff --git a/examples/contracts/cw20-base/Cargo.toml b/examples/contracts/cw20-base/Cargo.toml index 8ac19901..e2f1c581 100644 --- a/examples/contracts/cw20-base/Cargo.toml +++ b/examples/contracts/cw20-base/Cargo.toml @@ -18,7 +18,7 @@ tests = ["library", "cw-multi-test", "anyhow"] [dependencies] anyhow = { version = "1.0", optional = true } cosmwasm-schema = "1.2" -cosmwasm-std = { version = "1.2", features = ["staking"] } +cosmwasm-std = { version = "1.3", features = ["staking"] } cw-multi-test = { version = "0.16", optional = true } cw-storage-plus = "1.0" cw-utils = "1.0" @@ -39,7 +39,7 @@ cw-multi-test = "0.16" cw-utils = "1.0" sylvia = { path = "../../../sylvia", features = ["mt"] } cw20-allowances = { path = "../../interfaces/cw20-allowances", features = [ - "mt", + "mt", ] } cw20-marketing = { path = "../../interfaces/cw20-marketing", features = ["mt"] } cw20-minting = { path = "../../interfaces/cw20-minting", features = ["mt"] } diff --git a/examples/contracts/entry-points-overriding/Cargo.toml b/examples/contracts/entry-points-overriding/Cargo.toml index 91dbdf80..911bab58 100644 --- a/examples/contracts/entry-points-overriding/Cargo.toml +++ b/examples/contracts/entry-points-overriding/Cargo.toml @@ -18,7 +18,7 @@ tests = ["library", "cw-multi-test", "anyhow"] [dependencies] anyhow = { version = "1.0", optional = true } cosmwasm-schema = "1.2" -cosmwasm-std = { version = "1.2", features = ["staking"] } +cosmwasm-std = { version = "1.3", features = ["staking"] } cw-multi-test = { version = "0.16", optional = true } cw-storage-plus = "1.0" cw-utils = "1.0" diff --git a/examples/interfaces/cw1/Cargo.toml b/examples/interfaces/cw1/Cargo.toml index ac280e2e..8b8b7ad1 100644 --- a/examples/interfaces/cw1/Cargo.toml +++ b/examples/interfaces/cw1/Cargo.toml @@ -12,7 +12,7 @@ homepage = "https://cosmwasm.com" mt = ["sylvia/mt"] [dependencies] -cosmwasm-std = { version = "1.2", features = ["staking"] } +cosmwasm-std = { version = "1.3", features = ["staking"] } cosmwasm-schema = "1.2" serde = { version = "1.0", default-features = false, features = ["derive"] } sylvia = { path = "../../../sylvia" } diff --git a/examples/interfaces/cw20-allowances/Cargo.toml b/examples/interfaces/cw20-allowances/Cargo.toml index 71bbfd3c..d169a8f9 100644 --- a/examples/interfaces/cw20-allowances/Cargo.toml +++ b/examples/interfaces/cw20-allowances/Cargo.toml @@ -12,7 +12,7 @@ homepage = "https://cosmwasm.com" mt = ["sylvia/mt"] [dependencies] -cosmwasm-std = { version = "1.2", features = ["staking"] } +cosmwasm-std = { version = "1.3", features = ["staking"] } cosmwasm-schema = "1.2" serde = { version = "1.0", default-features = false, features = ["derive"] } sylvia = { path = "../../../sylvia" } diff --git a/examples/interfaces/cw20-marketing/Cargo.toml b/examples/interfaces/cw20-marketing/Cargo.toml index 508b5c44..f4613fb4 100644 --- a/examples/interfaces/cw20-marketing/Cargo.toml +++ b/examples/interfaces/cw20-marketing/Cargo.toml @@ -12,7 +12,7 @@ homepage = "https://cosmwasm.com" mt = ["sylvia/mt"] [dependencies] -cosmwasm-std = { version = "1.2", features = ["staking"] } +cosmwasm-std = { version = "1.3", features = ["staking"] } cosmwasm-schema = "1.2" serde = { version = "1.0", default-features = false, features = ["derive"] } sylvia = { path = "../../../sylvia" } diff --git a/examples/interfaces/cw20-minting/Cargo.toml b/examples/interfaces/cw20-minting/Cargo.toml index 65a51b51..ef7abfb9 100644 --- a/examples/interfaces/cw20-minting/Cargo.toml +++ b/examples/interfaces/cw20-minting/Cargo.toml @@ -12,7 +12,7 @@ homepage = "https://cosmwasm.com" mt = ["sylvia/mt"] [dependencies] -cosmwasm-std = { version = "1.2", features = ["staking"] } +cosmwasm-std = { version = "1.3", features = ["staking"] } cosmwasm-schema = "1.2" serde = { version = "1.0", default-features = false, features = ["derive"] } sylvia = { path = "../../../sylvia" } diff --git a/examples/interfaces/cw4/Cargo.toml b/examples/interfaces/cw4/Cargo.toml index 30ce3757..de683614 100644 --- a/examples/interfaces/cw4/Cargo.toml +++ b/examples/interfaces/cw4/Cargo.toml @@ -12,7 +12,7 @@ homepage = "https://cosmwasm.com" mt = ["sylvia/mt"] [dependencies] -cosmwasm-std = { version = "1.2.1", features = ["staking"] } +cosmwasm-std = { version = "1.3", features = ["staking"] } cosmwasm-schema = "1.2" serde = { version = "1.0", default-features = false, features = ["derive"] } sylvia = { path = "../../../sylvia" } diff --git a/sylvia-derive/src/message.rs b/sylvia-derive/src/message.rs index 35f4df21..e0456c82 100644 --- a/sylvia-derive/src/message.rs +++ b/sylvia-derive/src/message.rs @@ -901,15 +901,28 @@ impl<'a> GlueMessage<'a> { let ContractMessageAttr { variant, has_custom_msg, + has_custom_query, .. } = interface; - match *has_custom_msg&& msg_ty == &MsgType::Exec - { - true => quote! { #contract_name :: #variant(msg) => Ok( #sylvia ::into_response::IntoResponse::into_response(msg.dispatch(contract, Into::into(ctx))?)?) }, - false => quote! { #contract_name :: #variant(msg) => msg.dispatch(contract, Into::into(ctx)) } - } + let ctx = match (msg_ty, has_custom_query) { + (MsgType::Exec, true )=> quote! { + ( ctx.0.into_empty(), ctx.1, ctx.2) + }, + (MsgType::Query, true )=> quote! { + ( ctx.0.into_empty(), ctx.1) + }, + _=> quote! { ctx }, + }; + match (msg_ty, has_custom_msg) { + (MsgType::Exec, true) => quote! { + #contract_name :: #variant(msg) => #sylvia ::into_response::IntoResponse::into_response(msg.dispatch(contract, Into::into( #ctx ))?) + }, + _ => quote! { + #contract_name :: #variant(msg) => msg.dispatch(contract, Into::into( #ctx )) + }, + } }); let dispatch_arm = quote! {#contract_name :: #contract (msg) =>msg.dispatch(contract, ctx)}; diff --git a/sylvia-derive/src/parser.rs b/sylvia-derive/src/parser.rs index 475b8e22..b809d70d 100644 --- a/sylvia-derive/src/parser.rs +++ b/sylvia-derive/src/parser.rs @@ -236,6 +236,7 @@ pub struct ContractMessageAttr { pub query_generic_params: Vec, pub variant: Ident, pub has_custom_msg: bool, + pub has_custom_query: bool, } #[cfg(not(tarpaulin_include))] @@ -262,6 +263,35 @@ fn parse_generics(content: &ParseBuffer) -> Result> { Ok(params) } +fn interface_has_custom(content: ParseStream) -> Result<(bool, bool)> { + let mut has_custom_msg = false; + let mut has_custom_query = false; + + let _: Token![:] = content.parse()?; + let attr: Ident = content.parse()?; + if attr != "custom" { + return Ok((has_custom_msg, has_custom_query)); + } + + let custom_content; + parenthesized!(custom_content in content); + + while !custom_content.is_empty() { + let custom = custom_content.parse::()?; + match custom.get_ident() { + Some(ident) if ident == "msg" => has_custom_msg = true, + Some(ident) if ident == "query" => has_custom_query = true, + _ => { + return Err(Error::new( + custom.span(), + "Invalid custom attribute, expected one of: `msg`, `query`", + )) + } + } + } + Ok((has_custom_msg, has_custom_query)) +} + #[cfg(not(tarpaulin_include))] // False negative. It is being called in closure impl Parse for ContractMessageAttr { @@ -274,7 +304,6 @@ impl Parse for ContractMessageAttr { let generics_open: Option = content.parse()?; let mut exec_generic_params = vec![]; let mut query_generic_params = vec![]; - let mut has_custom_msg = false; if generics_open.is_some() { loop { @@ -300,16 +329,11 @@ impl Parse for ContractMessageAttr { let _: Token![as] = content.parse()?; let variant = content.parse()?; - if content.peek(Token![:]) { - let _: Token![:] = content.parse()?; - let attr: Ident = content.parse()?; - if attr == "custom" { - let custom_content; - parenthesized!(custom_content in content); - let custom = custom_content.parse::()?; - has_custom_msg = custom.is_ident("msg"); - } - } + let (has_custom_msg, has_custom_query) = if content.peek(Token![:]) { + interface_has_custom(&content)? + } else { + (false, false) + }; if !content.is_empty() { return Err(Error::new( @@ -324,6 +348,7 @@ impl Parse for ContractMessageAttr { query_generic_params, variant, has_custom_msg, + has_custom_query, }) } } diff --git a/sylvia/Cargo.toml b/sylvia/Cargo.toml index a4cba7d0..121bb6cc 100644 --- a/sylvia/Cargo.toml +++ b/sylvia/Cargo.toml @@ -17,7 +17,7 @@ staking = ["cosmwasm-std/staking", "cw-multi-test?/staking"] [dependencies] sylvia-derive = { workspace = true } -cosmwasm-std = { version = "1.2", features = ["staking"] } +cosmwasm-std = { version = "1.3", features = ["staking"] } cosmwasm-schema = "1.2" schemars = "0.8" serde = { version = "1.0", default-features = false, features = ["derive"] } diff --git a/sylvia/src/into_deps.rs b/sylvia/src/into_deps.rs deleted file mode 100644 index 30a7e4dc..00000000 --- a/sylvia/src/into_deps.rs +++ /dev/null @@ -1,133 +0,0 @@ -use cosmwasm_std::{CustomQuery, Deps, DepsMut, Empty, QuerierWrapper}; - -/// Trait converting `Deps` to one operating on another `Query` type. By default only conversions -/// from any `Deps` to `Deps` are possible, and in general - only converting to `Deps` -/// over simpler query (being a subset of the original one) should be allowed. -trait IntoDeps<'deps, Q> -where - Q: CustomQuery, -{ - fn into_deps(self) -> Deps<'deps, Q>; -} - -/// Any `Deps` can be made into `Deps` -/// -/// It would be better to define it on owned `Deps`, but the `QuerierWrapper::querier` is not -/// accessible - some destructuring function for it would be helpfull here -impl<'deps, Q> IntoDeps<'deps, Empty> for &'deps Deps<'deps, Q> -where - Q: CustomQuery, -{ - fn into_deps(self) -> Deps<'deps, Empty> { - Deps { - storage: self.storage, - api: self.api, - querier: QuerierWrapper::new(&*self.querier), - } - } -} - -/// Trait converting `DepsMut` to one operating on another `Query` type. By default only -/// conversions from any `DepsMut` to `DepsMut` are possible, and in general - only -/// converting to `DepsMut` over simpler query (being a subset of the original one) should be -/// allowed. -trait IntoDepsMut<'deps, Q> -where - Q: CustomQuery, -{ - fn into_deps_mut(self) -> DepsMut<'deps, Q>; -} - -/// Any `DepsMut` can be made into `DepsMut` -/// -/// It would be better to define it on owned `DepsMut`, but the `QuerierWrapper::querier` is not -/// accessible - some destructuring function for it would be helpfull here -impl<'deps, Q> IntoDepsMut<'deps, Empty> for &'deps mut DepsMut<'deps, Q> -where - Q: CustomQuery, -{ - fn into_deps_mut(self) -> DepsMut<'deps, Empty> { - DepsMut { - storage: self.storage, - api: self.api, - querier: QuerierWrapper::new(&*self.querier), - } - } -} - -#[cfg(test)] -mod tests { - use cosmwasm_std::testing::{mock_dependencies, MockApi, MockStorage}; - use cosmwasm_std::{CustomQuery, Deps, DepsMut, Empty, QuerierWrapper}; - use schemars::JsonSchema; - use serde::{Deserialize, Serialize}; - - use crate::into_deps::IntoDeps; - - use super::IntoDepsMut; - - #[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq, Eq)] - struct MyQuery {} - - impl CustomQuery for MyQuery {} - - #[test] - fn empty_into_deps() { - let deps = mock_dependencies(); - let storage = MockStorage::new(); - let api = MockApi::default(); - let querier = QuerierWrapper::::new(&deps.querier); - - let deps = Deps { - storage: &storage, - api: &api, - querier, - }; - let _: Deps = deps.into_deps(); - } - - #[test] - fn custom_into_deps() { - let deps = mock_dependencies(); - let storage = MockStorage::new(); - let api = MockApi::default(); - let querier = QuerierWrapper::::new(&deps.querier); - - let deps = Deps { - storage: &storage, - api: &api, - querier, - }; - let _: Deps = deps.into_deps(); - } - - #[test] - fn empty_into_deps_mut() { - let deps = mock_dependencies(); - let mut storage = MockStorage::new(); - let api = MockApi::default(); - let querier = QuerierWrapper::::new(&deps.querier); - - let mut deps = DepsMut { - storage: &mut storage, - api: &api, - querier, - }; - let _: DepsMut = deps.into_deps_mut(); - } - - #[test] - fn custom_into_deps_mut() { - let deps = mock_dependencies(); - let mut storage = MockStorage::new(); - let api = MockApi::default(); - let querier = QuerierWrapper::::new(&deps.querier); - - let mut deps = DepsMut { - storage: &mut storage, - api: &api, - querier, - }; - let _: DepsMut = deps.into_deps_mut(); - } -} diff --git a/sylvia/src/lib.rs b/sylvia/src/lib.rs index 68355429..f3502c47 100644 --- a/sylvia/src/lib.rs +++ b/sylvia/src/lib.rs @@ -2,7 +2,6 @@ //! //! Most of implementation lies in `cw-derive-ng` crate which is reexported here -pub mod into_deps; pub mod into_response; #[cfg(feature = "mt")] pub mod multitest; diff --git a/sylvia/tests/custom_query.rs b/sylvia/tests/custom_query.rs index 7e1fc2ba..cb92e811 100644 --- a/sylvia/tests/custom_query.rs +++ b/sylvia/tests/custom_query.rs @@ -134,10 +134,48 @@ mod associated_type_interface { } } +mod default_query_interface { + use cosmwasm_std::{Response, StdError, StdResult}; + use sylvia::types::{ExecCtx, QueryCtx}; + use sylvia::{contract, interface}; + + use crate::SomeResponse; + + #[interface] + pub trait DefaultQueryInterface { + type Error: From; + + #[cfg(not(tarpaulin_include))] + #[msg(query)] + fn default_query(&self, ctx: QueryCtx) -> StdResult; + + #[cfg(not(tarpaulin_include))] + #[msg(exec)] + fn default_exec(&self, ctx: ExecCtx) -> StdResult; + } + + #[contract(module=super)] + #[sv::custom(query=MyQuery)] + impl DefaultQueryInterface for crate::MyContract { + type Error = StdError; + + #[msg(query)] + fn default_query(&self, _ctx: QueryCtx) -> StdResult { + Ok(SomeResponse) + } + + #[msg(exec)] + fn default_exec(&self, _ctx: ExecCtx) -> StdResult { + Ok(Response::default()) + } + } +} + #[contract] #[messages(some_interface as SomeInterface)] #[messages(associated_type_interface as AssociatedTypeInterface)] #[messages(interface as Interface)] +#[messages(default_query_interface as DefaultQueryInterface: custom(query))] #[sv::custom(query=MyQuery)] impl MyContract { #[allow(clippy::new_without_default)] @@ -170,6 +208,7 @@ impl MyContract { #[cfg(all(test, feature = "mt"))] mod tests { use crate::associated_type_interface::test_utils::AssociatedTypeInterface; + use crate::default_query_interface::test_utils::DefaultQueryInterface; use crate::some_interface::test_utils::SomeInterface; use crate::{interface::test_utils::Interface, MyContract, MyQuery}; @@ -222,5 +261,16 @@ mod tests { .interface_exec() .call(owner) .unwrap(); + + // Neither `custom` attribute nor associated type + contract + .default_query_interface_proxy() + .default_query() + .unwrap(); + contract + .default_query_interface_proxy() + .default_exec() + .call(owner) + .unwrap(); } } From c55ad1ffc24ac849f1ad4ddb0dc0ce4a9fac8e91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Wo=C5=BAniak?= Date: Thu, 31 Aug 2023 13:07:16 +0200 Subject: [PATCH 2/2] feat: Forward `CustomQuery` to entry points --- .github/workflows/ci.yml | 14 ++- examples/Cargo.lock | 13 +++ examples/Cargo.toml | 1 + examples/contracts/custom/.cargo/config | 6 ++ examples/contracts/custom/Cargo.toml | 28 ++++++ examples/contracts/custom/src/bin/schema.rs | 12 +++ examples/contracts/custom/src/contract.rs | 41 ++++++++ examples/contracts/custom/src/lib.rs | 4 + examples/contracts/custom/src/messages.rs | 21 ++++ examples/contracts/custom/src/multitest.rs | 2 + .../custom/src/multitest/custom_module.rs | 96 +++++++++++++++++++ .../contracts/custom/src/multitest/tests.rs | 27 ++++++ sylvia-derive/src/message.rs | 4 +- sylvia-derive/src/parser.rs | 11 ++- sylvia/tests/custom_msg.rs | 7 +- 15 files changed, 273 insertions(+), 14 deletions(-) create mode 100644 examples/contracts/custom/.cargo/config create mode 100644 examples/contracts/custom/Cargo.toml create mode 100644 examples/contracts/custom/src/bin/schema.rs create mode 100644 examples/contracts/custom/src/contract.rs create mode 100644 examples/contracts/custom/src/lib.rs create mode 100644 examples/contracts/custom/src/messages.rs create mode 100644 examples/contracts/custom/src/multitest.rs create mode 100644 examples/contracts/custom/src/multitest/custom_module.rs create mode 100644 examples/contracts/custom/src/multitest/tests.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 50407918..31b3ba7e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,7 +51,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.66.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -87,6 +87,9 @@ jobs: - name: Build entry-points-overriding working-directory: examples/contracts/entry-points-overriding run: cargo build --release --target wasm32-unknown-unknown --locked --lib + - name: Build custom + working-directory: examples/contracts/custom + run: cargo build --release --target wasm32-unknown-unknown --locked --lib - name: Install cosmwasm-check run: cargo install cosmwasm-check --force - name: Check contracts @@ -103,6 +106,9 @@ jobs: - name: Entry-points-overriding schema working-directory: examples/contracts/entry-points-overriding run: cargo schema + - name: Custom schema + working-directory: examples/contracts/custom + run: cargo schema - name: Cw1-whitelist ts-codegen working-directory: examples/contracts/cw1-whitelist/ run: cosmwasm-ts-codegen generate --plugin client --schema ./schema --out ./ts --name cw1-whitelist --no-bundle @@ -115,6 +121,9 @@ jobs: - name: Entry-points-overriding ts-codegen working-directory: examples/contracts/entry-points-overriding run: cosmwasm-ts-codegen generate --plugin client --schema ./schema --out ./ts --name entry-points-overriding --no-bundle + - name: Custom ts-codegen + working-directory: examples/contracts/custom/ + run: cosmwasm-ts-codegen generate --plugin client --schema ./schema --out ./ts --name custom --no-bundle - name: Archive schema artifats uses: actions/upload-artifact@v3 with: @@ -124,6 +133,7 @@ jobs: examples/contracts/cw1-whitelist/schema/cw1-whitelist.json examples/contracts/cw20-base/schema/cw20-base.json examples/contracts/entry-points-overriding/schema/entry-points-overriding.json + examples/contracts/custom/schema/custom.json coverage: name: Code coverage @@ -146,7 +156,7 @@ jobs: key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - name: Generate code coverage run: | - cargo tarpaulin --verbose --all-features --workspace --timeout 120 --out Xml --engine llvm + cargo tarpaulin --verbose --all-features --workspace --timeout 120 --out xml --engine llvm - name: Upload to codecov.io uses: codecov/codecov-action@v2 with: diff --git a/examples/Cargo.lock b/examples/Cargo.lock index 4a897b66..7e7fef3e 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -228,6 +228,19 @@ dependencies = [ "zeroize", ] +[[package]] +name = "custom" +version = "0.5.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus", + "serde", + "sylvia", +] + [[package]] name = "cw-multi-test" version = "0.16.5" diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 7314a3b6..a8a0e3ad 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -12,6 +12,7 @@ members = [ "contracts/cw1-subkeys", "contracts/cw20-base", "contracts/entry-points-overriding", + "contracts/custom", ] resolver = "2" diff --git a/examples/contracts/custom/.cargo/config b/examples/contracts/custom/.cargo/config new file mode 100644 index 00000000..d8ab80fe --- /dev/null +++ b/examples/contracts/custom/.cargo/config @@ -0,0 +1,6 @@ +[alias] +wasm = "build --release --target wasm32-unknown-unknown --lib" +wasm-debug = "build --target wasm32-unknown-unknown --lib" +unit-test = "test --lib" +integration-test = "test --test integration" +schema = "run --bin schema" diff --git a/examples/contracts/custom/Cargo.toml b/examples/contracts/custom/Cargo.toml new file mode 100644 index 00000000..57dd33b6 --- /dev/null +++ b/examples/contracts/custom/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "custom" +version = { workspace = true } +authors = ["Jan Woźniak "] +edition = { workspace = true } +description = "Example of custom message usage." +license = "Apache-2.0" +repository = "https://github.com/CosmWasm/sylvia" +homepage = "https://cosmwasm.com" + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +library = [] +mt = ["library"] + +[dependencies] +cosmwasm-schema = "1.2" +cosmwasm-std = { version = "1.3", features = ["staking"] } +cw-storage-plus = "1.0" +serde = { version = "1.0", default-features = false, features = ["derive"] } +sylvia = { path = "../../../sylvia" } + +[dev-dependencies] +anyhow = "1.0" +cw-multi-test = "0.16" +sylvia = { path = "../../../sylvia", features = ["mt"] } diff --git a/examples/contracts/custom/src/bin/schema.rs b/examples/contracts/custom/src/bin/schema.rs new file mode 100644 index 00000000..a60261b8 --- /dev/null +++ b/examples/contracts/custom/src/bin/schema.rs @@ -0,0 +1,12 @@ +use cosmwasm_schema::write_api; + +use custom::contract::{ContractExecMsg, ContractQueryMsg, InstantiateMsg}; + +#[cfg(not(tarpaulin_include))] +fn main() { + write_api! { + instantiate: InstantiateMsg, + execute: ContractExecMsg, + query: ContractQueryMsg, + } +} diff --git a/examples/contracts/custom/src/contract.rs b/examples/contracts/custom/src/contract.rs new file mode 100644 index 00000000..f4d30075 --- /dev/null +++ b/examples/contracts/custom/src/contract.rs @@ -0,0 +1,41 @@ +use cosmwasm_std::{CosmosMsg, QueryRequest, Response, StdResult}; +use sylvia::types::{ExecCtx, InstantiateCtx, QueryCtx}; +use sylvia::{contract, entry_points, schemars}; + +use crate::messages::{CountResponse, CounterMsg, CounterQuery}; + +pub struct CustomContract; + +#[cfg_attr(not(feature = "mt"), entry_points)] +#[contract] +#[sv::custom(query=CounterQuery, msg=CounterMsg)] +impl CustomContract { + pub const fn new() -> Self { + Self + } + + #[msg(instantiate)] + pub fn instantiate( + &self, + _ctx: InstantiateCtx, + ) -> StdResult> { + Ok(Response::default()) + } + + #[msg(exec)] + pub fn send_custom(&self, _ctx: ExecCtx) -> StdResult> { + let msg = CosmosMsg::Custom(CounterMsg::Increment {}); + let resp = Response::default().add_message(msg); + Ok(resp) + } + + #[msg(query)] + pub fn query_custom(&self, ctx: QueryCtx) -> StdResult { + let resp = ctx + .deps + .querier + .query::(&QueryRequest::Custom(CounterQuery::Count {}))?; + + Ok(resp) + } +} diff --git a/examples/contracts/custom/src/lib.rs b/examples/contracts/custom/src/lib.rs new file mode 100644 index 00000000..cceb968f --- /dev/null +++ b/examples/contracts/custom/src/lib.rs @@ -0,0 +1,4 @@ +pub mod contract; +pub mod messages; +#[cfg(any(test, feature = "mt"))] +pub mod multitest; diff --git a/examples/contracts/custom/src/messages.rs b/examples/contracts/custom/src/messages.rs new file mode 100644 index 00000000..9461363f --- /dev/null +++ b/examples/contracts/custom/src/messages.rs @@ -0,0 +1,21 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{CustomMsg, CustomQuery}; + +#[cw_serde] +pub struct CountResponse { + pub count: u64, +} + +#[cw_serde] +pub enum CounterMsg { + Increment {}, +} + +#[cw_serde] +pub enum CounterQuery { + Count {}, +} + +impl CustomMsg for CounterMsg {} + +impl CustomQuery for CounterQuery {} diff --git a/examples/contracts/custom/src/multitest.rs b/examples/contracts/custom/src/multitest.rs new file mode 100644 index 00000000..f44455f7 --- /dev/null +++ b/examples/contracts/custom/src/multitest.rs @@ -0,0 +1,2 @@ +mod custom_module; +mod tests; diff --git a/examples/contracts/custom/src/multitest/custom_module.rs b/examples/contracts/custom/src/multitest/custom_module.rs new file mode 100644 index 00000000..7a10d52e --- /dev/null +++ b/examples/contracts/custom/src/multitest/custom_module.rs @@ -0,0 +1,96 @@ +use cosmwasm_schema::schemars::JsonSchema; +use cosmwasm_std::testing::{MockApi, MockStorage}; +use cosmwasm_std::{ + to_binary, Addr, Api, Binary, BlockInfo, CustomQuery, Empty, Querier, StdError, StdResult, + Storage, +}; +use cw_multi_test::{AppResponse, BankKeeper, CosmosRouter, Module, WasmKeeper}; +use cw_storage_plus::Item; +use serde::de::DeserializeOwned; +use std::fmt::Debug; + +use crate::messages::{CountResponse, CounterMsg, CounterQuery}; + +pub type CustomApp = cw_multi_test::App< + BankKeeper, + MockApi, + MockStorage, + CustomModule, + WasmKeeper, +>; + +pub struct CustomModule { + pub counter: Item<'static, u64>, +} + +impl CustomModule { + pub fn new() -> Self { + Self { + counter: Item::new("counter"), + } + } + + pub fn save_counter(&self, storage: &mut dyn Storage, value: u64) -> StdResult<()> { + self.counter.save(storage, &value) + } +} + +impl Module for CustomModule { + type ExecT = CounterMsg; + type QueryT = CounterQuery; + type SudoT = Empty; + + fn execute( + &self, + _api: &dyn Api, + storage: &mut dyn Storage, + _router: &dyn CosmosRouter, + _block: &BlockInfo, + _sender: Addr, + msg: Self::ExecT, + ) -> anyhow::Result + where + ExecC: Debug + Clone + PartialEq + JsonSchema + DeserializeOwned + 'static, + QueryC: CustomQuery + DeserializeOwned + 'static, + { + match msg { + CounterMsg::Increment {} => { + self.counter + .update(storage, |value| Ok::<_, StdError>(value + 1))?; + Ok(AppResponse::default()) + } + } + } + + fn sudo( + &self, + _api: &dyn Api, + _storage: &mut dyn Storage, + _router: &dyn CosmosRouter, + _block: &BlockInfo, + _msg: Self::SudoT, + ) -> anyhow::Result + where + ExecC: Debug + Clone + PartialEq + JsonSchema + DeserializeOwned + 'static, + QueryC: CustomQuery + DeserializeOwned + 'static, + { + Ok(AppResponse::default()) + } + + fn query( + &self, + _api: &dyn Api, + storage: &dyn Storage, + _querier: &dyn Querier, + _block: &BlockInfo, + request: Self::QueryT, + ) -> anyhow::Result { + match request { + CounterQuery::Count {} => { + let count = self.counter.load(storage)?; + let res = CountResponse { count }; + to_binary(&res).map_err(Into::into) + } + } + } +} diff --git a/examples/contracts/custom/src/multitest/tests.rs b/examples/contracts/custom/src/multitest/tests.rs new file mode 100644 index 00000000..5bb92866 --- /dev/null +++ b/examples/contracts/custom/src/multitest/tests.rs @@ -0,0 +1,27 @@ +use sylvia::multitest::App; + +use crate::contract::multitest_utils::CodeId; + +use super::custom_module::{CustomApp, CustomModule}; + +#[test] +fn test_custom() { + let owner = "owner"; + + let mt_app = cw_multi_test::BasicAppBuilder::new_custom() + .with_custom(CustomModule::new()) + .build(|router, _, storage| { + router.custom.save_counter(storage, 0).unwrap(); + }); + + let app = App::::new(mt_app); + + let code_id = CodeId::store_code(&app); + + let contract = code_id.instantiate().call(owner).unwrap(); + + contract.send_custom().call(owner).unwrap(); + + let count = contract.query_custom().unwrap().count; + assert_eq!(count, 1); +} diff --git a/sylvia-derive/src/message.rs b/sylvia-derive/src/message.rs index e0456c82..b86402c4 100644 --- a/sylvia-derive/src/message.rs +++ b/sylvia-derive/src/message.rs @@ -1096,6 +1096,7 @@ impl<'a> EntryPoints<'a> { let sylvia = crate_module(); let custom_msg = custom.msg_or_default(); + let custom_query = custom.query_or_default(); #[cfg(not(tarpaulin_include))] { @@ -1106,6 +1107,7 @@ impl<'a> EntryPoints<'a> { Some(_) => quote! {}, None => OverrideEntryPoint::emit_default_entry_point( &custom_msg, + &custom_query, name, error, msg_type, @@ -1120,7 +1122,7 @@ impl<'a> EntryPoints<'a> { Some(reply) => quote! { #[#sylvia ::cw_std::entry_point] pub fn reply( - deps: #sylvia ::cw_std::DepsMut, + deps: #sylvia ::cw_std::DepsMut< #custom_query >, env: #sylvia ::cw_std::Env, msg: #sylvia ::cw_std::Reply, ) -> Result<#sylvia ::cw_std::Response < #custom_msg >, #error> { diff --git a/sylvia-derive/src/parser.rs b/sylvia-derive/src/parser.rs index b809d70d..96717708 100644 --- a/sylvia-derive/src/parser.rs +++ b/sylvia-derive/src/parser.rs @@ -83,20 +83,20 @@ impl MsgType { } #[cfg(not(tarpaulin_include))] - pub fn emit_ctx_params(self) -> TokenStream { + pub fn emit_ctx_params(self, query_type: &Type) -> TokenStream { use MsgType::*; let sylvia = crate_module(); match self { Exec | Instantiate => quote! { - deps: #sylvia ::cw_std::DepsMut, env: #sylvia ::cw_std::Env, info: #sylvia ::cw_std::MessageInfo + deps: #sylvia ::cw_std::DepsMut< #query_type>, env: #sylvia ::cw_std::Env, info: #sylvia ::cw_std::MessageInfo }, Migrate | Reply | Sudo => quote! { - deps: #sylvia ::cw_std::DepsMut, env: #sylvia ::cw_std::Env + deps: #sylvia ::cw_std::DepsMut< #query_type>, env: #sylvia ::cw_std::Env }, Query => quote! { - deps: #sylvia ::cw_std::Deps, env: #sylvia ::cw_std::Env + deps: #sylvia ::cw_std::Deps< #query_type>, env: #sylvia ::cw_std::Env }, } } @@ -540,6 +540,7 @@ impl OverrideEntryPoint { #[cfg(not(tarpaulin_include))] pub fn emit_default_entry_point( custom_msg: &Type, + custom_query: &Type, name: &Type, error: &Type, msg_type: MsgType, @@ -550,7 +551,7 @@ impl OverrideEntryPoint { MsgType::Query => quote! { #sylvia ::cw_std::Binary }, _ => quote! { #sylvia ::cw_std::Response < #custom_msg > }, }; - let params = msg_type.emit_ctx_params(); + let params = msg_type.emit_ctx_params(custom_query); let values = msg_type.emit_ctx_values(); let ep_name = msg_type.emit_ep_name(); let msg_name = msg_type.emit_msg_name(); diff --git a/sylvia/tests/custom_msg.rs b/sylvia/tests/custom_msg.rs index 03d2dae3..9365ba44 100644 --- a/sylvia/tests/custom_msg.rs +++ b/sylvia/tests/custom_msg.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{CustomMsg, CustomQuery, Response, StdResult}; +use cosmwasm_std::{CustomMsg, Response, StdResult}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use sylvia::contract; @@ -14,11 +14,6 @@ pub struct OtherMsg; impl CustomMsg for OtherMsg {} -#[derive(Clone, PartialEq, Serialize, Deserialize, Debug, JsonSchema)] -pub struct MyQuery; - -impl CustomQuery for MyQuery {} - pub struct MyContract; #[derive(Clone, PartialEq, Serialize, Deserialize, Debug, JsonSchema)]