From 7fefd4e90ad39d172522d64ebe4b1d1b6cdaccb8 Mon Sep 17 00:00:00 2001 From: sotnikov-s Date: Fri, 8 Nov 2024 13:24:51 +0300 Subject: [PATCH 1/4] add tests for ICQ module howtos --- src/helpers/constants.ts | 5 + .../icq_howto_register_custom_kv_icq.test.ts | 129 ++++++++++++++ .../icq_howto_register_kv_icq.test.ts | 134 +++++++++++++++ .../icq_howto_register_tx_icq.test.ts | 162 ++++++++++++++++++ 4 files changed, 430 insertions(+) create mode 100644 src/testcases/parallel/icq_howto_register_custom_kv_icq.test.ts create mode 100644 src/testcases/parallel/icq_howto_register_kv_icq.test.ts create mode 100644 src/testcases/parallel/icq_howto_register_tx_icq.test.ts diff --git a/src/helpers/constants.ts b/src/helpers/constants.ts index a3657ac0..1648bcd4 100644 --- a/src/helpers/constants.ts +++ b/src/helpers/constants.ts @@ -76,6 +76,11 @@ export const CONTRACTS = { MARKETMAP: 'marketmap.wasm', ORACLE: 'oracle.wasm', IBC_RATE_LIMITER: 'rate_limiter.wasm', + + // docs related contracts + HOWTO_REGISTER_KV_ICQ: 'howto_register_kv_icq.wasm', + HOWTO_REGISTER_CUSTOM_KV_ICQ: 'howto_register_custom_kv_icq.wasm', + HOWTO_REGISTER_TX_ICQ: 'howto_register_tx_icq.wasm', }; export const NEUTRON_PREFIX = process.env.NEUTRON_ADDRESS_PREFIX || 'neutron'; diff --git a/src/testcases/parallel/icq_howto_register_custom_kv_icq.test.ts b/src/testcases/parallel/icq_howto_register_custom_kv_icq.test.ts new file mode 100644 index 00000000..b5e60901 --- /dev/null +++ b/src/testcases/parallel/icq_howto_register_custom_kv_icq.test.ts @@ -0,0 +1,129 @@ +import config from '../../config.json'; +import { inject, RunnerTestSuite } from 'vitest'; +import { LocalState } from '../../helpers/local_state'; +import { Registry } from '@cosmjs/proto-signing'; +import { Wallet } from '../../helpers/wallet'; +import { defaultRegistryTypes, SigningStargateClient } from '@cosmjs/stargate'; +import { + COSMOS_DENOM, + CONTRACTS, + NEUTRON_DENOM, +} from '../../helpers/constants'; +import { GasPrice } from '@cosmjs/stargate/build/fee'; +import { SigningNeutronClient } from '../../helpers/signing_neutron_client'; +import { waitBlocks } from '@neutron-org/neutronjsplus/dist/wait'; + +// just a fresh test-specific address. don't use it in other parallel test cases to avoid races +const WATCHED_GAIA_ADDR = 'cosmos1yfhvt7uje9ztwr9mk6xnkg0thf83r2d53w38ja'; + +const CONNECTION_ID = 'connection-0'; +const ICQ_UPDATE_PERIOD = 5; + +describe( + 'Neutron / docs / interchainqueries / howto / register KV ICQ', + {}, + () => { + let testState: LocalState; + let gaiaClient: SigningStargateClient; + let gaiaAddress: string; + let neutronWallet: Wallet; + let neutronClient: SigningNeutronClient; + + beforeAll(async (suite: RunnerTestSuite) => { + testState = await LocalState.create(config, inject('mnemonics'), suite); + neutronWallet = await testState.nextWallet('neutron'); + + const galaWallet = await testState.nextWallet('cosmos'); + gaiaClient = await SigningStargateClient.connectWithSigner( + testState.rpcGaia, + galaWallet.directwallet, + { + registry: new Registry(defaultRegistryTypes), + gasPrice: GasPrice.fromString('0.05uatom'), + }, + ); + gaiaAddress = ( + await galaWallet.directwallet.getAccounts() + )[0].address.toString(); + + neutronClient = await SigningNeutronClient.connectWithSigner( + testState.rpcNeutron, + neutronWallet.directwallet, + neutronWallet.address, + ); + + await gaiaClient.sendTokens( + gaiaAddress, + WATCHED_GAIA_ADDR, + [ + { + amount: '1000000', + denom: COSMOS_DENOM, + }, + ], + 300000, + ); + }); + + let contractAddress: string; + describe('instantiate contract', () => { + let codeId: number; + test('store contract', async () => { + codeId = await neutronClient.upload( + CONTRACTS.HOWTO_REGISTER_CUSTOM_KV_ICQ, + ); + expect(codeId).toBeGreaterThan(0); + }); + test('instantiate contract', async () => { + contractAddress = await neutronClient.instantiate( + codeId, + {}, + 'howto_register_custom_kv_icq', + ); + }); + }); + + describe('register and execute KV ICQ', () => { + test('top up contract', async () => { + await neutronClient.sendTokens( + contractAddress, + [{ denom: NEUTRON_DENOM, amount: '1000000' }], + { + gas: '200000', + amount: [{ denom: NEUTRON_DENOM, amount: '1000' }], + }, + ); + }); + + test('register KV ICQ', async () => { + await neutronClient.execute( + contractAddress, + { + register_account_query: { + connection_id: CONNECTION_ID, + addr: WATCHED_GAIA_ADDR, + update_period: ICQ_UPDATE_PERIOD, + }, + }, + [], + { + amount: [{ denom: NEUTRON_DENOM, amount: '1000000' }], + gas: '2000000', + }, + ); + }); + + test('check ICQ submitted value result', async () => { + await waitBlocks(ICQ_UPDATE_PERIOD, neutronClient); + + const queryResult = await neutronClient.queryContractSmart( + contractAddress, + { account: { address: WATCHED_GAIA_ADDR } }, + ); + expect(queryResult.address).toEqual(WATCHED_GAIA_ADDR); + expect(+queryResult.sequence).toEqual(0); + expect(+queryResult.account_number).not.toEqual(0); + }); + }); + }, +); diff --git a/src/testcases/parallel/icq_howto_register_kv_icq.test.ts b/src/testcases/parallel/icq_howto_register_kv_icq.test.ts new file mode 100644 index 00000000..9f5e2247 --- /dev/null +++ b/src/testcases/parallel/icq_howto_register_kv_icq.test.ts @@ -0,0 +1,134 @@ +import config from '../../config.json'; +import { inject, RunnerTestSuite } from 'vitest'; +import { LocalState } from '../../helpers/local_state'; +import { Registry } from '@cosmjs/proto-signing'; +import { Wallet } from '../../helpers/wallet'; +import { defaultRegistryTypes, SigningStargateClient } from '@cosmjs/stargate'; +import { + COSMOS_DENOM, + CONTRACTS, + NEUTRON_DENOM, +} from '../../helpers/constants'; +import { GasPrice } from '@cosmjs/stargate/build/fee'; +import { SigningNeutronClient } from '../../helpers/signing_neutron_client'; +import { waitBlocks } from '@neutron-org/neutronjsplus/dist/wait'; + +// just a fresh test-specific address. don't use it in other parallel test cases to avoid races +const WATCHED_GAIA_ADDR = 'cosmos1gdzru2fzdn7czxn89phu9ergn7v8c7zpladz6f'; + +const WATCHED_GAIA_ADDR_BALANCE_UATOM = 100000; +const CONNECTION_ID = 'connection-0'; +const ICQ_UPDATE_PERIOD = 5; + +describe( + 'Neutron / docs / interchainqueries / howto / register KV ICQ', + {}, + () => { + let testState: LocalState; + let gaiaClient: SigningStargateClient; + let gaiaAddress: string; + let neutronWallet: Wallet; + let neutronClient: SigningNeutronClient; + + beforeAll(async (suite: RunnerTestSuite) => { + testState = await LocalState.create(config, inject('mnemonics'), suite); + neutronWallet = await testState.nextWallet('neutron'); + + const galaWallet = await testState.nextWallet('cosmos'); + gaiaClient = await SigningStargateClient.connectWithSigner( + testState.rpcGaia, + galaWallet.directwallet, + { + registry: new Registry(defaultRegistryTypes), + gasPrice: GasPrice.fromString('0.05uatom'), + }, + ); + gaiaAddress = ( + await galaWallet.directwallet.getAccounts() + )[0].address.toString(); + + neutronClient = await SigningNeutronClient.connectWithSigner( + testState.rpcNeutron, + neutronWallet.directwallet, + neutronWallet.address, + ); + + await gaiaClient.sendTokens( + gaiaAddress, + WATCHED_GAIA_ADDR, + [ + { + amount: WATCHED_GAIA_ADDR_BALANCE_UATOM.toString(), + denom: COSMOS_DENOM, + }, + ], + 300000, + ); + }); + + let contractAddress: string; + describe('instantiate contract', () => { + let codeId: number; + test('store contract', async () => { + codeId = await neutronClient.upload(CONTRACTS.HOWTO_REGISTER_KV_ICQ); + expect(codeId).toBeGreaterThan(0); + }); + test('instantiate contract', async () => { + contractAddress = await neutronClient.instantiate( + codeId, + {}, + 'howto_register_kv_icq', + ); + }); + }); + + describe('register and execute KV ICQ', () => { + test('top up contract', async () => { + await neutronClient.sendTokens( + contractAddress, + [{ denom: NEUTRON_DENOM, amount: '1000000' }], + { + gas: '200000', + amount: [{ denom: NEUTRON_DENOM, amount: '1000' }], + }, + ); + }); + + test('register KV ICQ', async () => { + await neutronClient.execute( + contractAddress, + { + register_balances_query: { + connection_id: CONNECTION_ID, + denoms: [COSMOS_DENOM], + addr: WATCHED_GAIA_ADDR, + update_period: ICQ_UPDATE_PERIOD, + }, + }, + [], + { + amount: [{ denom: NEUTRON_DENOM, amount: '1000000' }], + gas: '2000000', + }, + ); + }); + + test('check ICQ submitted value result', async () => { + await waitBlocks(ICQ_UPDATE_PERIOD, neutronClient); + + const queryResult = await neutronClient.queryContractSmart( + contractAddress, + { balances: { address: WATCHED_GAIA_ADDR } }, + ); + expect(queryResult).toEqual({ + coins: [ + { + denom: COSMOS_DENOM, + amount: WATCHED_GAIA_ADDR_BALANCE_UATOM.toString(), + }, + ], + }); + }); + }); + }, +); diff --git a/src/testcases/parallel/icq_howto_register_tx_icq.test.ts b/src/testcases/parallel/icq_howto_register_tx_icq.test.ts new file mode 100644 index 00000000..579abed8 --- /dev/null +++ b/src/testcases/parallel/icq_howto_register_tx_icq.test.ts @@ -0,0 +1,162 @@ +import config from '../../config.json'; +import { inject, RunnerTestSuite } from 'vitest'; +import { LocalState } from '../../helpers/local_state'; +import { Coin, Registry } from '@cosmjs/proto-signing'; +import { Wallet } from '../../helpers/wallet'; +import { defaultRegistryTypes, SigningStargateClient } from '@cosmjs/stargate'; +import { + COSMOS_DENOM, + CONTRACTS, + NEUTRON_DENOM, +} from '../../helpers/constants'; +import { GasPrice } from '@cosmjs/stargate/build/fee'; +import { SigningNeutronClient } from '../../helpers/signing_neutron_client'; +import { getWithAttempts } from '@neutron-org/neutronjsplus/dist/wait'; + +const CONNECTION_ID = 'connection-0'; +const ICQ_UPDATE_PERIOD = 5; +const GAIA_VAL_ADDR = 'cosmosvaloper18hl5c9xn5dze2g50uaw0l2mr02ew57zk0auktn'; +const DELEGATION_AMOUNT = 1000000; + +describe( + 'Neutron / docs / interchainqueries / howto / register TX ICQ', + {}, + () => { + let testState: LocalState; + let gaiaClient: SigningStargateClient; + let gaiaWallet: Wallet; + let neutronWallet: Wallet; + let neutronClient: SigningNeutronClient; + + beforeAll(async (suite: RunnerTestSuite) => { + testState = await LocalState.create(config, inject('mnemonics'), suite); + + neutronWallet = await testState.nextWallet('neutron'); + neutronClient = await SigningNeutronClient.connectWithSigner( + testState.rpcNeutron, + neutronWallet.directwallet, + neutronWallet.address, + ); + + gaiaWallet = await testState.nextWallet('cosmos'); + gaiaClient = await SigningStargateClient.connectWithSigner( + testState.rpcGaia, + gaiaWallet.directwallet, + { + registry: new Registry(defaultRegistryTypes), + gasPrice: GasPrice.fromString('0.05uatom'), + }, + ); + + let resp = await gaiaClient.delegateTokens( + gaiaWallet.address.toString(), + GAIA_VAL_ADDR, + { amount: DELEGATION_AMOUNT.toString(), denom: COSMOS_DENOM }, + 'auto', + ); + expect(resp.code).toBe(0); + await getWithAttempts( + gaiaClient, + async () => + await gaiaClient.getDelegation( + gaiaWallet.address.toString(), + GAIA_VAL_ADDR, + ), + async (response) => response.amount == DELEGATION_AMOUNT.toString(), + ); + + resp = await gaiaClient.undelegateTokens( + gaiaWallet.address.toString(), + GAIA_VAL_ADDR, + { amount: (DELEGATION_AMOUNT / 2).toString(), denom: COSMOS_DENOM }, + 'auto', + ); + expect(resp.code).toBe(0); + }); + + let contractAddress: string; + describe('instantiate contract', () => { + let codeId: number; + test('store contract', async () => { + codeId = await neutronClient.upload(CONTRACTS.HOWTO_REGISTER_TX_ICQ); + expect(codeId).toBeGreaterThan(0); + }); + test('instantiate contract', async () => { + contractAddress = await neutronClient.instantiate( + codeId, + {}, + 'howto_register_custom_tx_icq', + ); + }); + }); + + describe('register and execute TX ICQ', () => { + test('top up contract', async () => { + await neutronClient.sendTokens( + contractAddress, + [{ denom: NEUTRON_DENOM, amount: '1000000' }], + { + gas: '200000', + amount: [{ denom: NEUTRON_DENOM, amount: '1000' }], + }, + ); + }); + + test('register TX ICQ', async () => { + await neutronClient.execute( + contractAddress, + { + register_undelegations_query: { + connection_id: CONNECTION_ID, + addr: gaiaWallet.address.toString(), + update_period: ICQ_UPDATE_PERIOD, + }, + }, + [], + { + amount: [{ denom: NEUTRON_DENOM, amount: '1000000' }], + gas: '2000000', + }, + ); + }); + + describe('check ICQ submitted value result', () => { + test('beforeAll undelegation result submission', async () => { + await getWithAttempts( + neutronClient, + async (): Promise => + await neutronClient.queryContractSmart(contractAddress, { + undelegated_amount: { address: gaiaWallet.address.toString() }, + }), + async (response) => + response.length == 1 && + response[0].amount == (DELEGATION_AMOUNT / 2).toString(), + ); + }); + + test('undelegate once more', async () => { + const resp = await gaiaClient.undelegateTokens( + gaiaWallet.address.toString(), + GAIA_VAL_ADDR, + { amount: (DELEGATION_AMOUNT / 4).toString(), denom: COSMOS_DENOM }, + 'auto', + ); + expect(resp.code).toBe(0); + }); + + test('one more undelegation result submission', async () => { + await getWithAttempts( + neutronClient, + async (): Promise => + await neutronClient.queryContractSmart(contractAddress, { + undelegated_amount: { address: gaiaWallet.address.toString() }, + }), + async (response) => + response.length == 2 && + response[1].amount == (DELEGATION_AMOUNT / 4).toString(), + ); + }); + }); + }); + }, +); From 6dcaf33044fab0099aa43cb463763f8c43225669 Mon Sep 17 00:00:00 2001 From: sotnikov-s Date: Thu, 14 Nov 2024 17:29:38 +0300 Subject: [PATCH 2/4] fix race in TX ICQ resubmit test and fix ICQ ID field type --- src/helpers/interchainqueries.ts | 5 +++-- .../interchain_tx_query_resubmit.test.ts | 11 ++++++++--- .../run_in_band/interchain_kv_query.test.ts | 18 +++++++++--------- .../interchain_tx_query_plain.test.ts | 14 +++++++------- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/helpers/interchainqueries.ts b/src/helpers/interchainqueries.ts index 51bc596f..7e641652 100644 --- a/src/helpers/interchainqueries.ts +++ b/src/helpers/interchainqueries.ts @@ -511,7 +511,7 @@ export const getRegisteredQuery = async ( contractAddress: string, queryId: number, ): Promise<{ - id: number; + id: string; owner: string; keys: { path: string; @@ -634,7 +634,7 @@ export const registerTransfersQuery = async ( connectionId: string, updatePeriod: number, recipients: string[], -) => { +): Promise => { const res = await client.execute(contractAddress, { register_transfers_query: { connection_id: connectionId, @@ -646,6 +646,7 @@ export const registerTransfersQuery = async ( if (res.code != 0) { throw new Error('res.code != 0'); } + return parseInt(getEventAttribute(res.events, 'neutron', 'query_id')); }; /** diff --git a/src/testcases/parallel/interchain_tx_query_resubmit.test.ts b/src/testcases/parallel/interchain_tx_query_resubmit.test.ts index b1ae758d..9f2bb5f2 100644 --- a/src/testcases/parallel/interchain_tx_query_resubmit.test.ts +++ b/src/testcases/parallel/interchain_tx_query_resubmit.test.ts @@ -71,6 +71,7 @@ describe('Neutron / Interchain TX Query Resubmit', () => { const watchedAddr1: string = addrFirst; const query1UpdatePeriod = 4; + let queryId: number; describe('utilise single transfers query', () => { test('register transfers query', async () => { // Top up contract address before running query @@ -82,7 +83,7 @@ describe('Neutron / Interchain TX Query Resubmit', () => { amount: [{ denom: NEUTRON_DENOM, amount: '1000' }], }, ); - await registerTransfersQuery( + queryId = await registerTransfersQuery( neutronClient, contractAddress, connectionId, @@ -92,8 +93,12 @@ describe('Neutron / Interchain TX Query Resubmit', () => { }); test('check registered transfers query', async () => { - const query = await getRegisteredQuery(neutronClient, contractAddress, 1); - expect(query.id).toEqual('1'); + const query = await getRegisteredQuery( + neutronClient, + contractAddress, + queryId, + ); + expect(+query.id).toEqual(queryId); expect(query.owner).toEqual(contractAddress); expect(query.keys.length).toEqual(0); expect(query.query_type).toEqual('tx'); diff --git a/src/testcases/run_in_band/interchain_kv_query.test.ts b/src/testcases/run_in_band/interchain_kv_query.test.ts index 1e589183..417b07e9 100644 --- a/src/testcases/run_in_band/interchain_kv_query.test.ts +++ b/src/testcases/run_in_band/interchain_kv_query.test.ts @@ -373,7 +373,7 @@ describe('Neutron / Interchain KV Query', () => { contractAddress, queryId, ); - expect(queryResult.id).toEqual(queryId.toString()); + expect(+queryResult.id).toEqual(queryId); expect(queryResult.owner).toEqual(contractAddress); expect(queryResult.keys.length).toEqual(1); expect(queryResult.keys[0].path).toEqual('bank'); @@ -394,7 +394,7 @@ describe('Neutron / Interchain KV Query', () => { contractAddress, queryId, ); - expect(queryResult.id).toEqual(queryId.toString()); + expect(+queryResult.id).toEqual(queryId); expect(queryResult.keys.length).toEqual(1); expect(queryResult.update_period).toEqual( updatePeriods[queryId].toString(), @@ -408,7 +408,7 @@ describe('Neutron / Interchain KV Query', () => { contractAddress, queryId, ); - expect(queryResult.id).toEqual(queryId.toString()); + expect(+queryResult.id).toEqual(queryId); expect(queryResult.owner).toEqual(contractAddress); // we expect three keys, 1 always + 2 per validator expect(queryResult.keys.length).toEqual(3); @@ -427,7 +427,7 @@ describe('Neutron / Interchain KV Query', () => { contractAddress, queryId, ); - expect(queryResult.id).toEqual(queryId.toString()); + expect(+queryResult.id).toEqual(queryId); expect(queryResult.owner).toEqual(contractAddress); expect(queryResult.keys.length).toEqual(2); expect(queryResult.keys[0].path).toEqual('bank'); @@ -449,7 +449,7 @@ describe('Neutron / Interchain KV Query', () => { contractAddress, queryId, ); - expect(queryResult.id).toEqual(queryId.toString()); + expect(+queryResult.id).toEqual(queryId); expect(queryResult.owner).toEqual(contractAddress); expect(queryResult.keys.length).toEqual(100); for (let i = 0; i < queryResult.keys.length; i++) { @@ -961,7 +961,7 @@ describe('Neutron / Interchain KV Query', () => { contractAddress, queryId, ); - expect(queryResult.id).toEqual(queryId.toString()); + expect(+queryResult.id).toEqual(queryId); expect(queryResult.owner).toEqual(contractAddress); // XXX: I could actually check that "key" is correctly derived from contractAddress, // but this requires bech32 decoding/encoding shenanigans @@ -1042,7 +1042,7 @@ describe('Neutron / Interchain KV Query', () => { contractAddress, queryId, ); - expect(queryResult.id).toEqual(queryId.toString()); + expect(+queryResult.id).toEqual(queryId); expect(queryResult.owner).toEqual(contractAddress); // XXX: I could actually check that "key" is correctly derived from contractAddress, // but this requires bech32 decoding/encoding shenanigans @@ -1148,7 +1148,7 @@ describe('Neutron / Interchain KV Query', () => { contractAddress, queryId, ); - expect(queryResult.id).toEqual(queryId.toString()); + expect(+queryResult.id).toEqual(queryId); expect(queryResult.owner).toEqual(contractAddress); expect(queryResult.keys.length).toEqual(1); expect(queryResult.keys[0].path).toEqual('slashing'); @@ -1232,7 +1232,7 @@ describe('Neutron / Interchain KV Query', () => { contractAddress, queryId, ); - expect(queryResult.id).toEqual(queryId.toString()); + expect(+queryResult.id).toEqual(queryId); expect(queryResult.owner).toEqual(contractAddress); expect(queryResult.keys.length).toEqual(1); expect(queryResult.keys[0].path).toEqual('staking'); diff --git a/src/testcases/run_in_band/interchain_tx_query_plain.test.ts b/src/testcases/run_in_band/interchain_tx_query_plain.test.ts index 923ee031..7944aba0 100644 --- a/src/testcases/run_in_band/interchain_tx_query_plain.test.ts +++ b/src/testcases/run_in_band/interchain_tx_query_plain.test.ts @@ -136,7 +136,7 @@ describe('Neutron / Interchain TX Query', () => { test('check registered transfers query', async () => { const query = await getRegisteredQuery(neutronClient, contractAddress, 1); - expect(query.id).toEqual('1'); + expect(+query.id).toEqual(1); expect(query.owner).toEqual(contractAddress); expect(query.keys.length).toEqual(0); expect(query.query_type).toEqual('tx'); @@ -299,7 +299,7 @@ describe('Neutron / Interchain TX Query', () => { test('check registered transfers query', async () => { const query = await getRegisteredQuery(neutronClient, contractAddress, 2); - expect(query.id).toEqual('2'); + expect(+query.id).toEqual(2); expect(query.owner).toEqual(contractAddress); expect(query.keys.length).toEqual(0); expect(query.query_type).toEqual('tx'); @@ -368,7 +368,7 @@ describe('Neutron / Interchain TX Query', () => { test('check registered transfers query', async () => { const query = await getRegisteredQuery(neutronClient, contractAddress, 3); - expect(query.id).toEqual('3'); + expect(+query.id).toEqual(3); expect(query.owner).toEqual(contractAddress); expect(query.keys.length).toEqual(0); expect(query.query_type).toEqual('tx'); @@ -698,7 +698,7 @@ describe('Neutron / Interchain TX Query', () => { test('check registered transfers query', async () => { let query = await getRegisteredQuery(neutronClient, contractAddress, 4); - expect(query.id).toEqual('4'); + expect(+query.id).toEqual(4); expect(query.owner).toEqual(contractAddress); expect(query.keys.length).toEqual(0); expect(query.query_type).toEqual('tx'); @@ -711,7 +711,7 @@ describe('Neutron / Interchain TX Query', () => { expect(query.update_period).toEqual(query4UpdatePeriod.toString()); query = await getRegisteredQuery(neutronClient, contractAddress, 5); - expect(query.id).toEqual('5'); + expect(+query.id).toEqual(5); expect(query.owner).toEqual(contractAddress); expect(query.keys.length).toEqual(0); expect(query.query_type).toEqual('tx'); @@ -845,7 +845,7 @@ describe('Neutron / Interchain TX Query', () => { test('check registered transfers query', async () => { const query = await getRegisteredQuery(neutronClient, contractAddress, 6); - expect(query.id).toEqual('6'); + expect(+query.id).toEqual(6); expect(query.owner).toEqual(contractAddress); expect(query.keys.length).toEqual(0); expect(query.query_type).toEqual('tx'); @@ -937,7 +937,7 @@ describe('Neutron / Interchain TX Query', () => { }); it('seems registered transfers query is updated', async () => { const query = await getRegisteredQuery(neutronClient, contractAddress, 3); - expect(query.id).toEqual('3'); + expect(+query.id).toEqual(3); expect(query.owner).toEqual(contractAddress); expect(query.keys.length).toEqual(0); expect(query.query_type).toEqual('tx'); From bd13ff2c52fbc1a376c779ad5914e2d14862c323 Mon Sep 17 00:00:00 2001 From: sotnikov-s Date: Thu, 14 Nov 2024 18:03:47 +0300 Subject: [PATCH 3/4] use getWIthAttempts instead of waitBlocks for howto ICQ tests in ICQ result submission wait --- .../icq_howto_register_custom_kv_icq.test.ts | 23 ++++++++------- .../icq_howto_register_kv_icq.test.ts | 28 +++++++++---------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/testcases/parallel/icq_howto_register_custom_kv_icq.test.ts b/src/testcases/parallel/icq_howto_register_custom_kv_icq.test.ts index b5e60901..c3acb14e 100644 --- a/src/testcases/parallel/icq_howto_register_custom_kv_icq.test.ts +++ b/src/testcases/parallel/icq_howto_register_custom_kv_icq.test.ts @@ -11,7 +11,8 @@ import { } from '../../helpers/constants'; import { GasPrice } from '@cosmjs/stargate/build/fee'; import { SigningNeutronClient } from '../../helpers/signing_neutron_client'; -import { waitBlocks } from '@neutron-org/neutronjsplus/dist/wait'; +import { getWithAttempts } from '@neutron-org/neutronjsplus/dist/wait'; +import { BaseAccount } from '@neutron-org/neutronjs/src/cosmos/auth/v1beta1/auth'; // just a fresh test-specific address. don't use it in other parallel test cases to avoid races const WATCHED_GAIA_ADDR = 'cosmos1yfhvt7uje9ztwr9mk6xnkg0thf83r2d53w38ja'; @@ -20,7 +21,7 @@ const CONNECTION_ID = 'connection-0'; const ICQ_UPDATE_PERIOD = 5; describe( - 'Neutron / docs / interchainqueries / howto / register KV ICQ', + 'Neutron / docs / interchainqueries / howto / register KV ICQ with custom keys', {}, () => { let testState: LocalState; @@ -114,15 +115,17 @@ describe( }); test('check ICQ submitted value result', async () => { - await waitBlocks(ICQ_UPDATE_PERIOD, neutronClient); - - const queryResult = await neutronClient.queryContractSmart( - contractAddress, - { account: { address: WATCHED_GAIA_ADDR } }, + await getWithAttempts( + neutronClient, + async (): Promise => + await neutronClient.queryContractSmart(contractAddress, { + account: { address: WATCHED_GAIA_ADDR }, + }), + async (response) => + response.address == WATCHED_GAIA_ADDR && + response.sequence == BigInt(0) && + response.accountNumber != BigInt(0), ); - expect(queryResult.address).toEqual(WATCHED_GAIA_ADDR); - expect(+queryResult.sequence).toEqual(0); - expect(+queryResult.account_number).not.toEqual(0); }); }); }, diff --git a/src/testcases/parallel/icq_howto_register_kv_icq.test.ts b/src/testcases/parallel/icq_howto_register_kv_icq.test.ts index 9f5e2247..af36bbbf 100644 --- a/src/testcases/parallel/icq_howto_register_kv_icq.test.ts +++ b/src/testcases/parallel/icq_howto_register_kv_icq.test.ts @@ -1,7 +1,7 @@ import config from '../../config.json'; import { inject, RunnerTestSuite } from 'vitest'; import { LocalState } from '../../helpers/local_state'; -import { Registry } from '@cosmjs/proto-signing'; +import { Registry, Coin } from '@cosmjs/proto-signing'; import { Wallet } from '../../helpers/wallet'; import { defaultRegistryTypes, SigningStargateClient } from '@cosmjs/stargate'; import { @@ -11,7 +11,7 @@ import { } from '../../helpers/constants'; import { GasPrice } from '@cosmjs/stargate/build/fee'; import { SigningNeutronClient } from '../../helpers/signing_neutron_client'; -import { waitBlocks } from '@neutron-org/neutronjsplus/dist/wait'; +import { getWithAttempts } from '@neutron-org/neutronjsplus/dist/wait'; // just a fresh test-specific address. don't use it in other parallel test cases to avoid races const WATCHED_GAIA_ADDR = 'cosmos1gdzru2fzdn7czxn89phu9ergn7v8c7zpladz6f'; @@ -114,20 +114,18 @@ describe( }); test('check ICQ submitted value result', async () => { - await waitBlocks(ICQ_UPDATE_PERIOD, neutronClient); - - const queryResult = await neutronClient.queryContractSmart( - contractAddress, - { balances: { address: WATCHED_GAIA_ADDR } }, + await getWithAttempts( + neutronClient, + async (): Promise<{ coins: Coin[] }> => + await neutronClient.queryContractSmart(contractAddress, { + balances: { address: WATCHED_GAIA_ADDR }, + }), + async (response) => + response.coins.length == 1 && + response.coins[0].amount == + WATCHED_GAIA_ADDR_BALANCE_UATOM.toString() && + response.coins[0].denom == COSMOS_DENOM, ); - expect(queryResult).toEqual({ - coins: [ - { - denom: COSMOS_DENOM, - amount: WATCHED_GAIA_ADDR_BALANCE_UATOM.toString(), - }, - ], - }); }); }); }, From 7576e2d62f572b4d0fdee872d6d5844f935de959 Mon Sep 17 00:00:00 2001 From: sotnikov-s Date: Thu, 14 Nov 2024 18:51:47 +0300 Subject: [PATCH 4/4] decrease pause in failing IBC transfer with sudo test --- src/testcases/parallel/ibc_transfer.test.ts | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/testcases/parallel/ibc_transfer.test.ts b/src/testcases/parallel/ibc_transfer.test.ts index 6f41728f..9edcfa73 100644 --- a/src/testcases/parallel/ibc_transfer.test.ts +++ b/src/testcases/parallel/ibc_transfer.test.ts @@ -471,19 +471,13 @@ describe('Neutron / IBC transfer', () => { }, }); - /* - What is going on here. To test SudoTimeout handler functionality - we have to make an IBC package delivery by hermes really slowly. - But, actually there is no any activity on the IBC channel at this stage, as a result - hermes does not send any UpdateClient messages from gaia to neuron. - Gaia keeps building blocks and hermes knows nothing about it. - We get the height =N of the gaia chain, wait 15 blocks. - Send ibc package from neutron from gaia with timeout N+5 - current gaia block is actually N+15, but neutron knows nothing about it, and successfully sends package - hermes checks height on remote chain and Timeout error occurs. - */ + // to test SudoTimeout handler functionality we have to do a late IBC package delivery + // by hermes. We get the height =N of the gaia chain, wait 5 blocks, and send ibc package + // from neutron to gaia with timeout N+5. Current gaia block is N+5, but neutron knows + // nothing about it, and successfully sends package whereas hermes checks height on remote + // chain and Timeout error occurs. const currentHeight = await gaiaClient.getHeight(); - await waitBlocks(15, gaiaClient); + await waitBlocks(5, gaiaClient); await neutronClient.execute(ibcContract, { send: {