Skip to content

Commit

Permalink
FIXME: VBANK_BALANCE_UPDATE errors
Browse files Browse the repository at this point in the history
  • Loading branch information
turadg committed May 23, 2024
1 parent b0e1fba commit 50f9493
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 35 deletions.
1 change: 1 addition & 0 deletions packages/vats/src/vat-bank.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down
100 changes: 65 additions & 35 deletions packages/vats/test/localchain.test.js
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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<ReturnType<makeTestContext>>} */
/** @type {import('ava').TestFn<Awaited<ReturnType<makeTestContext>>>} */
const test = anyTest;

const { fakeVomKit } = reincarnate({ relaxDurabilityRules: false });
Expand All @@ -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 => {
Expand All @@ -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 () => {
Expand All @@ -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<Payment<"nat", any>>'.
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"/,
},
);
},
};
};
Expand Down

0 comments on commit 50f9493

Please sign in to comment.