Skip to content

Commit

Permalink
feat: LCA looks up denoms
Browse files Browse the repository at this point in the history
  • Loading branch information
turadg committed Aug 28, 2024
1 parent c33219b commit 5aa48dc
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 75 deletions.
16 changes: 3 additions & 13 deletions packages/orchestration/src/exos/cosmos-orchestration-account.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
} from '@agoric/cosmic-proto/cosmos/staking/v1beta1/tx.js';
import { Any } from '@agoric/cosmic-proto/google/protobuf/any.js';
import { MsgTransfer } from '@agoric/cosmic-proto/ibc/applications/transfer/v1/tx.js';
import { makeTracer, NonNullish } from '@agoric/internal';
import { makeTracer } from '@agoric/internal';
import { Shape as NetworkShape } from '@agoric/network';
import { M } from '@agoric/vat-data';
import { VowShape } from '@agoric/vow';
Expand All @@ -31,7 +31,7 @@ import {
DenomAmountShape,
IBCTransferOptionsShape,
} from '../typeGuards.js';
import { coerceDenom } from '../utils/amounts.js';
import { coerceCoin, coerceDenom } from '../utils/amounts.js';
import { maxClockSkew, tryDecodeResponse } from '../utils/cosmos.js';
import { orchestrationAccountMethods } from '../utils/orchestrationAccount.js';
import { makeTimestampHelper } from '../utils/time.js';
Expand Down Expand Up @@ -215,17 +215,7 @@ export const prepareCosmosOrchestrationAccountKit = (
* @returns {Coin}
*/
amountToCoin(amount) {
const denom =
'denom' in amount
? amount.denom
: NonNullish(
chainHub.lookupDenom(amount.brand),
`No denomination for brand ${amount.brand}`,
);
return harden({
denom,
amount: String(amount.value),
});
return coerceCoin(chainHub, amount);
},
},
balanceQueryWatcher: {
Expand Down
32 changes: 10 additions & 22 deletions packages/orchestration/src/exos/local-orchestration-account.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { orchestrationAccountMethods } from '../utils/orchestrationAccount.js';
import { makeTimestampHelper } from '../utils/time.js';
import { preparePacketTools } from './packet-tools.js';
import { prepareIBCTools } from './ibc-packet.js';
import { coerceCoin, coerceDenomAmount } from '../utils/amounts.js';

/**
* @import {HostOf} from '@agoric/async-flow';
Expand Down Expand Up @@ -175,15 +176,7 @@ export const prepareLocalOrchestrationAccountKit = (
* @returns {Coin}
*/
amountToCoin(amount) {
if (!('denom' in amount)) {
// FIXME(#9211) look up values from brands
trace('TODO #9211: handle brand', amount);
throw Fail`Brands not currently supported.`;
}
return harden({
denom: amount.denom,
amount: String(amount.value),
});
return coerceCoin(chainHub, amount);
},
},
invitationMakers: {
Expand Down Expand Up @@ -437,13 +430,10 @@ export const prepareLocalOrchestrationAccountKit = (
* @param {Amount<'nat'>} ertpAmount
*/
delegate(validatorAddress, ertpAmount) {
// TODO #9211 lookup denom from brand
const amount = {
amount: String(ertpAmount.value),
denom: 'ubld',
};
const { account: lca } = this.state;

const amount = coerceCoin(chainHub, ertpAmount);

return watch(
E(lca).executeTx([
typedJson('/cosmos.staking.v1beta1.MsgDelegate', {
Expand All @@ -462,11 +452,7 @@ export const prepareLocalOrchestrationAccountKit = (
* @returns {Vow<void | TimestampRecord>}
*/
undelegate(validatorAddress, ertpAmount) {
// TODO #9211 lookup denom from brand
const amount = {
amount: String(ertpAmount.value),
denom: 'ubld',
};
const amount = coerceCoin(chainHub, ertpAmount);
const { account: lca } = this.state;
return watch(
E(lca).executeTx([
Expand Down Expand Up @@ -557,8 +543,6 @@ export const prepareLocalOrchestrationAccountKit = (
transfer(amount, destination, opts) {
return asVow(() => {
trace('Transferring funds from LCA over IBC');
// TODO #9211 lookup denom from brand
if ('brand' in amount) throw Fail`ERTP Amounts not yet supported`;

const connectionInfoV = watch(
chainHub.getConnectionInfo(
Expand All @@ -580,7 +564,11 @@ export const prepareLocalOrchestrationAccountKit = (
const resultV = watch(
allVows([connectionInfoV, timeoutTimestampVowOrValue]),
this.facets.transferWatcher,
{ opts, amount, destination },
{
opts,
amount: coerceDenomAmount(chainHub, amount),
destination,
},
);
return resultV;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@ import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js';

import { AmountMath } from '@agoric/ertp';
import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js';
import { heapVowE as VE } from '@agoric/vow/vat.js';
import { TargetApp } from '@agoric/vats/src/bridge-target.js';
import { SIMULATED_ERRORS } from '@agoric/vats/tools/fake-bridge.js';
import { heapVowE as VE } from '@agoric/vow/vat.js';
import { ChainAddress, type AmountArg } from '../../src/orchestration-api.js';
import { maxClockSkew } from '../../src/utils/cosmos.js';
import { NANOSECONDS_PER_SECOND } from '../../src/utils/time.js';
import { commonSetup } from '../supports.js';
import { buildVTransferEvent } from '../../tools/ibc-mocks.js';
import { UNBOND_PERIOD_SECONDS } from '../ibc-mocks.js';
import { maxClockSkew } from '../../src/utils/cosmos.js';
import { commonSetup } from '../supports.js';
import { prepareMakeTestLOAKit } from './make-test-loa-kit.js';
import { buildVTransferEvent } from '../../tools/ibc-mocks.js';

test('deposit, withdraw', async t => {
const common = await commonSetup(t);
const makeTestLOAKit = prepareMakeTestLOAKit(t, common.bootstrap);
const makeTestLOAKit = prepareMakeTestLOAKit(t, common);
const account = await makeTestLOAKit();

const {
Expand All @@ -27,8 +27,10 @@ test('deposit, withdraw', async t => {

t.log('deposit 100 bld to account');
await VE(account).deposit(oneHundredStakePmt);
// FIXME #9211
// t.deepEqual(await E(account).getBalance('ubld'), stake.units(100));
t.deepEqual(await VE(account).getBalance('ubld'), {
denom: 'ubld',
value: stake.units(100).value,
});

// XXX races in the bridge
await eventLoopIteration();
Expand Down Expand Up @@ -58,7 +60,7 @@ test('deposit, withdraw', async t => {

test('delegate, undelegate', async t => {
const common = await commonSetup(t);
const makeTestLOAKit = prepareMakeTestLOAKit(t, common.bootstrap);
const makeTestLOAKit = prepareMakeTestLOAKit(t, common);
const account = await makeTestLOAKit();

const {
Expand Down Expand Up @@ -94,7 +96,7 @@ test('delegate, undelegate', async t => {

test('transfer', async t => {
const common = await commonSetup(t);
const makeTestLOAKit = prepareMakeTestLOAKit(t, common.bootstrap);
const makeTestLOAKit = prepareMakeTestLOAKit(t, common);
const account = await makeTestLOAKit();

const { value: sender } = await VE(account).getAddress();
Expand All @@ -111,8 +113,10 @@ test('transfer', async t => {

t.log('deposit 100 bld to account');
await VE(account).deposit(oneHundredStakePmt);
// FIXME #9211
// t.deepEqual(await E(account).getBalance('ubld'), stake.units(100));
t.deepEqual(await VE(account).getBalance('ubld'), {
denom: 'ubld',
value: stake.units(100).value,
});

const destination: ChainAddress = {
chainId: 'cosmoshub-4',
Expand Down Expand Up @@ -144,12 +148,6 @@ test('transfer', async t => {
return { transferP };
};

// TODO #9211, support ERTP amounts
t.log('ERTP Amounts not yet supported for AmountArg');
await t.throwsAsync(() => VE(account).transfer(stake.units(1), destination), {
message: 'ERTP Amounts not yet supported',
});

t.log('.transfer() 1 bld to cosmos using DenomAmount');
const { transferP } = await startTransfer(
{ denom: 'ubld', value: 1_000_000n },
Expand Down Expand Up @@ -247,7 +245,7 @@ test('transfer', async t => {

test('monitor transfers', async t => {
const common = await commonSetup(t);
const makeTestLOAKit = prepareMakeTestLOAKit(t, common.bootstrap);
const makeTestLOAKit = prepareMakeTestLOAKit(t, common);
const account = await makeTestLOAKit();
const {
mocks: { transferBridge },
Expand Down Expand Up @@ -290,15 +288,15 @@ test('monitor transfers', async t => {
});

test('send', async t => {
const {
bootstrap,
brands: { bld: stake, ist: stable },
utils: { pourPayment, inspectLocalBridge },
} = await commonSetup(t);
const makeTestLOAKit = prepareMakeTestLOAKit(t, bootstrap);
const common = await commonSetup(t);
const makeTestLOAKit = prepareMakeTestLOAKit(t, common);
const account = await makeTestLOAKit();
t.truthy(account, 'account is returned');

const {
brands: { bld: stake, ist: stable },
utils: { pourPayment, inspectLocalBridge },
} = common;
const oneHundredStakePmt = await pourPayment(stake.units(100));
const oneHundredStablePmt = await pourPayment(stable.units(100));
t.log('deposit 100 bld to account');
Expand All @@ -313,10 +311,7 @@ test('send', async t => {
};

t.log(`send 10 bld to ${toAddress.value}`);
await t.throwsAsync(VE(account).send(toAddress, stake.units(10)), {
message: 'Brands not currently supported.',
});
await VE(account).send(toAddress, { denom: 'ubld', value: 10_000_000n });
await VE(account).send(toAddress, stake.units(10));

// this would normally fail since we do not have ibc/1234 in our wallet,
// but the mocked localchain bridge doesn't currently know about balances
Expand Down
28 changes: 20 additions & 8 deletions packages/orchestration/test/exos/make-test-loa-kit.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
/* eslint-disable jsdoc/require-param -- ts types */
import { makeIssuerKit } from '@agoric/ertp';
import { heapVowE as E } from '@agoric/vow/vat.js';
import { prepareRecorderKitMakers } from '@agoric/zoe/src/contractSupport/recorder.js';
import { withAmountUtils } from '@agoric/zoe/tools/test-utils.js';
import { Far } from '@endo/far';
import { ExecutionContext } from 'ava';
import { prepareLocalOrchestrationAccountKit } from '../../src/exos/local-orchestration-account.js';
import { makeChainHub } from '../../src/exos/chain-hub.js';
import { prepareLocalOrchestrationAccountKit } from '../../src/exos/local-orchestration-account.js';
import fetchedChainInfo from '../../src/fetched-chain-info.js';
import { commonSetup } from '../supports.js';

/**
Expand All @@ -13,15 +17,13 @@ import { commonSetup } from '../supports.js';
*
* Helps reduce boilerplate in test files, and retains testing context through
* parameterized endowments.
*
* @param t
* @param bootstrap
* @param opts
* @param opts.zcf
*/
export const prepareMakeTestLOAKit = (
t: ExecutionContext,
bootstrap: Awaited<ReturnType<typeof commonSetup>>['bootstrap'],
{
bootstrap,
brands,
}: Pick<Awaited<ReturnType<typeof commonSetup>>, 'bootstrap' | 'brands'>,
{ zcf = Far('MockZCF', {}) } = {},
) => {
const { timer, localchain, marshaller, rootZone, vowTools, agoricNames } =
Expand All @@ -32,16 +34,26 @@ export const prepareMakeTestLOAKit = (
marshaller,
);

const chainHub = makeChainHub(agoricNames, vowTools);
const makeLocalOrchestrationAccountKit = prepareLocalOrchestrationAccountKit(
rootZone,
makeRecorderKit,
// @ts-expect-error mocked zcf. use `stake-bld.contract.test.ts` to test LCA with offer
zcf,
timer,
vowTools,
makeChainHub(agoricNames, vowTools),
chainHub,
);

const bld = withAmountUtils(makeIssuerKit('BLD'));
chainHub.registerChain('agoric', fetchedChainInfo.agoric);
chainHub.registerAsset('ubld', {
chainName: 'agoric',
baseName: 'agoric',
baseDenom: 'ubld',
brand: brands.bld.brand,
});

return async ({
storageNode = bootstrap.storage.rootNode.makeChildNode('accounts'),
} = {}) => {
Expand Down
10 changes: 6 additions & 4 deletions packages/orchestration/test/exos/portfolio-holder-kit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { prepareMakeTestLOAKit } from './make-test-loa-kit.js';
import { prepareMakeTestCOAKit } from './make-test-coa-kit.js';

test('portfolio holder kit behaviors', async t => {
const { bootstrap } = await commonSetup(t);
const { rootZone, storage, vowTools } = bootstrap;
const common = await commonSetup(t);
const { rootZone, storage, vowTools } = common.bootstrap;
const storageNode = storage.rootNode.makeChildNode('accounts');

/**
Expand All @@ -23,8 +23,10 @@ test('portfolio holder kit behaviors', async t => {
},
});

const makeTestCOAKit = prepareMakeTestCOAKit(t, bootstrap, { zcf: mockZcf });
const makeTestLOAKit = prepareMakeTestLOAKit(t, bootstrap, { zcf: mockZcf });
const makeTestCOAKit = prepareMakeTestCOAKit(t, common.bootstrap, {
zcf: mockZcf,
});
const makeTestLOAKit = prepareMakeTestLOAKit(t, common, { zcf: mockZcf });
const makeCosmosAccount = async ({
chainId,
hostConnectionId,
Expand Down

0 comments on commit 5aa48dc

Please sign in to comment.