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

test: continuing offers in orchestrate async-flows #9679

Merged
merged 8 commits into from
Jul 11, 2024
Merged
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
2 changes: 1 addition & 1 deletion multichain-testing/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
.yarn/*
!.yarn/patches/*
revise-chain-info*
start-*
start*
121 changes: 121 additions & 0 deletions multichain-testing/test/basic-flows.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import anyTest from '@endo/ses-ava/prepare-endo.js';
import type { TestFn } from 'ava';
import { commonSetup, SetupContextWithWallets } from './support.js';
import { makeDoOffer } from '../tools/e2e-tools.js';
import { chainConfig, chainNames } from './support.js';

const test = anyTest as TestFn<SetupContextWithWallets>;

const accounts = ['user1', 'user2', 'user3']; // one account for each scenario

const contractName = 'basicFlows';
const contractBuilder =
'../packages/builders/scripts/orchestration/init-basic-flows.js';

test.before(async t => {
const { deleteTestKeys, setupTestKeys, ...rest } = await commonSetup(t);
deleteTestKeys(accounts).catch();
const wallets = await setupTestKeys(accounts);
t.context = { ...rest, wallets, deleteTestKeys };

t.log('bundle and install contract', contractName);
await t.context.deployBuilder(contractBuilder);
const vstorageClient = t.context.makeQueryTool();
await t.context.retryUntilCondition(
() => vstorageClient.queryData(`published.agoricNames.instance`),
res => contractName in Object.fromEntries(res),
`${contractName} instance is available`,
);
});

test.after(async t => {
const { deleteTestKeys } = t.context;
deleteTestKeys(accounts);
});

const makeAccountScenario = test.macro({
title: (_, chainName: string) => `Create account on ${chainName}`,
exec: async (t, chainName: string) => {
const config = chainConfig[chainName];
if (!config) return t.fail(`Unknown chain: ${chainName}`);

const {
wallets,
provisionSmartWallet,
makeQueryTool,
retryUntilCondition,
} = t.context;

const vstorageClient = makeQueryTool();

const wallet = accounts[chainNames.indexOf(chainName)];
const wdUser1 = await provisionSmartWallet(wallets[wallet], {
BLD: 100n,
IST: 100n,
});
t.log(`provisioning agoric smart wallet for ${wallets[wallet]}`);

const doOffer = makeDoOffer(wdUser1);
t.log(`${chainName} makeAccount offer`);
const offerId = `${chainName}-makeAccount-${Date.now()}`;

// FIXME we get payouts but not an offer result; it times out
// https://github.com/Agoric/agoric-sdk/issues/9643
// chain logs shows an UNPUBLISHED result
const _offerResult = await doOffer({
id: offerId,
invitationSpec: {
source: 'agoricContract',
instancePath: [contractName],
callPipe: [['makeOrchAccountInvitation']],
},
offerArgs: { chainName },
proposal: {},
});
t.true(_offerResult);
// t.is(await _offerResult, 'UNPUBLISHED', 'representation of continuing offer');

// TODO fix above so we don't have to poll for the offer result to be published
// https://github.com/Agoric/agoric-sdk/issues/9643
const currentWalletRecord = await retryUntilCondition(
() =>
vstorageClient.queryData(`published.wallet.${wallets[wallet]}.current`),
({ offerToPublicSubscriberPaths }) =>
Object.fromEntries(offerToPublicSubscriberPaths)[offerId],
`${offerId} continuing invitation is in vstorage`,
);

const offerToPublicSubscriberMap = Object.fromEntries(
currentWalletRecord.offerToPublicSubscriberPaths,
);

const address = offerToPublicSubscriberMap[offerId]?.account
.split('.')
.pop();
t.log('Got address:', address);
t.regex(
address,
new RegExp(`^${config.expectedAddressPrefix}1`),
`address for ${chainName} is valid`,
);

const latestWalletUpdate = await vstorageClient.queryData(
`published.wallet.${wallets[wallet]}`,
);
t.log('latest wallet update', latestWalletUpdate);
t.like(
latestWalletUpdate.status,
{
id: offerId,
numWantsSatisfied: 1,
result: 'UNPUBLISHED',
error: undefined,
},
'wallet offer satisfied without errors',
);
},
});

test.serial(makeAccountScenario, 'agoric');
test.serial(makeAccountScenario, 'cosmoshub');
test.serial(makeAccountScenario, 'osmosis');
17 changes: 15 additions & 2 deletions multichain-testing/test/stake-ica.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ const stakeScenario = test.macro(async (t, scenario: StakeIcaScenario) => {
const queryClient = makeQueryClient(getRestEndpoint());

t.log('Requesting faucet funds');
// XXX fails intermitently until https://github.com/cosmology-tech/starship/issues/417
// XXX fails intermittently until https://github.com/cosmology-tech/starship/issues/417
await creditFromFaucet(address);

const { balances } = await retryUntilCondition(
Expand All @@ -136,7 +136,7 @@ const stakeScenario = test.macro(async (t, scenario: StakeIcaScenario) => {
t.truthy(validatorAddress, 'found a validator to delegate to');
t.log({ validatorAddress }, 'found a validator to delegate to');
const validatorChainAddress = {
address: validatorAddress,
value: validatorAddress,
chainId: scenario.chainId,
encoding: 'bech32',
};
Expand All @@ -155,6 +155,19 @@ const stakeScenario = test.macro(async (t, scenario: StakeIcaScenario) => {
});
t.true(_delegateOfferResult, 'delegate payouts (none) returned');

const latestWalletUpdate = await vstorageClient.queryData(
`published.wallet.${wallets[scenario.wallet]}`,
);
t.log('latest wallet update', latestWalletUpdate);
t.like(
latestWalletUpdate.status,
{
id: delegateOfferId,
error: undefined,
numWantsSatisfied: 1,
},
`${scenario.chain} delegate offer satisfied without errors`,
);
// query remote chain to verify delegations
const { delegation_responses } = await retryUntilCondition(
() => queryClient.queryDelegations(address),
Expand Down
20 changes: 20 additions & 0 deletions multichain-testing/test/support.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,26 @@ import { makeDeployBuilder } from '../tools/deploy.js';

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

export const chainConfig = {
cosmoshub: {
chainId: 'gaialocal',
denom: 'uatom',
expectedAddressPrefix: 'cosmos',
},
osmosis: {
chainId: 'osmosislocal',
denom: 'uosmo',
expectedAddressPrefix: 'osmo',
},
agoric: {
chainId: 'agoriclocal',
denom: 'ubld',
expectedAddressPrefix: 'agoric',
},
};

export const chainNames = Object.keys(chainConfig);

const makeKeyring = async (
e2eTools: Pick<E2ETools, 'addKey' | 'deleteKey'>,
) => {
Expand Down
2 changes: 1 addition & 1 deletion multichain-testing/tools/agd-tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const makeAgdTools = async (
execFileSync,
}: Pick<typeof import('child_process'), 'execFile' | 'execFileSync'>,
) => {
const bundleCache = unsafeMakeBundleCache('bundles');
const bundleCache = await unsafeMakeBundleCache('bundles');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how was this discovered? do we need more CI for multichain-testing?

maybe that's why you're proposing it be in force-integration

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typescript error (warning?) in the test runner. We don't have lint:types included in lint since it looks like:

Found 383 errors in 25 files.

Errors  Files
     2  ../packages/deploy-script-support/src/coreProposalBehavior.js:44
     1  ../packages/deploy-script-support/src/writeCoreEvalParts.js:74
     1  ../packages/governance/src/quorumCounter.js:17
     2  ../packages/inter-protocol/src/provisionPool.js:50
     3  ../packages/inter-protocol/src/provisionPoolKit.js:69
    12  ../packages/internal/src/callback.js:45
     1  ../packages/internal/src/lib-chainStorage.js:304
     4  ../packages/internal/src/storage-test-utils.js:122
     4  ../packages/network/src/bytes.js:10
    85  ../packages/network/src/network.js:69
    15  ../packages/network/src/router.js:53
    73  ../packages/network/src/types.js:29
     2  ../packages/swing-store/src/snapStore.js:52
     4  ../packages/SwingSet/src/kernel/state/storageHelper.js:9
    70  ../packages/vats/src/ibc.js:37
    23  ../packages/vats/src/localchain.js:34
     2  ../packages/vats/src/transfer.js:40
    20  ../packages/vow/src/E.js:61
     7  ../packages/vow/src/tools.js:17
     3  ../packages/vow/src/types.js:65
    11  ../packages/vow/src/vow-utils.js:23
     6  ../packages/vow/src/vow.js:25
     9  ../packages/vow/src/watch-utils.js:38
    18  ../packages/vow/src/watch.js:13
     5  ../packages/vow/src/when.js:7

Aside - a UX consideration to keep in mind for orch devs working outside agoric-sdk. Aside, aside - appreciate the work you've personally done to make these warning virtually non-existent for the bulk of agoric-sdk/packages/*

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe that's why you're proposing it be in force-integration

Yes, please chime in on this thread to affirm or suggest an alternate plan

const tools = await makeE2ETools(log, bundleCache, {
execFileSync,
execFile,
Expand Down
66 changes: 1 addition & 65 deletions multichain-testing/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -671,13 +671,6 @@ __metadata:
languageName: node
linkType: hard

"@pkgr/core@npm:^0.1.0":
version: 0.1.1
resolution: "@pkgr/core@npm:0.1.1"
checksum: 10c0/3f7536bc7f57320ab2cf96f8973664bef624710c403357429fbf680a5c3b4843c1dbd389bb43daa6b1f6f1f007bb082f5abcb76bb2b5dc9f421647743b71d3d8
languageName: node
linkType: hard

"@protobufjs/aspromise@npm:^1.1.1, @protobufjs/aspromise@npm:^1.1.2":
version: 1.1.2
resolution: "@protobufjs/aspromise@npm:1.1.2"
Expand Down Expand Up @@ -1938,26 +1931,6 @@ __metadata:
languageName: node
linkType: hard

"eslint-plugin-prettier@npm:^5.1.3":
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How / when can we make the Multichain E2E Testing job part of force-integration?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@toliaqat, happen to know how we can add Multichain E2E Testing job to force-integration?

Based on history, successful runs are all under 17 mins and failed runs take several minutes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @LuqiPan @toliaqat. I am sending this PR to the merge queue, but interested to see where we land on this.

version: 5.1.3
resolution: "eslint-plugin-prettier@npm:5.1.3"
dependencies:
prettier-linter-helpers: "npm:^1.0.0"
synckit: "npm:^0.8.6"
peerDependencies:
"@types/eslint": ">=8.0.0"
eslint: ">=8.0.0"
eslint-config-prettier: "*"
prettier: ">=3.0.0"
peerDependenciesMeta:
"@types/eslint":
optional: true
eslint-config-prettier:
optional: true
checksum: 10c0/f45d5fc1fcfec6b0cf038a7a65ddd10a25df4fe3f9e1f6b7f0d5100e66f046a26a2492e69ee765dddf461b93c114cf2e1eb18d4970aafa6f385448985c136e09
languageName: node
linkType: hard

"eslint-scope@npm:^7.2.2":
version: 7.2.2
resolution: "eslint-scope@npm:7.2.2"
Expand Down Expand Up @@ -2126,7 +2099,7 @@ __metadata:
languageName: node
linkType: hard

"fast-diff@npm:^1.1.2, fast-diff@npm:^1.2.0":
"fast-diff@npm:^1.2.0":
version: 1.3.0
resolution: "fast-diff@npm:1.3.0"
checksum: 10c0/5c19af237edb5d5effda008c891a18a585f74bf12953be57923f17a3a4d0979565fc64dbc73b9e20926b9d895f5b690c618cbb969af0cf022e3222471220ad29
Expand Down Expand Up @@ -3653,24 +3626,6 @@ __metadata:
languageName: node
linkType: hard

"prettier-linter-helpers@npm:^1.0.0":
version: 1.0.0
resolution: "prettier-linter-helpers@npm:1.0.0"
dependencies:
fast-diff: "npm:^1.1.2"
checksum: 10c0/81e0027d731b7b3697ccd2129470ed9913ecb111e4ec175a12f0fcfab0096516373bf0af2fef132af50cafb0a905b74ff57996d615f59512bb9ac7378fcc64ab
languageName: node
linkType: hard

"prettier@npm:^3.2.4":
version: 3.3.1
resolution: "prettier@npm:3.3.1"
bin:
prettier: bin/prettier.cjs
checksum: 10c0/c25a709c9f0be670dc6bcb190b622347e1dbeb6c3e7df8b0711724cb64d8647c60b839937a4df4df18e9cfb556c2b08ca9d24d9645eb5488a7fc032a2c4d5cb3
languageName: node
linkType: hard

"pretty-ms@npm:^9.0.0":
version: 9.0.0
resolution: "pretty-ms@npm:9.0.0"
Expand Down Expand Up @@ -3885,11 +3840,9 @@ __metadata:
ava: "npm:^6.1.3"
eslint: "npm:^8.56.0"
eslint-config-prettier: "npm:^9.1.0"
eslint-plugin-prettier: "npm:^5.1.3"
execa: "npm:^9.2.0"
fs-extra: "npm:^11.2.0"
patch-package: "npm:^8.0.0"
prettier: "npm:^3.2.4"
starshipjs: "npm:2.0.0"
tsimp: "npm:^2.0.10"
tsx: "npm:^4.15.6"
Expand Down Expand Up @@ -4241,16 +4194,6 @@ __metadata:
languageName: node
linkType: hard

"synckit@npm:^0.8.6":
version: 0.8.8
resolution: "synckit@npm:0.8.8"
dependencies:
"@pkgr/core": "npm:^0.1.0"
tslib: "npm:^2.6.2"
checksum: 10c0/c3d3aa8e284f3f84f2f868b960c9f49239b364e35f6d20825a448449a3e9c8f49fe36cdd5196b30615682f007830d46f2ea354003954c7336723cb821e4b6519
languageName: node
linkType: hard

"tar@npm:^6.1.11, tar@npm:^6.1.2":
version: 6.2.1
resolution: "tar@npm:6.2.1"
Expand Down Expand Up @@ -4341,13 +4284,6 @@ __metadata:
languageName: node
linkType: hard

"tslib@npm:^2.6.2":
version: 2.6.3
resolution: "tslib@npm:2.6.3"
checksum: 10c0/2598aef53d9dbe711af75522464b2104724d6467b26a60f2bdac8297d2b5f1f6b86a71f61717384aa8fd897240467aaa7bcc36a0700a0faf751293d1331db39a
languageName: node
linkType: hard

"tsx@npm:^4.15.6":
version: 4.15.6
resolution: "tsx@npm:4.15.6"
Expand Down
65 changes: 65 additions & 0 deletions packages/boot/test/bootstrapTests/orchestration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,68 @@ test.serial('revise chain info', async t => {
client_id: '07-tendermint-3',
});
});

test('basic-flows', async t => {
const { buildProposal, evalProposal, agoricNamesRemotes, readLatest } =
t.context;

await evalProposal(
buildProposal('@agoric/builders/scripts/orchestration/init-basic-flows.js'),
);

const wd =
await t.context.walletFactoryDriver.provideSmartWallet('agoric1test');

// create a cosmos orchestration account
await wd.executeOffer({
id: 'request-coa',
invitationSpec: {
source: 'agoricContract',
instancePath: ['basicFlows'],
callPipe: [['makeOrchAccountInvitation']],
},
offerArgs: {
chainName: 'cosmoshub',
},
proposal: {},
});
t.like(wd.getCurrentWalletRecord(), {
offerToPublicSubscriberPaths: [
[
'request-coa',
{
account: 'published.basicFlows.cosmos1test',
},
],
],
});
t.like(wd.getLatestUpdateRecord(), {
status: { id: 'request-coa', numWantsSatisfied: 1 },
});
t.is(readLatest('published.basicFlows.cosmos1test'), '');

// create a local orchestration account
await wd.executeOffer({
id: 'request-loa',
invitationSpec: {
source: 'agoricContract',
instancePath: ['basicFlows'],
callPipe: [['makeOrchAccountInvitation']],
},
offerArgs: {
chainName: 'agoric',
},
proposal: {},
});

const publicSubscriberPaths = Object.fromEntries(
wd.getCurrentWalletRecord().offerToPublicSubscriberPaths,
);
t.deepEqual(publicSubscriberPaths['request-loa'], {
account: 'published.basicFlows.agoric1mockVlocalchainAddress',
});
t.like(wd.getLatestUpdateRecord(), {
status: { id: 'request-loa', numWantsSatisfied: 1 },
});
t.is(readLatest('published.basicFlows.agoric1mockVlocalchainAddress'), '');
});
1 change: 1 addition & 0 deletions packages/builders/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"@agoric/deploy-script-support": "^0.10.3",
"@agoric/governance": "^0.10.3",
"@agoric/inter-protocol": "^0.16.1",
"@agoric/orchestration": "^0.1.0",
"@agoric/store": "^0.9.2",
"@agoric/swing-store": "^0.9.1",
"@agoric/swingset-liveslots": "^0.10.2",
Expand Down
Loading
Loading