From 2af78e510b67989d783c1ac7626780912b50db8a Mon Sep 17 00:00:00 2001 From: 0xPatrick Date: Mon, 12 Aug 2024 18:56:04 -0400 Subject: [PATCH 1/7] fix: unsubscribeFromTransfers returns undefined --- packages/orchestration/src/exos/packet-tools.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/orchestration/src/exos/packet-tools.js b/packages/orchestration/src/exos/packet-tools.js index fc78bdff30f..a4ba79c2455 100644 --- a/packages/orchestration/src/exos/packet-tools.js +++ b/packages/orchestration/src/exos/packet-tools.js @@ -109,7 +109,7 @@ export const preparePacketTools = (zone, vowTools) => { }), utils: M.interface('utils', { subscribeToTransfers: M.call().returns(M.promise()), - unsubscribeFromTransfers: M.call().returns(M.promise()), + unsubscribeFromTransfers: M.call().returns(M.undefined()), incrPendingPatterns: M.call().returns(Vow$(M.undefined())), decrPendingPatterns: M.call().returns(Vow$(M.undefined())), }), From 0b9791672f91890a9de13511d0a6e7290d30d4d5 Mon Sep 17 00:00:00 2001 From: 0xPatrick Date: Wed, 14 Aug 2024 14:22:56 -0400 Subject: [PATCH 2/7] feat: include issuerKeywordRecord in start-sendAnywhere.js --- packages/builders/scripts/testing/start-sendAnywhere.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/builders/scripts/testing/start-sendAnywhere.js b/packages/builders/scripts/testing/start-sendAnywhere.js index 87bc18cd2a7..21528f38cef 100644 --- a/packages/builders/scripts/testing/start-sendAnywhere.js +++ b/packages/builders/scripts/testing/start-sendAnywhere.js @@ -46,6 +46,9 @@ export const startSendAnywhere = async ({ // @ts-expect-error unknown instance produce: { sendAnywhere: produceInstance }, }, + issuer: { + consume: { IST }, + }, }) => { trace(startSendAnywhere.name); @@ -67,6 +70,7 @@ export const startSendAnywhere = async ({ const { instance } = await E(startUpgradable)({ label: 'sendAnywhere', installation: sendAnywhere, + issuerKeywordRecord: { Stable: await IST }, privateArgs, }); produceInstance.resolve(instance); @@ -94,6 +98,9 @@ export const getManifest = ({ restoreRef }, { installationRef }) => { instance: { produce: { sendAnywhere: true }, }, + issuer: { + consume: { IST: true }, + }, }, }, installations: { From 061c67842a2114bef51223f9b755a10ae907fd5a Mon Sep 17 00:00:00 2001 From: 0xPatrick Date: Wed, 14 Aug 2024 14:27:12 -0400 Subject: [PATCH 3/7] feat: ensure smart-wallet and test are using same marshaller - allows us to use brands from vstroage.query(published.agoricNames.brand) with walletDriver (provisionSmartWallet) --- multichain-testing/test/auto-stake-it.test.ts | 5 ++--- multichain-testing/test/basic-flows.test.ts | 6 ++---- multichain-testing/test/smart-wallet.test.ts | 4 +--- multichain-testing/test/stake-ica.test.ts | 3 +-- multichain-testing/tools/e2e-tools.js | 15 +++++++++++---- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/multichain-testing/test/auto-stake-it.test.ts b/multichain-testing/test/auto-stake-it.test.ts index 0c1ab6abbe7..e9a82de97a2 100644 --- a/multichain-testing/test/auto-stake-it.test.ts +++ b/multichain-testing/test/auto-stake-it.test.ts @@ -28,7 +28,7 @@ test.before(async t => { t.log('bundle and install contract', contractName); await t.context.deployBuilder(contractBuilder); - const vstorageClient = t.context.makeQueryTool(); + const { vstorageClient } = t.context; await t.context.retryUntilCondition( () => vstorageClient.queryData(`published.agoricNames.instance`), res => contractName in Object.fromEntries(res), @@ -91,7 +91,7 @@ const autoStakeItScenario = test.macro({ exec: async (t, chainName: string) => { const { wallets, - makeQueryTool, + vstorageClient, provisionSmartWallet, retryUntilCondition, } = t.context; @@ -174,7 +174,6 @@ const autoStakeItScenario = test.macro({ }); // FIXME https://github.com/Agoric/agoric-sdk/issues/9643 - const vstorageClient = makeQueryTool(); const currentWalletRecord = await retryUntilCondition( () => vstorageClient.queryData(`published.wallet.${agoricUserAddr}.current`), diff --git a/multichain-testing/test/basic-flows.test.ts b/multichain-testing/test/basic-flows.test.ts index f6649e0100b..f9e710c5be3 100644 --- a/multichain-testing/test/basic-flows.test.ts +++ b/multichain-testing/test/basic-flows.test.ts @@ -23,7 +23,7 @@ test.before(async t => { t.log('bundle and install contract', contractName); await t.context.deployBuilder(contractBuilder); - const vstorageClient = t.context.makeQueryTool(); + const { vstorageClient } = t.context; await t.context.retryUntilCondition( () => vstorageClient.queryData(`published.agoricNames.instance`), res => contractName in Object.fromEntries(res), @@ -45,12 +45,10 @@ const makeAccountScenario = test.macro({ const { wallets, provisionSmartWallet, - makeQueryTool, + vstorageClient, retryUntilCondition, } = t.context; - const vstorageClient = makeQueryTool(); - const agoricAddr = wallets[chainName]; const wdUser1 = await provisionSmartWallet(agoricAddr, { BLD: 100n, diff --git a/multichain-testing/test/smart-wallet.test.ts b/multichain-testing/test/smart-wallet.test.ts index 4dc3d664e45..04fb0e20fd3 100644 --- a/multichain-testing/test/smart-wallet.test.ts +++ b/multichain-testing/test/smart-wallet.test.ts @@ -17,13 +17,11 @@ test.after(async t => { }); test('provision smart wallet', async t => { - const { wallets, provisionSmartWallet, makeQueryTool, useChain } = t.context; + const { wallets, provisionSmartWallet, vstorageClient, useChain } = t.context; const wallet = await provisionSmartWallet(wallets.user1, { BLD: 100n }); t.log('wallet', wallet); - const vstorageClient = makeQueryTool(); - const walletCurrent = await vstorageClient.queryData( `published.wallet.${wallets.user1}.current`, ); diff --git a/multichain-testing/test/stake-ica.test.ts b/multichain-testing/test/stake-ica.test.ts index ec61537d716..735b65703d4 100644 --- a/multichain-testing/test/stake-ica.test.ts +++ b/multichain-testing/test/stake-ica.test.ts @@ -40,7 +40,7 @@ const stakeScenario = test.macro(async (t, scenario: StakeIcaScenario) => { const { wallets, provisionSmartWallet, - makeQueryTool, + vstorageClient, retryUntilCondition, useChain, deployBuilder, @@ -48,7 +48,6 @@ const stakeScenario = test.macro(async (t, scenario: StakeIcaScenario) => { t.log('bundle and install contract', scenario); await deployBuilder(scenario.builder); - const vstorageClient = makeQueryTool(); await retryUntilCondition( () => vstorageClient.queryData(`published.agoricNames.instance`), res => scenario.contractName in Object.fromEntries(res), diff --git a/multichain-testing/tools/e2e-tools.js b/multichain-testing/tools/e2e-tools.js index d7d7d2c6620..df46fbd65b0 100644 --- a/multichain-testing/tools/e2e-tools.js +++ b/multichain-testing/tools/e2e-tools.js @@ -136,10 +136,9 @@ export const provisionSmartWallet = async ( chainId = 'agoriclocal', whale = 'faucet', progress = console.log, + q = makeQueryKit(makeVStorage(lcd)).query, }, ) => { - const { query: q } = makeQueryKit(makeVStorage(lcd)); - // TODO: skip this query if balances is {} const vbankEntries = await q.queryData('published.agoricNames.vbankAsset'); const byName = Object.fromEntries( @@ -507,8 +506,10 @@ export const makeE2ETools = async ( const copyFiles = makeCopyFiles({ execFileSync, log }); + const vstorageClient = makeQueryKit(vstorage).query; + return { - makeQueryTool: () => makeQueryKit(vstorage).query, + vstorageClient, installBundles, runCoreEval: buildAndRunCoreEval, /** @@ -516,7 +517,13 @@ export const makeE2ETools = async ( * @param {Record} amount */ provisionSmartWallet: (address, amount) => - provisionSmartWallet(address, amount, { agd, blockTool, lcd, delay }), + provisionSmartWallet(address, amount, { + agd, + blockTool, + lcd, + delay, + q: vstorageClient, + }), /** * @param {string} name * @param {EnglishMnemonic | string} mnemonic From 12243e77a6aa553cadf61278a03d2ca01e13f7e0 Mon Sep 17 00:00:00 2001 From: 0xPatrick Date: Wed, 14 Aug 2024 14:48:53 -0400 Subject: [PATCH 4/7] test: sendAnywhere.contract.js e2e test --- multichain-testing/test/send-anywhere.test.ts | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 multichain-testing/test/send-anywhere.test.ts diff --git a/multichain-testing/test/send-anywhere.test.ts b/multichain-testing/test/send-anywhere.test.ts new file mode 100644 index 00000000000..d27639c8607 --- /dev/null +++ b/multichain-testing/test/send-anywhere.test.ts @@ -0,0 +1,137 @@ +import anyTest from '@endo/ses-ava/prepare-endo.js'; +import type { TestFn } from 'ava'; +import { makeDoOffer } from '../tools/e2e-tools.js'; +import { + commonSetup, + SetupContextWithWallets, + chainConfig, +} from './support.js'; +import { createWallet } from '../tools/wallet.js'; +import { AmountMath } from '@agoric/ertp'; +import { makeQueryClient } from '../tools/query.js'; +import type { Amount } from '@agoric/ertp/src/types.js'; + +const test = anyTest as TestFn; + +const accounts = ['osmosis1', 'osmosis2', 'cosmoshub1', 'cosmoshub2']; + +const contractName = 'sendAnywhere'; +const contractBuilder = + '../packages/builders/scripts/testing/start-sendAnywhere.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; + 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 sendAnywhereScenario = test.macro({ + title: (_, chainName: string, acctIdx: number) => + `sendAnywhere ${chainName}${acctIdx}`, + exec: async (t, chainName: string, acctIdx: number) => { + const config = chainConfig[chainName]; + if (!config) return t.fail(`Unknown chain: ${chainName}`); + + const { + wallets, + provisionSmartWallet, + vstorageClient, + retryUntilCondition, + useChain, + } = t.context; + + t.log('Create a receiving wallet for the sendAnywhere transfer'); + const chain = useChain(chainName).chain; + + t.log('Create an agoric smart wallet to initiate sendAnywhere transfer'); + const agoricAddr = wallets[`${chainName}${acctIdx}`]; + const wdUser1 = await provisionSmartWallet(agoricAddr, { + BLD: 100_000n, + IST: 100_000n, + }); + t.log(`provisioning agoric smart wallet for ${agoricAddr}`); + + const doOffer = makeDoOffer(wdUser1); + + const brands = await vstorageClient.queryData( + 'published.agoricNames.brand', + ); + const istBrand = Object.fromEntries(brands).IST; + + const apiUrl = await useChain(chainName).getRestEndpoint(); + const queryClient = makeQueryClient(apiUrl); + t.log(`Made ${chainName} query client`); + + const doSendAnywhere = async (amount: Amount) => { + t.log(`Sending ${amount.value} ${amount.brand}.`); + const wallet = await createWallet(chain.bech32_prefix); + const receiver = { + chainId: chain.chain_id, + value: (await wallet.getAccounts())[0].address, + encoding: 'bech32', + }; + t.log('Will send payment to:', receiver); + t.log(`${chainName} offer`); + const offerId = `${chainName}-makeSendInvitation-${Date.now()}`; + await doOffer({ + id: offerId, + invitationSpec: { + source: 'agoricContract', + instancePath: [contractName], + callPipe: [['makeSendInvitation']], + }, + offerArgs: { destAddr: receiver.value, chainName }, + proposal: { give: { Send: amount } }, + }); + + const { balances } = await retryUntilCondition( + () => queryClient.queryBalances(receiver.value), + ({ balances }) => 'amount' in balances[0], + `${receiver.value} ${amount.value} balance available from sendAnywhere`, + ); + + t.log(`${receiver.value} Balances`, balances); + t.like(balances, [ + { + // XXX consider verifying uist hash + amount: String(amount.value), + }, + ]); + }; + + const makeRandomValue = (min: number, max: number) => + BigInt(Math.floor(Math.random() * (max - min + 1)) + min); + // send 3 offers from each account. different values help distinguish + // one offer/result from another. + const offerAmounts = [ + makeRandomValue(1, 33), + makeRandomValue(34, 66), + makeRandomValue(67, 100), + ]; + console.log(`${agoricAddr} offer amounts:`, offerAmounts); + + for (const value of offerAmounts) { + await doSendAnywhere(AmountMath.make(istBrand, value)); + } + }, +}); + +test.serial(sendAnywhereScenario, 'osmosis', 1); +test.serial(sendAnywhereScenario, 'osmosis', 2); +test.serial(sendAnywhereScenario, 'cosmoshub', 1); +test.serial(sendAnywhereScenario, 'cosmoshub', 2); From bc0dce30b46cdf90d5c7092fa49681661d989452 Mon Sep 17 00:00:00 2001 From: 0xPatrick Date: Wed, 14 Aug 2024 16:52:13 -0400 Subject: [PATCH 5/7] fix(sendAnywhere): exit seat --- packages/orchestration/src/examples/sendAnywhere.flows.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/orchestration/src/examples/sendAnywhere.flows.js b/packages/orchestration/src/examples/sendAnywhere.flows.js index f00c288aa48..8573dea7b13 100644 --- a/packages/orchestration/src/examples/sendAnywhere.flows.js +++ b/packages/orchestration/src/examples/sendAnywhere.flows.js @@ -59,5 +59,6 @@ export const sendIt = async ( chainId, }, ); + seat.exit(); }; harden(sendIt); From 7d4800ce77fc985985b4d7277bd71b5a47dff6cb Mon Sep 17 00:00:00 2001 From: 0xPatrick Date: Thu, 15 Aug 2024 14:04:48 -0400 Subject: [PATCH 6/7] fix(localTransfer): ensure results of deposit are returned --- packages/orchestration/src/utils/zoe-tools.js | 6 ++++-- .../orchestration/test/examples/swapExample.test.ts | 10 +--------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/packages/orchestration/src/utils/zoe-tools.js b/packages/orchestration/src/utils/zoe-tools.js index b8aca53a790..abf7f5bb683 100644 --- a/packages/orchestration/src/utils/zoe-tools.js +++ b/packages/orchestration/src/utils/zoe-tools.js @@ -64,13 +64,15 @@ export const makeZoeTools = (zone, { zcf, vowTools }) => { // Now all the `give` are accessible, so we can move them to the localAccount` - const promises = Object.entries(give).map(async ([kw, _amount]) => { + const depositVs = Object.entries(give).map(async ([kw, _amount]) => { const pmt = await E(userSeat).getPayout(kw); // TODO arrange recovery on upgrade of pmt? return localAccount.deposit(pmt); }); - await Promise.all(promises); + await vowTools.when(vowTools.allVows(depositVs)); // TODO remove userSeat from baggage + // TODO reject non-vbank issuers + // TODO recover failed deposits }, ); diff --git a/packages/orchestration/test/examples/swapExample.test.ts b/packages/orchestration/test/examples/swapExample.test.ts index 12a79c09c1d..2c59723510b 100644 --- a/packages/orchestration/test/examples/swapExample.test.ts +++ b/packages/orchestration/test/examples/swapExample.test.ts @@ -12,15 +12,7 @@ const contractFile = `${dirname}/../../src/examples/swapExample.contract.js`; type StartFn = typeof import('@agoric/orchestration/src/examples/swapExample.contract.js').start; -/* Not sure why it is failing. Possibly relevant symptoms. -``` ------ ComosOrchestrationAccountHolder.6 3 TODO: handle brand { brand: Object [Alleged: IST brand] {}, value: 10000000n } -REJECTED at top of event loop (Error#20) -Error#20: {"type":1,"data":"CmgKIy9jb3Ntb3Muc3Rha2luZy52MWJldGExLk1zZ0RlbGVnYXRlEkEKGFVOUEFSU0FCTEVfQ0hBSU5fQUREUkVTUxISYWdvcmljMXZhbG9wZXJmdWZ1GhEKBXVmbGl4EggxMDAwMDAwMA==","memo":""} - at parseTxPacket (file:///Users/markmiller/src/ongithub/agoric/agoric-sdk/packages/orchestration/src/utils/packet.js:87:14) -``` -*/ -test.failing('start', async t => { +test('start', async t => { const { bootstrap, brands: { ist }, From c3c11bed29543b601c2a4ce28bca4c92a72d5a0c Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Fri, 16 Aug 2024 07:36:35 -0400 Subject: [PATCH 7/7] test: base a3p on upgrade-15 until it works on top of new (upgrade-16) --- a3p-integration/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/a3p-integration/package.json b/a3p-integration/package.json index 71207d38918..2872b5eac7e 100644 --- a/a3p-integration/package.json +++ b/a3p-integration/package.json @@ -1,7 +1,7 @@ { "private": true, "agoricSyntheticChain": { - "fromTag": "latest" + "fromTag": "use-upgrade-15" }, "scripts": { "build": "yarn run build:sdk && yarn run build:submissions && yarn run build:synthetic-chain",