Skip to content

Commit

Permalink
feat(fast-usdc): publish feeConfig to vstorage (#10587)
Browse files Browse the repository at this point in the history
closes: #10509

I accidentally closed #10583 when squashing the merge commits, making a new PR
  • Loading branch information
mergify[bot] authored Nov 28, 2024
2 parents 45d0417 + fe1df43 commit 8a52ddd
Show file tree
Hide file tree
Showing 8 changed files with 2,083 additions and 133 deletions.
7 changes: 6 additions & 1 deletion packages/boot/test/bootstrapTests/orchestration.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { test as anyTest } from '@agoric/zoe/tools/prepare-test-env-ava.js';

import { Fail } from '@endo/errors';
import { documentStorageSchema } from '@agoric/internal/src/storage-test-utils.js';
import {
defaultMarshaller,
documentStorageSchema,
} from '@agoric/internal/src/storage-test-utils.js';
import type { CosmosValidatorAddress } from '@agoric/orchestration';
import type { start as startStakeIca } from '@agoric/orchestration/src/examples/stake-ica.contract.js';
import type { Instance } from '@agoric/zoe/src/zoeService/utils.js';
Expand Down Expand Up @@ -52,6 +55,7 @@ test.serial('config', async t => {
await documentStorageSchema(t, storage, {
note: 'Chain info for Orchestration',
node: 'agoricNames.chain',
showValue: v => defaultMarshaller.fromCapData(JSON.parse(v)),
});
}

Expand All @@ -73,6 +77,7 @@ test.serial('config', async t => {
await documentStorageSchema(t, storage, {
note: 'Chain connections for Orchestration',
node: 'agoricNames.chainConnection',
showValue: v => defaultMarshaller.fromCapData(JSON.parse(v)),
});
}
{
Expand Down
2,076 changes: 1,961 additions & 115 deletions packages/boot/test/bootstrapTests/snapshots/orchestration.test.ts.md

Large diffs are not rendered by default.

Binary file not shown.
14 changes: 13 additions & 1 deletion packages/boot/test/fast-usdc/fast-usdc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { documentStorageSchema } from '@agoric/governance/tools/storageDoc.js';
import { Fail } from '@endo/errors';
import { unmarshalFromVstorage } from '@agoric/internal/src/marshal.js';
import { makeMarshal } from '@endo/marshal';
import { defaultMarshaller } from '@agoric/internal/src/storage-test-utils.js';
import {
makeWalletFactoryContext,
type WalletFactoryTestContext,
Expand Down Expand Up @@ -110,9 +111,20 @@ test.serial(

test.serial('writes feed policy to vstorage', async t => {
const { storage } = t.context;
const doc = {
const opts = {
node: 'fastUsdc.feedPolicy',
owner: 'the general and chain-specific policies for the Fast USDC feed',
showValue: JSON.parse,
};
await documentStorageSchema(t, storage, opts);
});

test.serial('writes fee config to vstorage', async t => {
const { storage } = t.context;
const doc = {
node: 'fastUsdc.feeConfig',
owner: 'the fee configuration for Fast USDC',
showValue: v => defaultMarshaller.fromCapData(JSON.parse(v)),
};
await documentStorageSchema(t, storage, doc);
});
Expand Down
60 changes: 57 additions & 3 deletions packages/boot/test/fast-usdc/snapshots/fast-usdc.test.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,61 @@ Generated by [AVA](https://avajs.dev).
[
[
'published.fastUsdc.feedPolicy',
'{"blockHeight":"0","values":["{\\"chainPolicies\\":{\\"Arbitrum\\":{\\"cctpTokenMessengerAddress\\":\\"0x19330d10D9Cc8751218eaf51E8885D058642E08A\\",\\"chainId\\":42161,\\"confirmations\\":2,\\"nobleContractAddress\\":\\"0x19330d10D9Cc8751218eaf51E8885D058642E08A\\"}},\\"nobleAgoricChannelId\\":\\"channel-21\\",\\"nobleDomainId\\":4}"]}',
{
chainPolicies: {
Arbitrum: {
cctpTokenMessengerAddress: '0x19330d10D9Cc8751218eaf51E8885D058642E08A',
chainId: 42161,
confirmations: 2,
nobleContractAddress: '0x19330d10D9Cc8751218eaf51E8885D058642E08A',
},
},
nobleAgoricChannelId: 'channel-21',
nobleDomainId: 4,
},
],
]

## writes fee config to vstorage

> Under "published", the "fastUsdc.feeConfig" node is delegated to the fee configuration for Fast USDC.
> The example below illustrates the schema of the data published there.
>
> See also board marshalling conventions (_to appear_).
[
[
'published.fastUsdc.feeConfig',
{
contractRate: {
denominator: {
brand: Object @Alleged: USDC brand {},
value: 10n,
},
numerator: {
brand: Object @Alleged: USDC brand {},
value: 2n,
},
},
flat: {
brand: Object @Alleged: USDC brand {},
value: 10000n,
},
maxVariable: {
brand: Object @Alleged: USDC brand {},
value: 5000000n,
},
variableRate: {
denominator: {
brand: Object @Alleged: USDC brand {},
value: 100n,
},
numerator: {
brand: Object @Alleged: USDC brand {},
value: 1n,
},
},
},
],
]

Expand All @@ -28,10 +82,10 @@ Generated by [AVA](https://avajs.dev).
[
[
'published.fastUsdc.status.0xc81bc6105b60a234c7c50ac17816ebcd5561d366df8bf3be59ff387552761702',
'{"blockHeight":"0","values":["OBSERVED"]}',
'OBSERVED',
],
[
'published.fastUsdc.status.0xd81bc6105b60a234c7c50ac17816ebcd5561d366df8bf3be59ff387552761799',
'{"blockHeight":"0","values":["OBSERVED"]}',
'OBSERVED',
],
]
Binary file modified packages/boot/test/fast-usdc/snapshots/fast-usdc.test.ts.snap
Binary file not shown.
22 changes: 18 additions & 4 deletions packages/fast-usdc/src/fast-usdc.contract.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@ import * as flows from './fast-usdc.flows.js';
const trace = makeTracer('FastUsdc');

const STATUS_NODE = 'status';
const FEE_NODE = 'feeConfig';

/**
* @import {HostInterface} from '@agoric/async-flow';
* @import {CosmosChainInfo, Denom, DenomDetail, OrchestrationAccount} from '@agoric/orchestration';
* @import {OrchestrationPowers, OrchestrationTools} from '@agoric/orchestration/src/utils/start-helper.js';
* @import {Vow} from '@agoric/vow';
* @import {Remote} from '@agoric/internal';
* @import {Marshaller, StorageNode} from '@agoric/internal/src/lib-chainStorage.js'
* @import {Zone} from '@agoric/zone';
* @import {OperatorKit} from './exos/operator-kit.js';
* @import {CctpTxEvidence, FeeConfig} from './types.js';
Expand Down Expand Up @@ -63,6 +65,17 @@ export const meta = {
};
harden(meta);

/**
* @param {Remote<StorageNode>} node
* @param {ERef<Marshaller>} marshaller
* @param {FeeConfig} feeConfig
*/
const publishFeeConfig = async (node, marshaller, feeConfig) => {
const feeNode = E(node).makeChildNode(FEE_NODE);
const value = await E(marshaller).toCapData(feeConfig);
return E(feeNode).setValue(JSON.stringify(value));
};

/**
* @param {ZCF<FastUsdcTerms>} zcf
* @param {OrchestrationPowers & {
Expand All @@ -80,14 +93,13 @@ export const contract = async (zcf, privateArgs, zone, tools) => {
assert('USDC' in terms.brands, 'no USDC brand');
assert('usdcDenom' in terms, 'no usdcDenom');

const { feeConfig, marshaller } = privateArgs;
const { feeConfig, marshaller, storageNode } = privateArgs;
const { makeRecorderKit } = prepareRecorderKitMakers(
zone.mapStore('vstorage'),
marshaller,
);

const makeStatusNode = () =>
E(privateArgs.storageNode).makeChildNode(STATUS_NODE);
const makeStatusNode = () => E(storageNode).makeChildNode(STATUS_NODE);
const statusManager = prepareStatusManager(zone, makeStatusNode);

const { USDC } = terms.brands;
Expand Down Expand Up @@ -209,6 +221,8 @@ export const contract = async (zcf, privateArgs, zone, tools) => {
// So we use zone.exoClassKit above to define the liquidity pool kind
// and pass the shareMint into the maker / init function.

void publishFeeConfig(storageNode, marshaller, feeConfig);

const shareMint = await provideSingleton(
zone.mapStore('mint'),
'PoolShare',
Expand Down
37 changes: 28 additions & 9 deletions packages/internal/src/storage-test-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { makeTracer } from './debug.js';
import { isStreamCell, makeChainStorageRoot } from './lib-chainStorage.js';
import { bindAllMethods } from './method-tools.js';
import { eventLoopIteration } from './testing-utils.js';
import { NonNullish } from './errors.js';

/**
* @import {TotalMap} from './types.js';
Expand Down Expand Up @@ -250,30 +251,48 @@ export const makeMockChainStorageRoot = () => {
* @param {import('ava').ExecutionContext<unknown>} t
* @param {MockChainStorageRoot | FakeStorageKit} storage
* @param {({ note: string } | { node: string; owner: string }) &
* ({ pattern: string; replacement: string } | {})} opts
* ({ pattern: string; replacement: string } | {}) & {
* showValue?: (v: string) => unknown;
* }} opts
*/
export const documentStorageSchema = async (t, storage, opts) => {
// chainStorage publication is unsynchronized
await eventLoopIteration();

const getLast = (/** @type {string} */ cell) =>
JSON.parse(cell).values.at(-1) || assert.fail();
const { showValue = s => s } = opts;
/** @type {(d: Map<string, string>, k: string) => unknown} */
const getBodyDefault = (d, k) => showValue(getLast(NonNullish(d.get(k))));

const [keys, getBody] =
'keys' in storage
? [storage.keys(), (/** @type {string} */ k) => storage.getBody(k)]
: [storage.data.keys(), (/** @type {string} */ k) => storage.data.get(k)];
: [
storage.data.keys(),
(/** @type {string} */ k) => getBodyDefault(storage.data, k),
];

const { pattern, replacement } =
'pattern' in opts
? opts
: { pattern: 'mockChainStorageRoot.', replacement: 'published.' };
const illustration = [...keys].sort().map(

const pruned = [...keys]
.sort()
.filter(
'node' in opts
? key =>
key
.replace(pattern, replacement)
.startsWith(`published.${opts.node}`)
: _entry => true,
);

const illustration = pruned.map(
/** @type {(k: string) => [string, unknown]} */
key => [key.replace(pattern, replacement), getBody(key)],
);
const pruned = illustration.filter(
'node' in opts
? ([key, _]) => key.startsWith(`published.${opts.node}`)
: _entry => true,
);

const note =
'note' in opts
Expand All @@ -283,5 +302,5 @@ export const documentStorageSchema = async (t, storage, opts) => {
The example below illustrates the schema of the data published there.
See also board marshalling conventions (_to appear_).`;
t.snapshot(pruned, note + boilerplate);
t.snapshot(illustration, note + boilerplate);
};

0 comments on commit 8a52ddd

Please sign in to comment.