use std::marker::PhantomData;
use std::vec::Vec;
use serde::de::DeserializeOwned;
use crate::deps::OwnedDeps;
#[cfg(feature = "stargate")]
use crate::ibc::{
IbcBasicResponse, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg,
IbcChannelOpenResponse, IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg,
IbcReceiveResponse,
};
use crate::imports::{ExternalApi, ExternalQuerier, ExternalStorage};
use crate::memory::{alloc, consume_region, release_buffer, Region};
#[cfg(feature = "abort")]
use crate::panic::install_panic_handler;
use crate::query::CustomQuery;
use crate::results::{ContractResult, QueryResponse, Reply, Response};
use crate::serde::{from_slice, to_vec};
use crate::types::Env;
use crate::{CustomMsg, Deps, DepsMut, MessageInfo};
#[cfg(feature = "iterator")]
#[no_mangle]
extern "C" fn requires_iterator() -> () {}
#[cfg(feature = "staking")]
#[no_mangle]
extern "C" fn requires_staking() -> () {}
#[cfg(feature = "stargate")]
#[no_mangle]
extern "C" fn requires_stargate() -> () {}
#[no_mangle]
extern "C" fn interface_version_8() -> () {}
#[no_mangle]
extern "C" fn allocate(size: usize) -> u32 {
alloc(size) as u32
}
#[no_mangle]
extern "C" fn deallocate(pointer: u32) {
let _ = unsafe { consume_region(pointer as *mut Region) };
}
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)
};
}
pub fn do_instantiate<Q, M, C, E>(
instantiate_fn: &dyn Fn(DepsMut<Q>, Env, MessageInfo, M) -> Result<Response<C>, E>,
env_ptr: u32,
info_ptr: u32,
msg_ptr: u32,
) -> u32
where
Q: CustomQuery,
M: DeserializeOwned,
C: CustomMsg,
E: ToString,
{
#[cfg(feature = "abort")]
install_panic_handler();
let res = _do_instantiate(
instantiate_fn,
env_ptr as *mut Region,
info_ptr as *mut Region,
msg_ptr as *mut Region,
);
let v = to_vec(&res).unwrap();
release_buffer(v) as u32
}
pub fn do_execute<Q, M, C, E>(
execute_fn: &dyn Fn(DepsMut<Q>, Env, MessageInfo, M) -> Result<Response<C>, E>,
env_ptr: u32,
info_ptr: u32,
msg_ptr: u32,
) -> u32
where
Q: CustomQuery,
M: DeserializeOwned,
C: CustomMsg,
E: ToString,
{
#[cfg(feature = "abort")]
install_panic_handler();
let res = _do_execute(
execute_fn,
env_ptr as *mut Region,
info_ptr as *mut Region,
msg_ptr as *mut Region,
);
let v = to_vec(&res).unwrap();
release_buffer(v) as u32
}
pub fn do_migrate<Q, M, C, E>(
migrate_fn: &dyn Fn(DepsMut<Q>, Env, M) -> Result<Response<C>, E>,
env_ptr: u32,
msg_ptr: u32,
) -> u32
where
Q: CustomQuery,
M: DeserializeOwned,
C: CustomMsg,
E: ToString,
{
#[cfg(feature = "abort")]
install_panic_handler();
let res = _do_migrate(migrate_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
let v = to_vec(&res).unwrap();
release_buffer(v) as u32
}
pub fn do_sudo<Q, M, C, E>(
sudo_fn: &dyn Fn(DepsMut<Q>, Env, M) -> Result<Response<C>, E>,
env_ptr: u32,
msg_ptr: u32,
) -> u32
where
Q: CustomQuery,
M: DeserializeOwned,
C: CustomMsg,
E: ToString,
{
#[cfg(feature = "abort")]
install_panic_handler();
let res = _do_sudo(sudo_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
let v = to_vec(&res).unwrap();
release_buffer(v) as u32
}
pub fn do_reply<Q, C, E>(
reply_fn: &dyn Fn(DepsMut<Q>, Env, Reply) -> Result<Response<C>, E>,
env_ptr: u32,
msg_ptr: u32,
) -> u32
where
Q: CustomQuery,
C: CustomMsg,
E: ToString,
{
#[cfg(feature = "abort")]
install_panic_handler();
let res = _do_reply(reply_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
let v = to_vec(&res).unwrap();
release_buffer(v) as u32
}
pub fn do_query<Q, M, E>(
query_fn: &dyn Fn(Deps<Q>, Env, M) -> Result<QueryResponse, E>,
env_ptr: u32,
msg_ptr: u32,
) -> u32
where
Q: CustomQuery,
M: DeserializeOwned,
E: ToString,
{
#[cfg(feature = "abort")]
install_panic_handler();
let res = _do_query(query_fn, env_ptr as *mut Region, msg_ptr as *mut Region);
let v = to_vec(&res).unwrap();
release_buffer(v) as u32
}
#[cfg(feature = "stargate")]
pub fn do_ibc_channel_open<Q, E>(
contract_fn: &dyn Fn(DepsMut<Q>, Env, IbcChannelOpenMsg) -> Result<IbcChannelOpenResponse, E>,
env_ptr: u32,
msg_ptr: u32,
) -> u32
where
Q: CustomQuery,
E: ToString,
{
#[cfg(feature = "abort")]
install_panic_handler();
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
}
#[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: CustomMsg,
E: ToString,
{
#[cfg(feature = "abort")]
install_panic_handler();
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
}
#[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: CustomMsg,
E: ToString,
{
#[cfg(feature = "abort")]
install_panic_handler();
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
}
#[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: CustomMsg,
E: ToString,
{
#[cfg(feature = "abort")]
install_panic_handler();
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
}
#[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: CustomMsg,
E: ToString,
{
#[cfg(feature = "abort")]
install_panic_handler();
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
}
#[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: CustomMsg,
E: ToString,
{
#[cfg(feature = "abort")]
install_panic_handler();
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>,
env_ptr: *mut Region,
info_ptr: *mut Region,
msg_ptr: *mut Region,
) -> ContractResult<Response<C>>
where
Q: CustomQuery,
M: DeserializeOwned,
C: CustomMsg,
E: ToString,
{
let env: Vec<u8> = unsafe { consume_region(env_ptr) };
let info: Vec<u8> = unsafe { consume_region(info_ptr) };
let msg: Vec<u8> = unsafe { consume_region(msg_ptr) };
let env: Env = try_into_contract_result!(from_slice(&env));
let info: MessageInfo = try_into_contract_result!(from_slice(&info));
let msg: M = try_into_contract_result!(from_slice(&msg));
let mut deps = make_dependencies();
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>,
env_ptr: *mut Region,
info_ptr: *mut Region,
msg_ptr: *mut Region,
) -> ContractResult<Response<C>>
where
Q: CustomQuery,
M: DeserializeOwned,
C: CustomMsg,
E: ToString,
{
let env: Vec<u8> = unsafe { consume_region(env_ptr) };
let info: Vec<u8> = unsafe { consume_region(info_ptr) };
let msg: Vec<u8> = unsafe { consume_region(msg_ptr) };
let env: Env = try_into_contract_result!(from_slice(&env));
let info: MessageInfo = try_into_contract_result!(from_slice(&info));
let msg: M = try_into_contract_result!(from_slice(&msg));
let mut deps = make_dependencies();
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>,
env_ptr: *mut Region,
msg_ptr: *mut Region,
) -> ContractResult<Response<C>>
where
Q: CustomQuery,
M: DeserializeOwned,
C: CustomMsg,
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: M = try_into_contract_result!(from_slice(&msg));
let mut deps = make_dependencies();
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>,
env_ptr: *mut Region,
msg_ptr: *mut Region,
) -> ContractResult<Response<C>>
where
Q: CustomQuery,
M: DeserializeOwned,
C: CustomMsg,
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: M = try_into_contract_result!(from_slice(&msg));
let mut deps = make_dependencies();
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>,
env_ptr: *mut Region,
msg_ptr: *mut Region,
) -> ContractResult<Response<C>>
where
Q: CustomQuery,
C: CustomMsg,
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: Reply = try_into_contract_result!(from_slice(&msg));
let mut deps = make_dependencies();
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>,
env_ptr: *mut Region,
msg_ptr: *mut Region,
) -> ContractResult<QueryResponse>
where
Q: CustomQuery,
M: DeserializeOwned,
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: M = try_into_contract_result!(from_slice(&msg));
let deps = make_dependencies();
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<IbcChannelOpenResponse, E>,
env_ptr: *mut Region,
msg_ptr: *mut Region,
) -> ContractResult<IbcChannelOpenResponse>
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: CustomMsg,
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: CustomMsg,
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: CustomMsg,
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: CustomMsg,
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: CustomMsg,
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()
}
pub(crate) fn make_dependencies<Q>() -> OwnedDeps<ExternalStorage, ExternalApi, ExternalQuerier, Q>
where
Q: CustomQuery,
{
OwnedDeps {
storage: ExternalStorage::new(),
api: ExternalApi::new(),
querier: ExternalQuerier::new(),
custom_query_type: PhantomData,
}
}