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

[NTRN-142] feat: enhance contract failure with error #236

Draft
wants to merge 2 commits into
base: feat/upd-47
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions src/helpers/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ type Failure = {
address: string;
id: string;
sudo_payload: string; // base64 encoded json bytes
error: string;
};

export type ScheduleResponse = {
Expand Down
111 changes: 79 additions & 32 deletions src/testcases/run_in_band/interchaintx.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'jest-extended';
import { execSync } from 'child_process';
import cosmosclient from '@cosmos-client/core';
import { AccAddress } from '@cosmos-client/core/cjs/types';
import {
Expand Down Expand Up @@ -890,44 +891,85 @@ describe('Neutron / Interchain TXs', () => {
test('check stored failures and acks', async () => {
const failures = await neutronChain.queryAckFailures(contractAddress);
// 4 ack failures, 2 timeout failure, just as described in the tests above
expect(failures.failures).toEqual([
expect.objectContaining({
address:
'neutron1m0z0kk0qqug74n9u9ul23e28x5fszr628h20xwt6jywjpp64xn4qatgvm0',
id: '0',
}),
expect.objectContaining({
address:
'neutron1m0z0kk0qqug74n9u9ul23e28x5fszr628h20xwt6jywjpp64xn4qatgvm0',
id: '1',
}),
expect.objectContaining({
address:
'neutron1m0z0kk0qqug74n9u9ul23e28x5fszr628h20xwt6jywjpp64xn4qatgvm0',
id: '2',
}),
expect.objectContaining({
address:
'neutron1m0z0kk0qqug74n9u9ul23e28x5fszr628h20xwt6jywjpp64xn4qatgvm0',
id: '3',
}),
expect.objectContaining({
address:
'neutron1m0z0kk0qqug74n9u9ul23e28x5fszr628h20xwt6jywjpp64xn4qatgvm0',
id: '4',
}),
expect.objectContaining({
address:
'neutron1m0z0kk0qqug74n9u9ul23e28x5fszr628h20xwt6jywjpp64xn4qatgvm0',
id: '5',
}),
]);
expect(failures.failures).toEqual(
expect.arrayContaining([
expect.objectContaining({
address:
'neutron1m0z0kk0qqug74n9u9ul23e28x5fszr628h20xwt6jywjpp64xn4qatgvm0',
id: '0',
error: 'codespace: wasm, code: 5', // execute wasm contract failer
}),
expect.objectContaining({
address:
'neutron1m0z0kk0qqug74n9u9ul23e28x5fszr628h20xwt6jywjpp64xn4qatgvm0',
id: '1',
error: 'codespace: wasm, code: 5', // execute wasm contract failer
}),
expect.objectContaining({
address:
'neutron1m0z0kk0qqug74n9u9ul23e28x5fszr628h20xwt6jywjpp64xn4qatgvm0',
id: '2',
error: 'codespace: wasm, code: 5', // execute wasm contract failer
}),
expect.objectContaining({
address:
'neutron1m0z0kk0qqug74n9u9ul23e28x5fszr628h20xwt6jywjpp64xn4qatgvm0',
id: '3',
error: 'codespace: contractmanager, code: 1103', // contractmanager sudo limit exceeded
}),
expect.objectContaining({
address:
'neutron1m0z0kk0qqug74n9u9ul23e28x5fszr628h20xwt6jywjpp64xn4qatgvm0',
id: '4',
error: 'codespace: wasm, code: 5', // execute wasm contract failer
}),
expect.objectContaining({
address:
'neutron1m0z0kk0qqug74n9u9ul23e28x5fszr628h20xwt6jywjpp64xn4qatgvm0',
id: '5',
error: 'codespace: contractmanager, code: 1103', // contractmanager sudo limit exceeded
}),
]),
);

const acks = await getAcks(neutronChain, contractAddress);
// no acks at all because all sudo handling cases resulted in an error
expect(acks).toEqual([]);
});

describe('get failure details via contractmanager failure-details query', () => {
test('ack failure during sudo', async () => {
expect(queryFailureDetails(contractAddress, 0)).toContain(
'Generic error: Integrations test mock error: execute wasm contract failed',
);
});
test('ack failure during sudo submsg', async () => {
expect(queryFailureDetails(contractAddress, 1)).toContain(
'dispatch: submessages: Generic error: Integrations test mock submsg error: execute wasm contract failed',
);
});
test('ack failure during sudo submsg reply', async () => {
expect(queryFailureDetails(contractAddress, 2)).toContain(
'dispatch: submessages: reply: Generic error: Integrations test mock reply error: execute wasm contract failed',
);
});
test('ack failure during sudo out of gas', async () => {
expect(queryFailureDetails(contractAddress, 3)).toContain(
'sudo handling went beyond the gas limit allowed by the module',
);
});
test('timeout failure during sudo', async () => {
expect(queryFailureDetails(contractAddress, 4)).toContain(
'Generic error: Integrations test mock error: execute wasm contract failed',
);
});
test('out of gas failure during sudo timeout', async () => {
expect(queryFailureDetails(contractAddress, 5)).toContain(
'sudo handling went beyond the gas limit allowed by the module',
);
});
});

test('failed attempt to resubmit failure', async () => {
// Mock sudo handler to fail
await neutronAccount.executeContract(
Expand Down Expand Up @@ -1074,3 +1116,8 @@ type AcksResponse = {
port_id: string;
sequence_id: number;
};

const queryFailureDetails = (address: string, failureID: number) =>
execSync(
`neutrond q contractmanager failure-details ${address} ${failureID}`,
).toString();