Skip to content

Commit

Permalink
refactor: cosmos-orchestration-account-kit.test.ts
Browse files Browse the repository at this point in the history
this test can no longer rely on the IST brand being available, so we
 - added checks to ensure brands are accepted for `.transfer` and `.send`. marked as failing for now
 - filed #10449 since this surfaced a bug in `amountToCoin`
 - use Moolah issuer for "no denom for brand" failure path tests
  • Loading branch information
0xpatrickdev committed Dec 3, 2024
1 parent fbbd169 commit 66f7cf7
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 19 deletions.
4 changes: 3 additions & 1 deletion packages/boot/test/bootstrapTests/orchestration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,9 @@ test.serial('stakeAtom - smart wallet', async t => {
proposal: {},
}),
{
message: 'No denom for brand [object Alleged: ATOM brand]',
// TODO #10449
message:
"'amountToCoin' not working for \"[Alleged: ATOM brand]\" until #10449; use 'DenomAmount' for now",
},
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ const contract = async (
);

const orchFns = orchestrateAll(flows, {
chainHub,
sharedLocalAccountP,
makeCombineInvitationMakers,
makeExtraInvitationMaker,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* @import {GuestInterface} from '@agoric/async-flow';
* @import {Orchestrator, OrchestrationFlow, AmountArg, CosmosValidatorAddress, ChainAddress, LocalAccountMethods, OrchestrationAccountI} from '../types.js'
* @import {Orchestrator, OrchestrationFlow, AmountArg, CosmosValidatorAddress, ChainAddress, LocalAccountMethods, OrchestrationAccountI, ChainHub} from '../types.js'
* @import {ContinuingOfferResult, InvitationMakers} from '@agoric/smart-wallet/src/types.js';
* @import {LocalOrchestrationAccountKit} from '../exos/local-orchestration-account.js';
* @import {MakeCombineInvitationMakers} from '../exos/combine-invitation-makers.js';
Expand All @@ -9,7 +9,7 @@
*/

import { mustMatch } from '@endo/patterns';
import { makeError, q } from '@endo/errors';
import { Fail, makeError, q } from '@endo/errors';
import { makeTracer } from '@agoric/internal';
import { ChainAddressShape } from '../typeGuards.js';

Expand Down Expand Up @@ -48,6 +48,7 @@ harden(makeAccount);
* @satisfies {OrchestrationFlow}
* @param {Orchestrator} orch
* @param {object} ctx
* @param {GuestInterface<ChainHub>} ctx.chainHub
* @param {Promise<GuestInterface<LocalOrchestrationAccountKit['holder']>>} ctx.sharedLocalAccountP
* @param {GuestInterface<ZoeTools>} ctx.zoeTools
* @param {GuestInterface<CosmosOrchestrationAccount>} account
Expand All @@ -57,7 +58,7 @@ harden(makeAccount);
*/
export const depositAndDelegate = async (
orch,
{ sharedLocalAccountP, zoeTools },
{ chainHub, sharedLocalAccountP, zoeTools },
account,
seat,
validator,
Expand All @@ -84,7 +85,11 @@ export const depositAndDelegate = async (
throw errMsg;
}
seat.exit();
await account.delegate(validator, give.Stake);
const denom = chainHub.getDenom(give.Stake.brand);
if (!denom) throw Fail`unknown brand ${q(give.Stake.brand)}`;
// TODO #10449 amountToCoin accepts brands
const denomAmount = harden({ denom, value: give.Stake.value });
await account.delegate(validator, denomAmount);
};
harden(depositAndDelegate);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,8 @@ export const prepareCosmosOrchestrationAccountKit = (
* @returns {Coin}
*/
amountToCoin(amount) {
!('brand' in amount) ||
Fail`'amountToCoin' not working for ${q(amount.brand)} until #10449; use 'DenomAmount' for now`;
return coerceCoin(chainHub, amount);
},
},
Expand Down
104 changes: 90 additions & 14 deletions packages/orchestration/test/exos/cosmos-orchestration-account.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import {
QueryBalanceRequest,
QueryBalanceResponse,
} from '@agoric/cosmic-proto/cosmos/bank/v1beta1/query.js';
import {
MsgSend,
MsgSendResponse,
} from '@agoric/cosmic-proto/cosmos/bank/v1beta1/tx.js';
import { Coin } from '@agoric/cosmic-proto/cosmos/base/v1beta1/coin.js';
import {
QueryDelegationRequest,
Expand All @@ -38,6 +42,8 @@ import {
MsgDelegate,
MsgDelegateResponse,
} from '@agoric/cosmic-proto/cosmos/staking/v1beta1/tx.js';
import { withAmountUtils } from '@agoric/zoe/tools/test-utils.js';
import { makeIssuerKit } from '@agoric/ertp';
import { decodeBase64 } from '@endo/base64';
import { commonSetup } from '../supports.js';
import type {
Expand All @@ -55,6 +61,8 @@ import {
} from '../../tools/ibc-mocks.js';
import type { CosmosValidatorAddress } from '../../src/cosmos-api.js';
import { protoMsgMocks } from '../ibc-mocks.js';
import fetchedChainInfo from '../../src/fetched-chain-info.js';
import { assetOn } from '../../src/utils/asset.js';

type TestContext = Awaited<ReturnType<typeof commonSetup>>;

Expand All @@ -64,9 +72,18 @@ test.beforeEach(async t => {
t.context = await commonSetup(t);
});

const [uistOnCosmos] = assetOn(
'uist',
'agoric',
undefined,
'cosmoshub',
fetchedChainInfo,
);

test('send (to addr on same chain)', async t => {
const {
brands: { ist },
mocks: { ibcBridge },
utils: { inspectDibcBridge, populateChainHub },
} = t.context;
populateChainHub();
Expand All @@ -89,17 +106,60 @@ test('send (to addr on same chain)', async t => {
undefined,
);

// register handler for ist bank send
ibcBridge.addMockAck(
buildTxPacketString([
MsgSend.toProtoMsg({
fromAddress: 'cosmos1test',
toAddress: 'cosmos99test',
amount: [
{
denom: uistOnCosmos,
// denom: 'ibc/uisthash',
amount: '10',
},
],
}),
]),
buildMsgResponseString(MsgSendResponse, {}),
);

t.is(
await E(account).send(toAddress, {
denom: uistOnCosmos,
value: 10n,
} as AmountArg),
undefined,
'send accepts Amount',
);

await t.throwsAsync(
() => E(account).send(toAddress, ist.make(10n) as AmountArg),
{
message:
"'amountToCoin' not working for \"[Alleged: IST brand]\" until #10449; use 'DenomAmount' for now",
},
'TODO #10449 amountToCoin for CosmosOrchestrationAccount',
);

// simulate timeout error
await t.throwsAsync(
E(account).send(toAddress, { value: 504n, denom: 'uatom' } as AmountArg),
// TODO #9629 decode error messages
{ message: 'ABCI code: 5: error handling packet: see events for details' },
);

// IST not registered
await t.throwsAsync(E(account).send(toAddress, ist.make(10n) as AmountArg), {
message: 'No denom for brand [object Alleged: IST brand]',
});
// MOO brand not registered
const moolah = withAmountUtils(makeIssuerKit('MOO'));
await t.throwsAsync(
E(account).send(toAddress, moolah.make(10n) as AmountArg),
{
// TODO #10449
// message: 'No denom for brand [object Alleged: MOO brand]',
message:
"'amountToCoin' not working for \"[Alleged: MOO brand]\" until #10449; use 'DenomAmount' for now",
},
);

// multi-send (sendAll)
t.is(
Expand All @@ -111,11 +171,10 @@ test('send (to addr on same chain)', async t => {
);

const { bridgeDowncalls } = await inspectDibcBridge();

t.is(
bridgeDowncalls.filter(d => d.method === 'sendPacket').length,
3,
'sent 2 successful txs and 1 failed. 1 rejected before sending',
4,
'sent 3 successful txs and 1 failed. 1 rejected before sending',
);
});

Expand Down Expand Up @@ -186,13 +245,22 @@ test('transfer', async t => {
},
});

const umooTransfer = toTransferTxPacket({
...mockIbcTransfer,
token: {
denom: 'umoo',
amount: '10',
},
});

return {
[defaultTransfer]: transferResp,
[customTimeoutHeight]: transferResp,
[customTimeoutTimestamp]: transferResp,
[customTimeout]: transferResp,
[customMemo]: transferResp,
[uistTransfer]: transferResp,
[umooTransfer]: transferResp,
};
};
ibcBridge.setMockAck(buildMocks());
Expand Down Expand Up @@ -309,18 +377,26 @@ test('transfer', async t => {
},
);

const moolah = withAmountUtils(makeIssuerKit('MOO'));
t.log('transfer throws if asset is not in its chainHub');
await t.throwsAsync(E(account).transfer(mockDestination, ist.make(10n)), {
message: 'No denom for brand [object Alleged: IST brand]',
await t.throwsAsync(E(account).transfer(mockDestination, moolah.make(10n)), {
// TODO #10449
// message: 'No denom for brand [object Alleged: MOO brand]',
message:
"'amountToCoin' not working for \"[Alleged: MOO brand]\" until #10449; use 'DenomAmount' for now",
});
chainHub.registerAsset('uist', {
baseDenom: 'uist',
chainHub.registerAsset('umoo', {
baseDenom: 'umoo',
baseName: 'agoric',
brand: ist.brand,
brand: moolah.brand,
chainName: 'agoric',
});
// uses uistTransfer mock above
await E(account).transfer(mockDestination, ist.make(10n));
// uses umooTransfer mock above
await E(account).transfer(
mockDestination,
// moolah.make(10n), // TODO #10449 restore
{ denom: 'umoo', value: 10n },
);

t.log('transfer timeout error recieved and handled from the bridge');
await t.throwsAsync(
Expand Down
1 change: 1 addition & 0 deletions packages/orchestration/test/supports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ export const commonSetup = async (t: ExecutionContext<any>) => {
const commonAssetInfo = harden([
assetOn('ubld', 'agoric', bldSansMint.brand),
assetOn('uist', 'agoric', istSansMint.brand),
assetOn('uist', 'agoric', undefined, 'cosmoshub', chainInfoWithCaps),
assetOn('uusdc', 'noble', undefined, 'agoric', chainInfoWithCaps),
assetOn('uatom', 'cosmoshub', undefined, 'agoric', chainInfoWithCaps),
assetOn('uusdc', 'noble', undefined, 'dydx', chainInfoWithCaps),
Expand Down

0 comments on commit 66f7cf7

Please sign in to comment.