Skip to content

Commit

Permalink
feat(orchestration): e2e tests with starship
Browse files Browse the repository at this point in the history
  • Loading branch information
0xpatrickdev committed Jun 6, 2024
1 parent a50864a commit 0dd975c
Show file tree
Hide file tree
Showing 16 changed files with 5,192 additions and 0 deletions.
49 changes: 49 additions & 0 deletions .github/workflows/multichain-e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Multichain E2E Tests

on:
# for now, only run on-demand
workflow_dispatch:
pull_request:

jobs:
multichain-e2e:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: ['18.x']

steps:
- uses: actions/checkout@v4
with:
submodules: 'true'
path: ./agoric-sdk
- uses: ./agoric-sdk/.github/actions/restore-node
with:
node-version: ${{ matrix.node-version }}
path: ./agoric-sdk

- name: Enable Corepack
run: corepack enable || sudo corepack enable
working-directory: ./agoric-sdk/multichain-testing

- name: Install @agoric/multichain-testing deps
run: yarn install
working-directory: ./agoric-sdk/multichain-testing

- name: Lint @agoric/multichain-testing
run: yarn lint
working-directory: ./agoric-sdk/multichain-testing

- name: Set Up Starship Infrastructure
id: starship-infra
uses: cosmology-tech/[email protected]
with:
# uses ghcr.io/agoric/agoric-sdk:dev image (latest master)
values: ./agoric-sdk/multichain-testing/config.ci.yaml
port-forward: true
version: 0.2.2
timeout: 30m

- name: Run @agoric/multichain-testing E2E Tests
run: yarn test
working-directory: ./agoric-sdk/multichain-testing
2 changes: 2 additions & 0 deletions multichain-testing/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.tsimp
.yarn
1 change: 1 addition & 0 deletions multichain-testing/.yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodeLinker: node-modules
126 changes: 126 additions & 0 deletions multichain-testing/config.ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
chains:
- id: agoriclocal
name: agoric
image: ghcr.io/agoric/agoric-sdk:dev
numValidators: 1
env:
- name: DEBUG
value: SwingSet:vat,SwingSet:ls
genesis:
app_state:
staking:
params:
# TODO determine shortest unbonding time that doesn't affect ibc connection availability
unbonding_time: "48h"
swingset:
params:
bootstrap_vat_config: "@agoric/vm-config/decentral-devnet-config.json"
faucet:
enabled: false
ports:
rest: 1317
rpc: 26657
exposer: 38087
grpc: 9090
resources:
cpu: 1
memory: 4Gi
- id: osmosislocal
name: osmosis
numValidators: 1
genesis:
app_state:
staking:
params:
unbonding_time: "48h"
interchain_accounts:
host_genesis_state:
params:
host_enabled: true
allow_messages: ["*"]
interchainquery:
host_port: "icqhost"
params:
host_enabled: true
allow_queries: ["*"]
faucet:
enabled: true
type: starship
ports:
rest: 1315
rpc: 26655
grpc: 9093
faucet: 8084
resources:
cpu: "0.5"
memory: "500M"
- id: gaialocal
name: cosmoshub
numValidators: 1
genesis:
app_state:
staking:
params:
unbonding_time: "48h"
interchain_accounts:
host_genesis_state:
params:
host_enabled: true
allow_messages: ["*"]
faucet:
enabled: true
ports:
rest: 1314
rpc: 26654
grpc: 9092
faucet: 8083
resources:
cpu: "0.5"
memory: "500M"

relayers:
- name: osmosis-gaia
type: hermes
replicas: 1
chains:
- osmosislocal
- gaialocal
resources:
cpu: "0.2"
memory: "200M"
- name: agoric-osmosis
type: hermes
replicas: 1
chains:
- agoriclocal
- osmosislocal
resources:
cpu: "0.2"
memory: "200M"
- name: agoric-gaia
type: hermes
replicas: 1
chains:
- agoriclocal
- gaialocal
resources:
cpu: "0.2"
memory: "200M"

registry:
enabled: true
ports:
rest: 8081
resources:
cpu: "0.2"
memory: "200M"

exposer:
resources:
cpu: "0.2"
memory: "200M"

faucet:
resources:
cpu: "0.2"
memory: "200M"
80 changes: 80 additions & 0 deletions multichain-testing/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
{
"name": "@agoric/multichain-testing",
"version": "0.1.0",
"description": "E2E Interchain testing environment for Agoric smart contracts.",
"type": "module",
"scripts": {
"build": "exit 0",
"lint": "run-s --continue-on-error lint:*",
"lint:eslint": "eslint .",
"lint:types": "tsc --noEmit",
"lint-fix": "yarn lint:eslint --fix",
"test": "ava",
"postinstall": "patch-package",
"starship:setup": "make setup-deps setup-kind",
"starship:install": "make install",
"starship:port-forward": "make port-forward",
"starship:stop": "make stop"
},
"packageManager": "[email protected]",
"devDependencies": {
"@agoric/cosmic-proto": "0.4.1-dev-08f8549.0",
"@cosmjs/crypto": "^0.32.2",
"@cosmjs/proto-signing": "^0.32.2",
"@cosmjs/stargate": "^0.32.2",
"@types/eslint": "^8",
"@types/node": "^20.11.13",
"@typescript-eslint/eslint-plugin": "^6.20.0",
"@typescript-eslint/parser": "^6.20.0",
"ava": "^6.1.1",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"npm-run-all": "^4.1.5",
"patch-package": "^8.0.0",
"prettier": "^3.2.4",
"starshipjs": "^2.0.0",
"tsimp": "^2.0.10",
"typescript": "^5.3.3"
},
"ava": {
"extensions": {
"ts": "module"
},
"nodeArguments": [
"--import=tsimp/import"
],
"files": [
"**/*.test.ts"
]
},
"prettier": {
"semi": true,
"singleQuote": true,
"trailingComma": "all"
},
"eslintConfig": {
"root": true,
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint",
"prettier"
],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"rules": {
"prettier/prettier": "error",
"@typescript-eslint/no-unused-vars": [
"error",
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_"
}
]
}
},
"license": "Apache-2.0"
}
35 changes: 35 additions & 0 deletions multichain-testing/patches/starshipjs+2.0.0.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
diff --git a/node_modules/starshipjs/hooks.js b/node_modules/starshipjs/hooks.js
index fb3e3cf..6b6567b 100644
--- a/node_modules/starshipjs/hooks.js
+++ b/node_modules/starshipjs/hooks.js
@@ -14,7 +14,7 @@ const useRegistry = async (configFile) => {
const registryUrl = `http://localhost:${config.registry.ports.rest}`;
const urls = [];
config.chains?.forEach((chain) => {
- urls.push(`${registryUrl}/chains/${chain.name}`, `${registryUrl}/chains/${chain.name}/assets`);
+ urls.push(`${registryUrl}/chains/${chain.id}`, `${registryUrl}/chains/${chain.id}/assets`);
});
config.relayers?.forEach((relayer) => {
urls.push(`${registryUrl}/ibc/${relayer.chains[0]}/${relayer.chains[1]}`, `${registryUrl}/ibc/${relayer.chains[1]}/${relayer.chains[0]}`);
@@ -35,10 +35,10 @@ const useChain = (chainName) => {
const chainInfo = registry.getChainInfo(chainName);
const chainID = chainInfo.chain.chain_id;
const getRpcEndpoint = () => {
- return `http://localhost:${config.chains.find((chain) => chain.name === chainID).ports.rpc}`;
+ return `http://localhost:${config.chains.find((chain) => chain.id === chainID).ports.rpc}`;
};
const getRestEndpoint = () => {
- return `http://localhost:${config.chains.find((chain) => chain.name === chainID).ports.rest}`;
+ return `http://localhost:${config.chains.find((chain) => chain.id === chainID).ports.rest}`;
};
const getGenesisMnemonic = async () => {
const url = `http://localhost:${config.registry.ports.rest}/chains/${chainID}/keys`;
@@ -50,7 +50,7 @@ const useChain = (chainName) => {
return chainInfo.fetcher.getChainAssetList(chainName).assets[0];
};
const creditFromFaucet = async (address, denom = null) => {
- const faucetEndpoint = `http://localhost:${config.chains.find((chain) => chain.name === chainID).ports.faucet}/credit`;
+ const faucetEndpoint = `http://localhost:${config.chains.find((chain) => chain.id === chainID).ports.faucet}/credit`;
if (!denom) {
denom = getCoin().base;
}
77 changes: 77 additions & 0 deletions multichain-testing/test/cosmos-staking.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import anyTest, { TestFn } from 'ava';

import { createWallet } from '../tools/wallet.js';
import { makeQueryClient } from '../tools/query.js';
import { commonSetup } from './support.js';

const test = anyTest as TestFn<Record<string, never>>;

test.failing('send a wallet offer to an orchestration contract', async (t) => {
const { useChain } = await commonSetup();

const prefix = useChain('agroic').chain.bech32_prefix;
const wallet = await createWallet(prefix);
const address = (await wallet.getAccounts())[0].address;
t.regex(address, /^agroic1/);
t.log('Made temp agoric wallet:', address);

const apiUrl = useChain('cosmoshub').getRestEndpoint();
const _cosmosQueryClient = makeQueryClient(apiUrl);
t.log('Made query client');

t.log('todo: make agoric smart wallet connection');
// FIXME SyntaxError: The requested module '@agoric/web-components' does not provide an export named 'agoricConverters'
// const connection = await makeSmartWalletConnection({
// apiUrl: useChain('agroic').getRestEndpoint(),
// rpcUrl: useChain('agroic').getRpcEndpoint(),
// chainName: useChain('agroic').chainInfo.chainName,
// aminoSigner: wallet,
// address,
// });

t.log('todo: send faucet funds to smart wallet user');
// confirm that faucet: true for agoric works
// alternatively, create a wallet w genesis key (useChain('agoric').getGenesisMnemonic()) and send funds from there

t.log('todo: provision smart wallet');
// connection.provisionSmartWallet();

t.log('todo: stake atom makeAcountInvitationMaker offer');
// await connection.makeOffer(
// {
// source: 'agoricContract',
// instancePath: ['stakeAtom'],
// callPipe: [['makeAcountInvitationMaker']],
// },
// {}, // empty proposal
// { exampleArg: 'foo' },
// ({ status, data }) => {
// if (status === 'error') {
// t.fail(data);
// }
// if (status === 'seated') {
// console.log('Transaction submitted:', data.txn);
// console.log('Offer id:', data.offerId); // persist for continuing inv.
// console.log('Offer status:', data.status);
// }
// if (status === 'refunded') {
// console.log('Offer refunded');
// }
// if (status === 'accepted') {
// console.log('Offer accepted');
// }
// },
// );

t.log('todo: get chain address from vstorage');
// XXX need to publish address in vstorage, or return in offer result. contract doesn't currently do this
// for now, we might consider querying cosmos' ports since there aren't many of them.

t.log('todo: send funds from faucet to ICA');
// useChain('gaia').creditFromFaucet(address);

t.log('todo: Delegate offer with continuing inv');
// await connection.makeOffer()...
});

test.todo('sign and broadcast a wallet transaction');
10 changes: 10 additions & 0 deletions multichain-testing/test/support.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { ExecutionContext } from 'ava';
import { dirname, join } from 'path';
import { makeGetConfigFile, makeSetupRegistry } from '../tools/registry.js';

const setupRegistry = makeSetupRegistry(makeGetConfigFile({ dirname, join }));

export const commonSetup = async (_t?: ExecutionContext) => {
const { useChain } = await setupRegistry();
return { useChain };
};
Loading

0 comments on commit 0dd975c

Please sign in to comment.