Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: refactor ICQ module documentation [NTRN-349] #367

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/helpers/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,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';
Expand Down
5 changes: 3 additions & 2 deletions src/helpers/interchainqueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ export const getRegisteredQuery = async (
contractAddress: string,
queryId: number,
): Promise<{
id: number;
id: string;
owner: string;
keys: {
path: string;
Expand Down Expand Up @@ -634,7 +634,7 @@ export const registerTransfersQuery = async (
connectionId: string,
updatePeriod: number,
recipients: string[],
) => {
): Promise<number> => {
const res = await client.execute(contractAddress, {
register_transfers_query: {
connection_id: connectionId,
Expand All @@ -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'));
};

/**
Expand Down
18 changes: 6 additions & 12 deletions src/testcases/parallel/ibc_transfer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
132 changes: 132 additions & 0 deletions src/testcases/parallel/icq_howto_register_custom_kv_icq.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
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 { 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';

const CONNECTION_ID = 'connection-0';
const ICQ_UPDATE_PERIOD = 5;

describe(
'Neutron / docs / interchainqueries / howto / register KV ICQ with custom keys',
{},
() => {
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 getWithAttempts(
neutronClient,
async (): Promise<BaseAccount> =>
await neutronClient.queryContractSmart(contractAddress, {
account: { address: WATCHED_GAIA_ADDR },
}),
async (response) =>
response.address == WATCHED_GAIA_ADDR &&
response.sequence == BigInt(0) &&
response.accountNumber != BigInt(0),
);
});
});
},
);
132 changes: 132 additions & 0 deletions src/testcases/parallel/icq_howto_register_kv_icq.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import config from '../../config.json';
import { inject, RunnerTestSuite } from 'vitest';
import { LocalState } from '../../helpers/local_state';
import { Registry, Coin } 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';

// 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 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,
);
});
});
},
);
Loading
Loading