From 8f36b22c94610a86afcdd8cb87fd3a6028411602 Mon Sep 17 00:00:00 2001 From: emidev98 Date: Wed, 15 Nov 2023 12:22:20 +0200 Subject: [PATCH 1/4] reafact: ibchooks init --- Makefile | 4 - integration-tests/jest.config.js | 1 + integration-tests/package.json | 2 +- .../src/contracts}/counter.wasm | Bin integration-tests/src/helpers/const.ts | 5 +- integration-tests/src/helpers/index.ts | 2 + integration-tests/src/helpers/mnemonics.ts | 6 +- .../src/modules/ibc-hooks/ibc-hooks.test.ts | 110 +++++ .../modules/tokenfactory/tokenfactory.test.ts | 2 +- scripts/tests/ibc-hooks/counter/Cargo.toml | 43 -- scripts/tests/ibc-hooks/counter/README.md | 11 - .../ibc-hooks/counter/artifacts/checksums.txt | 1 - .../artifacts/checksums_intermediate.txt | 1 - .../tests/ibc-hooks/counter/src/contract.rs | 395 ------------------ scripts/tests/ibc-hooks/counter/src/error.rs | 16 - .../tests/ibc-hooks/counter/src/helpers.rs | 48 --- .../counter/src/integration_tests.rs | 71 ---- scripts/tests/ibc-hooks/counter/src/lib.rs | 9 - scripts/tests/ibc-hooks/counter/src/msg.rs | 63 --- scripts/tests/ibc-hooks/counter/src/state.rs | 14 - scripts/tests/ibc-hooks/increment.sh | 80 ---- scripts/tests/init-test-framework.sh | 7 +- x/wasmd/types/executed_contracts.pb.go | 324 -------------- 23 files changed, 130 insertions(+), 1085 deletions(-) rename {scripts/tests/ibc-hooks/counter/artifacts => integration-tests/src/contracts}/counter.wasm (100%) create mode 100644 integration-tests/src/modules/ibc-hooks/ibc-hooks.test.ts delete mode 100644 scripts/tests/ibc-hooks/counter/Cargo.toml delete mode 100644 scripts/tests/ibc-hooks/counter/README.md delete mode 100644 scripts/tests/ibc-hooks/counter/artifacts/checksums.txt delete mode 100644 scripts/tests/ibc-hooks/counter/artifacts/checksums_intermediate.txt delete mode 100644 scripts/tests/ibc-hooks/counter/src/contract.rs delete mode 100644 scripts/tests/ibc-hooks/counter/src/error.rs delete mode 100644 scripts/tests/ibc-hooks/counter/src/helpers.rs delete mode 100644 scripts/tests/ibc-hooks/counter/src/integration_tests.rs delete mode 100644 scripts/tests/ibc-hooks/counter/src/lib.rs delete mode 100644 scripts/tests/ibc-hooks/counter/src/msg.rs delete mode 100644 scripts/tests/ibc-hooks/counter/src/state.rs delete mode 100755 scripts/tests/ibc-hooks/increment.sh delete mode 100644 x/wasmd/types/executed_contracts.pb.go diff --git a/Makefile b/Makefile index 85d7ce84..dbc0e6b7 100644 --- a/Makefile +++ b/Makefile @@ -211,10 +211,6 @@ init-test-framework: clean-testing-data install @echo "Testing relayer..." ./scripts/tests/relayer/interchain-acc-config/rly-init.sh -test-ibc-hooks: - @echo "Testing ibc hooks..." - ./scripts/tests/ibc-hooks/increment.sh - test-tokenfactory: @echo "Testing tokenfactory..." ./scripts/tests/tokenfactory/tokenfactory.sh diff --git a/integration-tests/jest.config.js b/integration-tests/jest.config.js index 55a51a90..77330a61 100644 --- a/integration-tests/jest.config.js +++ b/integration-tests/jest.config.js @@ -5,4 +5,5 @@ module.exports = { testMatch: ['**/*.test.ts'], verbose: true, testTimeout: 30000, + maxConcurrency: 4, }; \ No newline at end of file diff --git a/integration-tests/package.json b/integration-tests/package.json index c0085c73..38aed0aa 100644 --- a/integration-tests/package.json +++ b/integration-tests/package.json @@ -4,7 +4,7 @@ "description": "Integration tests for Core using feather.js", "main": "index.ts", "scripts": { - "test": "jest --maxConcurrency=4" + "test": "jest" }, "repository": { "type": "git", diff --git a/scripts/tests/ibc-hooks/counter/artifacts/counter.wasm b/integration-tests/src/contracts/counter.wasm similarity index 100% rename from scripts/tests/ibc-hooks/counter/artifacts/counter.wasm rename to integration-tests/src/contracts/counter.wasm diff --git a/integration-tests/src/helpers/const.ts b/integration-tests/src/helpers/const.ts index ff9446fa..d023245c 100644 --- a/integration-tests/src/helpers/const.ts +++ b/integration-tests/src/helpers/const.ts @@ -1,4 +1,7 @@ export const SAFE_VOTING_PERIOD_TIME = 4100; +export const SAFE_IBC_TRANSFER = 4100; export const SAFE_BLOCK_INCLUSION_TIME = 1100; + export const blockInclusion = () => new Promise((resolve) => setTimeout(() => resolve(SAFE_BLOCK_INCLUSION_TIME), SAFE_BLOCK_INCLUSION_TIME)); -export const votingPeriod = () => new Promise((resolve) => setTimeout(() => resolve(SAFE_VOTING_PERIOD_TIME), SAFE_VOTING_PERIOD_TIME)); +export const ibcTransfer = () => new Promise((resolve) => setTimeout(() => resolve(SAFE_IBC_TRANSFER), SAFE_IBC_TRANSFER)); +export const votingPeriod = () => new Promise((resolve) => setTimeout(() => resolve(SAFE_VOTING_PERIOD_TIME), SAFE_VOTING_PERIOD_TIME)); \ No newline at end of file diff --git a/integration-tests/src/helpers/index.ts b/integration-tests/src/helpers/index.ts index 5df186bc..1a0f7f12 100644 --- a/integration-tests/src/helpers/index.ts +++ b/integration-tests/src/helpers/index.ts @@ -3,6 +3,7 @@ import { SAFE_VOTING_PERIOD_TIME, blockInclusion, votingPeriod, + ibcTransfer, } from "./const" import { getMnemonics } from "./mnemonics" import { getLCDClient } from "./lcd.connection" @@ -12,6 +13,7 @@ export { SAFE_VOTING_PERIOD_TIME, blockInclusion, votingPeriod, + ibcTransfer, getMnemonics, getLCDClient } \ No newline at end of file diff --git a/integration-tests/src/helpers/mnemonics.ts b/integration-tests/src/helpers/mnemonics.ts index b352f382..6d8c82a9 100644 --- a/integration-tests/src/helpers/mnemonics.ts +++ b/integration-tests/src/helpers/mnemonics.ts @@ -42,6 +42,9 @@ export function getMnemonics() { let tokenFactoryMnemonic = new MnemonicKey({ mnemonic: "year aim panel oyster sunny faint dress skin describe chair guilt possible venue pottery inflict mass debate poverty multiply pulse ability purse situate inmate" }) + let ibcHooksMnemonic = new MnemonicKey({ + mnemonic: "leave side blue panel curve ancient suspect slide seminar neutral doctor boring only curious spell surround remind obtain slogan hire giant soccer crunch system" + }) return { val1, @@ -55,6 +58,7 @@ export function getMnemonics() { genesisVesting, genesisVesting1, icaMnemonic, - tokenFactoryMnemonic + tokenFactoryMnemonic, + ibcHooksMnemonic } } \ No newline at end of file diff --git a/integration-tests/src/modules/ibc-hooks/ibc-hooks.test.ts b/integration-tests/src/modules/ibc-hooks/ibc-hooks.test.ts new file mode 100644 index 00000000..3f0bbfb5 --- /dev/null +++ b/integration-tests/src/modules/ibc-hooks/ibc-hooks.test.ts @@ -0,0 +1,110 @@ +import { Coin, Coins, MsgInstantiateContract, MsgStoreCode, MsgTransfer } from "@terra-money/feather.js"; +import { ibcTransfer, getMnemonics, getLCDClient, blockInclusion } from "../../helpers"; +import fs from "fs"; +import path from 'path'; +import moment from "moment"; + +describe("IbcHooks Module (github.com/cosmos/ibc-apps/modules/ibc-hooks/v7) ", () => { + // Prepare the LCD and wallets. chain1Wallet is the one that will + // deploy the contract on chain 1 and chain2Wallet will be used + // to send IBC messages from chain 2 to interact with the contract. + const LCD = getLCDClient(); + const accounts = getMnemonics(); + const chain1Wallet = LCD.chain1.wallet(accounts.ibcHooksMnemonic); + const chain2Wallet = LCD.chain2.wallet(accounts.ibcHooksMnemonic); + const walletAddress = accounts.ibcHooksMnemonic.accAddress("terra"); + let contractAddress: string; + + // Read the counter contract, store on chain, + // instantiate to be used in the following tests + // and finally save the contract address. + beforeAll(async () => { + let tx = await chain1Wallet.createAndSignTx({ + msgs: [new MsgStoreCode( + walletAddress, + fs.readFileSync(path.join(__dirname, "/../../contracts/counter.wasm")).toString("base64"), + )], + chainID: "test-1", + }); + + let result = await LCD.chain1.tx.broadcastSync(tx, "test-1"); + await blockInclusion(); + let txResult = await LCD.chain1.tx.txInfo(result.txhash, "test-1") as any; + let codeId = Number(txResult.logs[0].events[1].attributes[1].value); + expect(codeId).toBeDefined(); + + const msgInstantiateContract = new MsgInstantiateContract( + walletAddress, + walletAddress, + codeId, + { count: 0 }, + Coins.fromString("1uluna"), + "counter contract " + Math.random(), + ); + + tx = await chain1Wallet.createAndSignTx({ + msgs: [msgInstantiateContract], + chainID: "test-1", + }); + result = await LCD.chain1.tx.broadcastSync(tx, "test-1"); + await blockInclusion(); + txResult = await LCD.chain1.tx.txInfo(result.txhash, "test-1") as any; + contractAddress = txResult.logs[0].events[4].attributes[0].value; + expect(contractAddress).toBeDefined(); + }) + + describe("Must send IBC messages from chain 2 to chain 1", () => { + test('must incrementing the counter', async () => { + try { + const resw = await LCD.chain1.wasm.contractQuery( + contractAddress, + { + "get_count": { + "addr": walletAddress + } + } + ); + console.log(JSON.stringify(resw)); + let tx = await chain2Wallet.createAndSignTx({ + msgs: [ + new MsgTransfer( + "transfer", + "channel-0", + Coin.fromString("10000000uluna"), + walletAddress, + contractAddress, + undefined, + moment.utc().add(1.5, "day").unix().toString() + "000000000", + `{"wasm":{"contract": "${contractAddress}" ,"msg": {"increment": {}}}}` + ), + ], + chainID: "test-2", + }); + let result = await LCD.chain2.tx.broadcastSync(tx, "test-2"); + await ibcTransfer(); + let txResult = await LCD.chain2.tx.txInfo(result.txhash, "test-2") as any; + expect(txResult.logs[0].eventsByType.ibc_transfer) + .toStrictEqual({ + "sender": [walletAddress], + "receiver": [contractAddress], + "amount": ["10000000"], + "denom": ["uluna"], + "memo": [`{"wasm":{"contract": "${contractAddress}" ,"msg": {"increment": {}}}}`] + }); + + const res = await LCD.chain1.wasm.contractQuery( + contractAddress, + { + "get_count": { + "addr": walletAddress + } + } + ); + console.log(JSON.stringify(res)); + } + catch (e) { + console.log(e) + } + }) + }) +}); \ No newline at end of file diff --git a/integration-tests/src/modules/tokenfactory/tokenfactory.test.ts b/integration-tests/src/modules/tokenfactory/tokenfactory.test.ts index 9de2e9bb..646edf50 100644 --- a/integration-tests/src/modules/tokenfactory/tokenfactory.test.ts +++ b/integration-tests/src/modules/tokenfactory/tokenfactory.test.ts @@ -3,7 +3,7 @@ import { getMnemonics, getLCDClient, blockInclusion } from "../../helpers"; import fs from "fs"; import path from 'path'; -describe("Feeshare Module (https://github.com/terra-money/core/tree/release/v2.7/x/feeshare) ", () => { +describe("TokenFactory Module (https://github.com/terra-money/core/tree/release/v2.7/x/tokenfactory) ", () => { // Prepare environment clients, accounts and wallets const LCD = getLCDClient(); const accounts = getMnemonics(); diff --git a/scripts/tests/ibc-hooks/counter/Cargo.toml b/scripts/tests/ibc-hooks/counter/Cargo.toml deleted file mode 100644 index f164afc0..00000000 --- a/scripts/tests/ibc-hooks/counter/Cargo.toml +++ /dev/null @@ -1,43 +0,0 @@ -[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 deleted file mode 100644 index f4394fe8..00000000 --- a/scripts/tests/ibc-hooks/counter/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# 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 deleted file mode 100644 index 1f542142..00000000 --- a/scripts/tests/ibc-hooks/counter/artifacts/checksums.txt +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 0394e5fc..00000000 --- a/scripts/tests/ibc-hooks/counter/artifacts/checksums_intermediate.txt +++ /dev/null @@ -1 +0,0 @@ -bffb3256d4fd5668e497ae5671844ef3dcdf1a5f2594747b894dfc02e243ab0e ./target/wasm32-unknown-unknown/release/counter.wasm diff --git a/scripts/tests/ibc-hooks/counter/src/contract.rs b/scripts/tests/ibc-hooks/counter/src/contract.rs deleted file mode 100644 index 259d3634..00000000 --- a/scripts/tests/ibc-hooks/counter/src/contract.rs +++ /dev/null @@ -1,395 +0,0 @@ -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 deleted file mode 100644 index 3caf0c5c..00000000 --- a/scripts/tests/ibc-hooks/counter/src/error.rs +++ /dev/null @@ -1,16 +0,0 @@ -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 deleted file mode 100644 index c943c136..00000000 --- a/scripts/tests/ibc-hooks/counter/src/helpers.rs +++ /dev/null @@ -1,48 +0,0 @@ -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 deleted file mode 100644 index 4c507846..00000000 --- a/scripts/tests/ibc-hooks/counter/src/integration_tests.rs +++ /dev/null @@ -1,71 +0,0 @@ -#[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 deleted file mode 100644 index ffd1f6ac..00000000 --- a/scripts/tests/ibc-hooks/counter/src/lib.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![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 deleted file mode 100644 index 037d8c57..00000000 --- a/scripts/tests/ibc-hooks/counter/src/msg.rs +++ /dev/null @@ -1,63 +0,0 @@ -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 deleted file mode 100644 index 4b8002fc..00000000 --- a/scripts/tests/ibc-hooks/counter/src/state.rs +++ /dev/null @@ -1,14 +0,0 @@ -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 deleted file mode 100755 index d6aa10db..00000000 --- a/scripts/tests/ibc-hooks/increment.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash - -echo "" -echo "#################" -echo "# IBC Hook call #" -echo "#################" -echo "" - -BINARY=terrad -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) - -# 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 -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 -o json | jq -r '.txhash') -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 "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 1uluna --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 -y -o json) -sleep 3 -# ... then send another transfer to increments the count value from 0 to 1, send 1 more uluna 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 1uluna --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 -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) - -COUNT_RES="" -COUNT_FUNDS_RES="" -while [ "$COUNT_RES" != "1" ] || [ "$COUNT_FUNDS_RES" != "2" ]; do - sleep 3 - # Query to assert that the counter value is 1 and the fund send are 2uluna (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 1uluna --memo='{"ibc_callback":"'"$CONTRACT_ADDRESS"'"}' --chain-id test-2 --home $CHAIN_DIR/test-2 --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 1uluna --memo='{"ibc_callback":"'"$CONTRACT_ADDRESS"'"}' --chain-id test-2 --home $CHAIN_DIR/test-2 --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 1uluna --packet-timeout-height="0-1" --memo='{"ibc_callback":"'"$CONTRACT_ADDRESS"'"}' --chain-id test-2 --home $CHAIN_DIR/test-2 --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 1uluna --packet-timeout-height="0-1" --memo='{"ibc_callback":"'"$CONTRACT_ADDRESS"'"}' --chain-id test-2 --home $CHAIN_DIR/test-2 --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/init-test-framework.sh b/scripts/tests/init-test-framework.sh index 4a5578f6..e49f3540 100755 --- a/scripts/tests/init-test-framework.sh +++ b/scripts/tests/init-test-framework.sh @@ -17,7 +17,7 @@ WALLET_MNEMONIC_5="same heavy travel border destroy catalog music manual love fe WALLET_MNEMONIC_6="broken title little open demand ladder mimic keen execute word couple door relief rule pulp demand believe cactus swing fluid tired what crop purse" WALLET_MNEMONIC_7="unit question bulk desk slush answer share bird earth brave book wing special gorilla ozone release permit mercy luxury version advice impact unfair drama" WALLET_MNEMONIC_8="year aim panel oyster sunny faint dress skin describe chair guilt possible venue pottery inflict mass debate poverty multiply pulse ability purse situate inmate" - +WALLET_MNEMONIC_9="leave side blue panel curve ancient suspect slide seminar neutral doctor boring only curious spell surround remind obtain slogan hire giant soccer crunch system" # Chain2 VAL_MNEMONIC_2="angry twist harsh drastic left brass behave host shove marriage fall update business leg direct reward object ugly security warm tuna model broccoli choice" @@ -73,6 +73,7 @@ echo $WALLET_MNEMONIC_5 | $BINARY keys add wallet5 --home $CHAIN_DIR/$CHAINID_1 echo $WALLET_MNEMONIC_6 | $BINARY keys add wallet6 --home $CHAIN_DIR/$CHAINID_1 --recover --keyring-backend=test echo $WALLET_MNEMONIC_7 | $BINARY keys add wallet7 --home $CHAIN_DIR/$CHAINID_1 --recover --keyring-backend=test echo $WALLET_MNEMONIC_8 | $BINARY keys add wallet8 --home $CHAIN_DIR/$CHAINID_1 --recover --keyring-backend=test +echo $WALLET_MNEMONIC_9 | $BINARY keys add wallet9 --home $CHAIN_DIR/$CHAINID_1 --recover --keyring-backend=test echo $WALLET_MNEMONIC_1 | $BINARY keys add wallet1 --home $CHAIN_DIR/$CHAINID_2 --recover --keyring-backend=test echo $WALLET_MNEMONIC_2 | $BINARY keys add wallet2 --home $CHAIN_DIR/$CHAINID_2 --recover --keyring-backend=test @@ -82,6 +83,7 @@ echo $WALLET_MNEMONIC_5 | $BINARY keys add wallet5 --home $CHAIN_DIR/$CHAINID_2 echo $WALLET_MNEMONIC_6 | $BINARY keys add wallet6 --home $CHAIN_DIR/$CHAINID_2 --recover --keyring-backend=test echo $WALLET_MNEMONIC_7 | $BINARY keys add wallet7 --home $CHAIN_DIR/$CHAINID_2 --recover --keyring-backend=test echo $WALLET_MNEMONIC_8 | $BINARY keys add wallet8 --home $CHAIN_DIR/$CHAINID_2 --recover --keyring-backend=test +echo $WALLET_MNEMONIC_9 | $BINARY keys add wallet9 --home $CHAIN_DIR/$CHAINID_2 --recover --keyring-backend=test echo $VAL_MNEMONIC_2 | $BINARY keys add val2 --home $CHAIN_DIR/$CHAINID_2 --recover --keyring-backend=test echo $RLY_MNEMONIC_2 | $BINARY keys add rly2 --home $CHAIN_DIR/$CHAINID_2 --recover --keyring-backend=test @@ -91,6 +93,7 @@ WALLET1_ADDR=$($BINARY keys show wallet1 --home $CHAIN_DIR/$CHAINID_1 --keyring- WALLET3_ADDR=$($BINARY keys show wallet3 --home $CHAIN_DIR/$CHAINID_1 --keyring-backend test -a) WALLET5_ADDR=$($BINARY keys show wallet5 --home $CHAIN_DIR/$CHAINID_1 --keyring-backend test -a) WALLET7_ADDR=$($BINARY keys show wallet7 --home $CHAIN_DIR/$CHAINID_1 --keyring-backend test -a) +WALLET9_ADDR=$($BINARY keys show wallet9 --home $CHAIN_DIR/$CHAINID_1 --keyring-backend test -a) RLY1_ADDR=$($BINARY keys show rly1 --home $CHAIN_DIR/$CHAINID_1 --keyring-backend test -a) VAL2_ADDR=$($BINARY keys show val2 --home $CHAIN_DIR/$CHAINID_2 --keyring-backend test -a) @@ -109,6 +112,7 @@ $BINARY genesis add-genesis-account $WALLET5_ADDR 1000000000000uluna --home $CHA $BINARY genesis add-genesis-account $WALLET6_ADDR 1000000000000uluna --home $CHAIN_DIR/$CHAINID_1 $BINARY genesis add-genesis-account $WALLET7_ADDR 1000000000000uluna --home $CHAIN_DIR/$CHAINID_1 $BINARY genesis add-genesis-account $WALLET8_ADDR 1000000000000uluna --home $CHAIN_DIR/$CHAINID_1 +$BINARY genesis add-genesis-account $WALLET9_ADDR 1000000000000uluna --home $CHAIN_DIR/$CHAINID_1 $BINARY genesis add-genesis-account $RLY1_ADDR 1000000000000uluna --home $CHAIN_DIR/$CHAINID_1 $BINARY genesis add-genesis-account $VAL2_ADDR 1000000000000uluna --home $CHAIN_DIR/$CHAINID_2 @@ -120,6 +124,7 @@ $BINARY genesis add-genesis-account $WALLET5_ADDR 1000000000000uluna --home $CHA $BINARY genesis add-genesis-account $WALLET6_ADDR 1000000000000uluna --home $CHAIN_DIR/$CHAINID_2 $BINARY genesis add-genesis-account $WALLET7_ADDR 1000000000000uluna --home $CHAIN_DIR/$CHAINID_2 $BINARY genesis add-genesis-account $WALLET8_ADDR 1000000000000uluna --home $CHAIN_DIR/$CHAINID_2 +$BINARY genesis add-genesis-account $WALLET9_ADDR 1000000000000uluna --home $CHAIN_DIR/$CHAINID_2 $BINARY genesis add-genesis-account $RLY2_ADDR 1000000000000uluna --home $CHAIN_DIR/$CHAINID_2 echo "Creating and collecting gentx..." diff --git a/x/wasmd/types/executed_contracts.pb.go b/x/wasmd/types/executed_contracts.pb.go deleted file mode 100644 index 0726c1ce..00000000 --- a/x/wasmd/types/executed_contracts.pb.go +++ /dev/null @@ -1,324 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: terra/wasm/v1/executed_contracts.proto - -package types - -import ( - fmt "fmt" - proto "github.com/cosmos/gogoproto/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -// ExecutedContracts is a structure type that contains the list of executed contracts -// in a specific transaction. -type ExecutedContracts struct { - ContractAddresses []string `protobuf:"bytes,1,rep,name=contract_addresses,json=contractAddresses,proto3" json:"contract_addresses,omitempty"` -} - -func (m *ExecutedContracts) Reset() { *m = ExecutedContracts{} } -func (m *ExecutedContracts) String() string { return proto.CompactTextString(m) } -func (*ExecutedContracts) ProtoMessage() {} -func (*ExecutedContracts) Descriptor() ([]byte, []int) { - return fileDescriptor_200f5f891d4ef8d1, []int{0} -} -func (m *ExecutedContracts) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ExecutedContracts) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ExecutedContracts.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *ExecutedContracts) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecutedContracts.Merge(m, src) -} -func (m *ExecutedContracts) XXX_Size() int { - return m.Size() -} -func (m *ExecutedContracts) XXX_DiscardUnknown() { - xxx_messageInfo_ExecutedContracts.DiscardUnknown(m) -} - -var xxx_messageInfo_ExecutedContracts proto.InternalMessageInfo - -func (m *ExecutedContracts) GetContractAddresses() []string { - if m != nil { - return m.ContractAddresses - } - return nil -} - -func init() { - proto.RegisterType((*ExecutedContracts)(nil), "terra.wasm.v1.ExecutedContracts") -} - -func init() { - proto.RegisterFile("terra/wasm/v1/executed_contracts.proto", fileDescriptor_200f5f891d4ef8d1) -} - -var fileDescriptor_200f5f891d4ef8d1 = []byte{ - // 186 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x2b, 0x49, 0x2d, 0x2a, - 0x4a, 0xd4, 0x2f, 0x4f, 0x2c, 0xce, 0xd5, 0x2f, 0x33, 0xd4, 0x4f, 0xad, 0x48, 0x4d, 0x2e, 0x2d, - 0x49, 0x4d, 0x89, 0x4f, 0xce, 0xcf, 0x2b, 0x29, 0x4a, 0x4c, 0x2e, 0x29, 0xd6, 0x2b, 0x28, 0xca, - 0x2f, 0xc9, 0x17, 0xe2, 0x05, 0xab, 0xd3, 0x03, 0xa9, 0xd3, 0x2b, 0x33, 0x54, 0x72, 0xe2, 0x12, - 0x74, 0x85, 0x2a, 0x75, 0x86, 0xa9, 0x14, 0xd2, 0xe5, 0x12, 0x82, 0x69, 0x8b, 0x4f, 0x4c, 0x49, - 0x29, 0x4a, 0x2d, 0x2e, 0x4e, 0x2d, 0x96, 0x60, 0x54, 0x60, 0xd6, 0xe0, 0x0c, 0x12, 0x84, 0xc9, - 0x38, 0xc2, 0x24, 0x9c, 0xdc, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, - 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x4a, - 0x27, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x1f, 0x6c, 0xaf, 0x6e, 0x6e, - 0x7e, 0x5e, 0x6a, 0xa5, 0x7e, 0x72, 0x7e, 0x51, 0xaa, 0x7e, 0x99, 0x91, 0x7e, 0x05, 0xd8, 0xbd, - 0x29, 0xfa, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0x60, 0x17, 0x1a, 0x03, 0x02, 0x00, 0x00, - 0xff, 0xff, 0xdf, 0xf2, 0xb2, 0xd1, 0xcb, 0x00, 0x00, 0x00, -} - -func (m *ExecutedContracts) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ExecutedContracts) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ExecutedContracts) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.ContractAddresses) > 0 { - for iNdEx := len(m.ContractAddresses) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.ContractAddresses[iNdEx]) - copy(dAtA[i:], m.ContractAddresses[iNdEx]) - i = encodeVarintExecutedContracts(dAtA, i, uint64(len(m.ContractAddresses[iNdEx]))) - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func encodeVarintExecutedContracts(dAtA []byte, offset int, v uint64) int { - offset -= sovExecutedContracts(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *ExecutedContracts) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.ContractAddresses) > 0 { - for _, s := range m.ContractAddresses { - l = len(s) - n += 1 + l + sovExecutedContracts(uint64(l)) - } - } - return n -} - -func sovExecutedContracts(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozExecutedContracts(x uint64) (n int) { - return sovExecutedContracts(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *ExecutedContracts) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowExecutedContracts - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ExecutedContracts: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ExecutedContracts: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ContractAddresses", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowExecutedContracts - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthExecutedContracts - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthExecutedContracts - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ContractAddresses = append(m.ContractAddresses, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipExecutedContracts(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthExecutedContracts - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipExecutedContracts(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowExecutedContracts - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowExecutedContracts - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowExecutedContracts - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthExecutedContracts - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupExecutedContracts - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthExecutedContracts - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthExecutedContracts = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowExecutedContracts = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupExecutedContracts = fmt.Errorf("proto: unexpected end of group") -) From baf15e3b17b1f36018abc4d9f989dda67d638fe4 Mon Sep 17 00:00:00 2001 From: emidev98 Date: Thu, 16 Nov 2023 19:17:25 +0200 Subject: [PATCH 2/4] wip --- integration-tests/jest.config.js | 2 +- integration-tests/package-lock.json | 14 +-- integration-tests/package.json | 2 +- .../src/modules/ibc-hooks/ibc-hooks.test.ts | 89 +++++++++++++++---- 4 files changed, 82 insertions(+), 25 deletions(-) diff --git a/integration-tests/jest.config.js b/integration-tests/jest.config.js index 77330a61..bbf2be55 100644 --- a/integration-tests/jest.config.js +++ b/integration-tests/jest.config.js @@ -5,5 +5,5 @@ module.exports = { testMatch: ['**/*.test.ts'], verbose: true, testTimeout: 30000, - maxConcurrency: 4, + maxConcurrency: 3, }; \ No newline at end of file diff --git a/integration-tests/package-lock.json b/integration-tests/package-lock.json index 31a99be5..08bdc3ec 100644 --- a/integration-tests/package-lock.json +++ b/integration-tests/package-lock.json @@ -9,7 +9,7 @@ "version": "v2.7.0", "license": "MIT", "dependencies": { - "@terra-money/feather.js": "^2.0.0-beta.12", + "@terra-money/feather.js": "^2.0.0-beta.13", "@terra-money/terra.proto": "^4.0.1", "moment": "^2.29.4" }, @@ -1803,9 +1803,9 @@ } }, "node_modules/@terra-money/feather.js": { - "version": "2.0.0-beta.12", - "resolved": "https://registry.npmjs.org/@terra-money/feather.js/-/feather.js-2.0.0-beta.12.tgz", - "integrity": "sha512-qxUQJtHOp3Ybpr5T5s1XXYiADZbH6g0HdLEhkPkJtBtjxxKN+UeLVJ+4SmkxglA7sITCuSoZebBrv8yukHsmJw==", + "version": "2.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@terra-money/feather.js/-/feather.js-2.0.0-beta.13.tgz", + "integrity": "sha512-r4/BsFCGsWKnOil0iMe8ZyquqAoZbbFlcKLNWb72lbBvkUAfzHjJA/WBBy13vuGuS7Y80jsDbFBditBMaV7cvA==", "dependencies": { "@ethersproject/bytes": "^5.7.0", "@terra-money/legacy.proto": "npm:@terra-money/terra.proto@^0.1.7", @@ -7008,9 +7008,9 @@ } }, "@terra-money/feather.js": { - "version": "2.0.0-beta.12", - "resolved": "https://registry.npmjs.org/@terra-money/feather.js/-/feather.js-2.0.0-beta.12.tgz", - "integrity": "sha512-qxUQJtHOp3Ybpr5T5s1XXYiADZbH6g0HdLEhkPkJtBtjxxKN+UeLVJ+4SmkxglA7sITCuSoZebBrv8yukHsmJw==", + "version": "2.0.0-beta.13", + "resolved": "https://registry.npmjs.org/@terra-money/feather.js/-/feather.js-2.0.0-beta.13.tgz", + "integrity": "sha512-r4/BsFCGsWKnOil0iMe8ZyquqAoZbbFlcKLNWb72lbBvkUAfzHjJA/WBBy13vuGuS7Y80jsDbFBditBMaV7cvA==", "requires": { "@ethersproject/bytes": "^5.7.0", "@terra-money/legacy.proto": "npm:@terra-money/terra.proto@^0.1.7", diff --git a/integration-tests/package.json b/integration-tests/package.json index 38aed0aa..e245832b 100644 --- a/integration-tests/package.json +++ b/integration-tests/package.json @@ -30,7 +30,7 @@ "typescript": "^5.2.2" }, "dependencies": { - "@terra-money/feather.js": "^2.0.0-beta.12", + "@terra-money/feather.js": "^2.0.0-beta.13", "@terra-money/terra.proto": "^4.0.1", "moment": "^2.29.4" } diff --git a/integration-tests/src/modules/ibc-hooks/ibc-hooks.test.ts b/integration-tests/src/modules/ibc-hooks/ibc-hooks.test.ts index 3f0bbfb5..99e238f4 100644 --- a/integration-tests/src/modules/ibc-hooks/ibc-hooks.test.ts +++ b/integration-tests/src/modules/ibc-hooks/ibc-hooks.test.ts @@ -1,4 +1,5 @@ import { Coin, Coins, MsgInstantiateContract, MsgStoreCode, MsgTransfer } from "@terra-money/feather.js"; +import { deriveIbcHooksSender } from "@terra-money/feather.js/dist/core/ibc-hooks"; import { ibcTransfer, getMnemonics, getLCDClient, blockInclusion } from "../../helpers"; import fs from "fs"; import path from 'path'; @@ -55,27 +56,80 @@ describe("IbcHooks Module (github.com/cosmos/ibc-apps/modules/ibc-hooks/v7) ", ( describe("Must send IBC messages from chain 2 to chain 1", () => { test('must incrementing the counter', async () => { - try { - const resw = await LCD.chain1.wasm.contractQuery( - contractAddress, - { - "get_count": { - "addr": walletAddress - } + let tx = await chain2Wallet.createAndSignTx({ + msgs: [ + new MsgTransfer( + "transfer", + "channel-0", + Coin.fromString("1uluna"), + walletAddress, + contractAddress, + undefined, + moment.utc().add(1, "minute").unix().toString() + "000000000", + `{"wasm":{"contract": "${contractAddress}" ,"msg": {"increment": {}}}}` + ), + new MsgTransfer( + "transfer", + "channel-0", + Coin.fromString("1uluna"), + walletAddress, + contractAddress, + undefined, + moment.utc().add(1, "minute").unix().toString() + "000000000", + `{"wasm":{"contract": "${contractAddress}" ,"msg": {"increment": {}}}}` + ), + ], + chainID: "test-2", + }); + let result = await LCD.chain2.tx.broadcastSync(tx, "test-2"); + await ibcTransfer(); + let txResult = await LCD.chain2.tx.txInfo(result.txhash, "test-2") as any; + expect(txResult.logs[0].eventsByType.ibc_transfer) + .toStrictEqual({ + "sender": [walletAddress], + "receiver": [contractAddress], + "amount": ["1"], + "denom": ["uluna"], + "memo": [`{"wasm":{"contract": "${contractAddress}" ,"msg": {"increment": {}}}}`] + }); + + const res = await LCD.chain1.wasm.contractQuery( + contractAddress, + { + "get_count": { + "addr": deriveIbcHooksSender("channel-0", walletAddress, "terra") } - ); - console.log(JSON.stringify(resw)); + } + ); + expect(res) + .toStrictEqual({ "count": 1 }); + }); + }) + + describe("Must send IBC messages from chain 2 to chain 1", ()=> { + test('must incrementing the counter with a callback', async () => { + try { let tx = await chain2Wallet.createAndSignTx({ msgs: [ new MsgTransfer( "transfer", "channel-0", - Coin.fromString("10000000uluna"), + Coin.fromString("1uluna"), + walletAddress, + contractAddress, + undefined, + moment.utc().add(1,"minute").unix().toString() + "000000000", + `{"ibc_callback": "${contractAddress}"}` + ), + new MsgTransfer( + "transfer", + "channel-0", + Coin.fromString("1uluna"), walletAddress, contractAddress, undefined, - moment.utc().add(1.5, "day").unix().toString() + "000000000", - `{"wasm":{"contract": "${contractAddress}" ,"msg": {"increment": {}}}}` + moment.utc().add(1,"minute").unix().toString() + "000000000", + `{"ibc_callback": "${contractAddress}"}` ), ], chainID: "test-2", @@ -87,20 +141,23 @@ describe("IbcHooks Module (github.com/cosmos/ibc-apps/modules/ibc-hooks/v7) ", ( .toStrictEqual({ "sender": [walletAddress], "receiver": [contractAddress], - "amount": ["10000000"], + "amount": ["1"], "denom": ["uluna"], - "memo": [`{"wasm":{"contract": "${contractAddress}" ,"msg": {"increment": {}}}}`] + "memo": [`{"ibc_callback": "${contractAddress}"}`] }); const res = await LCD.chain1.wasm.contractQuery( contractAddress, { "get_count": { - "addr": walletAddress + "addr": deriveIbcHooksSender("channel-0", walletAddress, "terra") } } ); - console.log(JSON.stringify(res)); + await ibcTransfer(); + await ibcTransfer(); + expect(res) + .toStrictEqual({ "count": 22 }); } catch (e) { console.log(e) From 9995f156cffc28183572051033480c0fe7253ea1 Mon Sep 17 00:00:00 2001 From: emidev98 Date: Tue, 21 Nov 2023 15:03:46 +0200 Subject: [PATCH 3/4] feat: clean authz test --- integration-tests/src/modules/authz.test.ts | 152 ------------------ .../src/modules/authz/authz.test.ts | 138 ++++++++++++++++ 2 files changed, 138 insertions(+), 152 deletions(-) delete mode 100644 integration-tests/src/modules/authz.test.ts create mode 100644 integration-tests/src/modules/authz/authz.test.ts diff --git a/integration-tests/src/modules/authz.test.ts b/integration-tests/src/modules/authz.test.ts deleted file mode 100644 index 2aa1fc3b..00000000 --- a/integration-tests/src/modules/authz.test.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { getMnemonics } from "../helpers/mnemonics"; -import { getLCDClient } from "../helpers/lcd.connection"; -import { StakeAuthorization, MsgGrantAuthorization, AuthorizationGrant, Coin, MsgExecAuthorized, MsgDelegate } from "@terra-money/feather.js"; -import { AuthorizationType } from "@terra-money/terra.proto/cosmos/staking/v1beta1/authz"; -import moment from "moment"; -import { blockInclusion } from "../helpers/const"; - -describe("Authz Module (https://github.com/terra-money/cosmos-sdk/tree/release/v0.47.x/x/authz)", () => { - const LCD = getLCDClient(); - const accounts = getMnemonics(); - // Accounts used in chain2, which means that - // will not cause conflicts with txs nonces - const granterWallet = LCD.chain2.wallet(accounts.feeshareMnemonic); - const granteeWallet = LCD.chain2.wallet(accounts.pobMnemonic); - const granterAddr = accounts.feeshareMnemonic.accAddress("terra"); - const granteeAddr = accounts.pobMnemonic.accAddress("terra"); - const val2Addr = accounts.val2.valAddress("terra"); - - test('Must register the granter', async () => { - let tx = await granterWallet.createAndSignTx({ - msgs: [new MsgGrantAuthorization( - granterAddr, - granteeAddr, - new AuthorizationGrant( - new StakeAuthorization( - AuthorizationType.AUTHORIZATION_TYPE_DELEGATE, - Coin.fromString("1000000uluna"), - ), - moment().add(1, "hour").toDate(), - ), - )], - chainID: "test-2", - }); - let result = await LCD.chain2.tx.broadcastSync(tx, "test-2"); - await blockInclusion(); - - // Check the MsgGrantAuthorization executed as expected - let txResult = await LCD.chain2.tx.txInfo(result.txhash, "test-2") as any; - expect(txResult.logs[0].events) - .toStrictEqual([{ - "type": "message", - "attributes": [{ - "key": "action", - "value": "/cosmos.authz.v1beta1.MsgGrant" - }, { - "key": "sender", - "value": "terra120rzk7n6cd2vufkmwrat34adqh0rgca9tkyfe5" - }, { - "key": "module", - "value": "authz" - }] - }, { - "type": "cosmos.authz.v1beta1.EventGrant", - "attributes": [{ - "key": "grantee", - "value": "\"terra1v0eee20gjl68fuk0chyrkch2z7suw2mhg3wkxf\"" - }, { - "key": "granter", - "value": "\"terra120rzk7n6cd2vufkmwrat34adqh0rgca9tkyfe5\"" - }, { - "key": "msg_type_url", - "value": "\"/cosmos.staking.v1beta1.MsgDelegate\"" - }] - }]); - }); - - describe("Grantee must execute", () => { - test("delegation on belhalf of granter", async () => { - try { - let tx = await granteeWallet.createAndSignTx({ - msgs: [new MsgExecAuthorized( - granteeAddr, - [new MsgDelegate( - granterAddr, - val2Addr, - Coin.fromString("1000000uluna"), - )] - )], - chainID: "test-2", - }); - let result = await LCD.chain2.tx.broadcastSync(tx, "test-2"); - await blockInclusion(); - - let txResult = await LCD.chain2.tx.txInfo(result.txhash, "test-2") as any; - let eventsList = txResult.logs[0].events; - expect(eventsList[0]) - .toStrictEqual({ - "type": "message", - "attributes": [{ - "key": "action", - "value": "/cosmos.authz.v1beta1.MsgExec" - }, { - "key": "sender", - "value": "terra1v0eee20gjl68fuk0chyrkch2z7suw2mhg3wkxf" - }, { - "key": "module", - "value": "authz" - }] - }); - expect(eventsList[1]) - .toStrictEqual({ - "type": "cosmos.authz.v1beta1.EventRevoke", - "attributes": [{ - "key": "grantee", - "value": "\"terra1v0eee20gjl68fuk0chyrkch2z7suw2mhg3wkxf\"" - }, { - "key": "granter", - "value": "\"terra120rzk7n6cd2vufkmwrat34adqh0rgca9tkyfe5\"" - }, { - "key": "msg_type_url", - "value": "\"/cosmos.staking.v1beta1.MsgDelegate\"" - }] - }); - expect(eventsList[5]) - .toStrictEqual({ - "type": "message", - "attributes": [{ - "key": "sender", - "value": "terra1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8pm7utl" - }, { - "key": "authz_msg_index", - "value": "0" - }] - }); - - expect(eventsList[9]) - .toStrictEqual({ - "type": "delegate", - "attributes": [{ - "key": "validator", - "value": "terravaloper1llgzglr9yyy4gyjh8p5kepgm5wyl358de47rqk" - }, { - "key": "delegator", - "value": "terra120rzk7n6cd2vufkmwrat34adqh0rgca9tkyfe5" - }, { - "key": "amount", - "value": "1000000uluna" - }, { - "key": "new_shares", - "value": "1000000.000000000000000000" - }, { - "key": "authz_msg_index", - "value": "0" - }] - }); - } - catch (e) { - console.log(e) - } - }); - }) -}); \ No newline at end of file diff --git a/integration-tests/src/modules/authz/authz.test.ts b/integration-tests/src/modules/authz/authz.test.ts new file mode 100644 index 00000000..1d5d94b7 --- /dev/null +++ b/integration-tests/src/modules/authz/authz.test.ts @@ -0,0 +1,138 @@ +import { getMnemonics } from "../../helpers/mnemonics"; +import { getLCDClient } from "../../helpers/lcd.connection"; +import { StakeAuthorization, MsgGrantAuthorization, AuthorizationGrant, Coin, MsgExecAuthorized, MsgDelegate } from "@terra-money/feather.js"; +import { AuthorizationType } from "@terra-money/terra.proto/cosmos/staking/v1beta1/authz"; +import moment from "moment"; +import { blockInclusion } from "../../helpers/const"; + +describe("Authz Module (https://github.com/terra-money/cosmos-sdk/tree/release/v0.47.x/x/authz)", () => { + const LCD = getLCDClient(); + const accounts = getMnemonics(); + // Accounts used in chain2, which means that + // will not cause conflicts with txs nonces + const granterWallet = LCD.chain2.wallet(accounts.feeshareMnemonic); + const granteeWallet = LCD.chain2.wallet(accounts.pobMnemonic); + const granterAddr = accounts.feeshareMnemonic.accAddress("terra"); + const granteeAddr = accounts.pobMnemonic.accAddress("terra"); + const val2Addr = accounts.val2.valAddress("terra"); + + test('Must register the granter', async () => { + let tx = await granterWallet.createAndSignTx({ + msgs: [new MsgGrantAuthorization( + granterAddr, + granteeAddr, + new AuthorizationGrant( + new StakeAuthorization( + AuthorizationType.AUTHORIZATION_TYPE_DELEGATE, + Coin.fromString("1000000uluna"), + ), + moment().add(1, "hour").toDate(), + ), + )], + chainID: "test-2", + }); + let result = await LCD.chain2.tx.broadcastSync(tx, "test-2"); + await blockInclusion(); + + // Check the MsgGrantAuthorization executed as expected + let txResult = await LCD.chain2.tx.txInfo(result.txhash, "test-2") as any; + expect(txResult.logs[0].events) + .toStrictEqual([{ + "type": "message", + "attributes": [{ + "key": "action", + "value": "/cosmos.authz.v1beta1.MsgGrant" + }, { + "key": "sender", + "value": "terra120rzk7n6cd2vufkmwrat34adqh0rgca9tkyfe5" + }, { + "key": "module", + "value": "authz" + }] + }, { + "type": "cosmos.authz.v1beta1.EventGrant", + "attributes": [{ + "key": "grantee", + "value": "\"terra1v0eee20gjl68fuk0chyrkch2z7suw2mhg3wkxf\"" + }, { + "key": "granter", + "value": "\"terra120rzk7n6cd2vufkmwrat34adqh0rgca9tkyfe5\"" + }, { + "key": "msg_type_url", + "value": "\"/cosmos.staking.v1beta1.MsgDelegate\"" + }] + }]); + }); + + describe("Grantee must execute", () => { + test("delegation on belhalf of granter", async () => { + let tx = await granteeWallet.createAndSignTx({ + msgs: [new MsgExecAuthorized( + granteeAddr, + [new MsgDelegate( + granterAddr, + val2Addr, + Coin.fromString("1000000uluna"), + )] + )], + chainID: "test-2", + }); + let result = await LCD.chain2.tx.broadcastSync(tx, "test-2"); + await blockInclusion(); + + let txResult = await LCD.chain2.tx.txInfo(result.txhash, "test-2") as any; + let eventsList = txResult.logs[0].events; + let latestIndex = eventsList.length - 1; + + expect(eventsList[0]) + .toStrictEqual({ + "type": "message", + "attributes": [{ + "key": "action", + "value": "/cosmos.authz.v1beta1.MsgExec" + }, { + "key": "sender", + "value": "terra1v0eee20gjl68fuk0chyrkch2z7suw2mhg3wkxf" + }, { + "key": "module", + "value": "authz" + }] + }); + expect(eventsList[1]) + .toStrictEqual({ + "type": "cosmos.authz.v1beta1.EventRevoke", + "attributes": [{ + "key": "grantee", + "value": "\"terra1v0eee20gjl68fuk0chyrkch2z7suw2mhg3wkxf\"" + }, { + "key": "granter", + "value": "\"terra120rzk7n6cd2vufkmwrat34adqh0rgca9tkyfe5\"" + }, { + "key": "msg_type_url", + "value": "\"/cosmos.staking.v1beta1.MsgDelegate\"" + }] + }); + + expect(eventsList[latestIndex]) + .toStrictEqual({ + "type": "delegate", + "attributes": [{ + "key": "validator", + "value": "terravaloper1llgzglr9yyy4gyjh8p5kepgm5wyl358de47rqk" + }, { + "key": "delegator", + "value": "terra120rzk7n6cd2vufkmwrat34adqh0rgca9tkyfe5" + }, { + "key": "amount", + "value": "1000000uluna" + }, { + "key": "new_shares", + "value": "1000000.000000000000000000" + }, { + "key": "authz_msg_index", + "value": "0" + }] + }); + }); + }) +}); \ No newline at end of file From ce9ba837bf940bcc3a3b70ec054cd062a67276aa Mon Sep 17 00:00:00 2001 From: emidev98 Date: Wed, 22 Nov 2023 11:42:10 +0200 Subject: [PATCH 4/4] feat: ibc-hook tests migrated to ts --- .../src/modules/ibc-hooks/ibc-hooks.test.ts | 133 ++++++++++++------ 1 file changed, 88 insertions(+), 45 deletions(-) diff --git a/integration-tests/src/modules/ibc-hooks/ibc-hooks.test.ts b/integration-tests/src/modules/ibc-hooks/ibc-hooks.test.ts index 99e238f4..5dcd2236 100644 --- a/integration-tests/src/modules/ibc-hooks/ibc-hooks.test.ts +++ b/integration-tests/src/modules/ibc-hooks/ibc-hooks.test.ts @@ -4,6 +4,7 @@ import { ibcTransfer, getMnemonics, getLCDClient, blockInclusion } from "../../h import fs from "fs"; import path from 'path'; import moment from "moment"; +// import { Height } from "@terra-money/feather.js/dist/core/ibc/core/client/Height"; describe("IbcHooks Module (github.com/cosmos/ibc-apps/modules/ibc-hooks/v7) ", () => { // Prepare the LCD and wallets. chain1Wallet is the one that will @@ -14,6 +15,7 @@ describe("IbcHooks Module (github.com/cosmos/ibc-apps/modules/ibc-hooks/v7) ", ( const chain1Wallet = LCD.chain1.wallet(accounts.ibcHooksMnemonic); const chain2Wallet = LCD.chain2.wallet(accounts.ibcHooksMnemonic); const walletAddress = accounts.ibcHooksMnemonic.accAddress("terra"); + const derivedHooksWalletAddress = deriveIbcHooksSender("channel-0", walletAddress, "terra"); let contractAddress: string; // Read the counter contract, store on chain, @@ -54,8 +56,10 @@ describe("IbcHooks Module (github.com/cosmos/ibc-apps/modules/ibc-hooks/v7) ", ( expect(contractAddress).toBeDefined(); }) - describe("Must send IBC messages from chain 2 to chain 1", () => { - test('must incrementing the counter', async () => { + // This test send an IBC message to **chain-2** which is **relayed** to **chain-1** + // The flow represents a successful MsgTransfe with IBCHooks request to the smart contrat. + describe("Should execute hooks from chain 2 to chain 1", () => { + test('must increment the counter successfully', async () => { let tx = await chain2Wallet.createAndSignTx({ msgs: [ new MsgTransfer( @@ -92,33 +96,42 @@ describe("IbcHooks Module (github.com/cosmos/ibc-apps/modules/ibc-hooks/v7) ", ( "denom": ["uluna"], "memo": [`{"wasm":{"contract": "${contractAddress}" ,"msg": {"increment": {}}}}`] }); + // query to validate the count is 1 + let res = await LCD.chain1.wasm.contractQuery( + contractAddress, + { "get_count": { "addr": derivedHooksWalletAddress } } + ); + expect(res).toStrictEqual({ "count": 1 }); - const res = await LCD.chain1.wasm.contractQuery( + // query to validate the count is 1 + res = await LCD.chain1.wasm.contractQuery( contractAddress, - { - "get_count": { - "addr": deriveIbcHooksSender("channel-0", walletAddress, "terra") - } - } + { "get_total_funds": { "addr": derivedHooksWalletAddress } } ); - expect(res) - .toStrictEqual({ "count": 1 }); + expect(res).toStrictEqual({ + "total_funds": [{ + "denom": "ibc/4627AD2524E3E0523047E35BB76CC90E37D9D57ACF14F0FCBCEB2480705F3CB8", + "amount": "2" + }] + }); }); }) - describe("Must send IBC messages from chain 2 to chain 1", ()=> { - test('must incrementing the counter with a callback', async () => { - try { - let tx = await chain2Wallet.createAndSignTx({ + // This test send an IBC message to **chain-1** which is **relayed** to **chain-2** + // with an acknowledgement callback for chain-1. + // The flow represents a successful MsgTransfer with callback to the smart contract. + describe("Must execute hooks callback from chain 1 to chain 2", () => { + test('increment the counter on successful callback', async () => { + let tx = await chain1Wallet.createAndSignTx({ msgs: [ new MsgTransfer( "transfer", "channel-0", Coin.fromString("1uluna"), walletAddress, - contractAddress, + derivedHooksWalletAddress, undefined, - moment.utc().add(1,"minute").unix().toString() + "000000000", + moment.utc().add(10, "second").unix().toString() + "000000000", `{"ibc_callback": "${contractAddress}"}` ), new MsgTransfer( @@ -126,42 +139,72 @@ describe("IbcHooks Module (github.com/cosmos/ibc-apps/modules/ibc-hooks/v7) ", ( "channel-0", Coin.fromString("1uluna"), walletAddress, - contractAddress, + derivedHooksWalletAddress, undefined, - moment.utc().add(1,"minute").unix().toString() + "000000000", + moment.utc().add(10, "second").unix().toString() + "000000000", `{"ibc_callback": "${contractAddress}"}` ), ], - chainID: "test-2", + chainID: "test-1", }); - let result = await LCD.chain2.tx.broadcastSync(tx, "test-2"); + await LCD.chain1.tx.broadcastSync(tx, "test-1") await ibcTransfer(); - let txResult = await LCD.chain2.tx.txInfo(result.txhash, "test-2") as any; - expect(txResult.logs[0].eventsByType.ibc_transfer) - .toStrictEqual({ - "sender": [walletAddress], - "receiver": [contractAddress], - "amount": ["1"], - "denom": ["uluna"], - "memo": [`{"ibc_callback": "${contractAddress}"}`] - }); - - const res = await LCD.chain1.wasm.contractQuery( + await blockInclusion(); + let res = await LCD.chain1.wasm.contractQuery( contractAddress, - { - "get_count": { - "addr": deriveIbcHooksSender("channel-0", walletAddress, "terra") - } - } + { "get_count": { "addr": contractAddress } } ); - await ibcTransfer(); - await ibcTransfer(); - expect(res) - .toStrictEqual({ "count": 22 }); - } - catch (e) { - console.log(e) - } - }) + expect(res).toStrictEqual({ "count": 2 }); + res = await LCD.chain1.wasm.contractQuery( + contractAddress, + { "get_total_funds": { "addr": contractAddress } } + ); + expect(res).toStrictEqual({ "total_funds": [] }); + }); }) + + + // This test send an IBC message to **chain-1** which is **NOT relayed** because of timeout. + // The flow represents a failed MsgTransfer with callback to the smart contract. + describe("Must execute hooks callback on chain 1", () => { + test('with a timeout of -1 second', async () => { + let tx = await chain1Wallet.createAndSignTx({ + msgs: [ + new MsgTransfer( + "transfer", + "channel-0", + Coin.fromString("1uluna"), + walletAddress, + derivedHooksWalletAddress, + undefined, + moment.utc().add(-1, "second").unix().toString() + "000000000", + `{"ibc_callback": "${contractAddress}"}` + ), + new MsgTransfer( + "transfer", + "channel-0", + Coin.fromString("1uluna"), + walletAddress, + derivedHooksWalletAddress, + undefined, + moment.utc().add(-1, "second").unix().toString() + "000000000", + `{"ibc_callback": "${contractAddress}"}` + ), + ], + chainID: "test-1", + }); + await LCD.chain1.tx.broadcastSync(tx, "test-1") + await ibcTransfer(); + let res = await LCD.chain1.wasm.contractQuery( + contractAddress, + { "get_count": { "addr": contractAddress } } + ); + expect(res).toStrictEqual({ "count": 22 }); + res = await LCD.chain1.wasm.contractQuery( + contractAddress, + { "get_total_funds": { "addr": contractAddress } } + ); + expect(res).toStrictEqual({ "total_funds": [] }); + }) + }); }); \ No newline at end of file