diff --git a/Makefile b/Makefile index 8016aef7..bcf6f841 100644 --- a/Makefile +++ b/Makefile @@ -151,8 +151,12 @@ ictest-all: ictest-start-cosmos ictest-ibc ### Integration Tests ### ############################################################################### -#./scripts/tests/relayer/interchain-acc-config/rly-init.sh - +integration-test-all: init-test-framework \ + test-ica \ + test-ibc-hooks \ + test-alliance \ + test-tokenfactory + init-test-framework: clean-testing-data install @echo "Initializing both blockchains..." ./scripts/tests/init-test-framework.sh @@ -162,9 +166,20 @@ test-tokenfactory: @echo "Testing tokenfactory..." ./scripts/tests/tokenfactory/tokenfactory.sh +test-alliance: + @echo "Testing alliance..." + ./scripts/tests/alliance/delegate.sh + +test-ica: + @echo "Testing ica..." + ./scripts/tests/ica/delegate.sh + +test-ibc-hooks: + @echo "Testing ibc-hooks..." + ./scripts/tests/ibc-hooks/increment.sh clean-testing-data: - @echo "Killing terrad and removing previous data" + @echo "Killing migallod and removing previous data" -@pkill $(BINARY) 2>/dev/null -@pkill rly 2>/dev/null -@pkill migalood_new 2>/dev/null diff --git a/app/app.go b/app/app.go index 168bb870..132aa6a7 100644 --- a/app/app.go +++ b/app/app.go @@ -3,6 +3,12 @@ package app import ( "encoding/json" "fmt" + "io" + "net/http" + "os" + "path/filepath" + "sort" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" @@ -44,11 +50,6 @@ import ( solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" icq "github.com/strangelove-ventures/async-icq/v7" - "io" - "net/http" - "os" - "path/filepath" - "sort" distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" @@ -296,7 +297,7 @@ type MigalooApp struct { // IBC hooks IBCHooksKeeper *ibchookskeeper.Keeper - TransferStack *ibchooks.IBCMiddleware + TransferStack *ibcporttypes.IBCModule ScopedIBCKeeper capabilitykeeper.ScopedKeeper ScopedICAHostKeeper capabilitykeeper.ScopedKeeper @@ -321,7 +322,7 @@ type MigalooApp struct { } func (app *MigalooApp) Close() error { - //TODO implement me + // TODO implement me panic("implement me") } @@ -568,7 +569,7 @@ func NewMigalooApp( // IBC Fee Module keeper app.IBCFeeKeeper = ibcfeekeeper.NewKeeper( appCodec, keys[ibcfeetypes.StoreKey], - app.IBCKeeper.ChannelKeeper, // may be replaced with IBC middleware + app.HooksICS4Wrapper, // may be replaced with IBC middleware app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, app.AccountKeeper, app.BankKeeper, ) @@ -667,16 +668,16 @@ func NewMigalooApp( var transferStack ibcporttypes.IBCModule transferStack = transfer.NewIBCModule(app.TransferKeeper) transferStack = ibcfee.NewIBCMiddleware(transferStack, app.IBCFeeKeeper) + transferStack = ibchooks.NewIBCMiddleware(transferStack, &app.HooksICS4Wrapper) transferStack = router.NewIBCMiddleware( transferStack, &app.RouterKeeper, - 0, + 5, routerkeeper.DefaultForwardTransferPacketTimeoutTimestamp, routerkeeper.DefaultRefundTransferPacketTimeoutTimestamp, ) // Hooks Middleware - hooksTransferStack := ibchooks.NewIBCMiddleware(transferStack, &app.HooksICS4Wrapper) - app.TransferStack = &hooksTransferStack + app.TransferStack = &transferStack // Create Interchain Accounts Stack // SendPacket, since it is originating from the application to core IBC: @@ -706,9 +707,10 @@ func NewMigalooApp( // Create static IBC router, add app routes, then set and seal it ibcRouter := ibcporttypes.NewRouter(). - AddRoute(ibctransfertypes.ModuleName, transferStack). - AddRoute(wasmtypes.ModuleName, wasmStack). + AddRoute(icacontrollertypes.SubModuleName, icaControllerStack). AddRoute(icahosttypes.SubModuleName, icaHostStack). + AddRoute(ibctransfertypes.ModuleName, *app.TransferStack). + AddRoute(wasmtypes.ModuleName, wasmStack). AddRoute(icqtypes.ModuleName, icqStack) app.IBCKeeper.SetRouter(ibcRouter) diff --git a/scripts/tests/alliance/delegate.sh b/scripts/tests/alliance/delegate.sh new file mode 100755 index 00000000..bd145bf0 --- /dev/null +++ b/scripts/tests/alliance/delegate.sh @@ -0,0 +1,108 @@ +#!/bin/bash + +echo "" +echo "#################################################" +echo "# Alliance: bridge funds and create an alliance #" +echo "#################################################" +echo "" + +BINARY=migalood +CHAIN_DIR=$(pwd)/data + +AMOUNT_TO_DELEGATE=10000000000 +UWHALE_DENOM=uwhale +VAL_WALLET_1=$($BINARY keys show val1 -a --keyring-backend test --home $CHAIN_DIR/test-1) +VAL_WALLET_2=$($BINARY keys show val2 -a --keyring-backend test --home $CHAIN_DIR/test-2) + +echo "Sending tokens from validator wallet on test-1 to validator wallet on test-2" +IBC_TRANSFER=$($BINARY tx ibc-transfer transfer transfer channel-0 $VAL_WALLET_2 $AMOUNT_TO_DELEGATE$UWHALE_DENOM --chain-id test-1 --from $VAL_WALLET_1 --home $CHAIN_DIR/test-1 --fees 60000$UWHALE_DENOM --node tcp://localhost:16657 --keyring-backend test -y -o json | jq -r '.raw_log' ) + +if [[ "$IBC_TRANSFER" == "failed to execute message"* ]]; then + echo "Error: IBC transfer failed, with error: $IBC_TRANSFER" + exit 1 +fi + +ACCOUNT_BALANCE="" +IBC_DENOM="" +while [ "$ACCOUNT_BALANCE" == "" ]; do + IBC_DENOM=$($BINARY q bank balances $VAL_WALLET_2 --chain-id test-2 --node tcp://localhost:26657 -o json | jq -r '.balances[0].denom') + IBC_QUERY=$($BINARY q bank balances $VAL_WALLET_2 --chain-id test-2 --node tcp://localhost:26657 -o json) + + echo $IBC_QUERY + if [ "$IBC_DENOM" != "$UWHALE_DENOM" ]; then + ACCOUNT_BALANCE=$($BINARY q bank balances $VAL_WALLET_2 --chain-id test-2 --node tcp://localhost:26657 -o json | jq -r '.balances[0].amount') + fi + sleep 2 +done + +GOV_ADDRESS=$($BINARY query auth module-account gov --output json | jq .account.base_account.address -r) +echo '{ + "messages": [ + { + "@type": "/alliance.alliance.MsgCreateAlliance", + "authority" : "'"$GOV_ADDRESS"'", + "denom": "'"$IBC_DENOM"'", + "reward_weight": "0.3", + "take_rate": "0.01", + "reward_change_rate": "0.01", + "reward_change_interval": "10s", + "reward_weight_range": { + "min":"0.0001", + "max":"0.3" + } + } + ], + "metadata": "", + "deposit": "25000000000'$UWHALE_DENOM'", + "title": "Create an Alliance!", + "summary": "Source Code Version https://github.com/terra-money/core" +}' > $CHAIN_DIR/create-alliance.json + + +echo "Creating an alliance with the denom $IBC_DENOM" +PROPOSAL_HEIGHT=$($BINARY tx gov submit-proposal $CHAIN_DIR/create-alliance.json --from=$VAL_WALLET_2 --home $CHAIN_DIR/test-2 --node tcp://localhost:26657 -o json --keyring-backend test --fees 60000$UWHALE_DENOM -y | jq -r '.height') +sleep 3 + + +PROPOSAL_ID=$($BINARY query gov proposals --home $CHAIN_DIR/test-2 --count-total --node tcp://localhost:26657 -o json --output json --chain-id=test-2 | jq .proposals[-1].id -r) + + +VOTE_RES=$($BINARY tx gov vote $PROPOSAL_ID yes --from=$VAL_WALLET_2 --home $CHAIN_DIR/test-2 --keyring-backend=test --fees 60000$UWHALE_DENOM --chain-id=test-2 --node tcp://localhost:26657 -o json -y) +echo "Vote res: $VOTE_RES" + +ALLIANCE="null" +while [ "$ALLIANCE" == "null" ]; do + echo "Waiting for alliance with denom $IBC_DENOM to be created" + ALLIANCE=$($BINARY q alliance alliances --chain-id test-2 --node tcp://localhost:26657 -o json | jq -r '.alliances[0]') + ALLIANCE_QUERY=$($BINARY q alliance alliances --chain-id test-2 --node tcp://localhost:26657 -o json) + echo $ALLIANCE_QUERY + + sleep 2 +done + +echo "Delegating $AMOUNT_TO_DELEGATE to the alliance $IBC_DENOM" +VAL_ADDR=$($BINARY query staking validators --output json | jq .validators[0].operator_address --raw-output) +DELEGATE_RES=$($BINARY tx alliance delegate $VAL_ADDR $AMOUNT_TO_DELEGATE$IBC_DENOM --from=node0 --from=$VAL_WALLET_2 --home $CHAIN_DIR/test-2 --keyring-backend=test --fees 60000$UWHALE_DENOM --chain-id=test-2 -o json -y) +sleep 3 +DELEGATIONS=$($BINARY query alliance delegation $VAL_WALLET_2 $VAL_ADDR $IBC_DENOM --chain-id test-2 --node tcp://localhost:26657 -o json | jq -r '.delegation.balance.amount') +if [[ "$DELEGATIONS" == "0" ]]; then + echo "Error: Alliance delegations expected to be greater than 0" + exit 1 +fi + +echo "Query bank balance after alliance creation" +TOTAL_SUPPLY_BEFORE_ALLIANCE=$($BINARY query bank total --denom $UWHALE_DENOM --height $PROPOSAL_HEIGHT -o json | jq -r '.amount') +TOTAL_SUPPLY_AFTER_ALLIANCE=$($BINARY query bank total --denom $UWHALE_DENOM -o json | jq -r '.amount') +TOTAL_SUPPLY_INCREMENT=$(($TOTAL_SUPPLY_BEFORE_ALLIANCE - $TOTAL_SUPPLY_AFTER_ALLIANCE)) + + +if [ "$TOTAL_SUPPLY_INCREMENT" -gt 100000 ] && [ "$TOTAL_SUPPLY_INCREMENT" -lt 1000000 ]; then + echo "Error: Something went wrong, total supply of $UWHALE_DENOM has increased out of range 100_000 between 1_000_000. current value $TOTAL_SUPPLY_INCREMENT" + exit 1 +fi + +echo "" +echo "#########################################################" +echo "# Success: Alliance bridge funds and create an alliance #" +echo "#########################################################" +echo "" \ No newline at end of file diff --git a/scripts/tests/ibc-hooks/counter/Cargo.toml b/scripts/tests/ibc-hooks/counter/Cargo.toml new file mode 100644 index 00000000..f164afc0 --- /dev/null +++ b/scripts/tests/ibc-hooks/counter/Cargo.toml @@ -0,0 +1,43 @@ +[package] +name = "counter" +description = "Cosmwasm counter dapp, with permissions for testing Osmosis wasmhooks" +version = "0.1.0" +authors = ["osmosis contributors"] +edition = "2021" + +exclude = [ + # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. + "contract.wasm", + "hash.txt", +] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] + +[package.metadata.scripts] +optimize = """docker run --rm -v "$(pwd)":/code \ + --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ + --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ + cosmwasm/rust-optimizer:0.12.6 +""" + +[dependencies] +cosmwasm-schema = "1.1.3" +cosmwasm-std = "1.1.3" +cosmwasm-storage = "1.1.3" +cw-storage-plus = "0.16.0" +cw2 = "0.16.0" +schemars = "0.8.10" +serde = { version = "1.0.145", default-features = false, features = ["derive"] } +thiserror = { version = "1.0.31" } + +[dev-dependencies] +cw-multi-test = "0.16.0" diff --git a/scripts/tests/ibc-hooks/counter/README.md b/scripts/tests/ibc-hooks/counter/README.md new file mode 100644 index 00000000..f4394fe8 --- /dev/null +++ b/scripts/tests/ibc-hooks/counter/README.md @@ -0,0 +1,11 @@ +# Counter contract from [Osmosis Labs](https://github.com/osmosis-labs/osmosis/commit/64393a14e18b2562d72a3892eec716197a3716c7) + +This contract is a modification of the standard cosmwasm `counter` contract. +Namely, it tracks a counter, _by sender_. +This is a better way to test wasmhooks. + +This contract tracks any funds sent to it by adding it to the state under the `sender` key. + +This way we can verify that, independently of the sender, the funds will end up under the +`WasmHooksModuleAccount` address when the contract is executed via an IBC send that goes +through the wasmhooks module. diff --git a/scripts/tests/ibc-hooks/counter/artifacts/checksums.txt b/scripts/tests/ibc-hooks/counter/artifacts/checksums.txt new file mode 100644 index 00000000..1f542142 --- /dev/null +++ b/scripts/tests/ibc-hooks/counter/artifacts/checksums.txt @@ -0,0 +1 @@ +c0e7a3b40d9710f6f72322293ba5cd871714008d9accd9a91c0fb08272609054 counter.wasm diff --git a/scripts/tests/ibc-hooks/counter/artifacts/checksums_intermediate.txt b/scripts/tests/ibc-hooks/counter/artifacts/checksums_intermediate.txt new file mode 100644 index 00000000..0394e5fc --- /dev/null +++ b/scripts/tests/ibc-hooks/counter/artifacts/checksums_intermediate.txt @@ -0,0 +1 @@ +bffb3256d4fd5668e497ae5671844ef3dcdf1a5f2594747b894dfc02e243ab0e ./target/wasm32-unknown-unknown/release/counter.wasm diff --git a/scripts/tests/ibc-hooks/counter/artifacts/counter.wasm b/scripts/tests/ibc-hooks/counter/artifacts/counter.wasm new file mode 100644 index 00000000..e3e5b53b Binary files /dev/null and b/scripts/tests/ibc-hooks/counter/artifacts/counter.wasm differ diff --git a/scripts/tests/ibc-hooks/counter/src/contract.rs b/scripts/tests/ibc-hooks/counter/src/contract.rs new file mode 100644 index 00000000..259d3634 --- /dev/null +++ b/scripts/tests/ibc-hooks/counter/src/contract.rs @@ -0,0 +1,395 @@ +use std::collections::HashMap; + +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{ + to_binary, Binary, Coin, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128, +}; +use cw2::set_contract_version; + +use crate::error::ContractError; +use crate::msg::*; +use crate::state::{Counter, COUNTERS}; + +// version info for migration info +const CONTRACT_NAME: &str = "osmosis:permissioned_counter"; +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + _env: Env, + info: MessageInfo, + msg: InstantiateMsg, +) -> Result { + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + let initial_counter = Counter { + count: msg.count, + total_funds: vec![], + owner: info.sender.clone(), + }; + COUNTERS.save(deps.storage, info.sender.clone(), &initial_counter)?; + + Ok(Response::new() + .add_attribute("method", "instantiate") + .add_attribute("owner", info.sender) + .add_attribute("count", msg.count.to_string())) +} + +pub mod utils { + use cosmwasm_std::Addr; + + use super::*; + + pub fn update_counter( + deps: DepsMut, + sender: Addr, + update_counter: &dyn Fn(&Option) -> i32, + update_funds: &dyn Fn(&Option) -> Vec, + ) -> Result { + COUNTERS + .update( + deps.storage, + sender.clone(), + |state| -> Result<_, ContractError> { + match state { + None => Ok(Counter { + count: update_counter(&None), + total_funds: update_funds(&None), + owner: sender, + }), + Some(counter) => Ok(Counter { + count: update_counter(&Some(counter.clone())), + total_funds: update_funds(&Some(counter)), + owner: sender, + }), + } + }, + ) + .map(|_r| true) + } +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + _env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + match msg { + ExecuteMsg::Increment {} => execute::increment(deps, info), + ExecuteMsg::Reset { count } => execute::reset(deps, info, count), + } +} + +pub mod execute { + use super::*; + + pub fn increment(deps: DepsMut, info: MessageInfo) -> Result { + utils::update_counter( + deps, + info.sender, + &|counter| match counter { + None => 0, + Some(counter) => counter.count + 1, + }, + &|counter| match counter { + None => info.funds.clone(), + Some(counter) => naive_add_coins(&info.funds, &counter.total_funds), + }, + )?; + Ok(Response::new().add_attribute("action", "increment")) + } + + pub fn reset(deps: DepsMut, info: MessageInfo, count: i32) -> Result { + utils::update_counter(deps, info.sender, &|_counter| count, &|_counter| vec![])?; + Ok(Response::new().add_attribute("action", "reset")) + } +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn sudo(deps: DepsMut, env: Env, msg: SudoMsg) -> Result { + match msg { + SudoMsg::IBCLifecycleComplete(IBCLifecycleComplete::IBCAck { + channel: _, + sequence: _, + ack: _, + success, + }) => sudo::receive_ack(deps, env.contract.address, success), + SudoMsg::IBCLifecycleComplete(IBCLifecycleComplete::IBCTimeout { + channel: _, + sequence: _, + }) => sudo::ibc_timeout(deps, env.contract.address), + } +} + +pub mod sudo { + use cosmwasm_std::Addr; + + use super::*; + + pub fn receive_ack( + deps: DepsMut, + contract: Addr, + _success: bool, + ) -> Result { + utils::update_counter( + deps, + contract, + &|counter| match counter { + None => 1, + Some(counter) => counter.count + 1, + }, + &|_counter| vec![], + )?; + Ok(Response::new().add_attribute("action", "ack")) + } + + pub(crate) fn ibc_timeout(deps: DepsMut, contract: Addr) -> Result { + utils::update_counter( + deps, + contract, + &|counter| match counter { + None => 10, + Some(counter) => counter.count + 10, + }, + &|_counter| vec![], + )?; + Ok(Response::new().add_attribute("action", "timeout")) + } +} + +pub fn naive_add_coins(lhs: &Vec, rhs: &Vec) -> Vec { + // This is a naive, inneficient implementation of Vec addition. + // This shouldn't be used in production but serves our purpose for this + // testing contract + let mut coins: HashMap = HashMap::new(); + for coin in lhs { + coins.insert(coin.denom.clone(), coin.amount); + } + + for coin in rhs { + coins + .entry(coin.denom.clone()) + .and_modify(|e| *e += coin.amount) + .or_insert(coin.amount); + } + coins.iter().map(|(d, &a)| Coin::new(a.into(), d)).collect() +} + +#[test] +fn coin_addition() { + let c1 = vec![Coin::new(1, "a"), Coin::new(2, "b")]; + let c2 = vec![Coin::new(7, "a"), Coin::new(2, "c")]; + + let mut sum = naive_add_coins(&c1, &c1); + sum.sort_by(|a, b| a.denom.cmp(&b.denom)); + assert_eq!(sum, vec![Coin::new(2, "a"), Coin::new(4, "b")]); + + let mut sum = naive_add_coins(&c1, &c2); + sum.sort_by(|a, b| a.denom.cmp(&b.denom)); + assert_eq!( + sum, + vec![Coin::new(8, "a"), Coin::new(2, "b"), Coin::new(2, "c"),] + ); + + let mut sum = naive_add_coins(&c2, &c2); + sum.sort_by(|a, b| a.denom.cmp(&b.denom)); + assert_eq!(sum, vec![Coin::new(14, "a"), Coin::new(4, "c"),]); + + let mut sum = naive_add_coins(&c2, &c1); + sum.sort_by(|a, b| a.denom.cmp(&b.denom)); + assert_eq!( + sum, + vec![Coin::new(8, "a"), Coin::new(2, "b"), Coin::new(2, "c"),] + ); + + let mut sum = naive_add_coins(&vec![], &c2); + sum.sort_by(|a, b| a.denom.cmp(&b.denom)); + assert_eq!(sum, c2); + + let mut sum = naive_add_coins(&c2, &vec![]); + sum.sort_by(|a, b| a.denom.cmp(&b.denom)); + assert_eq!(sum, c2); +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { + match msg { + QueryMsg::GetCount { addr } => to_binary(&query::count(deps, addr)?), + QueryMsg::GetTotalFunds { addr } => to_binary(&query::total_funds(deps, addr)?), + } +} + +pub mod query { + use cosmwasm_std::Addr; + + use super::*; + + pub fn count(deps: Deps, addr: Addr) -> StdResult { + let state = COUNTERS.load(deps.storage, addr)?; + Ok(GetCountResponse { count: state.count }) + } + + pub fn total_funds(deps: Deps, addr: Addr) -> StdResult { + let state = COUNTERS.load(deps.storage, addr)?; + Ok(GetTotalFundsResponse { + total_funds: state.total_funds, + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; + use cosmwasm_std::Addr; + use cosmwasm_std::{coins, from_binary}; + + #[test] + fn proper_initialization() { + let mut deps = mock_dependencies(); + + let msg = InstantiateMsg { count: 17 }; + let info = mock_info("creator", &coins(1000, "earth")); + + // we can just call .unwrap() to assert this was a success + let res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); + assert_eq!(0, res.messages.len()); + + // it worked, let's query the state + let res = query( + deps.as_ref(), + mock_env(), + QueryMsg::GetCount { + addr: Addr::unchecked("creator"), + }, + ) + .unwrap(); + let value: GetCountResponse = from_binary(&res).unwrap(); + assert_eq!(17, value.count); + } + + #[test] + fn increment() { + let mut deps = mock_dependencies(); + + let msg = InstantiateMsg { count: 17 }; + let info = mock_info("creator", &coins(2, "token")); + let _res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); + + let msg = InstantiateMsg { count: 17 }; + let info = mock_info("someone-else", &coins(2, "token")); + let _res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); + + let info = mock_info("creator", &coins(2, "token")); + let msg = ExecuteMsg::Increment {}; + let _res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + + // should increase counter by 1 + let res = query( + deps.as_ref(), + mock_env(), + QueryMsg::GetCount { + addr: Addr::unchecked("creator"), + }, + ) + .unwrap(); + let value: GetCountResponse = from_binary(&res).unwrap(); + assert_eq!(18, value.count); + + // Counter for someone else is not incremented + let res = query( + deps.as_ref(), + mock_env(), + QueryMsg::GetCount { + addr: Addr::unchecked("someone-else"), + }, + ) + .unwrap(); + let value: GetCountResponse = from_binary(&res).unwrap(); + assert_eq!(17, value.count); + } + + #[test] + fn reset() { + let mut deps = mock_dependencies(); + + let msg = InstantiateMsg { count: 17 }; + let info = mock_info("creator", &coins(2, "token")); + let _res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); + + // beneficiary can release it + let unauth_info = mock_info("anyone", &coins(2, "token")); + let msg = ExecuteMsg::Reset { count: 7 }; + let _res = execute(deps.as_mut(), mock_env(), unauth_info, msg); + + // should be 7 + let res = query( + deps.as_ref(), + mock_env(), + QueryMsg::GetCount { + addr: Addr::unchecked("anyone"), + }, + ) + .unwrap(); + let value: GetCountResponse = from_binary(&res).unwrap(); + assert_eq!(7, value.count); + + // only the original creator can reset the counter + let auth_info = mock_info("creator", &coins(2, "token")); + let msg = ExecuteMsg::Reset { count: 5 }; + let _res = execute(deps.as_mut(), mock_env(), auth_info, msg).unwrap(); + + // should now be 5 + let res = query( + deps.as_ref(), + mock_env(), + QueryMsg::GetCount { + addr: Addr::unchecked("creator"), + }, + ) + .unwrap(); + let value: GetCountResponse = from_binary(&res).unwrap(); + assert_eq!(5, value.count); + } + + #[test] + fn acks() { + let mut deps = mock_dependencies(); + let env = mock_env(); + let get_msg = QueryMsg::GetCount { + addr: Addr::unchecked(env.clone().contract.address), + }; + + // No acks + query(deps.as_ref(), env.clone(), get_msg.clone()).unwrap_err(); + + let msg = SudoMsg::ReceiveAck { + channel: format!("channel-0"), + sequence: 1, + ack: String::new(), + success: true, + }; + let _res = sudo(deps.as_mut(), env.clone(), msg).unwrap(); + + // should increase counter by 1 + let res = query(deps.as_ref(), env.clone(), get_msg.clone()).unwrap(); + let value: GetCountResponse = from_binary(&res).unwrap(); + assert_eq!(1, value.count); + + let msg = SudoMsg::ReceiveAck { + channel: format!("channel-0"), + sequence: 1, + ack: String::new(), + success: true, + }; + let _res = sudo(deps.as_mut(), env.clone(), msg).unwrap(); + + // should increase counter by 1 + let res = query(deps.as_ref(), env, get_msg).unwrap(); + let value: GetCountResponse = from_binary(&res).unwrap(); + assert_eq!(2, value.count); + } +} diff --git a/scripts/tests/ibc-hooks/counter/src/error.rs b/scripts/tests/ibc-hooks/counter/src/error.rs new file mode 100644 index 00000000..3caf0c5c --- /dev/null +++ b/scripts/tests/ibc-hooks/counter/src/error.rs @@ -0,0 +1,16 @@ +use cosmwasm_std::StdError; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum ContractError { + #[error("{0}")] + Std(#[from] StdError), + + #[error("Unauthorized")] + Unauthorized {}, + + #[error("Custom Error val: {val:?}")] + CustomError { val: String }, + // Add any other custom errors you like here. + // Look at https://docs.rs/thiserror/1.0.21/thiserror/ for details. +} diff --git a/scripts/tests/ibc-hooks/counter/src/helpers.rs b/scripts/tests/ibc-hooks/counter/src/helpers.rs new file mode 100644 index 00000000..c943c136 --- /dev/null +++ b/scripts/tests/ibc-hooks/counter/src/helpers.rs @@ -0,0 +1,48 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use cosmwasm_std::{ + to_binary, Addr, Coin, CosmosMsg, CustomQuery, Querier, QuerierWrapper, StdResult, WasmMsg, + WasmQuery, +}; + +use crate::msg::{ExecuteMsg, GetCountResponse, QueryMsg}; + +/// CwTemplateContract is a wrapper around Addr that provides a lot of helpers +/// for working with this. +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +pub struct CwTemplateContract(pub Addr); + +impl CwTemplateContract { + pub fn addr(&self) -> Addr { + self.0.clone() + } + + pub fn call>(&self, msg: T) -> StdResult { + let msg = to_binary(&msg.into())?; + Ok(WasmMsg::Execute { + contract_addr: self.addr().into(), + msg, + funds: vec![], + } + .into()) + } + + /// Get Count + pub fn count(&self, querier: &Q, addr: Addr) -> StdResult + where + Q: Querier, + T: Into, + CQ: CustomQuery, + { + let msg = QueryMsg::GetCount { addr }; + let query = WasmQuery::Smart { + contract_addr: self.addr().into(), + msg: to_binary(&msg)?, + } + .into(); + let res: GetCountResponse = QuerierWrapper::::new(querier).query(&query)?; + Ok(res) + } +} + diff --git a/scripts/tests/ibc-hooks/counter/src/integration_tests.rs b/scripts/tests/ibc-hooks/counter/src/integration_tests.rs new file mode 100644 index 00000000..4c507846 --- /dev/null +++ b/scripts/tests/ibc-hooks/counter/src/integration_tests.rs @@ -0,0 +1,71 @@ +#[cfg(test)] +mod tests { + use crate::helpers::CwTemplateContract; + use crate::msg::InstantiateMsg; + use cosmwasm_std::{Addr, Coin, Empty, Uint128}; + use cw_multi_test::{App, AppBuilder, Contract, ContractWrapper, Executor}; + + pub fn contract_template() -> Box> { + let contract = ContractWrapper::new( + crate::contract::execute, + crate::contract::instantiate, + crate::contract::query, + ); + Box::new(contract) + } + + const USER: &str = "USER"; + const ADMIN: &str = "ADMIN"; + const NATIVE_DENOM: &str = "denom"; + + fn mock_app() -> App { + AppBuilder::new().build(|router, _, storage| { + router + .bank + .init_balance( + storage, + &Addr::unchecked(USER), + vec![Coin { + denom: NATIVE_DENOM.to_string(), + amount: Uint128::new(1), + }], + ) + .unwrap(); + }) + } + + fn proper_instantiate() -> (App, CwTemplateContract) { + let mut app = mock_app(); + let cw_template_id = app.store_code(contract_template()); + + let msg = InstantiateMsg { count: 1i32 }; + let cw_template_contract_addr = app + .instantiate_contract( + cw_template_id, + Addr::unchecked(ADMIN), + &msg, + &[], + "test", + None, + ) + .unwrap(); + + let cw_template_contract = CwTemplateContract(cw_template_contract_addr); + + (app, cw_template_contract) + } + + mod count { + use super::*; + use crate::msg::ExecuteMsg; + + #[test] + fn count() { + let (mut app, cw_template_contract) = proper_instantiate(); + + let msg = ExecuteMsg::Increment {}; + let cosmos_msg = cw_template_contract.call(msg).unwrap(); + app.execute(Addr::unchecked(USER), cosmos_msg).unwrap(); + } + } +} diff --git a/scripts/tests/ibc-hooks/counter/src/lib.rs b/scripts/tests/ibc-hooks/counter/src/lib.rs new file mode 100644 index 00000000..ffd1f6ac --- /dev/null +++ b/scripts/tests/ibc-hooks/counter/src/lib.rs @@ -0,0 +1,9 @@ +#![allow(unused_imports)] +pub mod contract; +mod error; +pub mod helpers; +pub mod integration_tests; +pub mod msg; +pub mod state; + +pub use crate::error::ContractError; diff --git a/scripts/tests/ibc-hooks/counter/src/msg.rs b/scripts/tests/ibc-hooks/counter/src/msg.rs new file mode 100644 index 00000000..037d8c57 --- /dev/null +++ b/scripts/tests/ibc-hooks/counter/src/msg.rs @@ -0,0 +1,63 @@ +use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::{Addr, Coin}; + +#[cw_serde] +pub struct InstantiateMsg { + pub count: i32, +} + +#[cw_serde] +pub enum ExecuteMsg { + Increment {}, + Reset { count: i32 }, +} + +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + // GetCount returns the current count as a json-encoded number + #[returns(GetCountResponse)] + GetCount { addr: Addr }, + #[returns(GetTotalFundsResponse)] + GetTotalFunds { addr: Addr }, +} + +// We define a custom struct for each query response +#[cw_serde] +pub struct GetCountResponse { + pub count: i32, +} + +#[cw_serde] +pub struct GetTotalFundsResponse { + pub total_funds: Vec, +} + +#[cw_serde] +#[serde(rename = "ibc_lifecycle_complete")] +pub enum IBCLifecycleComplete { + #[serde(rename = "ibc_ack")] + IBCAck { + /// The source channel (terra side) of the IBC packet + channel: String, + /// The sequence number that the packet was sent with + sequence: u64, + /// String encoded version of the ack as seen by OnAcknowledgementPacket(..) + ack: String, + /// Weather an ack is a success of failure according to the transfer spec + success: bool, + }, + #[serde(rename = "ibc_timeout")] + IBCTimeout { + /// The source channel (terra side) of the IBC packet + channel: String, + /// The sequence number that the packet was sent with + sequence: u64, + }, +} + +#[cw_serde] +pub enum SudoMsg { + #[serde(rename = "ibc_lifecycle_complete")] + IBCLifecycleComplete(IBCLifecycleComplete), +} diff --git a/scripts/tests/ibc-hooks/counter/src/state.rs b/scripts/tests/ibc-hooks/counter/src/state.rs new file mode 100644 index 00000000..4b8002fc --- /dev/null +++ b/scripts/tests/ibc-hooks/counter/src/state.rs @@ -0,0 +1,14 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use cosmwasm_std::{Addr, Coin}; +use cw_storage_plus::{Item, Map}; + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +pub struct Counter { + pub count: i32, + pub total_funds: Vec, + pub owner: Addr, +} + +pub const COUNTERS: Map = Map::new("state"); diff --git a/scripts/tests/ibc-hooks/increment.sh b/scripts/tests/ibc-hooks/increment.sh new file mode 100755 index 00000000..4ae1cad9 --- /dev/null +++ b/scripts/tests/ibc-hooks/increment.sh @@ -0,0 +1,96 @@ +#!/bin/bash + +echo "" +echo "#################" +echo "# IBC Hook call #" +echo "#################" +echo "" + +BINARY=migalood +CHAIN_DIR=$(pwd)/data +WALLET_1=$($BINARY keys show wallet1 -a --keyring-backend test --home $CHAIN_DIR/test-1) +WALLET_2=$($BINARY keys show wallet2 -a --keyring-backend test --home $CHAIN_DIR/test-2) +DENOM=uwhale + +# Deploy the smart contract on chain to test the callbacks. (find the source code under the following url: `~/scripts/tests/ibc-hooks/counter/src/contract.rs`) +echo "Deploying counter contract" +TX_HASH=$($BINARY tx wasm store $(pwd)/scripts/tests/ibc-hooks/counter/artifacts/counter.wasm --from $WALLET_2 --chain-id test-2 --home $CHAIN_DIR/test-2 --node tcp://localhost:26657 --keyring-backend test -y --gas 10000000 --fees 6000000$DENOM -o json | jq -r '.txhash') +sleep 3 +CODE_ID=$($BINARY query tx $TX_HASH -o josn --chain-id test-2 --home $CHAIN_DIR/test-2 --node tcp://localhost:26657 | jq -r '.logs[0].events[1].attributes[1].value') + + +# Use Instantiate2 to instantiate the previous smart contract with a random hash to enable multiple instances of the same contract (when needed). +echo "Instantiating counter contract" +RANDOM_HASH=$(hexdump -vn16 -e'4/4 "%08X" 1 "\n"' /dev/urandom) +TX_HASH=$($BINARY tx wasm instantiate2 $CODE_ID '{"count": 0}' $RANDOM_HASH --no-admin --label="Label with $RANDOM_HASH" --from $WALLET_2 --chain-id test-2 --home $CHAIN_DIR/test-2 --node tcp://localhost:26657 --keyring-backend test -y --gas 10000000 --fees 6000000$DENOM -o json | jq -r '.txhash') + +echo "TX hash: $TX_HASH" +sleep 3 +CONTRACT_ADDRESS=$($BINARY query tx $TX_HASH -o josn --chain-id test-2 --home $CHAIN_DIR/test-2 --node tcp://localhost:26657 | jq -r '.logs[0].events[1].attributes[0].value') +echo "Contract address: $CONTRACT_ADDRESS" + +echo "Executing the IBC Hook to increment the counter" +# First execute an IBC transfer to create the entry in the smart contract with the sender address ... +IBC_HOOK_RES=$($BINARY tx ibc-transfer transfer transfer channel-0 $CONTRACT_ADDRESS 1uwhale --memo='{"wasm":{"contract": "'"$CONTRACT_ADDRESS"'" ,"msg": {"increment": {}}}}' --chain-id test-1 --home $CHAIN_DIR/test-1 --node tcp://localhost:16657 --keyring-backend test --from $WALLET_1 --fees 6000000$DENOM -y -o json) +echo "IBC Hook response: $IBC_HOOK_RES" +sleep 3 +# ... then send another transfer to increments the count value from 0 to 1, send 1 more uwhale to the contract address to validate that it increased the value correctly. +IBC_HOOK_RES=$($BINARY tx ibc-transfer transfer transfer channel-0 $CONTRACT_ADDRESS 1uwhale --memo='{"wasm":{"contract": "'"$CONTRACT_ADDRESS"'" ,"msg": {"increment": {}}}}' --chain-id test-1 --home $CHAIN_DIR/test-1 --fees 6000000$DENOM --node tcp://localhost:16657 --keyring-backend test --from $WALLET_1 -y -o json) +export WALLET_1_WASM_SENDER=$($BINARY q ibchooks wasm-sender channel-0 "$WALLET_1" --chain-id test-1 --home $CHAIN_DIR/test-1 --node tcp://localhost:16657) + +IBC_RECEIVER_BALANCE=$($BINARY query bank balances $WALLET_1 --chain-id test-1 --home $CHAIN_DIR/test-1 --node tcp://localhost:16657 -o json) +echo "IBC Receiver balance: $IBC_RECEIVER_BALANCE" + +echo "wallet 1 wasm sender: $WALLET_1_WASM_SENDER" + +COUNT_RES="" +COUNT_FUNDS_RES="" +while [ "$COUNT_RES" != "1" ] || [ "$COUNT_FUNDS_RES" != "2" ]; do + sleep 3 + # Get count res + RES=$($BINARY query wasm contract-state smart "$CONTRACT_ADDRESS" '{"get_count": {"addr": "'"$WALLET_1_WASM_SENDER"'"}}' --chain-id test-2 --home $CHAIN_DIR/test-2 --node tcp://localhost:26657 -o json) + echo "Query response: $RES" + + # Query to assert that the counter value is 1 and the fund send are 2uwhale (remeber that the first time fund are send to the contract the counter is set to 0 instead of 1) + COUNT_RES=$($BINARY query wasm contract-state smart "$CONTRACT_ADDRESS" '{"get_count": {"addr": "'"$WALLET_1_WASM_SENDER"'"}}' --chain-id test-2 --home $CHAIN_DIR/test-2 --node tcp://localhost:26657 -o json | jq -r '.data.count') + COUNT_FUNDS_RES=$($BINARY query wasm contract-state smart "$CONTRACT_ADDRESS" '{"get_total_funds": {"addr": "'"$WALLET_1_WASM_SENDER"'"}}' --chain-id test-2 --home $CHAIN_DIR/test-2 --node tcp://localhost:26657 -o json | jq -r '.data.total_funds[0].amount') + echo "transaction relayed count: $COUNT_RES and relayed funds: $COUNT_FUNDS_RES" +done + +echo "Executing the IBC Hook to increment the counter on callback" +# Execute an IBC transfer with ibc_callback to test the callback acknowledgement twice. +IBC_HOOK_RES=$($BINARY tx ibc-transfer transfer transfer channel-0 $WALLET_1_WASM_SENDER 1$DENOM --memo='{"ibc_callback":"'"$CONTRACT_ADDRESS"'"}' --chain-id test-2 --home $CHAIN_DIR/test-2 --fees 6000000$DENOM --node tcp://localhost:26657 --keyring-backend test --from $WALLET_2 -y -o json) + + +sleep 3 +IBC_HOOK_RES=$($BINARY tx ibc-transfer transfer transfer channel-0 $WALLET_1_WASM_SENDER 1$DENOM --memo='{"ibc_callback":"'"$CONTRACT_ADDRESS"'"}' --chain-id test-2 --home $CHAIN_DIR/test-2 --fees 6000000$DENOM --node tcp://localhost:26657 --keyring-backend test --from $WALLET_2 -y -o json) +export WALLET_2_WASM_SENDER=$($BINARY q ibchooks wasm-sender channel-0 "$WALLET_2" --chain-id test-2 --home $CHAIN_DIR/test-2 --node tcp://localhost:26657) + +COUNT_RES="" +while [ "$COUNT_RES" != "2" ]; do + sleep 3 + # Query the smart contract to validate that it received the callback twice (notice that the queried addess is the contract address itself). + COUNT_RES=$($BINARY query wasm contract-state smart "$CONTRACT_ADDRESS" '{"get_count": {"addr": "'"$CONTRACT_ADDRESS"'"}}' --chain-id test-2 --home $CHAIN_DIR/test-2 --node tcp://localhost:26657 -o json | jq -r '.data.count') + echo "relayed callback transaction count: $COUNT_RES" +done + +echo "Executing the IBC Hook to increment the counter on callback with timeout" +# Prepare two callback queries but this time with a timeout height that is unreachable (0-1) to test the timeout callback. +IBC_HOOK_RES=$($BINARY tx ibc-transfer transfer transfer channel-0 $WALLET_1_WASM_SENDER 1$DENOM --packet-timeout-height="0-1" --memo='{"ibc_callback":"'"$CONTRACT_ADDRESS"'"}' --chain-id test-2 --home $CHAIN_DIR/test-2 --fees 6000000$DENOM --node tcp://localhost:26657 --keyring-backend test --from $WALLET_2 -y -o json) +sleep 3 +IBC_HOOK_RES=$($BINARY tx ibc-transfer transfer transfer channel-0 $WALLET_1_WASM_SENDER 1$DENOM --packet-timeout-height="0-1" --memo='{"ibc_callback":"'"$CONTRACT_ADDRESS"'"}' --chain-id test-2 --home $CHAIN_DIR/test-2 --fees 6000000$DENOM --node tcp://localhost:26657 --keyring-backend test --from $WALLET_2 -y -o json) +export WALLET_2_WASM_SENDER=$($BINARY q ibchooks wasm-sender channel-0 "$WALLET_2" --chain-id test-2 --home $CHAIN_DIR/test-2 --node tcp://localhost:26657) + +COUNT_RES="" +while [ "$COUNT_RES" != "22" ]; do + sleep 3 + # Query the smart contract to validate that it received the timeout callback twice and keep in mind that per each timeout the contract increases 10 counts (notice that the queried addess is the contract address itself). + COUNT_RES=$($BINARY query wasm contract-state smart "$CONTRACT_ADDRESS" '{"get_count": {"addr": "'"$CONTRACT_ADDRESS"'"}}' --chain-id test-2 --home $CHAIN_DIR/test-2 --node tcp://localhost:26657 -o json | jq -r '.data.count') + echo "relayed timeout callback transaction count: $COUNT_RES" +done + +echo "" +echo "##########################" +echo "# SUCCESS: IBC Hook call #" +echo "##########################" +echo "" diff --git a/scripts/tests/ica/delegate.sh b/scripts/tests/ica/delegate.sh new file mode 100755 index 00000000..77230be9 --- /dev/null +++ b/scripts/tests/ica/delegate.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +echo "" +echo "###########################################" +echo "# ICA Cross Chain Delegation to Validator #" +echo "###########################################" +echo "" + +export BINARY=migalood +export CHAIN_DIR=$(pwd)/data +export DENOM=uwhale + +export WALLET_1=$($BINARY keys show wallet1 -a --keyring-backend test --home $CHAIN_DIR/test-1) +export WALLET_2=$($BINARY keys show wallet2 -a --keyring-backend test --home $CHAIN_DIR/test-2) + +echo "Registering ICA on chain test-1" +ICA_REGISTER_RESPONSE=$($BINARY tx interchain-accounts controller register connection-0 --from $WALLET_1 --chain-id test-1 --home $CHAIN_DIR/test-1 --node tcp://localhost:16657 --keyring-backend test --fees 3000000$DENOM -y --gas 10000000) + + +ICS_TX_RESULT="Error:" +ICS_TX_ERROR="Error:" +while [[ "$ICS_TX_ERROR" == "$ICS_TX_RESULT"* ]]; do + echo "Waiting for the transaction to be relayed..." + sleep 5 + ICS_TX_RESULT=$($BINARY query interchain-accounts controller interchain-account $WALLET_1 connection-0 --node tcp://localhost:16657 -o json | jq -r '.address') +done + +echo "Sending tokens to ICA on chain test-2" +$BINARY tx bank send $WALLET_2 $ICS_TX_RESULT 10000000$DENOM --chain-id test-2 --home $CHAIN_DIR/test-2 --fees 3000000$DENOM --node tcp://localhost:26657 --keyring-backend test -y &> /dev/null +sleep 5 +ICS_ACCOUNT_BALANCE=$($BINARY query bank balances $ICS_TX_RESULT --chain-id test-2 --node tcp://localhost:26657 -o json | jq -r '.balances[0].amount') + +if [[ "$ICS_ACCOUNT_BALANCE" != "10000000" ]]; then + echo "Error: ICA Have not received tokens" + exit 1 +fi + +echo "Executing Delegation from test-1 to test-2 via ICA" +VAL_ADDR_1=$(cat $CHAIN_DIR/test-2/config/genesis.json | jq -r '.app_state.genutil.gen_txs[0].body.messages[0].validator_address') + +GENERATED_PACKET=$($BINARY tx interchain-accounts host generate-packet-data '{ + "@type":"/cosmos.staking.v1beta1.MsgDelegate", + "delegator_address": "'"$ICS_TX_RESULT"'", + "validator_address": "'"$VAL_ADDR_1"'", + "amount": { + "denom": "'"$DENOM"'", + "amount": "'"$ICS_ACCOUNT_BALANCE"'" + } +}') + + +SEND_TX_RESULT=$($BINARY tx interchain-accounts controller send-tx connection-0 $GENERATED_PACKET --from $WALLET_1 --chain-id test-1 --home $CHAIN_DIR/test-1 --fees 3000000$DENOM --node tcp://localhost:16657 --keyring-backend test -y) + +PRE_VALIDATOR_DELEGATIONS="" +while [[ "$VALIDATOR_DELEGATIONS" != "$ICS_ACCOUNT_BALANCE" ]]; do + sleep 2 + echo "Waiting for the transaction '/cosmos.bank.v1beta1.MsgDelegate' to be relayed..." + VALIDATOR_DELEGATIONS=$($BINARY query staking delegations-to $VAL_ADDR_1 --home $CHAIN_DIR/test-2 --node tcp://localhost:26657 -o json | jq -r '.delegation_responses[-1].balance.amount') + + # log the validator delegations, and ics account balance + echo "Validator Delegations: $VALIDATOR_DELEGATIONS" + echo "ICS Account Balance: $ICS_ACCOUNT_BALANCE" +done + +echo "" +echo "####################################################" +echo "# SUCCESS: ICA Cross Chain Delegation to Validator #" +echo "####################################################" +echo "" diff --git a/scripts/tests/init-test-framework.sh b/scripts/tests/init-test-framework.sh index f1261723..9a153e2c 100755 --- a/scripts/tests/init-test-framework.sh +++ b/scripts/tests/init-test-framework.sh @@ -121,7 +121,7 @@ sed -i -e 's#":8080"#":'"$ROSETTA_2"'"#g' $CHAIN_DIR/$CHAINID_2/config/app.toml sed -i -e 's/enabled-unsafe-cors = false/enabled-unsafe-cors = true/g' $CHAIN_DIR/$CHAINID_2/config/app.toml -echo "Chaning genesis.json..." +echo "Changing genesis.json..." sed -i -e 's/"voting_period": "172800s"/"voting_period": "10s"/g' $CHAIN_DIR/$CHAINID_1/config/genesis.json sed -i -e 's/"voting_period": "172800s"/"voting_period": "10s"/g' $CHAIN_DIR/$CHAINID_2/config/genesis.json sed -i -e 's/"reward_delay_time": "604800s"/"reward_delay_time": "0s"/g' $CHAIN_DIR/$CHAINID_1/config/genesis.json @@ -134,10 +134,11 @@ update_test_genesis () { jq "$1" $GENESIS_2 > $TMP_GENESIS_2 && mv $TMP_GENESIS_2 $GENESIS_2 } +echo "update test genesis" update_test_genesis ".app_state[\"staking\"][\"params\"][\"bond_denom\"]=\"$DENOM\"" update_test_genesis ".app_state[\"mint\"][\"params\"][\"mint_denom\"]=\"$DENOM\"" update_test_genesis ".app_state[\"crisis\"][\"constant_fee\"][\"denom\"]=\"$DENOM\"" -update_test_genesis ".app_state[\"gov\"][\"deposit_params\"][\"min_deposit\"][0][\"denom\"]=\"$DENOM\"" +update_test_genesis ".app_state[\"gov\"][\"params\"][\"min_deposit\"][0][\"denom\"]=\"$DENOM\"" update_test_genesis ".app_state[\"tokenfactory\"][\"params\"][\"denom_creation_fee\"][0][\"denom\"]=\"$DENOM\"" diff --git a/scripts/tests/tokenfactory/tokenfactory.sh b/scripts/tests/tokenfactory/tokenfactory.sh index 9e2dc6b8..2d30a3dc 100755 --- a/scripts/tests/tokenfactory/tokenfactory.sh +++ b/scripts/tests/tokenfactory/tokenfactory.sh @@ -21,7 +21,7 @@ WALLET_3=$($BINARY keys show wallet3 -a --keyring-backend test --home $CHAIN_DIR echo "Creating token denom $TOKEN_DENOM with $WALLET_1 on chain test-1" TX_HASH=$($BINARY tx tokenfactory create-denom $TOKEN_DENOM --from $WALLET_1 --home $CHAIN_DIR/test-1 --chain-id test-1 --node tcp://localhost:16657 --gas "$GAS" --fees "$FEES" --keyring-backend test -o json -y | jq -r '.txhash') sleep 3 -CREATED_RES_DENOM=$($BINARY query tx $TX_HASH -o josn --chain-id test-1 --home $CHAIN_DIR/test-1 --node tcp://localhost:16657 | jq -r '.logs[0].events[5].attributes[1].value') +CREATED_RES_DENOM=$($BINARY query tx $TX_HASH -o json --chain-id test-1 --home $CHAIN_DIR/test-1 --node tcp://localhost:16657 | jq -r '.logs[0].events[5].attributes[1].value') if [ "$CREATED_RES_DENOM" != "factory/$WALLET_1/$TOKEN_DENOM" ]; then echo "ERROR: Tokenfactory creating denom error. Expected result 'factory/$WALLET_1/$TOKEN_DENOM', got '$CREATED_RES_DENOM'" @@ -31,14 +31,14 @@ fi echo "Minting $MINT_AMOUNT units of $TOKEN_DENOM with $WALLET_1 on chain test-1" TX_HASH=$($BINARY tx tokenfactory mint $MINT_AMOUNT$CREATED_RES_DENOM --from $WALLET_1 --home $CHAIN_DIR/test-1 --chain-id test-1 --node tcp://localhost:16657 --gas "$GAS" --fees "$FEES" --keyring-backend test -o json -y | jq -r '.txhash') sleep 3 -MINT_RES=$($BINARY query tx $TX_HASH -o josn --chain-id test-1 --home $CHAIN_DIR/test-1 --node tcp://localhost:16657 | jq -r '.logs[0].events[2].type') +MINT_RES=$($BINARY query tx $TX_HASH -o json --chain-id test-1 --home $CHAIN_DIR/test-1 --node tcp://localhost:16657 | jq -r '.logs[0].events[2].type') if [ "$MINT_RES" != "coinbase" ]; then echo "ERROR: Tokenfactory minting error. Expected result 'coinbase', got '$CREATED_RES_DENOM'" exit 1 fi echo "Querying $TOKEN_DENOM from $WALLET_1 on chain test-1 to validate the amount minted" -BALANCE_RES_AMOUNT=$($BINARY query bank balances $WALLET_1 --denom $CREATED_RES_DENOM --chain-id test-2 --node tcp://localhost:16657 -o json | jq -r '.amount') +BALANCE_RES_AMOUNT=$($BINARY query bank balances $WALLET_1 --denom $CREATED_RES_DENOM --chain-id test-1 --node tcp://localhost:16657 -o json | jq -r '.amount') if [ "$BALANCE_RES_AMOUNT" != $MINT_AMOUNT ]; then echo "ERROR: Tokenfactory minting error. Expected minted balance '$MINT_AMOUNT', got '$BALANCE_RES_AMOUNT'" exit 1 @@ -47,14 +47,14 @@ fi echo "Burning 1 $TOKEN_DENOM from $WALLET_1 on chain test-1" TX_HASH=$($BINARY tx tokenfactory burn 1$CREATED_RES_DENOM --from $WALLET_1 --home $CHAIN_DIR/test-1 --chain-id test-1 --node tcp://localhost:16657 --gas "$GAS" --fees "$FEES" --keyring-backend test -o json -y | jq -r '.txhash') sleep 3 -BURN_RES=$($BINARY query tx $TX_HASH -o josn --chain-id test-1 --home $CHAIN_DIR/test-1 --node tcp://localhost:16657 | jq -r '.logs[0].events[7].type') +BURN_RES=$($BINARY query tx $TX_HASH -o json --chain-id test-1 --home $CHAIN_DIR/test-1 --node tcp://localhost:16657 | jq -r '.logs[0].events[7].type') if [ "$BURN_RES" != "tf_burn" ]; then echo "ERROR: Tokenfactory burning error. Expected result 'tf_burn', got '$BURN_RES'" exit 1 fi echo "Querying $TOKEN_DENOM from $WALLET_1 on chain test-1 to validate the burned amount" -BALANCES_AFTER_BURNING=$($BINARY query bank balances $WALLET_1 --denom $CREATED_RES_DENOM --chain-id test-2 --node tcp://localhost:16657 -o json | jq -r '.amount') +BALANCES_AFTER_BURNING=$($BINARY query bank balances $WALLET_1 --denom $CREATED_RES_DENOM --chain-id test-1 --node tcp://localhost:16657 -o json | jq -r '.amount') if [ "$BALANCES_AFTER_BURNING" != 999999 ]; then echo "ERROR: Tokenfactory minting error. Expected minted balance '999999', got '$BALANCES_AFTER_BURNING'" exit 1 @@ -63,14 +63,14 @@ fi echo "Sending 1 $TOKEN_DENOM from $WALLET_1 to $WALLET_3 on chain test-1" TX_HASH=$($BINARY tx bank send $WALLET_1 $WALLET_3 1$CREATED_RES_DENOM --from $WALLET_1 --home $CHAIN_DIR/test-1 --chain-id test-1 --node tcp://localhost:16657 --gas "$GAS" --fees "$FEES" --keyring-backend test -o json -y | jq -r '.txhash') sleep 3 -SEND_RES_MSG_TYPE=$($BINARY query tx $TX_HASH -o josn --chain-id test-1 --home $CHAIN_DIR/test-1 --node tcp://localhost:16657 | jq -r '.logs[0].events[0].attributes[0].value') +SEND_RES_MSG_TYPE=$($BINARY query tx $TX_HASH -o json --chain-id test-1 --home $CHAIN_DIR/test-1 --node tcp://localhost:16657 | jq -r '.logs[0].events[0].attributes[0].value') if [ "$SEND_RES_MSG_TYPE" != "/cosmos.bank.v1beta1.MsgSend" ]; then echo "ERROR: Sending expected to be '/cosmos.bank.v1beta1.MsgSend' but got '$SEND_RES_MSG_TYPE'" exit 1 fi echo "Querying $TOKEN_DENOM from $WALLET_3 on chain test-1 to validate the funds were received" -BALANCES_RECEIVED=$($BINARY query bank balances $WALLET_3 --denom $CREATED_RES_DENOM --chain-id test-2 --node tcp://localhost:16657 -o json | jq -r '.amount') +BALANCES_RECEIVED=$($BINARY query bank balances $WALLET_3 --denom $CREATED_RES_DENOM --chain-id test-1 --node tcp://localhost:16657 -o json | jq -r '.amount') if [ "$BALANCES_RECEIVED" != 1 ]; then echo "ERROR: Tokenfactory minting error. Expected minted balance '1', got '$BALANCES_RECEIVED'" exit 1 @@ -80,7 +80,7 @@ fi echo "IBC'ing 1 $TOKEN_DENOM from $WALLET_1 chain test-1 to $WALLET_2 chain test-2" TX_HASH=$($BINARY tx ibc-transfer transfer transfer channel-0 $WALLET_2 1$CREATED_RES_DENOM --chain-id test-1 --home $CHAIN_DIR/test-1 --node tcp://localhost:16657 --keyring-backend test --gas "$GAS" --fees "$FEES" --from $WALLET_1 -y -o json | jq -r '.txhash') sleep 3 -IBC_SEND_RES=$($BINARY query tx $TX_HASH -o josn --chain-id test-1 --home $CHAIN_DIR/test-1 --node tcp://localhost:16657 | jq -r '.logs[0].events[0].attributes[0].value') +IBC_SEND_RES=$($BINARY query tx $TX_HASH -o json --chain-id test-1 --home $CHAIN_DIR/test-1 --node tcp://localhost:16657 | jq -r '.logs[0].events[0].attributes[0].value') if [ "$IBC_SEND_RES" != "/ibc.applications.transfer.v1.MsgTransfer" ]; then echo "ERROR: IBC'ing expected type '/ibc.applications.transfer.v1.MsgTransfer' but got '$IBC_SEND_RES'" exit 1 @@ -92,6 +92,7 @@ while [ "$IBC_RECEIVED_RES_AMOUNT" != "1" ] || [ "${IBC_RECEIVED_RES_DENOM:0:4}" sleep 2 IBC_RECEIVED_RES_AMOUNT=$($BINARY query bank balances $WALLET_2 --chain-id test-2 --node tcp://localhost:26657 -o json | jq -r '.balances[0].amount') IBC_RECEIVED_RES_DENOM=$($BINARY query bank balances $WALLET_2 --chain-id test-2 --node tcp://localhost:26657 -o json | jq -r '.balances[0].denom') + echo "Received:" $IBC_RECEIVED_RES_AMOUNT $IBC_RECEIVED_RES_DENOM done