Repository: CosmWasm/cosmwasm
Pull request #1102 (2021-09-22 18:53:42)

CustomMsg trait
We already have a `CustomQuery` trait, this takes a similar approach for `CustomMsg`, which was `T: Clone + fmt::Debug + PartialEq + JsonSchema` all over the code.

Even if we will need it fewer places now that the struct bound is gone, I figured it is nice to have a helper trait to combine all these requirements. 

Furthermore, since almost all structs (messages, query, state) fulfil those trait bounds, it is nice to explicitly mark one as a `CustomMsg`. These occur very rarely. Outside of cosmwasm tests, there will be one such type per blockchain that makes extensions. I am sure one line to implement this trait for that type is worth the type-safety and reduced verbosity other places. 

uint: I like it. Anything that makes types clearer is :ok_hand: in my book.
ethanfrey: I am also happy to revisit if `CustomMsg` really needs all of `: Clone + fmt::Debug + PartialEq + JsonSchema`.
But I would do that as another PR if desired, and having this one trait/alias will make it easier to change if we don't need them all.
ethanfrey: I guess I need to fix tests when the CI is working again...

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 40dce49c8..5332e9188 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -43,8 +43,6 @@ and this project adheres to
 - cosmwasm-std: Make method `Uint512::from_le_bytes` const.
 - cosmwasm-std: Rename `Pair` to `Record`. `Pair` is now an alias for `Record`
   and deprecated.
-- cosmwasm-vm: Bump required marker export `interface_version_7` to
-  `interface_version_8`.
 
 ### Removed
 
diff --git a/README.md b/README.md
index efa4bc7bb..2b2709f9d 100644
--- a/README.md
+++ b/README.md
@@ -120,8 +120,8 @@ If you haven't worked with WebAssembly before, please read an overview on
 The required exports provided by the cosmwasm smart contract are:
 
 ```rust
-// signal for 1.0 compatibility
-extern "C" fn interface_version_8() -> () {}
+// signal for 0.16 compatibility
+extern "C" fn interface_version_7() -> () {}
 
 // copy memory to/from host, so we can pass in/out Vec<u8>
 extern "C" fn allocate(size: usize) -> u32;
diff --git a/contracts/reflect/src/msg.rs b/contracts/reflect/src/msg.rs
index 6098e8568..4ff280a81 100644
--- a/contracts/reflect/src/msg.rs
+++ b/contracts/reflect/src/msg.rs
@@ -73,6 +73,8 @@ pub enum CustomMsg {
     Raw(Binary),
 }
 
+impl cosmwasm_std::CustomMsg for CustomMsg {}
+
 impl From<CustomMsg> for CosmosMsg<CustomMsg> {
     fn from(original: CustomMsg) -> Self {
         CosmosMsg::Custom(original)
diff --git a/packages/std/src/entry_points.rs b/packages/std/src/entry_points.rs
index bfc9f991e..62780e7db 100644
--- a/packages/std/src/entry_points.rs
+++ b/packages/std/src/entry_points.rs
@@ -81,7 +81,7 @@ macro_rules! create_entry_points {
 
             $crate::create_entry_points!(@migration; $contract, $migration);
 
-            // Other C externs like interface_version_8, allocate, deallocate are available
+            // Other C externs like interface_version_7, allocate, deallocate are available
             // automatically because we `use cosmwasm_std`.
         }
     };
diff --git a/packages/std/src/exports.rs b/packages/std/src/exports.rs
index 367912daf..41cde5a90 100644
--- a/packages/std/src/exports.rs
+++ b/packages/std/src/exports.rs
@@ -7,12 +7,10 @@
 //! and `do_sudo` should be wrapped with a extern "C" entry point including
 //! the contract-specific function pointer. This is done via the `#[entry_point]`
 //! macro attribute from cosmwasm-derive.
-use std::fmt;
 use std::marker::PhantomData;
 use std::vec::Vec;
 
-use schemars::JsonSchema;
-use serde::{de::DeserializeOwned, Serialize};
+use serde::de::DeserializeOwned;
 
 use crate::deps::OwnedDeps;
 #[cfg(feature = "stargate")]
@@ -26,7 +24,7 @@ use crate::query::CustomQuery;
 use crate::results::{ContractResult, QueryResponse, Reply, Response};
 use crate::serde::{from_slice, to_vec};
 use crate::types::Env;
-use crate::{Deps, DepsMut, MessageInfo};
+use crate::{CustomMsg, Deps, DepsMut, MessageInfo};
 
 #[cfg(feature = "iterator")]
 #[no_mangle]
@@ -44,7 +42,7 @@ extern "C" fn requires_stargate() -> () {}
 /// They can be checked by cosmwasm_vm.
 /// Update this whenever the Wasm VM interface breaks.
 #[no_mangle]
-extern "C" fn interface_version_8() -> () {}
+extern "C" fn interface_version_7() -> () {}
 
 /// allocate reserves the given number of bytes in wasm memory and returns a pointer
 /// to a Region defining this data. This space is managed by the calling process
@@ -91,8 +89,8 @@ pub fn do_instantiate<Q, M, C, E>(
 ) -> u32
 where
     Q: CustomQuery,
-    M: DeserializeOwned + JsonSchema,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    M: DeserializeOwned,
+    C: CustomMsg,
     E: ToString,
 {
     let res = _do_instantiate(
@@ -119,8 +117,8 @@ pub fn do_execute<Q, M, C, E>(
 ) -> u32
 where
     Q: CustomQuery,
-    M: DeserializeOwned + JsonSchema,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    M: DeserializeOwned,
+    C: CustomMsg,
     E: ToString,
 {
     let res = _do_execute(
@@ -146,8 +144,8 @@ pub fn do_migrate<Q, M, C, E>(
 ) -> u32
 where
     Q: CustomQuery,
-    M: DeserializeOwned + JsonSchema,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    M: DeserializeOwned,
+    C: CustomMsg,
     E: ToString,
 {
     let res = _do_migrate(migrate_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
@@ -168,8 +166,8 @@ pub fn do_sudo<Q, M, C, E>(
 ) -> u32
 where
     Q: CustomQuery,
-    M: DeserializeOwned + JsonSchema,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    M: DeserializeOwned,
+    C: CustomMsg,
     E: ToString,
 {
     let res = _do_sudo(sudo_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
@@ -190,7 +188,7 @@ pub fn do_reply<Q, C, E>(
 ) -> u32
 where
     Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    C: CustomMsg,
     E: ToString,
 {
     let res = _do_reply(reply_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
@@ -210,7 +208,7 @@ pub fn do_query<Q, M, E>(
 ) -> u32
 where
     Q: CustomQuery,
-    M: DeserializeOwned + JsonSchema,
+    M: DeserializeOwned,
     E: ToString,
 {
     let res = _do_query(query_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
@@ -254,7 +252,7 @@ pub fn do_ibc_channel_connect<Q, C, E>(
 ) -> u32
 where
     Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    C: CustomMsg,
     E: ToString,
 {
     let res = _do_ibc_channel_connect(contract_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
@@ -277,7 +275,7 @@ pub fn do_ibc_channel_close<Q, C, E>(
 ) -> u32
 where
     Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    C: CustomMsg,
     E: ToString,
 {
     let res = _do_ibc_channel_close(contract_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
@@ -301,7 +299,7 @@ pub fn do_ibc_packet_receive<Q, C, E>(
 ) -> u32
 where
     Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    C: CustomMsg,
     E: ToString,
 {
     let res = _do_ibc_packet_receive(contract_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
@@ -325,7 +323,7 @@ pub fn do_ibc_packet_ack<Q, C, E>(
 ) -> u32
 where
     Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    C: CustomMsg,
     E: ToString,
 {
     let res = _do_ibc_packet_ack(contract_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
@@ -350,7 +348,7 @@ pub fn do_ibc_packet_timeout<Q, C, E>(
 ) -> u32
 where
     Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    C: CustomMsg,
     E: ToString,
 {
     let res = _do_ibc_packet_timeout(contract_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
@@ -366,8 +364,8 @@ fn _do_instantiate<Q, M, C, E>(
 ) -> ContractResult<Response<C>>
 where
     Q: CustomQuery,
-    M: DeserializeOwned + JsonSchema,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    M: DeserializeOwned,
+    C: CustomMsg,
     E: ToString,
 {
     let env: Vec<u8> = unsafe { consume_region(env_ptr) };
@@ -390,8 +388,8 @@ fn _do_execute<Q, M, C, E>(
 ) -> ContractResult<Response<C>>
 where
     Q: CustomQuery,
-    M: DeserializeOwned + JsonSchema,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    M: DeserializeOwned,
+    C: CustomMsg,
     E: ToString,
 {
     let env: Vec<u8> = unsafe { consume_region(env_ptr) };
@@ -413,8 +411,8 @@ fn _do_migrate<Q, M, C, E>(
 ) -> ContractResult<Response<C>>
 where
     Q: CustomQuery,
-    M: DeserializeOwned + JsonSchema,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    M: DeserializeOwned,
+    C: CustomMsg,
     E: ToString,
 {
     let env: Vec<u8> = unsafe { consume_region(env_ptr) };
@@ -434,8 +432,8 @@ fn _do_sudo<Q, M, C, E>(
 ) -> ContractResult<Response<C>>
 where
     Q: CustomQuery,
-    M: DeserializeOwned + JsonSchema,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    M: DeserializeOwned,
+    C: CustomMsg,
     E: ToString,
 {
     let env: Vec<u8> = unsafe { consume_region(env_ptr) };
@@ -455,7 +453,7 @@ fn _do_reply<Q, C, E>(
 ) -> ContractResult<Response<C>>
 where
     Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    C: CustomMsg,
     E: ToString,
 {
     let env: Vec<u8> = unsafe { consume_region(env_ptr) };
@@ -475,7 +473,7 @@ fn _do_query<Q, M, E>(
 ) -> ContractResult<QueryResponse>
 where
     Q: CustomQuery,
-    M: DeserializeOwned + JsonSchema,
+    M: DeserializeOwned,
     E: ToString,
 {
     let env: Vec<u8> = unsafe { consume_region(env_ptr) };
@@ -516,7 +514,7 @@ fn _do_ibc_channel_connect<Q, C, E>(
 ) -> ContractResult<IbcBasicResponse<C>>
 where
     Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    C: CustomMsg,
     E: ToString,
 {
     let env: Vec<u8> = unsafe { consume_region(env_ptr) };
@@ -537,7 +535,7 @@ fn _do_ibc_channel_close<Q, C, E>(
 ) -> ContractResult<IbcBasicResponse<C>>
 where
     Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    C: CustomMsg,
     E: ToString,
 {
     let env: Vec<u8> = unsafe { consume_region(env_ptr) };
@@ -558,7 +556,7 @@ fn _do_ibc_packet_receive<Q, C, E>(
 ) -> ContractResult<IbcReceiveResponse<C>>
 where
     Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    C: CustomMsg,
     E: ToString,
 {
     let env: Vec<u8> = unsafe { consume_region(env_ptr) };
@@ -579,7 +577,7 @@ fn _do_ibc_packet_ack<Q, C, E>(
 ) -> ContractResult<IbcBasicResponse<C>>
 where
     Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    C: CustomMsg,
     E: ToString,
 {
     let env: Vec<u8> = unsafe { consume_region(env_ptr) };
@@ -600,7 +598,7 @@ fn _do_ibc_packet_timeout<Q, C, E>(
 ) -> ContractResult<IbcBasicResponse<C>>
 where
     Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    C: CustomMsg,
     E: ToString,
 {
     let env: Vec<u8> = unsafe { consume_region(env_ptr) };
diff --git a/packages/std/src/ibc.rs b/packages/std/src/ibc.rs
index 69cc2aa31..8a64fe07c 100644
--- a/packages/std/src/ibc.rs
+++ b/packages/std/src/ibc.rs
@@ -5,12 +5,11 @@
 use schemars::JsonSchema;
 use serde::{Deserialize, Serialize};
 use std::cmp::{Ord, Ordering, PartialOrd};
-use std::fmt;
 
 use crate::binary::Binary;
 use crate::coins::Coin;
 use crate::errors::StdResult;
-use crate::results::{Attribute, CosmosMsg, Empty, Event, SubMsg};
+use crate::results::{Attribute, CosmosMsg, CustomMsg, Empty, Event, SubMsg};
 use crate::serde::to_binary;
 use crate::timestamp::Timestamp;
 
@@ -441,7 +440,7 @@ impl IbcPacketTimeoutMsg {
 #[non_exhaustive]
 pub struct IbcBasicResponse<T = Empty>
 where
-    T: Clone + fmt::Debug + PartialEq + JsonSchema,
+    T: CustomMsg,
 {
     /// Optional list of messages to pass. These will be executed in order.
     /// If the ReplyOn member is set, they will invoke this contract's `reply` entry point
@@ -465,7 +464,7 @@ where
 
 impl<T> Default for IbcBasicResponse<T>
 where
-    T: Clone + fmt::Debug + PartialEq + JsonSchema,
+    T: CustomMsg,
 {
     fn default() -> Self {
         IbcBasicResponse {
@@ -478,7 +477,7 @@ where
 
 impl<T> IbcBasicResponse<T>
 where
-    T: Clone + fmt::Debug + PartialEq + JsonSchema,
+    T: CustomMsg,
 {
     pub fn new() -> Self {
         Self::default()
@@ -591,7 +590,7 @@ where
 #[non_exhaustive]
 pub struct IbcReceiveResponse<T = Empty>
 where
-    T: Clone + fmt::Debug + PartialEq + JsonSchema,
+    T: CustomMsg,
 {
     /// The bytes we return to the contract that sent the packet.
     /// This may represent a success or error of exection
@@ -618,7 +617,7 @@ where
 
 impl<T> Default for IbcReceiveResponse<T>
 where
-    T: Clone + fmt::Debug + PartialEq + JsonSchema,
+    T: CustomMsg,
 {
     fn default() -> Self {
         IbcReceiveResponse {
@@ -632,7 +631,7 @@ where
 
 impl<T> IbcReceiveResponse<T>
 where
-    T: Clone + fmt::Debug + PartialEq + JsonSchema,
+    T: CustomMsg,
 {
     pub fn new() -> Self {
         Self::default()
diff --git a/packages/std/src/lib.rs b/packages/std/src/lib.rs
index aa2da25cf..b4cd2bf06 100644
--- a/packages/std/src/lib.rs
+++ b/packages/std/src/lib.rs
@@ -58,9 +58,9 @@ pub use crate::query::{
 #[cfg(feature = "stargate")]
 pub use crate::query::{ChannelResponse, IbcQuery, ListChannelsResponse, PortIdResponse};
 pub use crate::results::{
-    attr, wasm_execute, wasm_instantiate, Attribute, BankMsg, ContractResult, CosmosMsg, Empty,
-    Event, QueryResponse, Reply, ReplyOn, Response, SubMsg, SubMsgExecutionResponse, SystemResult,
-    WasmMsg,
+    attr, wasm_execute, wasm_instantiate, Attribute, BankMsg, ContractResult, CosmosMsg, CustomMsg,
+    Empty, Event, QueryResponse, Reply, ReplyOn, Response, SubMsg, SubMsgExecutionResponse,
+    SystemResult, WasmMsg,
 };
 #[cfg(feature = "staking")]
 pub use crate::results::{DistributionMsg, StakingMsg};
diff --git a/packages/std/src/results/cosmos_msg.rs b/packages/std/src/results/cosmos_msg.rs
index 7a16c32bd..47307d67a 100644
--- a/packages/std/src/results/cosmos_msg.rs
+++ b/packages/std/src/results/cosmos_msg.rs
@@ -11,6 +11,12 @@ use crate::serde::to_binary;
 
 use super::Empty;
 
+/// Like CustomQuery for better type clarity.
+/// Also makes it shorter to use as a trait bound.
+pub trait CustomMsg: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema {}
+
+impl CustomMsg for Empty {}
+
 #[non_exhaustive]
 #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
 #[serde(rename_all = "snake_case")]
@@ -212,7 +218,7 @@ pub fn wasm_execute(
 
 impl<T> From<BankMsg> for CosmosMsg<T>
 where
-    T: Clone + fmt::Debug + PartialEq + JsonSchema,
+    T: CustomMsg,
 {
     fn from(msg: BankMsg) -> Self {
         CosmosMsg::Bank(msg)
@@ -222,7 +228,7 @@ where
 #[cfg(feature = "staking")]
 impl<T> From<StakingMsg> for CosmosMsg<T>
 where
-    T: Clone + fmt::Debug + PartialEq + JsonSchema,
+    T: CustomMsg,
 {
     fn from(msg: StakingMsg) -> Self {
         CosmosMsg::Staking(msg)
@@ -232,7 +238,7 @@ where
 #[cfg(feature = "staking")]
 impl<T> From<DistributionMsg> for CosmosMsg<T>
 where
-    T: Clone + fmt::Debug + PartialEq + JsonSchema,
+    T: CustomMsg,
 {
     fn from(msg: DistributionMsg) -> Self {
         CosmosMsg::Distribution(msg)
@@ -241,7 +247,7 @@ where
 
 impl<T> From<WasmMsg> for CosmosMsg<T>
 where
-    T: Clone + fmt::Debug + PartialEq + JsonSchema,
+    T: CustomMsg,
 {
     fn from(msg: WasmMsg) -> Self {
         CosmosMsg::Wasm(msg)
@@ -251,7 +257,7 @@ where
 #[cfg(feature = "stargate")]
 impl<T> From<IbcMsg> for CosmosMsg<T>
 where
-    T: Clone + fmt::Debug + PartialEq + JsonSchema,
+    T: CustomMsg,
 {
     fn from(msg: IbcMsg) -> Self {
         CosmosMsg::Ibc(msg)
@@ -261,7 +267,7 @@ where
 #[cfg(feature = "stargate")]
 impl<T> From<GovMsg> for CosmosMsg<T>
 where
-    T: Clone + fmt::Debug + PartialEq + JsonSchema,
+    T: CustomMsg,
 {
     fn from(msg: GovMsg) -> Self {
         CosmosMsg::Gov(msg)
diff --git a/packages/std/src/results/mod.rs b/packages/std/src/results/mod.rs
index ba4a7edf3..2bd4663fb 100644
--- a/packages/std/src/results/mod.rs
+++ b/packages/std/src/results/mod.rs
@@ -10,7 +10,7 @@ mod submessages;
 mod system_result;
 
 pub use contract_result::ContractResult;
-pub use cosmos_msg::{wasm_execute, wasm_instantiate, BankMsg, CosmosMsg, WasmMsg};
+pub use cosmos_msg::{wasm_execute, wasm_instantiate, BankMsg, CosmosMsg, CustomMsg, WasmMsg};
 #[cfg(feature = "staking")]
 pub use cosmos_msg::{DistributionMsg, StakingMsg};
 #[cfg(feature = "stargate")]
diff --git a/packages/vm/README.md b/packages/vm/README.md
index 4c484bb99..e8cdb46e1 100644
--- a/packages/vm/README.md
+++ b/packages/vm/README.md
@@ -16,7 +16,7 @@ compatibility list:
 
 | cosmwasm-vm | Supported interface versions | cosmwasm-std |
 | ----------- | ---------------------------- | ------------ |
-| 1.0         | `interface_version_8`        | 1.0          |
+| 1.0         | TBD                          | 1.0          |
 | 0.16        | `interface_version_7`        | 0.16         |
 | 0.15        | `interface_version_6`        | 0.15         |
 | 0.14        | `interface_version_5`        | 0.14         |
diff --git a/packages/vm/src/calls.rs b/packages/vm/src/calls.rs
index e27f5abb6..0d2aca747 100644
--- a/packages/vm/src/calls.rs
+++ b/packages/vm/src/calls.rs
@@ -1,9 +1,7 @@
-use schemars::JsonSchema;
 use serde::de::DeserializeOwned;
-use std::fmt;
 use wasmer::Val;
 
-use cosmwasm_std::{ContractResult, Env, MessageInfo, QueryResponse, Reply, Response};
+use cosmwasm_std::{ContractResult, CustomMsg, Env, MessageInfo, QueryResponse, Reply, Response};
 #[cfg(feature = "stargate")]
 use cosmwasm_std::{
     IbcBasicResponse, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcPacketAckMsg,
@@ -106,7 +104,7 @@ where
     A: BackendApi + 'static,
     S: Storage + 'static,
     Q: Querier + 'static,
-    U: DeserializeOwned + Clone + fmt::Debug + JsonSchema + PartialEq,
+    U: DeserializeOwned + CustomMsg,
 {
     let env = to_vec(env)?;
     let info = to_vec(info)?;
@@ -126,7 +124,7 @@ where
     A: BackendApi + 'static,
     S: Storage + 'static,
     Q: Querier + 'static,
-    U: DeserializeOwned + Clone + fmt::Debug + JsonSchema + PartialEq,
+    U: DeserializeOwned + CustomMsg,
 {
     let env = to_vec(env)?;
     let info = to_vec(info)?;
@@ -145,7 +143,7 @@ where
     A: BackendApi + 'static,
     S: Storage + 'static,
     Q: Querier + 'static,
-    U: DeserializeOwned + Clone + fmt::Debug + JsonSchema + PartialEq,
+    U: DeserializeOwned + CustomMsg,
 {
     let env = to_vec(env)?;
     let data = call_migrate_raw(instance, &env, msg)?;
@@ -163,7 +161,7 @@ where
     A: BackendApi + 'static,
     S: Storage + 'static,
     Q: Querier + 'static,
-    U: DeserializeOwned + Clone + fmt::Debug + JsonSchema + PartialEq,
+    U: DeserializeOwned + CustomMsg,
 {
     let env = to_vec(env)?;
     let data = call_sudo_raw(instance, &env, msg)?;
@@ -181,7 +179,7 @@ where
     A: BackendApi + 'static,
     S: Storage + 'static,
     Q: Querier + 'static,
-    U: DeserializeOwned + Clone + fmt::Debug + JsonSchema + PartialEq,
+    U: DeserializeOwned + CustomMsg,
 {
     let env = to_vec(env)?;
     let msg = to_vec(msg)?;
@@ -244,7 +242,7 @@ where
     A: BackendApi + 'static,
     S: Storage + 'static,
     Q: Querier + 'static,
-    U: DeserializeOwned + Clone + fmt::Debug + JsonSchema + PartialEq,
+    U: DeserializeOwned + CustomMsg,
 {
     let env = to_vec(env)?;
     let msg = to_vec(msg)?;
@@ -263,7 +261,7 @@ where
     A: BackendApi + 'static,
     S: Storage + 'static,
     Q: Querier + 'static,
-    U: DeserializeOwned + Clone + fmt::Debug + JsonSchema + PartialEq,
+    U: DeserializeOwned + CustomMsg,
 {
     let env = to_vec(env)?;
     let msg = to_vec(msg)?;
@@ -282,7 +280,7 @@ where
     A: BackendApi + 'static,
     S: Storage + 'static,
     Q: Querier + 'static,
-    U: DeserializeOwned + Clone + fmt::Debug + JsonSchema + PartialEq,
+    U: DeserializeOwned + CustomMsg,
 {
     let env = to_vec(env)?;
     let msg = to_vec(msg)?;
@@ -301,7 +299,7 @@ where
     A: BackendApi + 'static,
     S: Storage + 'static,
     Q: Querier + 'static,
-    U: DeserializeOwned + Clone + fmt::Debug + JsonSchema + PartialEq,
+    U: DeserializeOwned + CustomMsg,
 {
     let env = to_vec(env)?;
     let msg = to_vec(msg)?;
@@ -320,7 +318,7 @@ where
     A: BackendApi + 'static,
     S: Storage + 'static,
     Q: Querier + 'static,
-    U: DeserializeOwned + Clone + fmt::Debug + JsonSchema + PartialEq,
+    U: DeserializeOwned + CustomMsg,
 {
     let env = to_vec(env)?;
     let msg = to_vec(msg)?;
diff --git a/packages/vm/src/compatibility.rs b/packages/vm/src/compatibility.rs
index ee8b0a552..e0c485cf5 100644
--- a/packages/vm/src/compatibility.rs
+++ b/packages/vm/src/compatibility.rs
@@ -43,7 +43,7 @@ const REQUIRED_EXPORTS: &[&str] = &[
 const INTERFACE_VERSION_PREFIX: &str = "interface_version_";
 /// Only one version is supported right now. This could potentially turn into a list
 /// later, but maybe this never happens and new functionality is only added via features.
-const SUPPORTED_INTERFACE_VERSION: &str = "interface_version_8";
+const SUPPORTED_INTERFACE_VERSION: &str = "interface_version_7";
 
 const MEMORY_LIMIT: u32 = 512; // in pages
 
@@ -348,7 +348,7 @@ mod tests {
                 (func (type 0) nop)
                 (export "add_one" (func 0))
                 (export "allocate" (func 0))
-                (export "interface_version_8" (func 0))
+                (export "interface_version_7" (func 0))
                 (export "deallocate" (func 0))
                 (export "instantiate" (func 0))
             )"#,
@@ -387,8 +387,8 @@ mod tests {
                 (func (type 0) nop)
                 (export "add_one" (func 0))
                 (export "allocate" (func 0))
+                (export "interface_version_7" (func 0))
                 (export "interface_version_8" (func 0))
-                (export "interface_version_9" (func 0))
                 (export "deallocate" (func 0))
                 (export "instantiate" (func 0))
             )"#,
diff --git a/packages/vm/src/environment.rs b/packages/vm/src/environment.rs
index 6ef1333aa..26ab10fe4 100644
--- a/packages/vm/src/environment.rs
+++ b/packages/vm/src/environment.rs
@@ -704,7 +704,7 @@ mod tests {
         let (env, _instance) = make_instance(TESTING_GAS_LIMIT);
         leave_default_data(&env);
 
-        env.call_function0("interface_version_8", &[]).unwrap();
+        env.call_function0("interface_version_7", &[]).unwrap();
     }
 
     #[test]
diff --git a/packages/vm/src/instance.rs b/packages/vm/src/instance.rs
index ee305a26e..8e44d273b 100644
--- a/packages/vm/src/instance.rs
+++ b/packages/vm/src/instance.rs
@@ -476,7 +476,7 @@ mod tests {
         let instance = mock_instance(CONTRACT, &[]);
 
         instance
-            .call_function0("interface_version_8", &[])
+            .call_function0("interface_version_7", &[])
             .expect("error calling function");
     }
 
@@ -565,7 +565,7 @@ mod tests {
         // set up an instance that will experience an error in an import
         let error_message = "Api failed intentionally";
         let mut instance = mock_instance_with_failing_api(CONTRACT, &[], error_message);
-        let init_result = call_instantiate::<_, _, _, serde_json::Value>(
+        let init_result = call_instantiate::<_, _, _, Empty>(
             &mut instance,
             &mock_env(),
             &mock_info("someone", &[]),
@@ -619,7 +619,7 @@ mod tests {
 
                 (type (func))
                 (func (type 0) nop)
-                (export "interface_version_8" (func 0))
+                (export "interface_version_7" (func 0))
                 (export "instantiate" (func 0))
                 (export "allocate" (func 0))
                 (export "deallocate" (func 0))
@@ -637,7 +637,7 @@ mod tests {
 
                 (type (func))
                 (func (type 0) nop)
-                (export "interface_version_8" (func 0))
+                (export "interface_version_7" (func 0))
                 (export "instantiate" (func 0))
                 (export "allocate" (func 0))
                 (export "deallocate" (func 0))
diff --git a/packages/vm/src/static_analysis.rs b/packages/vm/src/static_analysis.rs
index a8e5386a2..4be596ff8 100644
--- a/packages/vm/src/static_analysis.rs
+++ b/packages/vm/src/static_analysis.rs
@@ -248,7 +248,7 @@ mod tests {
 
                 (type (func))
                 (func (type 0) nop)
-                (export "interface_version_8" (func 0))
+                (export "interface_version_7" (func 0))
                 (export "instantiate" (func 0))
                 (export "allocate" (func 0))
                 (export "deallocate" (func 0))
@@ -266,7 +266,7 @@ mod tests {
 
                 (type (func))
                 (func (type 0) nop)
-                (export "interface_version_8" (func 0))
+                (export "interface_version_7" (func 0))
                 (export "instantiate" (func 0))
                 (export "execute" (func 0))
                 (export "allocate" (func 0))
@@ -291,7 +291,7 @@ mod tests {
 
                 (type (func))
                 (func (type 0) nop)
-                (export "interface_version_8" (func 0))
+                (export "interface_version_7" (func 0))
                 (export "instantiate" (func 0))
                 (export "execute" (func 0))
                 (export "allocate" (func 0))


Test patch:
diff --git a/packages/vm/src/testing/calls.rs b/packages/vm/src/testing/calls.rs
index 55df5a196..286241b59 100644
--- a/packages/vm/src/testing/calls.rs
+++ b/packages/vm/src/testing/calls.rs
@@ -3,9 +3,8 @@
 //! use cosmwasm_vm::testing::X
 use schemars::JsonSchema;
 use serde::{de::DeserializeOwned, Serialize};
-use std::fmt;
 
-use cosmwasm_std::{ContractResult, Env, MessageInfo, QueryResponse, Reply, Response};
+use cosmwasm_std::{ContractResult, CustomMsg, Env, MessageInfo, QueryResponse, Reply, Response};
 #[cfg(feature = "stargate")]
 use cosmwasm_std::{
     IbcBasicResponse, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcPacketAckMsg,
@@ -38,7 +37,7 @@ where
     S: Storage + 'static,
     Q: Querier + 'static,
     M: Serialize + JsonSchema,
-    U: DeserializeOwned + Clone + PartialEq + JsonSchema + fmt::Debug,
+    U: DeserializeOwned + CustomMsg,
 {
     let serialized_msg = to_vec(&msg).expect("Testing error: Could not seralize request message");
     call_instantiate(instance, &env, &info, &serialized_msg).expect("VM error")
@@ -58,7 +57,7 @@ where
     S: Storage + 'static,
     Q: Querier + 'static,
     M: Serialize + JsonSchema,
-    U: DeserializeOwned + Clone + PartialEq + JsonSchema + fmt::Debug,
+    U: DeserializeOwned + CustomMsg,
 {
     let serialized_msg = to_vec(&msg).expect("Testing error: Could not seralize request message");
     call_execute(instance, &env, &info, &serialized_msg).expect("VM error")
@@ -77,7 +76,7 @@ where
     S: Storage + 'static,
     Q: Querier + 'static,
     M: Serialize + JsonSchema,
-    U: DeserializeOwned + Clone + PartialEq + JsonSchema + fmt::Debug,
+    U: DeserializeOwned + CustomMsg,
 {
     let serialized_msg = to_vec(&msg).expect("Testing error: Could not seralize request message");
     call_migrate(instance, &env, &serialized_msg).expect("VM error")
@@ -96,7 +95,7 @@ where
     S: Storage + 'static,
     Q: Querier + 'static,
     M: Serialize + JsonSchema,
-    U: DeserializeOwned + Clone + PartialEq + JsonSchema + fmt::Debug,
+    U: DeserializeOwned + CustomMsg,
 {
     let serialized_msg = to_vec(&msg).expect("Testing error: Could not seralize request message");
     call_sudo(instance, &env, &serialized_msg).expect("VM error")
@@ -114,7 +113,7 @@ where
     A: BackendApi + 'static,
     S: Storage + 'static,
     Q: Querier + 'static,
-    U: DeserializeOwned + Clone + PartialEq + JsonSchema + fmt::Debug,
+    U: DeserializeOwned + CustomMsg,
 {
     call_reply(instance, &env, &msg).expect("VM error")
 }
@@ -167,7 +166,7 @@ where
     A: BackendApi + 'static,
     S: Storage + 'static,
     Q: Querier + 'static,
-    U: DeserializeOwned + Clone + PartialEq + JsonSchema + fmt::Debug,
+    U: DeserializeOwned + CustomMsg,
 {
     call_ibc_channel_connect(instance, &env, &msg).expect("VM error")
 }
@@ -185,7 +184,7 @@ where
     A: BackendApi + 'static,
     S: Storage + 'static,
     Q: Querier + 'static,
-    U: DeserializeOwned + Clone + PartialEq + JsonSchema + fmt::Debug,
+    U: DeserializeOwned + CustomMsg,
 {
     call_ibc_channel_close(instance, &env, &msg).expect("VM error")
 }
@@ -203,7 +202,7 @@ where
     A: BackendApi + 'static,
     S: Storage + 'static,
     Q: Querier + 'static,
-    U: DeserializeOwned + Clone + PartialEq + JsonSchema + fmt::Debug,
+    U: DeserializeOwned + CustomMsg,
 {
     call_ibc_packet_receive(instance, &env, &msg).expect("VM error")
 }
@@ -221,7 +220,7 @@ where
     A: BackendApi + 'static,
     S: Storage + 'static,
     Q: Querier + 'static,
-    U: DeserializeOwned + Clone + PartialEq + JsonSchema + fmt::Debug,
+    U: DeserializeOwned + CustomMsg,
 {
     call_ibc_packet_ack(instance, &env, &msg).expect("VM error")
 }
@@ -239,7 +238,7 @@ where
     A: BackendApi + 'static,
     S: Storage + 'static,
     Q: Querier + 'static,
-    U: DeserializeOwned + Clone + PartialEq + JsonSchema + fmt::Debug,
+    U: DeserializeOwned + CustomMsg,
 {
     call_ibc_packet_timeout(instance, &env, &msg).expect("VM error")
 }