From 2f8cfe4687fd7a292489a8d4e009a3f57a867974 Mon Sep 17 00:00:00 2001 From: anilhelvaci Date: Mon, 30 Sep 2024 03:05:25 +0300 Subject: [PATCH] chore: switch `waitForBlock` with sync tools, WIP Refs: https://github.com/Agoric/BytePitchPartnerEng/issues/10 Refs: https://github.com/Agoric/agoric-3-proposals/issues/181 --- .../invitation-test-submission/send-script.js | 33 ++++++ .../z:acceptance/test-lib/sync-tools.js | 2 +- .../proposals/z:acceptance/test-lib/utils.js | 103 +++++++++++++++++- .../proposals/z:acceptance/vaults.test.js | 48 ++++---- .../proposals/z:acceptance/wallet.test.js | 29 ++--- packages/xsnap/xsnap-native | 2 +- 6 files changed, 175 insertions(+), 42 deletions(-) create mode 100644 a3p-integration/proposals/z:acceptance/invitation-test-submission/send-script.js diff --git a/a3p-integration/proposals/z:acceptance/invitation-test-submission/send-script.js b/a3p-integration/proposals/z:acceptance/invitation-test-submission/send-script.js new file mode 100644 index 000000000000..d89a367cbb73 --- /dev/null +++ b/a3p-integration/proposals/z:acceptance/invitation-test-submission/send-script.js @@ -0,0 +1,33 @@ +/* global E */ + +/// +/// + +/** + * The primary purpose of this script is to access the depositFacet of a given address + * via the namesByAddress and then send a payment to it. + * + * The agoric1ee9hr0jyrxhy999y755mp862ljgycmwyp4pl7q placeholder should be replaced with the desired address before use. + * + * The payment in this case is an invitation to add collateral to the reserve. + * However, the use of the reserve is incidental and simply provides an easy payment to construct. + * + * see a3p-integration/proposals/z:acceptance/wallet.test.js + * + * @param {BootstrapPowers} powers + */ +const sendIt = async powers => { + const addr = 'agoric1ee9hr0jyrxhy999y755mp862ljgycmwyp4pl7q'; + const { + consume: { namesByAddress, zoe }, + instance: { + consume: { reserve }, + }, + } = powers; + const pf = E(zoe).getPublicFacet(reserve); + const anInvitation = await E(pf).makeAddCollateralInvitation(); + const addressDepositFacet = E(namesByAddress).lookup(addr, 'depositFacet'); + await E(addressDepositFacet).receive(anInvitation); +}; + +sendIt; diff --git a/a3p-integration/proposals/z:acceptance/test-lib/sync-tools.js b/a3p-integration/proposals/z:acceptance/test-lib/sync-tools.js index 77683a04d8f7..3990279697f6 100644 --- a/a3p-integration/proposals/z:acceptance/test-lib/sync-tools.js +++ b/a3p-integration/proposals/z:acceptance/test-lib/sync-tools.js @@ -151,7 +151,7 @@ export const waitUntilContractDeplyed = (contractName, ambientAuthroity, options */ const makeQueryCosmosBalace = queryCb => async dest => { - const conins = await queryCb('bank', 'balances', dest); + const conins = await queryCb(['bank', 'balances', dest]); return conins.balances; }; diff --git a/a3p-integration/proposals/z:acceptance/test-lib/utils.js b/a3p-integration/proposals/z:acceptance/test-lib/utils.js index c2e861130c81..2243da07371f 100644 --- a/a3p-integration/proposals/z:acceptance/test-lib/utils.js +++ b/a3p-integration/proposals/z:acceptance/test-lib/utils.js @@ -1,4 +1,4 @@ -import { makeAgd, agops } from '@agoric/synthetic-chain'; +import { makeAgd, agops, executeOffer } from '@agoric/synthetic-chain'; import { execFileSync } from 'node:child_process'; import { readFile, writeFile } from 'node:fs/promises'; @@ -47,3 +47,104 @@ export const getBalances = async (addresses, targetDenom = undefined) => { export const agopsVaults = async addr => await agops.vaults('list', '--from', addr); + +/** + * From https://github.com/Agoric/agoric-3-proposals/blob/main/packages/synthetic-chain/src/lib/econHelpers.js#L16 + * @param {string} address + * @param {string} mint + * @param {string} collateral + * @param {string} [offerId] + */ +export const openVault = (address, mint, collateral, offerId) => { + let params = [ + 'open', + '--wantMinted', + mint, + '--giveCollateral', + collateral, + ]; + + if (offerId) { + params = [...params, '--offerId', offerId]; + } + + return executeOffer( + address, + // @ts-expect-error could return string[] but not in this case + agops.vaults(...params), + ); +}; + + +/** + * From https://github.com/Agoric/agoric-3-proposals/blob/main/packages/synthetic-chain/src/lib/econHelpers.js#L24 + * @param {string} address + * @param {string} vaultId + * @param {any} vaultParams + * @param {string} [offerId] + * @returns + */ +export const adjustVault = (address, vaultId, vaultParams, offerId) => { + let params = [ + 'adjust', + '--vaultId', + vaultId, + '--from', + address, + ' --keyring-backend=test', + ]; + + if ('wantCollateral' in vaultParams) { + params = [...params, '--wantCollateral', vaultParams.wantCollateral]; + } + + if ('wantMinted' in vaultParams) { + params = [...params, '--wantMinted', vaultParams.wantMinted]; + } + + if ('giveCollateral' in vaultParams) { + params = [...params, '--giveCollateral', vaultParams.giveCollateral]; + } + + if ('giveMinted' in vaultParams) { + params = [...params, '--giveMinted', vaultParams.giveMinted]; + } + + if (offerId) { + params = [...params, '--offerId', offerId]; + } + + // @ts-expect-error could return string[] but not in this case + return executeOffer(address, agops.vaults(...params)); +}; + +/** + * https://github.com/Agoric/agoric-3-proposals/blob/main/packages/synthetic-chain/src/lib/econHelpers.js#L54 + * @param {string} address + * @param {string} vaultId + * @param {string} mint + * @param {string} [offerId] + * @returns + */ +export const closeVault = (address, vaultId, mint, offerId) => { + let params = [ + 'close', + '--vaultId', + vaultId, + '--giveMinted', + mint, + '--from', + address, + '--keyring-backend=test', + ]; + + if (offerId) { + params = [...params, '--offerId', offerId]; + } + + return executeOffer( + address, + // @ts-expect-error could return string[] but not in this case + agops.vaults(...params), + ); +}; \ No newline at end of file diff --git a/a3p-integration/proposals/z:acceptance/vaults.test.js b/a3p-integration/proposals/z:acceptance/vaults.test.js index eea9b5899e96..84f814292719 100644 --- a/a3p-integration/proposals/z:acceptance/vaults.test.js +++ b/a3p-integration/proposals/z:acceptance/vaults.test.js @@ -3,18 +3,18 @@ import { agoric, bankSend, getUser, - openVault, - adjustVault, - closeVault, getISTBalance, getContractInfo, ATOM_DENOM, USER1ADDR, - waitForBlock, + agd, } from '@agoric/synthetic-chain'; -import { getBalances, agopsVaults } from './test-lib/utils.js'; +import { getBalances, agopsVaults, openVault, adjustVault, closeVault } from './test-lib/utils.js'; +import { waitUntilOfferResult } from './test-lib/sync-tools.js'; -test.serial('attempt to open vaults under the minimum amount', async t => { +const ambientAuthroity = { follow: agoric.follow, setTimeout: globalThis.setTimeout, query: agd.query } + +test.skip('attempt to open vaults under the minimum amount', async t => { const activeVaultsBefore = await agopsVaults(USER1ADDR); await bankSend(USER1ADDR, `20000000${ATOM_DENOM}`); t.log('active vaults before:', activeVaultsBefore); @@ -74,8 +74,9 @@ test.serial('remove collateral', async t => { const collateralBefore = vaultData.locked.value; t.log('vault collateral before:', collateralBefore); - await adjustVault(USER1ADDR, vaultID, { wantCollateral: 1.0 }); - await waitForBlock(); + const offerId = Date.now().toString(); + await adjustVault(USER1ADDR, vaultID, { wantCollateral: 1.0 }, offerId); + await waitUntilOfferResult(USER1ADDR, offerId, true, ambientAuthroity, { errorMessage: 'vault not adjusted yet' }) vaultData = await getContractInfo(vaultPath, { agoric, prefix: '' }); @@ -98,8 +99,9 @@ test.serial('remove IST', async t => { const debtBefore = vaultData.debtSnapshot.debt.value; t.log('vault debt before:', debtBefore); - await adjustVault(USER1ADDR, vaultID, { wantMinted: 1.0 }); - await waitForBlock(); + const offerId = Date.now().toString(); + await adjustVault(USER1ADDR, vaultID, { wantMinted: 1.0 }, offerId); + await waitUntilOfferResult(USER1ADDR, offerId, true, ambientAuthroity, { errorMessage: 'vault not adjusted yet' }) vaultData = await getContractInfo(vaultPath, { agoric, prefix: '' }); const debtAfter = vaultData.debtSnapshot.debt.value; @@ -124,8 +126,9 @@ test.serial('close vault', async t => { const atomBalanceBefore = await getBalances([USER1ADDR], ATOM_DENOM); t.log('atom balance before', atomBalanceBefore); - await closeVault(USER1ADDR, vaultID, 6.03); - await waitForBlock(); + const offerId = Date.now().toString(); + await closeVault(USER1ADDR, vaultID, 6.03, offerId); + await waitUntilOfferResult(USER1ADDR, offerId, true, ambientAuthroity, { errorMessage: 'vault not closed yet' }); const atomBalanceAfter = await getBalances([USER1ADDR], ATOM_DENOM); t.log('atom balance after', atomBalanceAfter); @@ -151,8 +154,10 @@ test.serial('open second vault', async t => { const mint = '7.0'; const collateral = '11.0'; - await openVault(user2Address, mint, collateral); - await waitForBlock(); + const offerId = Date.now().toString(); + await openVault(user2Address, mint, collateral, offerId); + // @ts-ignore + await waitUntilOfferResult(user2Address, offerId, true, ambientAuthroity, { errorMessage: 'vault not opened yet' }) const activeVaultsAfter = await agopsVaults(user2Address); t.log('active vaults after:', activeVaultsAfter); @@ -174,8 +179,9 @@ test.serial('add collateral', async t => { const collateralBefore = vaultData.locked.value; t.log('vault collateral before:', collateralBefore); - await adjustVault(user2Address, vaultID, { giveCollateral: 1.0 }); - await waitForBlock(); + const offerId = Date.now().toString(); + await adjustVault(user2Address, vaultID, { giveCollateral: 1.0 }, offerId); + await waitUntilOfferResult(user2Address, offerId, true, ambientAuthroity, {errorMessage: 'vault not adjusted yet'}); vaultData = await getContractInfo(vaultPath, { agoric, prefix: '' }); const collateralAfter = vaultData.locked.value; @@ -198,8 +204,9 @@ test.serial('add IST', async t => { const debtBefore = vaultData.debtSnapshot.debt.value; t.log('vault debt before:', debtBefore); - await adjustVault(user2Address, vaultID, { giveMinted: 1.0 }); - await waitForBlock(); + const offerId = Date.now().toString(); + await adjustVault(user2Address, vaultID, { giveMinted: 1.0 }, offerId); + await waitUntilOfferResult(user2Address, offerId, true, ambientAuthroity, {errorMessage: 'vault not adjusted yet'}); vaultData = await getContractInfo(vaultPath, { agoric, prefix: '' }); const debtAfter = vaultData.debtSnapshot.debt.value; @@ -225,8 +232,9 @@ test.serial('close second vault', async t => { const atomBalanceBefore = await getBalances([user2Address], ATOM_DENOM); t.log('atom balance before', atomBalanceBefore); - await closeVault(user2Address, vaultID, 6.035); - await waitForBlock(); + const offerId = Date.now().toString(); + await closeVault(user2Address, vaultID, 6.035, offerId); + await waitUntilOfferResult(user2Address, offerId, true, ambientAuthroity, { errorMessage: 'vault not closed yet'}); const atomBalanceAfter = await getBalances([user2Address], ATOM_DENOM); t.log('atom balance after', atomBalanceAfter); diff --git a/a3p-integration/proposals/z:acceptance/wallet.test.js b/a3p-integration/proposals/z:acceptance/wallet.test.js index d99600b2f977..6c263f447608 100644 --- a/a3p-integration/proposals/z:acceptance/wallet.test.js +++ b/a3p-integration/proposals/z:acceptance/wallet.test.js @@ -13,6 +13,9 @@ import { replaceTemplateValuesInFile, } from './test-lib/utils.js'; import { $ } from 'execa'; +import { waitUntilAccountFunded, waitUntilInvitationReceived, waitUntilOfferResult } from './test-lib/sync-tools.js'; + +const ambientAuthroity = { follow: agoric.follow, setTimeout: globalThis.setTimeout, query: agd.query } test.serial(`send invitation via namesByAddress`, async t => { const SUBMISSION_DIR = 'invitation-test-submission'; @@ -22,23 +25,8 @@ test.serial(`send invitation via namesByAddress`, async t => { }); await evalBundles(SUBMISSION_DIR); - const update = await agoric.follow('-lF', `:published.wallet.${GOV1ADDR}`); - - t.is( - update.updated, - 'balance', - 'The wallet update should indicate the "balance" was updated', - ); - t.notDeepEqual( - update.currentAmount.value, - [], - 'The currentAmount value should not be empty', - ); - t.regex( - update.currentAmount.brand, - /Invitation/, - 'The currentAmount brand should match "Invitation"', - ); + await waitUntilInvitationReceived(GOV1ADDR, ambientAuthroity, { errorMessage: 'invitations not sent yet' }); + t.pass(); }); test.serial('exitOffer tool reclaims stuck payment', async t => { @@ -49,7 +37,8 @@ test.serial('exitOffer tool reclaims stuck payment', async t => { t.log('uist balance before:', before); await $`node ./exitOffer.js --id ${offerId} --from ${from} `; - await waitForBlock(2); + // await waitForBlock() + await waitUntilAccountFunded(GOV1ADDR, ambientAuthroity, {denom: 'uist', value: Number(before)}, { errorMessage: 'acct not funded yet'}); const after = await getBalances([GOV1ADDR], 'uist'); t.log('uist balance after:', after); @@ -82,6 +71,8 @@ test.serial(`ante handler sends fee only to vbank/reserve`, async t => { const feeAmount = 999n; const feeDenom = 'uist'; + + const gov2Before = await getBalances([GOV2ADDR], 'ubld'); const result = await agd.tx( [ 'bank', @@ -95,7 +86,7 @@ test.serial(`ante handler sends fee only to vbank/reserve`, async t => { { chainId: CHAINID, from: GOV1ADDR, yes: true }, ); - await waitForBlock(); + await waitUntilAccountFunded(GOV2ADDR, ambientAuthroity, { denom: 'ubld', value: Number(gov2Before + 1n) }, { errorMessage: 'acct not funded yet' }); t.like(result, { code: 0 }); const [feeCollectorEndBalances, vbankReserveEndBalances] = await getBalances([ diff --git a/packages/xsnap/xsnap-native b/packages/xsnap/xsnap-native index 105bc6862050..eef9b67da551 160000 --- a/packages/xsnap/xsnap-native +++ b/packages/xsnap/xsnap-native @@ -1 +1 @@ -Subproject commit 105bc6862050695b1723fa76df91564fe8111a37 +Subproject commit eef9b67da5517ed18ff9e0073b842db20924eae3