Skip to content

Commit

Permalink
Merge pull request #34 from WHELP-project/coreum/multitest-app
Browse files Browse the repository at this point in the history
Multitest app: Custom module supporting coreum messages
  • Loading branch information
ueco-jb committed Nov 29, 2023
2 parents 2ff3aac + 1b4582f commit 7cea57c
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 0 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ derivative = "2.2"
dex = { path = "./packages/dex", default-features = false }
itertools = "0.10"
proptest = "1.0"
schemars = "0.8"
serde = { version = "1", default-features = false, features = ["derive"] }
thiserror = "1"
test-case = "2.2.1"
Expand Down
18 changes: 18 additions & 0 deletions packages/bindings-test/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "bindings-test"
version.workspace = true
authors = ["Jakub <[email protected]>"]
description = "Multitest app for Coreum-specific contracts"
edition.workspace = true
license.workspace = true
repository.workspace = true

[dependencies]
anyhow = { workspace = true }
coreum-wasm-sdk = { workspace = true }
cosmwasm-std = { workspace = true }
cw-multi-test = { workspace = true }
schemars = { workspace = true }
serde = { workspace = true }


5 changes: 5 additions & 0 deletions packages/bindings-test/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
mod multitest;

pub use multitest::{
mock_coreum_deps, CoreumApp, CoreumAppWrapped, CoreumDeps, CoreumModule, BLOCK_TIME,
};
183 changes: 183 additions & 0 deletions packages/bindings-test/src/multitest.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
use std::{
cmp::max,
fmt::Debug,
marker::PhantomData,
ops::{Deref, DerefMut},
};

use anyhow::{bail, Result as AnyResult};
use schemars::JsonSchema;
use serde::de::DeserializeOwned;

use coreum_wasm_sdk::{
assetft,
core::{CoreumMsg, CoreumQueries},
};
use cosmwasm_std::{
testing::{MockApi, MockQuerier, MockStorage},
to_json_binary, Addr, Api, BalanceResponse, BankMsg, BankQuery, Binary, BlockInfo, CustomQuery,
Empty, OwnedDeps, Querier, QuerierWrapper, QueryRequest, Storage,
};
use cw_multi_test::{
App, AppResponse, BankKeeper, BankSudo, BasicAppBuilder, CosmosRouter, Module, WasmKeeper,
};

/// How many seconds per block
/// (when we increment block.height, use this multiplier for block.time)
pub const BLOCK_TIME: u64 = 5;

pub type CoreumDeps = OwnedDeps<MockStorage, MockApi, MockQuerier, CoreumQueries>;

pub fn mock_coreum_deps() -> CoreumDeps {
CoreumDeps {
storage: MockStorage::default(),
api: MockApi::default(),
querier: MockQuerier::default(),
custom_query_type: PhantomData,
}
}

pub struct CoreumModule {}

impl Module for CoreumModule {
type ExecT = CoreumMsg;
type QueryT = CoreumQueries;
type SudoT = Empty;

fn execute<ExecC, QueryC>(
&self,
api: &dyn Api,
storage: &mut dyn Storage,
router: &dyn CosmosRouter<ExecC = ExecC, QueryC = QueryC>,
block: &BlockInfo,
sender: Addr,
msg: CoreumMsg,
) -> AnyResult<AppResponse>
where
ExecC: Debug + Clone + PartialEq + JsonSchema + DeserializeOwned + 'static,
QueryC: CustomQuery + DeserializeOwned + 'static,
{
match msg {
CoreumMsg::AssetFT(msg) => match msg {
// Just return empty response for now, issue does nothing in mock
assetft::Msg::Issue { .. } => Ok(AppResponse::default()),
assetft::Msg::Mint { coin } => {
let mint_msg = BankSudo::Mint {
to_address: sender.to_string(),
amount: vec![coin],
};
router.sudo(api, storage, block, mint_msg.into())
}
// Also do nothing for now
assetft::Msg::Burn { coin } => {
let burn_msg = BankMsg::Burn { amount: vec![coin] };
router.execute(api, storage, block, sender, burn_msg.into())
}
_ => bail!("Unsupported assetft message!"),
},
_ => bail!("Unsupported CoreumMsg execute!"),
}
}

fn query(
&self,
_api: &dyn Api,
_storage: &dyn Storage,
querier: &dyn Querier,
_block: &BlockInfo,
request: CoreumQueries,
) -> AnyResult<Binary> {
match request {
CoreumQueries::AssetFT(r) => match r {
assetft::Query::Balance { account, denom } => {
let bank_query: QueryRequest<cosmwasm_std::Empty> =
QueryRequest::Bank(BankQuery::Balance {
address: account,
denom,
});
let res: BalanceResponse = QuerierWrapper::new(querier).query(&bank_query)?;
Ok(to_json_binary(&assetft::BalanceResponse {
balance: res.amount.amount.to_string(),
whitelisted: "".to_owned(),
frozen: "".to_owned(),
locked: "".to_owned(),
})?)
}
_ => bail!("Unsupported assetft query!"),
},
_ => bail!("Unsupported CoreumQueries query!"),
}
}

fn sudo<ExecC, QueryC>(
&self,
_api: &dyn Api,
_storage: &mut dyn Storage,
_router: &dyn CosmosRouter<ExecC = ExecC, QueryC = QueryC>,
_block: &BlockInfo,
_msg: Self::SudoT,
) -> AnyResult<AppResponse>
where
ExecC: Debug + Clone + PartialEq + JsonSchema + DeserializeOwned + 'static,
QueryC: CustomQuery + DeserializeOwned + 'static,
{
bail!("sudo not implemented for CoreumModule")
}
}

pub type CoreumAppWrapped =
App<BankKeeper, MockApi, MockStorage, CoreumModule, WasmKeeper<CoreumMsg, CoreumQueries>>;

pub struct CoreumApp(CoreumAppWrapped);

impl Deref for CoreumApp {
type Target = CoreumAppWrapped;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl DerefMut for CoreumApp {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}

impl Default for CoreumApp {
fn default() -> Self {
Self::new()
}
}

impl CoreumApp {
pub fn new() -> Self {
Self(
BasicAppBuilder::<CoreumMsg, CoreumQueries>::new_custom()
.with_custom(CoreumModule {})
.build(|_router, _, _storage| ()),
)
}

pub fn block_info(&self) -> BlockInfo {
self.0.block_info()
}

/// This advances BlockInfo by given number of blocks.
/// It does not do any callbacks, but keeps the ratio of seconds/blokc
pub fn advance_blocks(&mut self, blocks: u64) {
self.update_block(|block| {
block.time = block.time.plus_seconds(BLOCK_TIME * blocks);
block.height += blocks;
});
}

/// This advances BlockInfo by given number of seconds.
/// It does not do any callbacks, but keeps the ratio of seconds/blokc
pub fn advance_seconds(&mut self, seconds: u64) {
self.update_block(|block| {
block.time = block.time.plus_seconds(seconds);
block.height += max(1, seconds / BLOCK_TIME);
});
}
}

0 comments on commit 7cea57c

Please sign in to comment.