Repository: CosmWasm/cosmwasm
Pull request #1085 (2021-09-09 06:08:12)

Enable injecting extra fn imports and middlewares to cosmwasm_vm::Instance
This enables us to inject middlewares and fn imports. This is for the contract profiler, which I'd like to remain a separate crate in this repo.

* Extra middlewares can now be added to a `cosmwasm_vm::Instance`.
* Extra fn imports can now be added to a `cosmwasm_vm::Instance`.
* `wasmer` types aren't leaked (except through `internals`).
* `MockInstance`s stay the same... for now.


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d9e114341..c60c40102 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,15 +12,6 @@ and this project adheres to
   flag is set (enabled by default).
 - cosmwasm-vm: Increase `MAX_LENGTH_HUMAN_ADDRESS` from 90 to 256 in order to
   support longer address formats than bech32.
-- cosmwasm-std: Make `CustomQuery` a subtrait of `Clone`, i.e. types that
-  implement `CustomQuery` need to be `Clone`able.
-- cosmwasm-std: Add generic for custom query type to `QuerierWrapper`, `Deps`,
-  `DepsMut` and `OwnedDeps`. Merge `QuerierWrapper::custom_query` into the now
-  fully typed `QuerierWrapper::query`.
-- cosmwasm-std: Add generic type `Q` for the custom query request type to
-  `do_instantiate`, `do_execute`, `do_migrate`, `do_sudo`, `do_reply`,
-  `do_query`, `ibc_channel_open`, `ibc_channel_connect`, `ibc_channel_close`,
-  `ibc_packet_receive`, `ibc_packet_ack` and `ibc_packet_timeout`.
 
 ### Removed
 
diff --git a/contracts/reflect/src/contract.rs b/contracts/reflect/src/contract.rs
index 3528e5635..02bfa51d8 100644
--- a/contracts/reflect/src/contract.rs
+++ b/contracts/reflect/src/contract.rs
@@ -12,7 +12,7 @@ use crate::msg::{
 use crate::state::{config, config_read, replies, replies_read, State};
 
 pub fn instantiate(
-    deps: DepsMut<SpecialQuery>,
+    deps: DepsMut,
     _env: Env,
     info: MessageInfo,
     _msg: InstantiateMsg,
@@ -23,7 +23,7 @@ pub fn instantiate(
 }
 
 pub fn execute(
-    deps: DepsMut<SpecialQuery>,
+    deps: DepsMut,
     env: Env,
     info: MessageInfo,
     msg: ExecuteMsg,
@@ -36,7 +36,7 @@ pub fn execute(
 }
 
 pub fn try_reflect(
-    deps: DepsMut<SpecialQuery>,
+    deps: DepsMut,
     _env: Env,
     info: MessageInfo,
     msgs: Vec<CosmosMsg<CustomMsg>>,
@@ -60,7 +60,7 @@ pub fn try_reflect(
 }
 
 pub fn try_reflect_subcall(
-    deps: DepsMut<SpecialQuery>,
+    deps: DepsMut,
     _env: Env,
     info: MessageInfo,
     msgs: Vec<SubMsg<CustomMsg>>,
@@ -83,7 +83,7 @@ pub fn try_reflect_subcall(
 }
 
 pub fn try_change_owner(
-    deps: DepsMut<SpecialQuery>,
+    deps: DepsMut,
     _env: Env,
     info: MessageInfo,
     new_owner: String,
@@ -106,13 +106,13 @@ pub fn try_change_owner(
 
 /// This just stores the result for future query
 #[entry_point]
-pub fn reply(deps: DepsMut<SpecialQuery>, _env: Env, msg: Reply) -> Result<Response, ReflectError> {
+pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result<Response, ReflectError> {
     let key = msg.id.to_be_bytes();
     replies(deps.storage).save(&key, &msg)?;
     Ok(Response::default())
 }
 
-pub fn query(deps: Deps<SpecialQuery>, _env: Env, msg: QueryMsg) -> StdResult<QueryResponse> {
+pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<QueryResponse> {
     match msg {
         QueryMsg::Owner {} => to_binary(&query_owner(deps)?),
         QueryMsg::Capitalized { text } => to_binary(&query_capitalized(deps, text)?),
@@ -122,7 +122,7 @@ pub fn query(deps: Deps<SpecialQuery>, _env: Env, msg: QueryMsg) -> StdResult<Qu
     }
 }
 
-fn query_owner(deps: Deps<SpecialQuery>) -> StdResult<OwnerResponse> {
+fn query_owner(deps: Deps) -> StdResult<OwnerResponse> {
     let state = config_read(deps.storage).load()?;
     let resp = OwnerResponse {
         owner: state.owner.into(),
@@ -130,21 +130,18 @@ fn query_owner(deps: Deps<SpecialQuery>) -> StdResult<OwnerResponse> {
     Ok(resp)
 }
 
-fn query_subcall(deps: Deps<SpecialQuery>, id: u64) -> StdResult<Reply> {
+fn query_subcall(deps: Deps, id: u64) -> StdResult<Reply> {
     let key = id.to_be_bytes();
     replies_read(deps.storage).load(&key)
 }
 
-fn query_capitalized(deps: Deps<SpecialQuery>, text: String) -> StdResult<CapitalizedResponse> {
+fn query_capitalized(deps: Deps, text: String) -> StdResult<CapitalizedResponse> {
     let req = SpecialQuery::Capitalized { text }.into();
-    let response: SpecialResponse = deps.querier.query(&req)?;
+    let response: SpecialResponse = deps.querier.custom_query(&req)?;
     Ok(CapitalizedResponse { text: response.msg })
 }
 
-fn query_chain(
-    deps: Deps<SpecialQuery>,
-    request: &QueryRequest<SpecialQuery>,
-) -> StdResult<ChainResponse> {
+fn query_chain(deps: Deps, request: &QueryRequest<SpecialQuery>) -> StdResult<ChainResponse> {
     let raw = to_vec(request).map_err(|serialize_err| {
         StdError::generic_err(format!("Serializing QueryRequest: {}", serialize_err))
     })?;
@@ -161,7 +158,7 @@ fn query_chain(
     }
 }
 
-fn query_raw(deps: Deps<SpecialQuery>, contract: String, key: Binary) -> StdResult<RawResponse> {
+fn query_raw(deps: Deps, contract: String, key: Binary) -> StdResult<RawResponse> {
     let response: Option<Vec<u8>> = deps.querier.query_wasm_raw(contract, key)?;
     Ok(RawResponse {
         data: response.unwrap_or_default().into(),
diff --git a/devtools/check_workspace.sh b/devtools/check_workspace.sh
index 5b5c856bb..713ab9e40 100755
--- a/devtools/check_workspace.sh
+++ b/devtools/check_workspace.sh
@@ -4,15 +4,7 @@ command -v shellcheck >/dev/null && shellcheck "$0"
 
 cargo fmt
 (cd packages/crypto && cargo build && cargo clippy --all-targets -- -D warnings)
-(
-  cd packages/std
-  cargo check
-  cargo check --features iterator,staking,stargate
-  cargo wasm-debug
-  cargo wasm-debug --features iterator,staking,stargate
-  cargo clippy --all-targets --features iterator,staking,stargate -- -D warnings
-  cargo schema
-)
+(cd packages/std && cargo wasm-debug --features iterator && cargo clippy --all-targets --features iterator -- -D warnings && cargo schema)
 (cd packages/storage && cargo build && cargo clippy --all-targets --features iterator -- -D warnings)
 (cd packages/schema && cargo build && cargo clippy --all-targets -- -D warnings)
 (cd packages/vm && cargo build --features iterator,stargate && cargo clippy --all-targets --features iterator,stargate -- -D warnings)
diff --git a/packages/std/src/deps.rs b/packages/std/src/deps.rs
index 1569e383c..4dfff8030 100644
--- a/packages/std/src/deps.rs
+++ b/packages/std/src/deps.rs
@@ -1,7 +1,3 @@
-use std::marker::PhantomData;
-
-use crate::query::CustomQuery;
-use crate::results::Empty;
 use crate::traits::{Api, Querier, Storage};
 use crate::QuerierWrapper;
 
@@ -9,34 +5,27 @@ use crate::QuerierWrapper;
 /// Designed to allow easy dependency injection at runtime.
 /// This cannot be copied or cloned since it would behave differently
 /// for mock storages and a bridge storage in the VM.
-pub struct OwnedDeps<S: Storage, A: Api, Q: Querier, C: CustomQuery = Empty> {
+pub struct OwnedDeps<S: Storage, A: Api, Q: Querier> {
     pub storage: S,
     pub api: A,
     pub querier: Q,
-    pub custom_query_type: PhantomData<C>,
 }
 
-pub struct DepsMut<'a, C: CustomQuery = Empty> {
+pub struct DepsMut<'a> {
     pub storage: &'a mut dyn Storage,
     pub api: &'a dyn Api,
-    pub querier: QuerierWrapper<'a, C>,
+    pub querier: QuerierWrapper<'a>,
 }
 
-#[derive(Clone)]
-pub struct Deps<'a, C: CustomQuery = Empty> {
+#[derive(Copy, Clone)]
+pub struct Deps<'a> {
     pub storage: &'a dyn Storage,
     pub api: &'a dyn Api,
-    pub querier: QuerierWrapper<'a, C>,
+    pub querier: QuerierWrapper<'a>,
 }
 
-// Use custom implementation on order to implement Copy in case `C` is not `Copy`.
-// See "There is a small difference between the two: the derive strategy will also
-// place a Copy bound on type parameters, which isn’t always desired."
-// https://doc.rust-lang.org/std/marker/trait.Copy.html
-impl<'a, C: CustomQuery> Copy for Deps<'a, C> {}
-
-impl<S: Storage, A: Api, Q: Querier, C: CustomQuery> OwnedDeps<S, A, Q, C> {
-    pub fn as_ref(&'_ self) -> Deps<'_, C> {
+impl<S: Storage, A: Api, Q: Querier> OwnedDeps<S, A, Q> {
+    pub fn as_ref(&'_ self) -> Deps<'_> {
         Deps {
             storage: &self.storage,
             api: &self.api,
@@ -44,7 +33,7 @@ impl<S: Storage, A: Api, Q: Querier, C: CustomQuery> OwnedDeps<S, A, Q, C> {
         }
     }
 
-    pub fn as_mut(&'_ mut self) -> DepsMut<'_, C> {
+    pub fn as_mut(&'_ mut self) -> DepsMut<'_> {
         DepsMut {
             storage: &mut self.storage,
             api: &self.api,
@@ -53,8 +42,8 @@ impl<S: Storage, A: Api, Q: Querier, C: CustomQuery> OwnedDeps<S, A, Q, C> {
     }
 }
 
-impl<'a, C: CustomQuery> DepsMut<'a, C> {
-    pub fn as_ref(&'_ self) -> Deps<'_, C> {
+impl<'a> DepsMut<'a> {
+    pub fn as_ref(&'_ self) -> Deps<'_> {
         Deps {
             storage: self.storage,
             api: self.api,
@@ -62,7 +51,7 @@ impl<'a, C: CustomQuery> DepsMut<'a, C> {
         }
     }
 
-    pub fn branch(&'_ mut self) -> DepsMut<'_, C> {
+    pub fn branch(&'_ mut self) -> DepsMut<'_> {
         DepsMut {
             storage: self.storage,
             api: self.api,
@@ -74,8 +63,7 @@ impl<'a, C: CustomQuery> DepsMut<'a, C> {
 #[cfg(test)]
 mod tests {
     use super::*;
-    use crate::mock::{mock_dependencies, MockApi, MockQuerier, MockStorage};
-    use serde::{Deserialize, Serialize};
+    use crate::mock::mock_dependencies;
 
     // ensure we can call these many times, eg. as sub-calls
     fn execute(mut deps: DepsMut) {
@@ -97,34 +85,4 @@ mod tests {
         execute(deps.as_mut());
         query(deps.as_ref())
     }
-
-    #[test]
-    fn deps_implements_copy() {
-        impl CustomQuery for u64 {}
-        #[derive(Clone, Serialize, Deserialize)]
-        struct MyQuery;
-        impl CustomQuery for MyQuery {}
-
-        // With C: Copy
-        let owned = OwnedDeps::<_, _, _, u64> {
-            storage: MockStorage::default(),
-            api: MockApi::default(),
-            querier: MockQuerier::<u64>::new(&[]),
-            custom_query_type: PhantomData,
-        };
-        let deps: Deps<u64> = owned.as_ref();
-        let _copy1 = deps;
-        let _copy2 = deps;
-
-        // Without C: Copy
-        let owned = OwnedDeps::<_, _, _, MyQuery> {
-            storage: MockStorage::default(),
-            api: MockApi::default(),
-            querier: MockQuerier::<MyQuery>::new(&[]),
-            custom_query_type: PhantomData,
-        };
-        let deps: Deps<MyQuery> = owned.as_ref();
-        let _copy1 = deps;
-        let _copy2 = deps;
-    }
 }
diff --git a/packages/std/src/exports.rs b/packages/std/src/exports.rs
index c41a3c224..0745d7d19 100644
--- a/packages/std/src/exports.rs
+++ b/packages/std/src/exports.rs
@@ -8,21 +8,14 @@
 //! 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 crate::deps::OwnedDeps;
-#[cfg(feature = "stargate")]
-use crate::ibc::{
-    IbcBasicResponse, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcPacketAckMsg,
-    IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse,
-};
 use crate::imports::{ExternalApi, ExternalQuerier, ExternalStorage};
 use crate::memory::{alloc, consume_region, release_buffer, Region};
-use crate::query::CustomQuery;
 use crate::results::{ContractResult, QueryResponse, Reply, Response};
 use crate::serde::{from_slice, to_vec};
 use crate::types::Env;
@@ -79,18 +72,16 @@ macro_rules! r#try_into_contract_result {
 
 /// This should be wrapped in an external "C" export, containing a contract-specific function as an argument.
 ///
-/// - `Q`: custom query type (see QueryRequest)
 /// - `M`: message type for request
 /// - `C`: custom response message type (see CosmosMsg)
 /// - `E`: error type for responses
-pub fn do_instantiate<Q, M, C, E>(
-    instantiate_fn: &dyn Fn(DepsMut<Q>, Env, MessageInfo, M) -> Result<Response<C>, E>,
+pub fn do_instantiate<M, C, E>(
+    instantiate_fn: &dyn Fn(DepsMut, Env, MessageInfo, M) -> Result<Response<C>, E>,
     env_ptr: u32,
     info_ptr: u32,
     msg_ptr: u32,
 ) -> u32
 where
-    Q: CustomQuery,
     M: DeserializeOwned + JsonSchema,
     C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
     E: ToString,
@@ -107,18 +98,16 @@ where
 
 /// do_execute should be wrapped in an external "C" export, containing a contract-specific function as arg
 ///
-/// - `Q`: custom query type (see QueryRequest)
 /// - `M`: message type for request
 /// - `C`: custom response message type (see CosmosMsg)
 /// - `E`: error type for responses
-pub fn do_execute<Q, M, C, E>(
-    execute_fn: &dyn Fn(DepsMut<Q>, Env, MessageInfo, M) -> Result<Response<C>, E>,
+pub fn do_execute<M, C, E>(
+    execute_fn: &dyn Fn(DepsMut, Env, MessageInfo, M) -> Result<Response<C>, E>,
     env_ptr: u32,
     info_ptr: u32,
     msg_ptr: u32,
 ) -> u32
 where
-    Q: CustomQuery,
     M: DeserializeOwned + JsonSchema,
     C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
     E: ToString,
@@ -135,17 +124,15 @@ where
 
 /// do_migrate should be wrapped in an external "C" export, containing a contract-specific function as arg
 ///
-/// - `Q`: custom query type (see QueryRequest)
 /// - `M`: message type for request
 /// - `C`: custom response message type (see CosmosMsg)
 /// - `E`: error type for responses
-pub fn do_migrate<Q, M, C, E>(
-    migrate_fn: &dyn Fn(DepsMut<Q>, Env, M) -> Result<Response<C>, E>,
+pub fn do_migrate<M, C, E>(
+    migrate_fn: &dyn Fn(DepsMut, Env, M) -> Result<Response<C>, E>,
     env_ptr: u32,
     msg_ptr: u32,
 ) -> u32
 where
-    Q: CustomQuery,
     M: DeserializeOwned + JsonSchema,
     C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
     E: ToString,
@@ -157,17 +144,15 @@ where
 
 /// do_sudo should be wrapped in an external "C" export, containing a contract-specific function as arg
 ///
-/// - `Q`: custom query type (see QueryRequest)
 /// - `M`: message type for request
 /// - `C`: custom response message type (see CosmosMsg)
 /// - `E`: error type for responses
-pub fn do_sudo<Q, M, C, E>(
-    sudo_fn: &dyn Fn(DepsMut<Q>, Env, M) -> Result<Response<C>, E>,
+pub fn do_sudo<M, C, E>(
+    sudo_fn: &dyn Fn(DepsMut, Env, M) -> Result<Response<C>, E>,
     env_ptr: u32,
     msg_ptr: u32,
 ) -> u32
 where
-    Q: CustomQuery,
     M: DeserializeOwned + JsonSchema,
     C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
     E: ToString,
@@ -179,17 +164,14 @@ where
 
 /// do_reply should be wrapped in an external "C" export, containing a contract-specific function as arg
 /// message body is always `SubcallResult`
-///
-/// - `Q`: custom query type (see QueryRequest)
 /// - `C`: custom response message type (see CosmosMsg)
 /// - `E`: error type for responses
-pub fn do_reply<Q, C, E>(
-    reply_fn: &dyn Fn(DepsMut<Q>, Env, Reply) -> Result<Response<C>, E>,
+pub fn do_reply<C, E>(
+    reply_fn: &dyn Fn(DepsMut, Env, Reply) -> Result<Response<C>, E>,
     env_ptr: u32,
     msg_ptr: u32,
 ) -> u32
 where
-    Q: CustomQuery,
     C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
     E: ToString,
 {
@@ -200,16 +182,14 @@ where
 
 /// do_query should be wrapped in an external "C" export, containing a contract-specific function as arg
 ///
-/// - `Q`: custom query type (see QueryRequest)
 /// - `M`: message type for request
 /// - `E`: error type for responses
-pub fn do_query<Q, M, E>(
-    query_fn: &dyn Fn(Deps<Q>, Env, M) -> Result<QueryResponse, E>,
+pub fn do_query<M, E>(
+    query_fn: &dyn Fn(Deps, Env, M) -> Result<QueryResponse, E>,
     env_ptr: u32,
     msg_ptr: u32,
 ) -> u32
 where
-    Q: CustomQuery,
     M: DeserializeOwned + JsonSchema,
     E: ToString,
 {
@@ -218,154 +198,13 @@ where
     release_buffer(v) as u32
 }
 
-/// do_ibc_channel_open is designed for use with #[entry_point] to make a "C" extern
-///
-/// contract_fn does the protocol version negotiation during channel handshake phase
-///
-/// - `Q`: custom query type (see QueryRequest)
-/// - `E`: error type for responses
-#[cfg(feature = "stargate")]
-pub fn do_ibc_channel_open<Q, E>(
-    contract_fn: &dyn Fn(DepsMut<Q>, Env, IbcChannelOpenMsg) -> Result<(), E>,
-    env_ptr: u32,
-    msg_ptr: u32,
-) -> u32
-where
-    Q: CustomQuery,
-    E: ToString,
-{
-    let res = _do_ibc_channel_open(contract_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
-    let v = to_vec(&res).unwrap();
-    release_buffer(v) as u32
-}
-
-/// do_ibc_channel_connect is designed for use with #[entry_point] to make a "C" extern
-///
-/// contract_fn is a callback when a IBC channel is established (after both sides agree in open)
-///
-/// - `Q`: custom query type (see QueryRequest)
-/// - `C`: custom response message type (see CosmosMsg)
-/// - `E`: error type for responses
-#[cfg(feature = "stargate")]
-pub fn do_ibc_channel_connect<Q, C, E>(
-    contract_fn: &dyn Fn(DepsMut<Q>, Env, IbcChannelConnectMsg) -> Result<IbcBasicResponse<C>, E>,
-    env_ptr: u32,
-    msg_ptr: u32,
-) -> u32
-where
-    Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
-    E: ToString,
-{
-    let res = _do_ibc_channel_connect(contract_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
-    let v = to_vec(&res).unwrap();
-    release_buffer(v) as u32
-}
-
-/// do_ibc_channel_close is designed for use with #[entry_point] to make a "C" extern
-///
-/// contract_fn is a callback when a IBC channel belonging to this contract is closed
-///
-/// - `Q`: custom query type (see QueryRequest)
-/// - `C`: custom response message type (see CosmosMsg)
-/// - `E`: error type for responses
-#[cfg(feature = "stargate")]
-pub fn do_ibc_channel_close<Q, C, E>(
-    contract_fn: &dyn Fn(DepsMut<Q>, Env, IbcChannelCloseMsg) -> Result<IbcBasicResponse<C>, E>,
-    env_ptr: u32,
-    msg_ptr: u32,
-) -> u32
-where
-    Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
-    E: ToString,
-{
-    let res = _do_ibc_channel_close(contract_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
-    let v = to_vec(&res).unwrap();
-    release_buffer(v) as u32
-}
-
-/// do_ibc_packet_receive is designed for use with #[entry_point] to make a "C" extern
-///
-/// contract_fn is called when this chain receives an IBC Packet on a channel belonging
-/// to this contract
-///
-/// - `Q`: custom query type (see QueryRequest)
-/// - `C`: custom response message type (see CosmosMsg)
-/// - `E`: error type for responses
-#[cfg(feature = "stargate")]
-pub fn do_ibc_packet_receive<Q, C, E>(
-    contract_fn: &dyn Fn(DepsMut<Q>, Env, IbcPacketReceiveMsg) -> Result<IbcReceiveResponse<C>, E>,
-    env_ptr: u32,
-    msg_ptr: u32,
-) -> u32
-where
-    Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
-    E: ToString,
-{
-    let res = _do_ibc_packet_receive(contract_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
-    let v = to_vec(&res).unwrap();
-    release_buffer(v) as u32
-}
-
-/// do_ibc_packet_ack is designed for use with #[entry_point] to make a "C" extern
-///
-/// contract_fn is called when this chain receives an IBC Acknowledgement for a packet
-/// that this contract previously sent
-///
-/// - `Q`: custom query type (see QueryRequest)
-/// - `C`: custom response message type (see CosmosMsg)
-/// - `E`: error type for responses
-#[cfg(feature = "stargate")]
-pub fn do_ibc_packet_ack<Q, C, E>(
-    contract_fn: &dyn Fn(DepsMut<Q>, Env, IbcPacketAckMsg) -> Result<IbcBasicResponse<C>, E>,
-    env_ptr: u32,
-    msg_ptr: u32,
-) -> u32
-where
-    Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
-    E: ToString,
-{
-    let res = _do_ibc_packet_ack(contract_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
-    let v = to_vec(&res).unwrap();
-    release_buffer(v) as u32
-}
-
-/// do_ibc_packet_timeout is designed for use with #[entry_point] to make a "C" extern
-///
-/// contract_fn is called when a packet that this contract previously sent has provably
-/// timedout and will never be relayed to the calling chain. This generally behaves
-/// like ick_ack_fn upon an acknowledgement containing an error.
-///
-/// - `Q`: custom query type (see QueryRequest)
-/// - `C`: custom response message type (see CosmosMsg)
-/// - `E`: error type for responses
-#[cfg(feature = "stargate")]
-pub fn do_ibc_packet_timeout<Q, C, E>(
-    contract_fn: &dyn Fn(DepsMut<Q>, Env, IbcPacketTimeoutMsg) -> Result<IbcBasicResponse<C>, E>,
-    env_ptr: u32,
-    msg_ptr: u32,
-) -> u32
-where
-    Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
-    E: ToString,
-{
-    let res = _do_ibc_packet_timeout(contract_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
-    let v = to_vec(&res).unwrap();
-    release_buffer(v) as u32
-}
-
-fn _do_instantiate<Q, M, C, E>(
-    instantiate_fn: &dyn Fn(DepsMut<Q>, Env, MessageInfo, M) -> Result<Response<C>, E>,
+fn _do_instantiate<M, C, E>(
+    instantiate_fn: &dyn Fn(DepsMut, Env, MessageInfo, M) -> Result<Response<C>, E>,
     env_ptr: *mut Region,
     info_ptr: *mut Region,
     msg_ptr: *mut Region,
 ) -> ContractResult<Response<C>>
 where
-    Q: CustomQuery,
     M: DeserializeOwned + JsonSchema,
     C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
     E: ToString,
@@ -382,14 +221,13 @@ where
     instantiate_fn(deps.as_mut(), env, info, msg).into()
 }
 
-fn _do_execute<Q, M, C, E>(
-    execute_fn: &dyn Fn(DepsMut<Q>, Env, MessageInfo, M) -> Result<Response<C>, E>,
+fn _do_execute<M, C, E>(
+    execute_fn: &dyn Fn(DepsMut, Env, MessageInfo, M) -> Result<Response<C>, E>,
     env_ptr: *mut Region,
     info_ptr: *mut Region,
     msg_ptr: *mut Region,
 ) -> ContractResult<Response<C>>
 where
-    Q: CustomQuery,
     M: DeserializeOwned + JsonSchema,
     C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
     E: ToString,
@@ -406,13 +244,12 @@ where
     execute_fn(deps.as_mut(), env, info, msg).into()
 }
 
-fn _do_migrate<Q, M, C, E>(
-    migrate_fn: &dyn Fn(DepsMut<Q>, Env, M) -> Result<Response<C>, E>,
+fn _do_migrate<M, C, E>(
+    migrate_fn: &dyn Fn(DepsMut, Env, M) -> Result<Response<C>, E>,
     env_ptr: *mut Region,
     msg_ptr: *mut Region,
 ) -> ContractResult<Response<C>>
 where
-    Q: CustomQuery,
     M: DeserializeOwned + JsonSchema,
     C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
     E: ToString,
@@ -427,13 +264,12 @@ where
     migrate_fn(deps.as_mut(), env, msg).into()
 }
 
-fn _do_sudo<Q, M, C, E>(
-    sudo_fn: &dyn Fn(DepsMut<Q>, Env, M) -> Result<Response<C>, E>,
+fn _do_sudo<M, C, E>(
+    sudo_fn: &dyn Fn(DepsMut, Env, M) -> Result<Response<C>, E>,
     env_ptr: *mut Region,
     msg_ptr: *mut Region,
 ) -> ContractResult<Response<C>>
 where
-    Q: CustomQuery,
     M: DeserializeOwned + JsonSchema,
     C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
     E: ToString,
@@ -448,13 +284,12 @@ where
     sudo_fn(deps.as_mut(), env, msg).into()
 }
 
-fn _do_reply<Q, C, E>(
-    reply_fn: &dyn Fn(DepsMut<Q>, Env, Reply) -> Result<Response<C>, E>,
+fn _do_reply<C, E>(
+    reply_fn: &dyn Fn(DepsMut, Env, Reply) -> Result<Response<C>, E>,
     env_ptr: *mut Region,
     msg_ptr: *mut Region,
 ) -> ContractResult<Response<C>>
 where
-    Q: CustomQuery,
     C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
     E: ToString,
 {
@@ -468,13 +303,12 @@ where
     reply_fn(deps.as_mut(), env, msg).into()
 }
 
-fn _do_query<Q, M, E>(
-    query_fn: &dyn Fn(Deps<Q>, Env, M) -> Result<QueryResponse, E>,
+fn _do_query<M, E>(
+    query_fn: &dyn Fn(Deps, Env, M) -> Result<QueryResponse, E>,
     env_ptr: *mut Region,
     msg_ptr: *mut Region,
 ) -> ContractResult<QueryResponse>
 where
-    Q: CustomQuery,
     M: DeserializeOwned + JsonSchema,
     E: ToString,
 {
@@ -488,140 +322,11 @@ where
     query_fn(deps.as_ref(), env, msg).into()
 }
 
-#[cfg(feature = "stargate")]
-fn _do_ibc_channel_open<Q, E>(
-    contract_fn: &dyn Fn(DepsMut<Q>, Env, IbcChannelOpenMsg) -> Result<(), E>,
-    env_ptr: *mut Region,
-    msg_ptr: *mut Region,
-) -> ContractResult<()>
-where
-    Q: CustomQuery,
-    E: ToString,
-{
-    let env: Vec<u8> = unsafe { consume_region(env_ptr) };
-    let msg: Vec<u8> = unsafe { consume_region(msg_ptr) };
-
-    let env: Env = try_into_contract_result!(from_slice(&env));
-    let msg: IbcChannelOpenMsg = try_into_contract_result!(from_slice(&msg));
-
-    let mut deps = make_dependencies();
-    contract_fn(deps.as_mut(), env, msg).into()
-}
-
-#[cfg(feature = "stargate")]
-fn _do_ibc_channel_connect<Q, C, E>(
-    contract_fn: &dyn Fn(DepsMut<Q>, Env, IbcChannelConnectMsg) -> Result<IbcBasicResponse<C>, E>,
-    env_ptr: *mut Region,
-    msg_ptr: *mut Region,
-) -> ContractResult<IbcBasicResponse<C>>
-where
-    Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
-    E: ToString,
-{
-    let env: Vec<u8> = unsafe { consume_region(env_ptr) };
-    let msg: Vec<u8> = unsafe { consume_region(msg_ptr) };
-
-    let env: Env = try_into_contract_result!(from_slice(&env));
-    let msg: IbcChannelConnectMsg = try_into_contract_result!(from_slice(&msg));
-
-    let mut deps = make_dependencies();
-    contract_fn(deps.as_mut(), env, msg).into()
-}
-
-#[cfg(feature = "stargate")]
-fn _do_ibc_channel_close<Q, C, E>(
-    contract_fn: &dyn Fn(DepsMut<Q>, Env, IbcChannelCloseMsg) -> Result<IbcBasicResponse<C>, E>,
-    env_ptr: *mut Region,
-    msg_ptr: *mut Region,
-) -> ContractResult<IbcBasicResponse<C>>
-where
-    Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
-    E: ToString,
-{
-    let env: Vec<u8> = unsafe { consume_region(env_ptr) };
-    let msg: Vec<u8> = unsafe { consume_region(msg_ptr) };
-
-    let env: Env = try_into_contract_result!(from_slice(&env));
-    let msg: IbcChannelCloseMsg = try_into_contract_result!(from_slice(&msg));
-
-    let mut deps = make_dependencies();
-    contract_fn(deps.as_mut(), env, msg).into()
-}
-
-#[cfg(feature = "stargate")]
-fn _do_ibc_packet_receive<Q, C, E>(
-    contract_fn: &dyn Fn(DepsMut<Q>, Env, IbcPacketReceiveMsg) -> Result<IbcReceiveResponse<C>, E>,
-    env_ptr: *mut Region,
-    msg_ptr: *mut Region,
-) -> ContractResult<IbcReceiveResponse<C>>
-where
-    Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
-    E: ToString,
-{
-    let env: Vec<u8> = unsafe { consume_region(env_ptr) };
-    let msg: Vec<u8> = unsafe { consume_region(msg_ptr) };
-
-    let env: Env = try_into_contract_result!(from_slice(&env));
-    let msg: IbcPacketReceiveMsg = try_into_contract_result!(from_slice(&msg));
-
-    let mut deps = make_dependencies();
-    contract_fn(deps.as_mut(), env, msg).into()
-}
-
-#[cfg(feature = "stargate")]
-fn _do_ibc_packet_ack<Q, C, E>(
-    contract_fn: &dyn Fn(DepsMut<Q>, Env, IbcPacketAckMsg) -> Result<IbcBasicResponse<C>, E>,
-    env_ptr: *mut Region,
-    msg_ptr: *mut Region,
-) -> ContractResult<IbcBasicResponse<C>>
-where
-    Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
-    E: ToString,
-{
-    let env: Vec<u8> = unsafe { consume_region(env_ptr) };
-    let msg: Vec<u8> = unsafe { consume_region(msg_ptr) };
-
-    let env: Env = try_into_contract_result!(from_slice(&env));
-    let msg: IbcPacketAckMsg = try_into_contract_result!(from_slice(&msg));
-
-    let mut deps = make_dependencies();
-    contract_fn(deps.as_mut(), env, msg).into()
-}
-
-#[cfg(feature = "stargate")]
-fn _do_ibc_packet_timeout<Q, C, E>(
-    contract_fn: &dyn Fn(DepsMut<Q>, Env, IbcPacketTimeoutMsg) -> Result<IbcBasicResponse<C>, E>,
-    env_ptr: *mut Region,
-    msg_ptr: *mut Region,
-) -> ContractResult<IbcBasicResponse<C>>
-where
-    Q: CustomQuery,
-    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
-    E: ToString,
-{
-    let env: Vec<u8> = unsafe { consume_region(env_ptr) };
-    let msg: Vec<u8> = unsafe { consume_region(msg_ptr) };
-
-    let env: Env = try_into_contract_result!(from_slice(&env));
-    let msg: IbcPacketTimeoutMsg = try_into_contract_result!(from_slice(&msg));
-
-    let mut deps = make_dependencies();
-    contract_fn(deps.as_mut(), env, msg).into()
-}
-
 /// Makes all bridges to external dependencies (i.e. Wasm imports) that are injected by the VM
-pub(crate) fn make_dependencies<Q>() -> OwnedDeps<ExternalStorage, ExternalApi, ExternalQuerier, Q>
-where
-    Q: CustomQuery,
-{
+pub(crate) fn make_dependencies() -> OwnedDeps<ExternalStorage, ExternalApi, ExternalQuerier> {
     OwnedDeps {
         storage: ExternalStorage::new(),
         api: ExternalApi::new(),
         querier: ExternalQuerier::new(),
-        custom_query_type: PhantomData,
     }
 }
diff --git a/packages/std/src/ibc_exports.rs b/packages/std/src/ibc_exports.rs
new file mode 100644
index 000000000..ca3762f42
--- /dev/null
+++ b/packages/std/src/ibc_exports.rs
@@ -0,0 +1,250 @@
+#![cfg(all(feature = "stargate", target_arch = "wasm32"))]
+use std::fmt;
+use std::vec::Vec;
+
+use schemars::JsonSchema;
+use serde::Serialize;
+
+use crate::deps::DepsMut;
+use crate::exports::make_dependencies;
+use crate::ibc::{
+    IbcBasicResponse, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcPacketAckMsg,
+    IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse,
+};
+use crate::memory::{consume_region, release_buffer, Region};
+use crate::results::ContractResult;
+use crate::serde::{from_slice, to_vec};
+use crate::types::Env;
+
+// TODO: replace with https://doc.rust-lang.org/std/ops/trait.Try.html once stabilized
+macro_rules! r#try_into_contract_result {
+    ($expr:expr) => {
+        match $expr {
+            Ok(val) => val,
+            Err(err) => {
+                return ContractResult::Err(err.to_string());
+            }
+        }
+    };
+    ($expr:expr,) => {
+        $crate::try_into_contract_result!($expr)
+    };
+}
+
+/// do_ibc_channel_open is designed for use with #[entry_point] to make a "C" extern
+///
+/// contract_fn does the protocol version negotiation during channel handshake phase
+pub fn do_ibc_channel_open<E>(
+    contract_fn: &dyn Fn(DepsMut, Env, IbcChannelOpenMsg) -> Result<(), E>,
+    env_ptr: u32,
+    msg_ptr: u32,
+) -> u32
+where
+    E: ToString,
+{
+    let res = _do_ibc_channel_open(contract_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
+    let v = to_vec(&res).unwrap();
+    release_buffer(v) as u32
+}
+
+fn _do_ibc_channel_open<E>(
+    contract_fn: &dyn Fn(DepsMut, Env, IbcChannelOpenMsg) -> Result<(), E>,
+    env_ptr: *mut Region,
+    msg_ptr: *mut Region,
+) -> ContractResult<()>
+where
+    E: ToString,
+{
+    let env: Vec<u8> = unsafe { consume_region(env_ptr) };
+    let msg: Vec<u8> = unsafe { consume_region(msg_ptr) };
+
+    let env: Env = try_into_contract_result!(from_slice(&env));
+    let msg: IbcChannelOpenMsg = try_into_contract_result!(from_slice(&msg));
+
+    let mut deps = make_dependencies();
+    contract_fn(deps.as_mut(), env, msg).into()
+}
+
+/// do_ibc_channel_connect is designed for use with #[entry_point] to make a "C" extern
+///
+/// contract_fn is a callback when a IBC channel is established (after both sides agree in open)
+pub fn do_ibc_channel_connect<C, E>(
+    contract_fn: &dyn Fn(DepsMut, Env, IbcChannelConnectMsg) -> Result<IbcBasicResponse<C>, E>,
+    env_ptr: u32,
+    msg_ptr: u32,
+) -> u32
+where
+    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    E: ToString,
+{
+    let res = _do_ibc_channel_connect(contract_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
+    let v = to_vec(&res).unwrap();
+    release_buffer(v) as u32
+}
+
+fn _do_ibc_channel_connect<C, E>(
+    contract_fn: &dyn Fn(DepsMut, Env, IbcChannelConnectMsg) -> Result<IbcBasicResponse<C>, E>,
+    env_ptr: *mut Region,
+    msg_ptr: *mut Region,
+) -> ContractResult<IbcBasicResponse<C>>
+where
+    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    E: ToString,
+{
+    let env: Vec<u8> = unsafe { consume_region(env_ptr) };
+    let msg: Vec<u8> = unsafe { consume_region(msg_ptr) };
+
+    let env: Env = try_into_contract_result!(from_slice(&env));
+    let msg: IbcChannelConnectMsg = try_into_contract_result!(from_slice(&msg));
+
+    let mut deps = make_dependencies();
+    contract_fn(deps.as_mut(), env, msg).into()
+}
+
+/// do_ibc_channel_close is designed for use with #[entry_point] to make a "C" extern
+///
+/// contract_fn is a callback when a IBC channel belonging to this contract is closed
+pub fn do_ibc_channel_close<C, E>(
+    contract_fn: &dyn Fn(DepsMut, Env, IbcChannelCloseMsg) -> Result<IbcBasicResponse<C>, E>,
+    env_ptr: u32,
+    msg_ptr: u32,
+) -> u32
+where
+    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    E: ToString,
+{
+    let res = _do_ibc_channel_close(contract_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
+    let v = to_vec(&res).unwrap();
+    release_buffer(v) as u32
+}
+
+fn _do_ibc_channel_close<C, E>(
+    contract_fn: &dyn Fn(DepsMut, Env, IbcChannelCloseMsg) -> Result<IbcBasicResponse<C>, E>,
+    env_ptr: *mut Region,
+    msg_ptr: *mut Region,
+) -> ContractResult<IbcBasicResponse<C>>
+where
+    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    E: ToString,
+{
+    let env: Vec<u8> = unsafe { consume_region(env_ptr) };
+    let msg: Vec<u8> = unsafe { consume_region(msg_ptr) };
+
+    let env: Env = try_into_contract_result!(from_slice(&env));
+    let msg: IbcChannelCloseMsg = try_into_contract_result!(from_slice(&msg));
+
+    let mut deps = make_dependencies();
+    contract_fn(deps.as_mut(), env, msg).into()
+}
+
+/// do_ibc_packet_receive is designed for use with #[entry_point] to make a "C" extern
+///
+/// contract_fn is called when this chain receives an IBC Packet on a channel belonging
+/// to this contract
+pub fn do_ibc_packet_receive<C, E>(
+    contract_fn: &dyn Fn(DepsMut, Env, IbcPacketReceiveMsg) -> Result<IbcReceiveResponse<C>, E>,
+    env_ptr: u32,
+    msg_ptr: u32,
+) -> u32
+where
+    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    E: ToString,
+{
+    let res = _do_ibc_packet_receive(contract_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
+    let v = to_vec(&res).unwrap();
+    release_buffer(v) as u32
+}
+
+fn _do_ibc_packet_receive<C, E>(
+    contract_fn: &dyn Fn(DepsMut, Env, IbcPacketReceiveMsg) -> Result<IbcReceiveResponse<C>, E>,
+    env_ptr: *mut Region,
+    msg_ptr: *mut Region,
+) -> ContractResult<IbcReceiveResponse<C>>
+where
+    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    E: ToString,
+{
+    let env: Vec<u8> = unsafe { consume_region(env_ptr) };
+    let msg: Vec<u8> = unsafe { consume_region(msg_ptr) };
+
+    let env: Env = try_into_contract_result!(from_slice(&env));
+    let msg: IbcPacketReceiveMsg = try_into_contract_result!(from_slice(&msg));
+
+    let mut deps = make_dependencies();
+    contract_fn(deps.as_mut(), env, msg).into()
+}
+
+/// do_ibc_packet_ack is designed for use with #[entry_point] to make a "C" extern
+///
+/// contract_fn is called when this chain receives an IBC Acknowledgement for a packet
+/// that this contract previously sent
+pub fn do_ibc_packet_ack<C, E>(
+    contract_fn: &dyn Fn(DepsMut, Env, IbcPacketAckMsg) -> Result<IbcBasicResponse<C>, E>,
+    env_ptr: u32,
+    msg_ptr: u32,
+) -> u32
+where
+    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    E: ToString,
+{
+    let res = _do_ibc_packet_ack(contract_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
+    let v = to_vec(&res).unwrap();
+    release_buffer(v) as u32
+}
+
+fn _do_ibc_packet_ack<C, E>(
+    contract_fn: &dyn Fn(DepsMut, Env, IbcPacketAckMsg) -> Result<IbcBasicResponse<C>, E>,
+    env_ptr: *mut Region,
+    msg_ptr: *mut Region,
+) -> ContractResult<IbcBasicResponse<C>>
+where
+    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    E: ToString,
+{
+    let env: Vec<u8> = unsafe { consume_region(env_ptr) };
+    let msg: Vec<u8> = unsafe { consume_region(msg_ptr) };
+
+    let env: Env = try_into_contract_result!(from_slice(&env));
+    let msg: IbcPacketAckMsg = try_into_contract_result!(from_slice(&msg));
+
+    let mut deps = make_dependencies();
+    contract_fn(deps.as_mut(), env, msg).into()
+}
+
+/// do_ibc_packet_timeout is designed for use with #[entry_point] to make a "C" extern
+///
+/// contract_fn is called when a packet that this contract previously sent has provably
+/// timedout and will never be relayed to the calling chain. This generally behaves
+/// like ick_ack_fn upon an acknowledgement containing an error.
+pub fn do_ibc_packet_timeout<C, E>(
+    contract_fn: &dyn Fn(DepsMut, Env, IbcPacketTimeoutMsg) -> Result<IbcBasicResponse<C>, E>,
+    env_ptr: u32,
+    msg_ptr: u32,
+) -> u32
+where
+    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    E: ToString,
+{
+    let res = _do_ibc_packet_timeout(contract_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
+    let v = to_vec(&res).unwrap();
+    release_buffer(v) as u32
+}
+
+fn _do_ibc_packet_timeout<C, E>(
+    contract_fn: &dyn Fn(DepsMut, Env, IbcPacketTimeoutMsg) -> Result<IbcBasicResponse<C>, E>,
+    env_ptr: *mut Region,
+    msg_ptr: *mut Region,
+) -> ContractResult<IbcBasicResponse<C>>
+where
+    C: Serialize + Clone + fmt::Debug + PartialEq + JsonSchema,
+    E: ToString,
+{
+    let env: Vec<u8> = unsafe { consume_region(env_ptr) };
+    let msg: Vec<u8> = unsafe { consume_region(msg_ptr) };
+
+    let env: Env = try_into_contract_result!(from_slice(&env));
+    let msg: IbcPacketTimeoutMsg = try_into_contract_result!(from_slice(&msg));
+
+    let mut deps = make_dependencies();
+    contract_fn(deps.as_mut(), env, msg).into()
+}
diff --git a/packages/std/src/lib.rs b/packages/std/src/lib.rs
index 4b702f9f7..c5be163e1 100644
--- a/packages/std/src/lib.rs
+++ b/packages/std/src/lib.rs
@@ -76,13 +76,16 @@ mod memory; // Used by exports and imports only. This assumes pointers are 32 bi
 
 #[cfg(target_arch = "wasm32")]
 pub use crate::exports::{do_execute, do_instantiate, do_migrate, do_query, do_reply, do_sudo};
+#[cfg(target_arch = "wasm32")]
+pub use crate::imports::{ExternalApi, ExternalQuerier, ExternalStorage};
+
 #[cfg(all(feature = "stargate", target_arch = "wasm32"))]
-pub use crate::exports::{
+mod ibc_exports;
+#[cfg(all(feature = "stargate", target_arch = "wasm32"))]
+pub use crate::ibc_exports::{
     do_ibc_channel_close, do_ibc_channel_connect, do_ibc_channel_open, do_ibc_packet_ack,
     do_ibc_packet_receive, do_ibc_packet_timeout,
 };
-#[cfg(target_arch = "wasm32")]
-pub use crate::imports::{ExternalApi, ExternalQuerier, ExternalStorage};
 
 // Exposed for testing only
 // Both unit tests and integration tests are compiled to native code, so everything in here does not need to compile to Wasm.
diff --git a/packages/std/src/mock.rs b/packages/std/src/mock.rs
index 9ea019351..a43e1957e 100644
--- a/packages/std/src/mock.rs
+++ b/packages/std/src/mock.rs
@@ -2,7 +2,6 @@ use serde::de::DeserializeOwned;
 #[cfg(feature = "stargate")]
 use serde::Serialize;
 use std::collections::HashMap;
-use std::marker::PhantomData;
 
 use crate::addresses::{Addr, CanonicalAddr};
 use crate::binary::Binary;
@@ -37,12 +36,11 @@ pub const MOCK_CONTRACT_ADDR: &str = "cosmos2contract";
 /// It sets the given balance for the contract itself, nothing else
 pub fn mock_dependencies(
     contract_balance: &[Coin],
-) -> OwnedDeps<MockStorage, MockApi, MockQuerier, Empty> {
+) -> OwnedDeps<MockStorage, MockApi, MockQuerier> {
     OwnedDeps {
         storage: MockStorage::default(),
         api: MockApi::default(),
         querier: MockQuerier::new(&[(MOCK_CONTRACT_ADDR, contract_balance)]),
-        custom_query_type: PhantomData,
     }
 }
 
@@ -55,7 +53,6 @@ pub fn mock_dependencies_with_balances(
         storage: MockStorage::default(),
         api: MockApi::default(),
         querier: MockQuerier::new(balances),
-        custom_query_type: PhantomData,
     }
 }
 
diff --git a/packages/std/src/query/mod.rs b/packages/std/src/query/mod.rs
index f1e6afff4..1b8a791c1 100644
--- a/packages/std/src/query/mod.rs
+++ b/packages/std/src/query/mod.rs
@@ -66,9 +66,7 @@ pub enum QueryRequest<C: CustomQuery> {
 ///
 /// impl CustomQuery for MyCustomQuery {}
 /// ```
-pub trait CustomQuery: Serialize + Clone {}
-// We require `Clone` because `Clone` in `QueryRequest<C>` is only derived for
-// `C: Clone` and we want consistent behaviour for all `QueryRequest<C>`
+pub trait CustomQuery: Serialize {}
 
 impl CustomQuery for Empty {}
 
diff --git a/packages/std/src/traits.rs b/packages/std/src/traits.rs
index 1e2cf2bd0..bb9ae0f78 100644
--- a/packages/std/src/traits.rs
+++ b/packages/std/src/traits.rs
@@ -1,5 +1,4 @@
 use serde::{de::DeserializeOwned, Serialize};
-use std::marker::PhantomData;
 use std::ops::Deref;
 
 use crate::addresses::{Addr, CanonicalAddr};
@@ -135,42 +134,41 @@ pub trait Querier {
     fn raw_query(&self, bin_request: &[u8]) -> QuerierResult;
 }
 
-#[derive(Clone)]
-pub struct QuerierWrapper<'a, C: CustomQuery = Empty> {
-    querier: &'a dyn Querier,
-    custom_query_type: PhantomData<C>,
-}
-
-// Use custom implementation on order to implement Copy in case `C` is not `Copy`.
-// See "There is a small difference between the two: the derive strategy will also
-// place a Copy bound on type parameters, which isn’t always desired."
-// https://doc.rust-lang.org/std/marker/trait.Copy.html
-impl<'a, C: CustomQuery> Copy for QuerierWrapper<'a, C> {}
+#[derive(Copy, Clone)]
+pub struct QuerierWrapper<'a>(&'a dyn Querier);
 
 /// This allows us to use self.raw_query to access the querier.
 /// It also allows external callers to access the querier easily.
-impl<'a, C: CustomQuery> Deref for QuerierWrapper<'a, C> {
+impl<'a> Deref for QuerierWrapper<'a> {
     type Target = dyn Querier + 'a;
 
     fn deref(&self) -> &Self::Target {
-        self.querier
+        self.0
     }
 }
 
-impl<'a, C: CustomQuery> QuerierWrapper<'a, C> {
+impl<'a> QuerierWrapper<'a> {
     pub fn new(querier: &'a dyn Querier) -> Self {
-        QuerierWrapper {
-            querier,
-            custom_query_type: PhantomData,
-        }
+        QuerierWrapper(querier)
     }
 
-    /// Makes the query and parses the response.
+    /// query is a shorthand for custom_query when we are not using a custom type,
+    /// this allows us to avoid specifying "Empty" in all the type definitions.
+    pub fn query<T: DeserializeOwned>(&self, request: &QueryRequest<Empty>) -> StdResult<T> {
+        self.custom_query(request)
+    }
+
+    /// Makes the query and parses the response. Also handles custom queries,
+    /// so you need to specify the custom query type in the function parameters.
+    /// If you are no using a custom query, just use `query` for easier interface.
     ///
     /// Any error (System Error, Error or called contract, or Parse Error) are flattened into
     /// one level. Only use this if you don't need to check the SystemError
     /// eg. If you don't differentiate between contract missing and contract returned error
-    pub fn query<U: DeserializeOwned>(&self, request: &QueryRequest<C>) -> StdResult<U> {
+    pub fn custom_query<C: CustomQuery, U: DeserializeOwned>(
+        &self,
+        request: &QueryRequest<C>,
+    ) -> StdResult<U> {
         let raw = to_vec(request).map_err(|serialize_err| {
             StdError::generic_err(format!("Serializing QueryRequest: {}", serialize_err))
         })?;
@@ -332,7 +330,7 @@ mod tests {
     #[test]
     fn use_querier_wrapper_as_querier() {
         let querier: MockQuerier<Empty> = MockQuerier::new(&[]);
-        let wrapper = QuerierWrapper::<Empty>::new(&querier);
+        let wrapper = QuerierWrapper::new(&querier);
 
         // call with deref shortcut
         let res = demo_helper(&*wrapper);
@@ -347,7 +345,7 @@ mod tests {
     fn auto_deref_raw_query() {
         let acct = String::from("foobar");
         let querier: MockQuerier<Empty> = MockQuerier::new(&[(&acct, &coins(5, "BTC"))]);
-        let wrapper = QuerierWrapper::<Empty>::new(&querier);
+        let wrapper = QuerierWrapper::new(&querier);
         let query = QueryRequest::<Empty>::Bank(BankQuery::Balance {
             address: acct,
             denom: "BTC".to_string(),
diff --git a/packages/vm/examples/check_contract.rs b/packages/vm/examples/check_contract.rs
index 978980693..c99e0cb6a 100644
--- a/packages/vm/examples/check_contract.rs
+++ b/packages/vm/examples/check_contract.rs
@@ -31,6 +31,6 @@ pub fn main() {
     check_wasm(&wasm, &features_from_csv("iterator,staking,stargate")).unwrap();
 
     // Compile module
-    compile(&wasm, None).unwrap();
+    compile(&wasm, None, &[]).unwrap();
     println!("contract checks passed.")
 }
diff --git a/packages/vm/examples/module_size.rs b/packages/vm/examples/module_size.rs
index 1cbbe0c6c..ac62a6b69 100644
--- a/packages/vm/examples/module_size.rs
+++ b/packages/vm/examples/module_size.rs
@@ -69,7 +69,7 @@ pub fn main() {
 
 #[inline(never)]
 fn module_compile(wasm: &[u8], memory_limit: Option<Size>) -> Module {
-    compile(wasm, memory_limit).unwrap()
+    compile(wasm, memory_limit, &[]).unwrap()
 }
 
 #[inline(never)]
diff --git a/packages/vm/src/cache.rs b/packages/vm/src/cache.rs
index 036cc6e56..3d709fc4e 100644
--- a/packages/vm/src/cache.rs
+++ b/packages/vm/src/cache.rs
@@ -151,7 +151,7 @@ where
 
     pub fn save_wasm(&self, wasm: &[u8]) -> VmResult<Checksum> {
         check_wasm(wasm, &self.supported_features)?;
-        let module = compile(wasm, None)?;
+        let module = compile(wasm, None, &[])?;
 
         let mut cache = self.inner.lock().unwrap();
         let checksum = save_wasm_to_disk(&cache.wasm_path, wasm)?;
@@ -224,7 +224,7 @@ where
 
         // Re-compile from original Wasm bytecode
         let code = self.load_wasm_with_path(&cache.wasm_path, checksum)?;
-        let module = compile(&code, Some(cache.instance_memory_limit))?;
+        let module = compile(&code, Some(cache.instance_memory_limit), &[])?;
         // Store into the fs cache too
         cache.fs_cache.store(checksum, &module)?;
         let module_size = loupe::size_of_val(&module);
@@ -257,8 +257,13 @@ where
         // Try to get module from the pinned memory cache
         if let Some(module) = cache.pinned_memory_cache.load(checksum)? {
             cache.stats.hits_pinned_memory_cache += 1;
-            let instance =
-                Instance::from_module(&module, backend, options.gas_limit, options.print_debug)?;
+            let instance = Instance::from_module(
+                &module,
+                backend,
+                options.gas_limit,
+                options.print_debug,
+                None,
+            )?;
             return Ok(instance);
         }
 
@@ -270,6 +275,7 @@ where
                 backend,
                 options.gas_limit,
                 options.print_debug,
+                None,
             )?;
             return Ok(instance);
         }
@@ -278,8 +284,13 @@ where
         let store = make_runtime_store(Some(cache.instance_memory_limit));
         if let Some(module) = cache.fs_cache.load(checksum, &store)? {
             cache.stats.hits_fs_cache += 1;
-            let instance =
-                Instance::from_module(&module, backend, options.gas_limit, options.print_debug)?;
+            let instance = Instance::from_module(
+                &module,
+                backend,
+                options.gas_limit,
+                options.print_debug,
+                None,
+            )?;
             let module_size = loupe::size_of_val(&module);
             cache.memory_cache.store(checksum, module, module_size)?;
             return Ok(instance);
@@ -292,9 +303,14 @@ where
         // stored the old module format.
         let wasm = self.load_wasm_with_path(&cache.wasm_path, checksum)?;
         cache.stats.misses += 1;
-        let module = compile(&wasm, Some(cache.instance_memory_limit))?;
-        let instance =
-            Instance::from_module(&module, backend, options.gas_limit, options.print_debug)?;
+        let module = compile(&wasm, Some(cache.instance_memory_limit), &[])?;
+        let instance = Instance::from_module(
+            &module,
+            backend,
+            options.gas_limit,
+            options.print_debug,
+            None,
+        )?;
         cache.fs_cache.store(checksum, &module)?;
         let module_size = loupe::size_of_val(&module);
         cache.memory_cache.store(checksum, module, module_size)?;
diff --git a/packages/vm/src/environment.rs b/packages/vm/src/environment.rs
index 179f6c1e2..26ab10fe4 100644
--- a/packages/vm/src/environment.rs
+++ b/packages/vm/src/environment.rs
@@ -418,7 +418,7 @@ mod tests {
     ) {
         let env = Environment::new(MockApi::default(), gas_limit, false);
 
-        let module = compile(CONTRACT, TESTING_MEMORY_LIMIT).unwrap();
+        let module = compile(CONTRACT, TESTING_MEMORY_LIMIT, &[]).unwrap();
         let store = module.store();
         // we need stubs for all required imports
         let import_obj = imports! {
diff --git a/packages/vm/src/imports.rs b/packages/vm/src/imports.rs
index 18027d22b..44faeda0e 100644
--- a/packages/vm/src/imports.rs
+++ b/packages/vm/src/imports.rs
@@ -481,7 +481,7 @@ mod tests {
         let gas_limit = TESTING_GAS_LIMIT;
         let env = Environment::new(api, gas_limit, false);
 
-        let module = compile(CONTRACT, TESTING_MEMORY_LIMIT).unwrap();
+        let module = compile(CONTRACT, TESTING_MEMORY_LIMIT, &[]).unwrap();
         let store = module.store();
         // we need stubs for all required imports
         let import_obj = imports! {
diff --git a/packages/vm/src/instance.rs b/packages/vm/src/instance.rs
index 48d0c66b1..f0cb0253f 100644
--- a/packages/vm/src/instance.rs
+++ b/packages/vm/src/instance.rs
@@ -1,4 +1,4 @@
-use std::collections::HashSet;
+use std::collections::{HashMap, HashSet};
 use std::ptr::NonNull;
 
 use wasmer::{Exports, Function, ImportObject, Instance as WasmerInstance, Module, Val};
@@ -62,8 +62,14 @@ where
         options: InstanceOptions,
         memory_limit: Option<Size>,
     ) -> VmResult<Self> {
-        let module = compile(code, memory_limit)?;
-        Instance::from_module(&module, backend, options.gas_limit, options.print_debug)
+        let module = compile(code, memory_limit, &[])?;
+        Instance::from_module(
+            &module,
+            backend,
+            options.gas_limit,
+            options.print_debug,
+            None,
+        )
     }
 
     pub(crate) fn from_module(
@@ -71,6 +77,7 @@ where
         backend: Backend<A, S, Q>,
         gas_limit: u64,
         print_debug: bool,
+        extra_imports: Option<HashMap<&str, Exports>>,
     ) -> VmResult<Self> {
         let store = module.store();
 
@@ -200,6 +207,12 @@ where
 
         import_obj.register("env", env_imports);
 
+        if let Some(extra_imports) = extra_imports {
+            for (namespace, exports_obj) in extra_imports {
+                import_obj.register(namespace, exports_obj);
+            }
+        }
+
         let wasmer_instance = Box::from(WasmerInstance::new(module, &import_obj).map_err(
             |original| {
                 VmError::instantiation_err(format!("Error instantiating module: {:?}", original))
@@ -336,8 +349,28 @@ where
     }
 }
 
+/// This exists only to be exported through `internals` for use by crates that are
+/// part of Cosmwasm.
+pub fn instance_from_module<A, S, Q>(
+    module: &Module,
+    backend: Backend<A, S, Q>,
+    gas_limit: u64,
+    print_debug: bool,
+    extra_imports: Option<HashMap<&str, Exports>>,
+) -> VmResult<Instance<A, S, Q>>
+where
+    A: BackendApi + 'static, // 'static is needed here to allow copying API instances into closures
+    S: Storage + 'static, // 'static is needed here to allow using this in an Environment that is cloned into closures
+    Q: Querier + 'static,
+{
+    Instance::from_module(module, backend, gas_limit, print_debug, extra_imports)
+}
+
 #[cfg(test)]
 mod tests {
+    use std::sync::atomic::{AtomicBool, Ordering};
+    use std::sync::Arc;
+
     use super::*;
     use crate::backend::Storage;
     use crate::call_instantiate;
@@ -391,6 +424,53 @@ mod tests {
         assert!(instance.required_features().contains("water"));
     }
 
+    #[test]
+    fn extra_imports_get_added() {
+        let wasm = wat::parse_str(
+            r#"(module
+            (import "foo" "bar" (func $bar))
+            (func (export "main") (call $bar))
+            )"#,
+        )
+        .unwrap();
+
+        let backend = mock_backend(&[]);
+        let (instance_options, memory_limit) = mock_instance_options();
+        let module = compile(&wasm, memory_limit, &[]).unwrap();
+
+        #[derive(wasmer::WasmerEnv, Clone)]
+        struct MyEnv {
+            // This can be mutated across threads safely. We initialize it as `false`
+            // and let our imported fn switch it to `true` to confirm it works.
+            called: Arc<AtomicBool>,
+        }
+
+        let my_env = MyEnv {
+            called: Arc::new(AtomicBool::new(false)),
+        };
+
+        let fun = Function::new_native_with_env(module.store(), my_env.clone(), |env: &MyEnv| {
+            env.called.store(true, Ordering::Relaxed);
+        });
+        let mut exports = Exports::new();
+        exports.insert("bar", fun);
+        let mut extra_imports = HashMap::new();
+        extra_imports.insert("foo", exports);
+        let instance = Instance::from_module(
+            &module,
+            backend,
+            instance_options.gas_limit,
+            false,
+            Some(extra_imports),
+        )
+        .unwrap();
+
+        let main = instance._inner.exports.get_function("main").unwrap();
+        main.call(&[]).unwrap();
+
+        assert!(my_env.called.load(Ordering::Relaxed));
+    }
+
     #[test]
     fn call_function0_works() {
         let instance = mock_instance(CONTRACT, &[]);
diff --git a/packages/vm/src/lib.rs b/packages/vm/src/lib.rs
index 82f957ba4..4fccca3ee 100644
--- a/packages/vm/src/lib.rs
+++ b/packages/vm/src/lib.rs
@@ -55,5 +55,6 @@ pub mod internals {
     //! they might change frequently or be removed in the future.
 
     pub use crate::compatibility::check_wasm;
+    pub use crate::instance::instance_from_module;
     pub use crate::wasm_backend::{compile, make_runtime_store};
 }
diff --git a/packages/vm/src/modules/file_system_cache.rs b/packages/vm/src/modules/file_system_cache.rs
index 1fc8b4b9f..91272334e 100644
--- a/packages/vm/src/modules/file_system_cache.rs
+++ b/packages/vm/src/modules/file_system_cache.rs
@@ -140,7 +140,7 @@ mod tests {
         assert!(cached.is_none());
 
         // Store module
-        let module = compile(&wasm, None).unwrap();
+        let module = compile(&wasm, None, &[]).unwrap();
         cache.store(&checksum, &module).unwrap();
 
         // Load module
diff --git a/packages/vm/src/modules/in_memory_cache.rs b/packages/vm/src/modules/in_memory_cache.rs
index 9f7d9eaa3..9a0f95a56 100644
--- a/packages/vm/src/modules/in_memory_cache.rs
+++ b/packages/vm/src/modules/in_memory_cache.rs
@@ -142,7 +142,7 @@ mod tests {
         assert!(cache_entry.is_none());
 
         // Compile module
-        let original = compile(&wasm, None).unwrap();
+        let original = compile(&wasm, None, &[]).unwrap();
 
         // Ensure original module can be executed
         {
@@ -213,19 +213,19 @@ mod tests {
 
         // Add 1
         cache
-            .store(&checksum1, compile(&wasm1, None).unwrap(), 900_000)
+            .store(&checksum1, compile(&wasm1, None, &[]).unwrap(), 900_000)
             .unwrap();
         assert_eq!(cache.len(), 1);
 
         // Add 2
         cache
-            .store(&checksum2, compile(&wasm2, None).unwrap(), 900_000)
+            .store(&checksum2, compile(&wasm2, None, &[]).unwrap(), 900_000)
             .unwrap();
         assert_eq!(cache.len(), 2);
 
         // Add 3 (pushes out the previous two)
         cache
-            .store(&checksum3, compile(&wasm3, None).unwrap(), 1_500_000)
+            .store(&checksum3, compile(&wasm3, None, &[]).unwrap(), 1_500_000)
             .unwrap();
         assert_eq!(cache.len(), 1);
     }
@@ -273,19 +273,19 @@ mod tests {
 
         // Add 1
         cache
-            .store(&checksum1, compile(&wasm1, None).unwrap(), 900_000)
+            .store(&checksum1, compile(&wasm1, None, &[]).unwrap(), 900_000)
             .unwrap();
         assert_eq!(cache.size(), 900_000);
 
         // Add 2
         cache
-            .store(&checksum2, compile(&wasm2, None).unwrap(), 800_000)
+            .store(&checksum2, compile(&wasm2, None, &[]).unwrap(), 800_000)
             .unwrap();
         assert_eq!(cache.size(), 1_700_000);
 
         // Add 3 (pushes out the previous two)
         cache
-            .store(&checksum3, compile(&wasm3, None).unwrap(), 1_500_000)
+            .store(&checksum3, compile(&wasm3, None, &[]).unwrap(), 1_500_000)
             .unwrap();
         assert_eq!(cache.size(), 1_500_000);
     }
diff --git a/packages/vm/src/modules/pinned_memory_cache.rs b/packages/vm/src/modules/pinned_memory_cache.rs
index 4efa5d497..24d397c19 100644
--- a/packages/vm/src/modules/pinned_memory_cache.rs
+++ b/packages/vm/src/modules/pinned_memory_cache.rs
@@ -87,7 +87,7 @@ mod tests {
         assert!(cache_entry.is_none());
 
         // Compile module
-        let original = compile(&wasm, None).unwrap();
+        let original = compile(&wasm, None, &[]).unwrap();
 
         // Ensure original module can be executed
         {
@@ -134,7 +134,7 @@ mod tests {
         assert!(!cache.has(&checksum));
 
         // Add
-        let original = compile(&wasm, None).unwrap();
+        let original = compile(&wasm, None, &[]).unwrap();
         cache.store(&checksum, original, 0).unwrap();
 
         assert!(cache.has(&checksum));
@@ -165,7 +165,7 @@ mod tests {
         assert_eq!(cache.len(), 0);
 
         // Add
-        let original = compile(&wasm, None).unwrap();
+        let original = compile(&wasm, None, &[]).unwrap();
         cache.store(&checksum, original, 0).unwrap();
 
         assert_eq!(cache.len(), 1);
@@ -207,12 +207,12 @@ mod tests {
         assert_eq!(cache.size(), 0);
 
         // Add 1
-        let original = compile(&wasm1, None).unwrap();
+        let original = compile(&wasm1, None, &[]).unwrap();
         cache.store(&checksum1, original, 500).unwrap();
         assert_eq!(cache.size(), 500);
 
         // Add 2
-        let original = compile(&wasm2, None).unwrap();
+        let original = compile(&wasm2, None, &[]).unwrap();
         cache.store(&checksum2, original, 300).unwrap();
         assert_eq!(cache.size(), 800);
 
diff --git a/packages/vm/src/wasm_backend/compile.rs b/packages/vm/src/wasm_backend/compile.rs
index 1b3ca63bb..a75099767 100644
--- a/packages/vm/src/wasm_backend/compile.rs
+++ b/packages/vm/src/wasm_backend/compile.rs
@@ -1,4 +1,6 @@
-use wasmer::Module;
+use std::sync::Arc;
+
+use wasmer::{Module, ModuleMiddleware};
 
 use crate::errors::VmResult;
 use crate::size::Size;
@@ -9,8 +11,12 @@ use super::store::make_compile_time_store;
 /// The given memory limit (in bytes) is used when memories are created.
 /// If no memory limit is passed, the resulting compiled module should
 /// not be used for execution.
-pub fn compile(code: &[u8], memory_limit: Option<Size>) -> VmResult<Module> {
-    let store = make_compile_time_store(memory_limit);
+pub fn compile(
+    code: &[u8],
+    memory_limit: Option<Size>,
+    middlewares: &[Arc<dyn ModuleMiddleware>],
+) -> VmResult<Module> {
+    let store = make_compile_time_store(memory_limit, middlewares);
     let module = Module::new(&store, code)?;
     Ok(module)
 }
@@ -23,7 +29,7 @@ mod tests {
 
     #[test]
     fn contract_with_floats_fails_check() {
-        let err = compile(CONTRACT, None).unwrap_err();
+        let err = compile(CONTRACT, None, &[]).unwrap_err();
         assert!(err.to_string().contains("Float operator detected:"));
     }
 }
diff --git a/packages/vm/src/wasm_backend/store.rs b/packages/vm/src/wasm_backend/store.rs
index 97a914360..25496bcf9 100644
--- a/packages/vm/src/wasm_backend/store.rs
+++ b/packages/vm/src/wasm_backend/store.rs
@@ -5,8 +5,8 @@ use wasmer::Cranelift;
 #[cfg(not(feature = "cranelift"))]
 use wasmer::Singlepass;
 use wasmer::{
-    wasmparser::Operator, BaseTunables, CompilerConfig, Engine, Pages, Store, Target, Universal,
-    WASM_PAGE_SIZE,
+    wasmparser::Operator, BaseTunables, CompilerConfig, Engine, ModuleMiddleware, Pages, Store,
+    Target, Universal, WASM_PAGE_SIZE,
 };
 use wasmer_middlewares::Metering;
 
@@ -30,7 +30,10 @@ fn cost(_operator: &Operator) -> u64 {
 
 /// Created a store with the default compiler and the given memory limit (in bytes).
 /// If memory_limit is None, no limit is applied.
-pub fn make_compile_time_store(memory_limit: Option<Size>) -> Store {
+pub fn make_compile_time_store(
+    memory_limit: Option<Size>,
+    middlewares: &[Arc<dyn ModuleMiddleware>],
+) -> Store {
     let gas_limit = 0;
     let deterministic = Arc::new(Gatekeeper::default());
     let metering = Arc::new(Metering::new(gas_limit, cost));
@@ -40,6 +43,9 @@ pub fn make_compile_time_store(memory_limit: Option<Size>) -> Store {
         let mut config = Cranelift::default();
         config.push_middleware(deterministic);
         config.push_middleware(metering);
+        for middleware in middlewares {
+            config.push_middleware(middleware.clone());
+        }
         let engine = Universal::new(config).engine();
         make_store_with_engine(&engine, memory_limit)
     }
@@ -49,6 +55,9 @@ pub fn make_compile_time_store(memory_limit: Option<Size>) -> Store {
         let mut config = Singlepass::default();
         config.push_middleware(deterministic);
         config.push_middleware(metering);
+        for middleware in middlewares {
+            config.push_middleware(middleware.clone());
+        }
         let engine = Universal::new(config).engine();
         make_store_with_engine(&engine, memory_limit)
     }
@@ -113,7 +122,7 @@ mod tests {
         let wasm = wat::parse_str(EXPORTED_MEMORY_WAT).unwrap();
 
         // No limit
-        let store = make_compile_time_store(None);
+        let store = make_compile_time_store(None, &[]);
         let module = Module::new(&store, &wasm).unwrap();
         let module_memory = module.info().memories.last().unwrap();
         assert_eq!(module_memory.minimum, Pages(4));
@@ -130,7 +139,7 @@ mod tests {
         assert_eq!(instance_memory.ty().maximum, None);
 
         // Set limit
-        let store = make_compile_time_store(Some(Size::kibi(23 * 64)));
+        let store = make_compile_time_store(Some(Size::kibi(23 * 64)), &[]);
         let module = Module::new(&store, &wasm).unwrap();
         let module_memory = module.info().memories.last().unwrap();
         assert_eq!(module_memory.minimum, Pages(4));
@@ -152,7 +161,7 @@ mod tests {
         // Compile
         let serialized = {
             let wasm = wat::parse_str(EXPORTED_MEMORY_WAT).unwrap();
-            let store = make_compile_time_store(None);
+            let store = make_compile_time_store(None, &[]);
             let module = Module::new(&store, &wasm).unwrap();
             module.serialize().unwrap()
         };


Test patch:
diff --git a/contracts/reflect/src/testing.rs b/contracts/reflect/src/testing.rs
index 8f6ce714b..8237329b1 100644
--- a/contracts/reflect/src/testing.rs
+++ b/contracts/reflect/src/testing.rs
@@ -1,5 +1,3 @@
-use std::marker::PhantomData;
-
 use crate::msg::{SpecialQuery, SpecialResponse};
 
 use cosmwasm_std::testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR};
@@ -9,7 +7,7 @@ use cosmwasm_std::{to_binary, Binary, Coin, ContractResult, OwnedDeps, SystemRes
 /// this uses our CustomQuerier.
 pub fn mock_dependencies_with_custom_querier(
     contract_balance: &[Coin],
-) -> OwnedDeps<MockStorage, MockApi, MockQuerier<SpecialQuery>, SpecialQuery> {
+) -> OwnedDeps<MockStorage, MockApi, MockQuerier<SpecialQuery>> {
     let custom_querier: MockQuerier<SpecialQuery> =
         MockQuerier::new(&[(MOCK_CONTRACT_ADDR, contract_balance)])
             .with_custom_handler(|query| SystemResult::Ok(custom_query_execute(query)));
@@ -17,7 +15,6 @@ pub fn mock_dependencies_with_custom_querier(
         storage: MockStorage::default(),
         api: MockApi::default(),
         querier: custom_querier,
-        custom_query_type: PhantomData,
     }
 }
 
@@ -59,7 +56,7 @@ mod tests {
         }
         .into();
         let wrapper = QuerierWrapper::new(&deps.querier);
-        let response: SpecialResponse = wrapper.query(&req).unwrap();
+        let response: SpecialResponse = wrapper.custom_query(&req).unwrap();
         assert_eq!(response.msg, "FOOD");
     }
 }