Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup multitest #324

Merged
merged 4 commits into from
Jul 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
maurolacy marked this conversation as resolved.
Show resolved Hide resolved
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