Skip to content

Commit

Permalink
Merge pull request #324 from CosmWasm/cleanup-multitest
Browse files Browse the repository at this point in the history
Cleanup multitest
  • Loading branch information
ethanfrey authored Jul 13, 2021
2 parents eaec2a1 + 6cce906 commit 551e793
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 108 deletions.
78 changes: 29 additions & 49 deletions packages/multi-test/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use serde::Serialize;
use cosmwasm_std::testing::{mock_env, MockApi};
use cosmwasm_std::{
from_slice, to_binary, to_vec, Addr, Api, Attribute, BankMsg, Binary, BlockInfo, Coin,
ContractResult, CosmosMsg, Empty, MessageInfo, Querier, QuerierResult, QuerierWrapper,
QueryRequest, Response, SubMsg, SystemError, SystemResult, WasmMsg,
ContractResult, CosmosMsg, Empty, Event, MessageInfo, Querier, QuerierResult, QuerierWrapper,
QueryRequest, ReplyOn, Response, SubMsg, SystemError, SystemResult, WasmMsg,
};

use crate::bank::{Bank, BankCache, BankOps, BankRouter};
Expand All @@ -16,44 +16,15 @@ use std::fmt;
#[derive(Default, Clone, Debug)]
pub struct AppResponse {
pub attributes: Vec<Attribute>,
pub events: Vec<Event>,
pub data: Option<Binary>,
}

// This can be Response, Response, MigrationResponse
#[derive(Default, Clone)]
pub struct ActionResponse<C>
fn init_response<C>(res: &mut Response<C>, contact_address: &Addr)
where
C: Clone + fmt::Debug + PartialEq + JsonSchema,
{
pub messages: Vec<CosmosMsg<C>>,
pub attributes: Vec<Attribute>,
pub data: Option<Binary>,
}

impl<C> From<Response<C>> for ActionResponse<C>
where
C: Clone + fmt::Debug + PartialEq + JsonSchema,
{
fn from(input: Response<C>) -> Self {
ActionResponse {
messages: input.messages.into_iter().map(|m| m.msg).collect(),
attributes: input.attributes,
data: input.data,
}
}
}

impl<C> ActionResponse<C>
where
C: Clone + fmt::Debug + PartialEq + JsonSchema,
{
fn init(input: Response<C>, address: Addr) -> Self {
ActionResponse {
messages: input.messages.into_iter().map(|m| m.msg).collect(),
attributes: input.attributes,
data: Some(address.as_ref().as_bytes().into()),
}
}
res.data = Some(contact_address.as_bytes().into());
}

impl<C> Querier for App<C>
Expand Down Expand Up @@ -305,19 +276,27 @@ where
/// For normal use cases, you can use Router::execute() or Router::execute_multi().
/// This is designed to be handled internally as part of larger process flows.
fn execute(&mut self, sender: Addr, msg: SubMsg<C>) -> Result<AppResponse, String> {
// TODO: actually handle reply semantics
if msg.reply_on != ReplyOn::Never {
unimplemented!();
}
match msg.msg {
CosmosMsg::Wasm(msg) => {
let (resender, res) = self.handle_wasm(sender, msg)?;
let (resender, res) = self.execute_wasm(sender, msg)?;
let mut attributes = res.attributes;
let mut events = res.events;
// recurse in all messages
for resend in res.messages {
let subres = self.execute(resender.clone(), SubMsg::new(resend))?;
let subres = self.execute(resender.clone(), resend)?;
// ignore the data now, just like in wasmd
// append the events
// TODO: is this correct for attributes??? Or do we turn them into sub-events?
attributes.extend_from_slice(&subres.attributes);
events.extend_from_slice(&subres.events);
}
Ok(AppResponse {
attributes,
events,
data: res.data,
})
}
Expand All @@ -332,25 +311,25 @@ where
fn sudo(&mut self, contract_addr: Addr, msg: Vec<u8>) -> Result<AppResponse, String> {
let res = self.wasm.sudo(contract_addr.clone(), self.router, msg)?;
let mut attributes = res.attributes;
let mut events = res.events;
// recurse in all messages
for resend in res.messages {
let subres = self.execute(contract_addr.clone(), resend)?;
// ignore the data now, just like in wasmd
// append the events
// TODO: is this correct for attributes??? Or do we turn them into sub-events?
attributes.extend_from_slice(&subres.attributes);
events.extend_from_slice(&subres.events);
}
Ok(AppResponse {
attributes,
events,
data: res.data,
})
}

// this returns the contract address as well, so we can properly resend the data
fn handle_wasm(
&mut self,
sender: Addr,
msg: WasmMsg,
) -> Result<(Addr, ActionResponse<C>), String> {
fn execute_wasm(&mut self, sender: Addr, msg: WasmMsg) -> Result<(Addr, Response<C>), String> {
match msg {
WasmMsg::Execute {
contract_addr,
Expand All @@ -364,8 +343,8 @@ where
let info = MessageInfo { sender, funds };
let res =
self.wasm
.handle(contract_addr.clone(), self.router, info, msg.to_vec())?;
Ok((contract_addr, res.into()))
.execute(contract_addr.clone(), self.router, info, msg.to_vec())?;
Ok((contract_addr, res))
}
WasmMsg::Instantiate {
admin: _,
Expand All @@ -379,13 +358,14 @@ where
self.send(sender.clone(), contract_addr.clone().into(), &funds)?;
// then call the contract
let info = MessageInfo { sender, funds };
let res = self
.wasm
.init(contract_addr.clone(), self.router, info, msg.to_vec())?;
Ok((
let mut res = self.wasm.instantiate(
contract_addr.clone(),
ActionResponse::init(res, contract_addr),
))
self.router,
info,
msg.to_vec(),
)?;
init_response(&mut res, &contract_addr);
Ok((contract_addr, res))
}
WasmMsg::Migrate { .. } => unimplemented!(),
m => panic!("Unsupported wasm message: {:?}", m),
Expand Down
19 changes: 10 additions & 9 deletions packages/multi-test/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const BALANCES: Map<&Addr, NativeBalance> = Map::new("balances");
/// Bank is a minimal contract-like interface that implements a bank module
/// It is initialized outside of the trait
pub trait Bank {
fn handle(&self, storage: &mut dyn Storage, sender: Addr, msg: BankMsg) -> Result<(), String>;
fn execute(&self, storage: &mut dyn Storage, sender: Addr, msg: BankMsg) -> Result<(), String>;

fn query(&self, storage: &dyn Storage, request: BankQuery) -> Result<Binary, String>;

Expand Down Expand Up @@ -85,7 +85,7 @@ impl<'a> BankCache<'a> {
}

pub fn execute(&mut self, sender: Addr, msg: BankMsg) -> Result<(), String> {
self.router.bank.handle(&mut self.state, sender, msg)
self.router.bank.execute(&mut self.state, sender, msg)
}
}

Expand Down Expand Up @@ -136,7 +136,7 @@ impl SimpleBank {
}

impl Bank for SimpleBank {
fn handle(&self, storage: &mut dyn Storage, sender: Addr, msg: BankMsg) -> Result<(), String> {
fn execute(&self, storage: &mut dyn Storage, sender: Addr, msg: BankMsg) -> Result<(), String> {
match msg {
BankMsg::Send { to_address, amount } => {
self.send(storage, sender, Addr::unchecked(to_address), amount)
Expand Down Expand Up @@ -273,21 +273,22 @@ mod test {
to_address: rcpt.clone().into(),
amount: to_send,
};
bank.handle(&mut store, owner.clone(), msg.clone()).unwrap();
bank.execute(&mut store, owner.clone(), msg.clone())
.unwrap();
let rich = bank.get_balance(&store, &owner).unwrap();
assert_eq!(vec![coin(15, "btc"), coin(70, "eth")], rich);
let poor = bank.get_balance(&store, &rcpt).unwrap();
assert_eq!(vec![coin(10, "btc"), coin(30, "eth")], poor);

// can send from any account with funds
bank.handle(&mut store, rcpt.clone(), msg).unwrap();
bank.execute(&mut store, rcpt.clone(), msg).unwrap();

// cannot send too much
let msg = BankMsg::Send {
to_address: rcpt.into(),
amount: coins(20, "btc"),
};
bank.handle(&mut store, owner.clone(), msg).unwrap_err();
bank.execute(&mut store, owner.clone(), msg).unwrap_err();

let rich = bank.get_balance(&store, &owner).unwrap();
assert_eq!(vec![coin(15, "btc"), coin(70, "eth")], rich);
Expand All @@ -308,15 +309,15 @@ mod test {
// send both tokens
let to_burn = vec![coin(30, "eth"), coin(5, "btc")];
let msg = BankMsg::Burn { amount: to_burn };
bank.handle(&mut store, owner.clone(), msg).unwrap();
bank.execute(&mut store, owner.clone(), msg).unwrap();
let rich = bank.get_balance(&store, &owner).unwrap();
assert_eq!(vec![coin(15, "btc"), coin(70, "eth")], rich);

// cannot burn too much
let msg = BankMsg::Burn {
amount: coins(20, "btc"),
};
let err = bank.handle(&mut store, owner.clone(), msg).unwrap_err();
let err = bank.execute(&mut store, owner.clone(), msg).unwrap_err();
assert!(err.contains("Overflow"));
let rich = bank.get_balance(&store, &owner).unwrap();
assert_eq!(vec![coin(15, "btc"), coin(70, "eth")], rich);
Expand All @@ -325,7 +326,7 @@ mod test {
let msg = BankMsg::Burn {
amount: coins(1, "btc"),
};
let err = bank.handle(&mut store, rcpt, msg).unwrap_err();
let err = bank.execute(&mut store, rcpt, msg).unwrap_err();
assert!(err.contains("Overflow"));
}
}
29 changes: 17 additions & 12 deletions packages/multi-test/src/test_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::wasm::{Contract, ContractWrapper};
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct EmptyMsg {}

fn init_error(
fn instantiate_error(
_deps: DepsMut,
_env: Env,
_info: MessageInfo,
Expand All @@ -23,7 +23,7 @@ fn init_error(
Err(StdError::generic_err("Init failed"))
}

fn handle_error(
fn execute_error(
_deps: DepsMut,
_env: Env,
_info: MessageInfo,
Expand All @@ -38,7 +38,7 @@ fn query_error(_deps: Deps, _env: Env, _msg: EmptyMsg) -> Result<Binary, StdErro

pub fn contract_error() -> Box<dyn Contract<Empty>> {
let contract: ContractWrapper<_, _, _, _, _, _, _, _, _> =
ContractWrapper::new(handle_error, init_error, query_error);
ContractWrapper::new(execute_error, instantiate_error, query_error);
Box::new(contract)
}

Expand All @@ -48,7 +48,7 @@ where
C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static,
{
let contract: ContractWrapper<_, _, _, _, _, _, _, _, _> =
ContractWrapper::new_with_empty(handle_error, init_error, query_error);
ContractWrapper::new_with_empty(execute_error, instantiate_error, query_error);
Box::new(contract)
}

Expand All @@ -58,7 +58,7 @@ pub struct PayoutMessage {
}
const PAYOUT: Item<PayoutMessage> = Item::new("payout");

fn init_payout(
fn instantiate_payout(
deps: DepsMut,
_env: Env,
_info: MessageInfo,
Expand All @@ -68,7 +68,7 @@ fn init_payout(
Ok(Response::default())
}

fn handle_payout(
fn execute_payout(
deps: DepsMut,
_env: Env,
info: MessageInfo,
Expand All @@ -95,15 +95,16 @@ fn query_payout(deps: Deps, _env: Env, _msg: EmptyMsg) -> Result<Binary, StdErro
}

pub fn contract_payout() -> Box<dyn Contract<Empty>> {
let contract = ContractWrapper::new(handle_payout, init_payout, query_payout);
let contract = ContractWrapper::new(execute_payout, instantiate_payout, query_payout);
Box::new(contract)
}

pub fn contract_payout_custom<C>() -> Box<dyn Contract<C>>
where
C: Clone + fmt::Debug + PartialEq + JsonSchema + 'static,
{
let contract = ContractWrapper::new_with_empty(handle_payout, init_payout, query_payout);
let contract =
ContractWrapper::new_with_empty(execute_payout, instantiate_payout, query_payout);
Box::new(contract)
}

Expand Down Expand Up @@ -132,7 +133,7 @@ pub struct ReflectResponse {

const REFLECT: Item<u32> = Item::new("reflect");

fn init_reflect(
fn instantiate_reflect(
deps: DepsMut,
_env: Env,
_info: MessageInfo,
Expand All @@ -142,7 +143,7 @@ fn init_reflect(
Ok(Response::default())
}

fn handle_reflect(
fn execute_reflect(
deps: DepsMut,
_env: Env,
_info: MessageInfo,
Expand Down Expand Up @@ -175,7 +176,11 @@ fn query_reflect(deps: Deps, _env: Env, _msg: EmptyMsg) -> Result<Binary, StdErr
}

pub fn contract_reflect() -> Box<dyn Contract<CustomMsg>> {
let contract =
ContractWrapper::new_with_sudo(handle_reflect, init_reflect, query_reflect, sudo_reflect);
let contract = ContractWrapper::new_with_sudo(
execute_reflect,
instantiate_reflect,
query_reflect,
sudo_reflect,
);
Box::new(contract)
}
Loading

0 comments on commit 551e793

Please sign in to comment.