From dc85d1257b62babf5601aef8bb3ab477bcaf83e1 Mon Sep 17 00:00:00 2001 From: nhpd Date: Tue, 14 Nov 2023 15:58:53 +0400 Subject: [PATCH 1/2] remove interchain_tx_in_progress from state --- .../artifacts/scripts/init-neutrond.sh | 2 +- integration-tests/src/testSuite.ts | 37 ++++++++++--------- integration-tests/testcases/claimer.test.ts | 24 ++++++------ src/contract.rs | 25 +------------ src/msg.rs | 3 -- src/state.rs | 3 -- 6 files changed, 34 insertions(+), 60 deletions(-) diff --git a/integration-tests/artifacts/scripts/init-neutrond.sh b/integration-tests/artifacts/scripts/init-neutrond.sh index 9d717b1..4739db9 100755 --- a/integration-tests/artifacts/scripts/init-neutrond.sh +++ b/integration-tests/artifacts/scripts/init-neutrond.sh @@ -10,7 +10,7 @@ THIRD_PARTY_CONTRACTS_DIR=${THIRD_PARTY_CONTRACTS_DIR:-/opt/contracts_thirdparty # IMPORTANT! minimum_gas_prices should always contain at least one record, otherwise the chain will not start or halt # ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2 denom is required by intgration tests (test:tokenomics) -MIN_GAS_PRICES_DEFAULT='[{"denom":"ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2","amount":"0"},{"denom":"untrn","amount":"0"}]' +MIN_GAS_PRICES_DEFAULT='[{"denom":"ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2","amount":"0"},{"denom":"untrn","amount":"0"}],' MIN_GAS_PRICES=${MIN_GAS_PRICES:-"$MIN_GAS_PRICES_DEFAULT"} diff --git a/integration-tests/src/testSuite.ts b/integration-tests/src/testSuite.ts index 81974c5..0fc8299 100644 --- a/integration-tests/src/testSuite.ts +++ b/integration-tests/src/testSuite.ts @@ -105,26 +105,27 @@ const awaitFirstBlock = async (rpc: string): Promise => } }, 20_000); -const awaitNeutronChannels = async (rest: string, rpc: string): Promise => - waitFor(async () => { - try { - const client = new NeutronClient({ - apiURL: `http://${rest}`, - rpcURL: rpc, - prefix: 'neutron', - }); - const res = await client.IbcCoreChannelV1.query.queryChannels(); - if (res.data.channels.length > 0) { - let channels = res.data.channels; - if (channels.every((c) => c.state === 'STATE_OPEN')) { - return true; - } +const awaitNeutronChannels = async (rest: string, rpc: string): Promise => { + const client = new NeutronClient({ + apiURL: `http://${rest}`, + rpcURL: rpc, + prefix: 'neutron', + }); + await waitFor(async () => { + try { + const res = await client.IbcCoreChannelV1.query.queryChannels(); + if (res.data.channels.length > 0) { + let channels = res.data.channels; + if (channels.every((c) => c.state === 'STATE_OPEN')) { + return true; } - } catch (e) { - console.log('failed to find channels: ' + e.message) - return false; } - }, 60_000); + } catch (e) { + console.log('failed to find channels: ' + e.message) + return false; + } + }, 60_000); +} export const generateWallets = async (): Promise> => keys.reduce( diff --git a/integration-tests/testcases/claimer.test.ts b/integration-tests/testcases/claimer.test.ts index a28e31d..91a234a 100644 --- a/integration-tests/testcases/claimer.test.ts +++ b/integration-tests/testcases/claimer.test.ts @@ -136,8 +136,8 @@ describe('Test claimer artifact', () => { // wait until interchain tx is not in progress await waitFor(async () => { - const inProgress = await client.queryContractSmart(claimerAddress, { interchain_tx_in_progress: {} }) - return !inProgress + const callbackStates = await client.queryContractSmart(claimerAddress, { ibc_callback_states: {} }) + return callbackStates.length === callbackStatesLengthBefore + 1 }, 500000) // expect timeout callback to be called @@ -173,8 +173,8 @@ describe('Test claimer artifact', () => { // wait until interchain tx is not in progress await waitFor(async () => { - const inProgress = await client.queryContractSmart(claimerAddress, { interchain_tx_in_progress: {} }) - return !inProgress + const callbackStates = await client.queryContractSmart(claimerAddress, { ibc_callback_states: {} }) + return callbackStates.length === callbackStatesLengthBefore + 1 }, 500000) // check callbacks @@ -202,8 +202,8 @@ describe('Test claimer artifact', () => { // wait until interchain tx is not in progress await waitFor(async () => { - const inProgress = await client.queryContractSmart(claimerAddress, { interchain_tx_in_progress: {} }) - return !inProgress + const callbackStates = await client.queryContractSmart(claimerAddress, { ibc_callback_states: {} }) + return callbackStates.length === callbackStatesLengthBefore + 1 }, 500000) // balance on contract should be 0 + 2500 refunded timeout fee @@ -240,8 +240,8 @@ describe('Test claimer artifact', () => { // wait until interchain tx is not in progress await waitFor(async () => { - const inProgress = await client.queryContractSmart(claimerAddress, { interchain_tx_in_progress: {} }) - return !inProgress + const callbackStates = await client.queryContractSmart(claimerAddress, { ibc_callback_states: {} }) + return callbackStates.length === callbackStatesLengthBefore + 1 }, 500000) // check new callback @@ -281,8 +281,8 @@ describe('Test claimer artifact', () => { // wait until interchain tx is not in progress await waitFor(async () => { - const inProgress = await client.queryContractSmart(claimerAddress, { interchain_tx_in_progress: {} }) - return !inProgress + const callbackStates = await client.queryContractSmart(claimerAddress, { ibc_callback_states: {} }) + return callbackStates.length === callbackStatesLengthBefore + 1 }, 500000) const ica = await client.queryContractSmart(claimerAddress, { interchain_account: {} }) @@ -302,8 +302,8 @@ describe('Test claimer artifact', () => { // wait until interchain tx is not in progress await waitFor(async () => { - const inProgress = await client.queryContractSmart(claimerAddress, { interchain_tx_in_progress: {} }) - return !inProgress + const callbackStates = await client.queryContractSmart(claimerAddress, { ibc_callback_states: {} }) + return callbackStates.length === callbackStatesLengthBefore + 1 }, 500000) // should return callback diff --git a/src/contract.rs b/src/contract.rs index 1f7c40b..7d80e23 100644 --- a/src/contract.rs +++ b/src/contract.rs @@ -21,7 +21,7 @@ use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; use crate::state::{ Config, IbcCallbackState, InterchainAccount, OpenAckVersion, CONFIG, IBC_CALLBACK_STATES, - INTERCHAIN_ACCOUNT, INTERCHAIN_TX_IN_PROGRESS, + INTERCHAIN_ACCOUNT, }; const ICA_ID: &str = "funder"; @@ -58,7 +58,6 @@ pub fn instantiate( }, )?; INTERCHAIN_ACCOUNT.save(deps.storage, &None)?; - INTERCHAIN_TX_IN_PROGRESS.save(deps.storage, &false)?; IBC_CALLBACK_STATES.save(deps.storage, &vec![])?; Ok(Response::default()) @@ -71,12 +70,6 @@ pub fn execute( info: MessageInfo, msg: ExecuteMsg, ) -> NeutronResult> { - if INTERCHAIN_TX_IN_PROGRESS.load(deps.storage)? { - return Err(NeutronError::Std(StdError::generic_err( - "interchain transaction is in progress", - ))); - } - match msg { ExecuteMsg::CreateHubICA {} => execute_create_hub_ica(deps, env, info), ExecuteMsg::SendClaimedTokensToICA {} => { @@ -112,8 +105,6 @@ fn execute_send_claimed_tokens_to_ica( env: Env, info: MessageInfo, ) -> NeutronResult> { - INTERCHAIN_TX_IN_PROGRESS.save(deps.storage, &true)?; - let config = CONFIG.load(deps.storage)?; let ica = INTERCHAIN_ACCOUNT.load(deps.storage)?.ok_or_else(|| { NeutronError::Std(StdError::generic_err( @@ -161,7 +152,6 @@ fn execute_fund_community_pool( info: MessageInfo, amount: Uint128, ) -> NeutronResult> { - INTERCHAIN_TX_IN_PROGRESS.save(deps.storage, &true)?; let config = CONFIG.load(deps.storage)?; let ica = INTERCHAIN_ACCOUNT.load(deps.storage)?.ok_or_else(|| { NeutronError::Std(StdError::generic_err( @@ -213,7 +203,6 @@ fn execute_fund_community_pool( pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { QueryMsg::InterchainAccount {} => query_interchain_account(deps), - QueryMsg::InterchainTxInProgress {} => query_interchain_tx_in_progress(deps), QueryMsg::IbcCallbackStates {} => query_ibc_callback_states(deps), } } @@ -223,11 +212,6 @@ fn query_interchain_account(deps: Deps) -> StdResult { to_binary(&ica) } -fn query_interchain_tx_in_progress(deps: Deps) -> StdResult { - let ica_in_progress = INTERCHAIN_TX_IN_PROGRESS.load(deps.storage)?; - to_binary(&ica_in_progress) -} - fn query_ibc_callback_states(deps: Deps) -> StdResult { let states = IBC_CALLBACK_STATES.load(deps.storage)?; to_binary(&states) @@ -262,8 +246,6 @@ fn sudo_response( request: RequestPacket, _data: Binary, ) -> StdResult { - INTERCHAIN_TX_IN_PROGRESS.save(deps.storage, &false)?; - save_ibc_callback_state( deps.storage, IbcCallbackState::Response(request, env.block.height), @@ -278,8 +260,6 @@ fn sudo_error( request: RequestPacket, details: String, ) -> StdResult { - INTERCHAIN_TX_IN_PROGRESS.save(deps.storage, &false)?; - save_ibc_callback_state( deps.storage, IbcCallbackState::Error(request, details, env.block.height), @@ -290,8 +270,7 @@ fn sudo_error( // can be called by response of create ica, ibc transfer and fund community pool fn sudo_timeout(deps: DepsMut, env: Env, request: RequestPacket) -> StdResult { - INTERCHAIN_TX_IN_PROGRESS.save(deps.storage, &false)?; - + // save into callback state and cleanup ICA let source_port = request .source_port .clone() diff --git a/src/msg.rs b/src/msg.rs index 0ce61cb..e974583 100644 --- a/src/msg.rs +++ b/src/msg.rs @@ -34,9 +34,6 @@ pub enum QueryMsg { #[returns(Option)] InterchainAccount {}, - #[returns(bool)] - InterchainTxInProgress {}, - #[returns(Vec)] IbcCallbackStates {}, } diff --git a/src/state.rs b/src/state.rs index 41f29f5..9f168a3 100644 --- a/src/state.rs +++ b/src/state.rs @@ -6,9 +6,6 @@ pub const CONFIG: Item = Item::new("config"); pub const INTERCHAIN_ACCOUNT: Item> = Item::new("interchain_account"); -// if true, interchain operation is in progress and we cannot make an operation -pub const INTERCHAIN_TX_IN_PROGRESS: Item = Item::new("interchain_tx_in_progress"); - // to understand what happened with IBC calls pub const IBC_CALLBACK_STATES: Item> = Item::new("ibc_callback_states"); From 6b4c0f3029d17b36076d066d23ba6e1023054a09 Mon Sep 17 00:00:00 2001 From: nhpd Date: Fri, 17 Nov 2023 13:33:27 +0400 Subject: [PATCH 2/2] feat: specify amount in the initialize message --- integration-tests/testcases/claimer.test.ts | 20 ++++++++++++++++---- src/contract.rs | 13 ++++++++----- src/msg.rs | 8 +++++++- src/state.rs | 2 ++ 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/integration-tests/testcases/claimer.test.ts b/integration-tests/testcases/claimer.test.ts index 91a234a..76accac 100644 --- a/integration-tests/testcases/claimer.test.ts +++ b/integration-tests/testcases/claimer.test.ts @@ -83,6 +83,7 @@ describe('Test claimer artifact', () => { transfer_channel_id: transferChannel.channel_id, // neutron to cosmoshub transfer channel id ibc_neutron_denom: ibcDenom, ibc_timeout_seconds: 3600 * 5, + amount: '14000', }, 'credits', 'auto', { admin: deployer // want to be able to migrate contract for testing purposes (set low timeout values) }) @@ -106,7 +107,7 @@ describe('Test claimer artifact', () => { await expect(() => client.execute(deployer, claimerAddress, { - fund_community_pool: { amount: '9000' }, + fund_community_pool: { }, }, 'auto', '', []) ).rejects.toThrowError(/ica is not created or open/) }) @@ -235,7 +236,7 @@ describe('Test claimer artifact', () => { const callbackStatesLengthBefore = (await client.queryContractSmart(claimerAddress, { ibc_callback_states: {} })).length await client.execute(deployer, claimerAddress, { - fund_community_pool: { amount: '14000' }, + fund_community_pool: { }, }, 'auto', 'fund community pool', [{ amount: '8000', denom: 'untrn' }]) // wait until interchain tx is not in progress @@ -274,9 +275,14 @@ describe('Test claimer artifact', () => { it('[error] fund community pool', async () => { const callbackStatesLengthBefore = (await client.queryContractSmart(claimerAddress, { ibc_callback_states: {} })).length + // migrate to big amount + await client.migrate(deployer, claimerAddress, claimerCodeId, { + amount: '200000', + }, 'auto') + // run step 3 with amount that is too big await client.execute(deployer, claimerAddress, { - fund_community_pool: { amount: '125000' }, + fund_community_pool: { }, }, 'auto', '', [{ amount: '8000', denom: 'untrn' }]) // wait until interchain tx is not in progress @@ -291,13 +297,19 @@ describe('Test claimer artifact', () => { const callbackStates = await client.queryContractSmart(claimerAddress, { ibc_callback_states: {} }) expect(callbackStates.length).toEqual(callbackStatesLengthBefore + 1) expect(callbackStates[callbackStates.length - 1].error[0].source_port).toEqual(ica.port_id) + + // returns back original amount + // migrate to big amount + await client.migrate(deployer, claimerAddress, claimerCodeId, { + amount: '14000', + }, 'auto') }) it('[success] fund community pool', async () => { const callbackStatesLengthBefore = (await client.queryContractSmart(claimerAddress, { ibc_callback_states: {} })).length await client.execute(deployer, claimerAddress, { - fund_community_pool: { amount: '14000' }, + fund_community_pool: { }, }, 'auto', '', [{ amount: '8000', denom: 'untrn' }]) // wait until interchain tx is not in progress diff --git a/src/contract.rs b/src/contract.rs index 7d80e23..c143c1f 100644 --- a/src/contract.rs +++ b/src/contract.rs @@ -55,6 +55,7 @@ pub fn instantiate( transfer_channel_id: msg.transfer_channel_id, ibc_neutron_denom: msg.ibc_neutron_denom, ibc_timeout_seconds: msg.ibc_timeout_seconds, + amount: msg.amount, }, )?; INTERCHAIN_ACCOUNT.save(deps.storage, &None)?; @@ -75,9 +76,7 @@ pub fn execute( ExecuteMsg::SendClaimedTokensToICA {} => { execute_send_claimed_tokens_to_ica(deps, env, info) } - ExecuteMsg::FundCommunityPool { amount } => { - execute_fund_community_pool(deps, env, info, amount) - } + ExecuteMsg::FundCommunityPool {} => execute_fund_community_pool(deps, env, info), } } @@ -150,7 +149,6 @@ fn execute_fund_community_pool( deps: DepsMut, _env: Env, info: MessageInfo, - amount: Uint128, ) -> NeutronResult> { let config = CONFIG.load(deps.storage)?; let ica = INTERCHAIN_ACCOUNT.load(deps.storage)?.ok_or_else(|| { @@ -161,7 +159,7 @@ fn execute_fund_community_pool( let coin = CosmosCoin { denom: config.ibc_neutron_denom.to_string(), - amount: amount.to_string(), + amount: config.amount.to_string(), }; let ica_msg = MsgFundCommunityPool { @@ -384,6 +382,11 @@ pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> StdResult if let Some(ibc_timeout_seconds) = msg.ibc_timeout_seconds { config.ibc_timeout_seconds = ibc_timeout_seconds; } + + if let Some(amount) = msg.amount { + config.amount = amount; + } + config }; CONFIG.save(deps.storage, &new_config)?; diff --git a/src/msg.rs b/src/msg.rs index e974583..1b89a94 100644 --- a/src/msg.rs +++ b/src/msg.rs @@ -14,6 +14,9 @@ pub struct InstantiateMsg { /// relative timeout for ica transactions pub ibc_timeout_seconds: u64, + + /// amount of tokens to fund community pool + pub amount: Uint128, } #[cw_serde] @@ -25,7 +28,7 @@ pub enum ExecuteMsg { SendClaimedTokensToICA {}, /// Requires ICA to be created and open. Funds cosmoshub community pool with given `amount` of funds. - FundCommunityPool { amount: Uint128 }, + FundCommunityPool {}, } #[cw_serde] @@ -46,4 +49,7 @@ pub struct MigrateMsg { // ica address to send funds to pub ica_address: Option, + + // amount to fund community pool + pub amount: Option, } diff --git a/src/state.rs b/src/state.rs index 9f168a3..57778c1 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,4 +1,5 @@ use cosmwasm_schema::cw_serde; +use cosmwasm_std::Uint128; use cw_storage_plus::Item; use neutron_sdk::sudo::msg::RequestPacket; @@ -15,6 +16,7 @@ pub struct Config { pub transfer_channel_id: String, pub ibc_neutron_denom: String, pub ibc_timeout_seconds: u64, + pub amount: Uint128, } #[cw_serde]