From 50f94936e038d6b8872dfde77b5f54811f339ccd Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Thu, 23 May 2024 16:25:36 -0700 Subject: [PATCH] FIXME: VBANK_BALANCE_UPDATE errors --- packages/vats/src/vat-bank.js | 1 + packages/vats/test/localchain.test.js | 100 +++++++++++++++++--------- 2 files changed, 66 insertions(+), 35 deletions(-) diff --git a/packages/vats/src/vat-bank.js b/packages/vats/src/vat-bank.js index 489df8bb8329..e4768120f0ad 100644 --- a/packages/vats/src/vat-bank.js +++ b/packages/vats/src/vat-bank.js @@ -206,6 +206,7 @@ const prepareBankChannelHandler = zone => try { updater.update(value, nonce); } catch (e) { + // NB: this failure does not propagate console.error('Error updating balance', update, e); } } diff --git a/packages/vats/test/localchain.test.js b/packages/vats/test/localchain.test.js index 630642a792d4..ffebbc065b8d 100644 --- a/packages/vats/test/localchain.test.js +++ b/packages/vats/test/localchain.test.js @@ -1,6 +1,7 @@ // @ts-check import { test as anyTest } from '@agoric/swingset-vat/tools/prepare-test-env-ava.js'; +import { NonNullish } from '@agoric/assert'; import { AmountMath, AssetKind, makeIssuerKit } from '@agoric/ertp'; import { reincarnate } from '@agoric/swingset-liveslots/tools/setup-vat-data.js'; import { withAmountUtils } from '@agoric/zoe/tools/test-utils.js'; @@ -9,15 +10,15 @@ import { E } from '@endo/far'; import { getInterfaceOf } from '@endo/marshal'; import { M } from '@endo/patterns'; import { prepareLocalChainTools } from '../src/localchain.js'; -import { makeFakeLocalchainBridge } from '../tools/fake-bridge.js'; import { makeFakeBankManagerKit } from '../tools/bank-utils.js'; +import { makeFakeLocalchainBridge } from '../tools/fake-bridge.js'; /** * @import {LocalChainAccount, LocalChainPowers} from '../src/localchain.js'; * @import {BridgeHandler, ScopedBridgeManager} from '../src/types.js'; */ -/** @type {import('ava').TestFn>} */ +/** @type {import('ava').TestFn>>} */ const test = anyTest; const { fakeVomKit } = reincarnate({ relaxDurabilityRules: false }); @@ -28,11 +29,20 @@ const provideBaggage = key => { }; const makeTestContext = async _t => { + const issuerKits = ['BLD', 'BEAN'].map(x => + makeIssuerKit(x, AssetKind.NAT, harden({ decimalPlaces: 6 })), + ); + const [bld, bean] = issuerKits.map(withAmountUtils); + const localchainBridge = makeFakeLocalchainBridge( makeDurableZone(provideBaggage('localchain')), ); - const { bankManager } = await makeFakeBankManagerKit(); + const { bankManager, pourPayment } = await makeFakeBankManagerKit({ + balances: { + // agoric1fakeBridgeAddress: { ubld: bld.units(100).value }, + }, + }); /** @param {LocalChainPowers} powers */ const makeLocalChain = async powers => { @@ -48,36 +58,36 @@ const makeTestContext = async _t => { }); return { + bld, + bean, bankManager, + issuerKits, localchain, + pourPayment, }; }; -test.beforeEach(t => { - t.context = makeTestContext(t); +test.beforeEach(async t => { + t.context = await makeTestContext(t); }); test('localchain - deposit and withdraw', async t => { - const issuerKits = ['BLD', 'BEAN'].map(x => - makeIssuerKit(x, AssetKind.NAT, harden({ decimalPlaces: 6 })), - ); - const [bld, bean] = issuerKits.map(withAmountUtils); + const { bld, bean, pourPayment } = t.context; + + const bldAmountShape = { brand: bld.brand, value: M.nat() }; const boot = async () => { const { bankManager } = await t.context; await t.notThrowsAsync( - E(bankManager).addAsset('ubld', 'BLD', 'Staking Token', issuerKits[0]), + E(bankManager).addAsset('ubld', 'BLD', 'Staking Token', bld.issuerKit), ); }; await boot(); const makeContract = async () => { - const { localchain } = await t.context; + const { localchain } = t.context; /** @type {LocalChainAccount | undefined} */ let contractsLca; - const contractsBldPurse = bld.issuer.makeEmptyPurse(); - // contract starts with 100 BLD in its Purse - contractsBldPurse.deposit(bld.mint.mintPayment(bld.make(100_000_000n))); return { makeAccount: async () => { @@ -89,50 +99,70 @@ test('localchain - deposit and withdraw', async t => { contractsLca = lca; }, deposit: async () => { - if (!contractsLca) throw Error('LCA not found.'); - const fiftyBldAmt = bld.make(50_000_000n); + assert(contractsLca, 'first makeAccount'); + t.deepEqual( + await E(contractsLca).getBalance(bld.brand), + bld.makeEmpty(), + ); + + const fiftyBldAmt = bld.units(50); const res = await E(contractsLca).deposit( - contractsBldPurse.withdraw(fiftyBldAmt), + await pourPayment(fiftyBldAmt), ); t.true(AmountMath.isEqual(res, fiftyBldAmt)); - const payment2 = contractsBldPurse.withdraw(fiftyBldAmt); + const payment2 = await pourPayment(fiftyBldAmt); await t.throwsAsync( () => - // @ts-expect-error LCA is possibly undefined - E(contractsLca).deposit(payment2, { - brand: M.remotable('Brand'), + E(NonNullish(contractsLca)).deposit(payment2, { + brand: bld.brand, value: M.record(), }), { message: /amount(.+) Must be a copyRecord/, }, ); - await E(contractsLca).deposit(payment2, { - brand: M.remotable('Brand'), - value: M.nat(), - }); + await E(contractsLca).deposit(payment2, bldAmountShape); + t.deepEqual( + await E(contractsLca).getBalance(bld.brand), + bld.units(100), + ); }, withdraw: async () => { - if (!contractsLca) throw Error('LCA not found.'); - const oneHundredBldAmt = bld.make(100_000_000n); - const oneHundredBeanAmt = bean.make(100_000_000n); + assert(contractsLca, 'first makeAccount'); + const oneHundredBldAmt = bld.units(100); + const oneHundredBeanAmt = bean.units(100); + t.deepEqual( + await E(contractsLca).getBalance(bld.brand), + bld.units(100), + ); const payment = await E(contractsLca).withdraw(oneHundredBldAmt); - // @ts-expect-error Argument of type 'Payment' is not assignable to parameter of type 'ERef>'. + t.deepEqual(await E(contractsLca).getBalance(bld.brand), bld.units(0)); const paymentAmount = await E(bld.issuer).getAmountOf(payment); t.true(AmountMath.isEqual(paymentAmount, oneHundredBldAmt)); + // FIXME + const payment2 = await E(contractsLca).withdraw(oneHundredBldAmt); + t.true( + AmountMath.isEqual( + await E(bld.issuer).getAmountOf(payment2), + oneHundredBldAmt, + ), + ); + + // FIXME it logs an error but doesn't throw await t.throwsAsync( - // @ts-expect-error LCA is possibly undefined - () => E(contractsLca).withdraw(oneHundredBldAmt), + () => E(NonNullish(contractsLca)).withdraw(oneHundredBldAmt), { message: /Withdrawal (.+) failed (.+) purse only contained/, }, ); - // @ts-expect-error LCA is possibly undefined - await t.throwsAsync(() => E(contractsLca).withdraw(oneHundredBeanAmt), { - message: /not found in collection "brandToAssetRecord"/, - }); + await t.throwsAsync( + () => E(NonNullish(contractsLca)).withdraw(oneHundredBeanAmt), + { + message: /not found in collection "brandToAssetRecord"/, + }, + ); }, }; };