Skip to content

Commit

Permalink
test of replacing fast-usdc operators (#10834)
Browse files Browse the repository at this point in the history
closes: #10754


## Description
Adds a test for adding new operators after removing

### Security Considerations


### Scaling Considerations


### Documentation Considerations


### Testing Considerations


### Upgrade Considerations
  • Loading branch information
mergify[bot] authored Jan 14, 2025
2 parents ad2ef34 + da7c727 commit 7e9048c
Show file tree
Hide file tree
Showing 18 changed files with 379 additions and 97 deletions.
1 change: 1 addition & 0 deletions a3p-integration/proposals/f:fast-usdc/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add-operators
9 changes: 2 additions & 7 deletions a3p-integration/proposals/f:fast-usdc/deploy.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,14 @@
/* eslint-env node */
import test from 'ava';
import '@endo/init/legacy.js'; // axios compat
import { makeSmartWalletKit } from '@agoric/client-utils';
import { LOCAL_CONFIG, makeSmartWalletKit } from '@agoric/client-utils';

const io = {
delay: ms => new Promise(resolve => setTimeout(() => resolve(undefined), ms)),
fetch: global.fetch,
};
const networkConfig = {
rpcAddrs: ['http://0.0.0.0:26657'],
chainName: 'agoriclocal',
};

test('fastUsdc is in agoricNames.instance', async t => {
const { agoricNames } = await makeSmartWalletKit(io, networkConfig);
const { agoricNames } = await makeSmartWalletKit(io, LOCAL_CONFIG);

t.log('agoricNames.instance keys', Object.keys(agoricNames.instance));
t.truthy(agoricNames.instance.fastUsdc);
Expand Down
78 changes: 78 additions & 0 deletions a3p-integration/proposals/f:fast-usdc/operators.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/* eslint-env node */
import unknownTest from 'ava';

import '@endo/init/legacy.js'; // axios compat

import { LOCAL_CONFIG, makeVstorageKit } from '@agoric/client-utils';
import { evalBundles, waitForBlock } from '@agoric/synthetic-chain';

// XXX ~copied to not take a dependency on Zoe
/**
* @typedef {object} InvitationDetails
* @property {unknown} installation
* @property {unknown} instance
* @property {InvitationHandle} handle
* @property {string} description
* @property {Record<string, any>} [customDetails]
*/

/**
* @import {VstorageKit} from '@agoric/client-utils';
*/

const test = /** @type {import('ava').TestFn<{ vstorageKit: VstorageKit}>} */ (
unknownTest
);

const ADD_OPERATORS_DIR = 'add-operators';

/**
* @typedef {import('@agoric/ertp').NatAmount} NatAmount
* @typedef {{
* allocations: { Fee: NatAmount, USD_LEMONS: NatAmount },
* }} ReserveAllocations
*/

test.before(async t => {
const vstorageKit = makeVstorageKit({ fetch }, LOCAL_CONFIG);

t.context = {
vstorageKit,
};
});

test.serial('add operators', async t => {
const { vstorageKit } = t.context;

const walletPath =
// account mem3 in test of crabble-start proposal (64)
// This must match the oracleNew value in the add-operators builder argument
'wallet.agoric1hmdue96vs0p6zj42aa26x6zrqlythpxnvgsgpr.current';

const readInvitationsPurseBalance = async () => {
const curr = await vstorageKit.readPublished(walletPath);
return /** @type {InvitationDetails[]} */ (curr.purses[0].balance.value);
};

let numInvitationsBefore = 0;
{
const invBalance = await readInvitationsPurseBalance();
numInvitationsBefore = invBalance.length;
t.false(
invBalance.some(inv => inv.description === 'oracle operator invitation'),
);
}

await evalBundles(ADD_OPERATORS_DIR);
// give time for the invitations to be deposited
await waitForBlock(5);

{
const invBalance = await readInvitationsPurseBalance();
console.log('after', invBalance);
t.is(invBalance.length, numInvitationsBefore + 1);
t.true(
invBalance.some(inv => inv.description === 'oracle operator invitation'),
);
}
});
3 changes: 2 additions & 1 deletion a3p-integration/proposals/f:fast-usdc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"agoricProposal": {
"source": "subdir",
"sdk-generate": [
"fast-usdc/init-fast-usdc.js submission --net A3P_INTEGRATION --noNoble"
"fast-usdc/start-fast-usdc.build.js submission --net A3P_INTEGRATION --noNoble",
"fast-usdc/add-operators.build.js add-operators --oracle oracleNew:agoric1hmdue96vs0p6zj42aa26x6zrqlythpxnvgsgpr"
],
"type": "/agoric.swingset.CoreEvalProposal"
},
Expand Down
3 changes: 3 additions & 0 deletions a3p-integration/proposals/f:fast-usdc/test.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#!/bin/bash
set -euo pipefail

echo AVAILABLE WALLETs
agd query vstorage children published.wallet

yarn ava

./test-cli.sh
2 changes: 1 addition & 1 deletion multichain-testing/scripts/fast-usdc-tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Examples:

const contractName = 'fastUsdc';
const contractBuilder =
'../packages/builders/scripts/fast-usdc/init-fast-usdc.js';
'../packages/builders/scripts/fast-usdc/start-fast-usdc.build.js';

/** ava test context partial, to appease dependencies expecting this */
const runT = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const parserOpts = {
assets: { type: 'string' },
};

/** @type {CoreEvalBuilder} */
/** @satisfies {CoreEvalBuilder} */
export const defaultProposalBuilder = async (_, options) => {
return harden({
sourceSpec:
Expand Down
2 changes: 1 addition & 1 deletion multichain-testing/test/fast-usdc/fast-usdc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const test = anyTest as TestFn<
const accounts = [...keys(oracleMnemonics), 'lp'];
const contractName = 'fastUsdc';
const contractBuilder =
'../packages/builders/scripts/fast-usdc/init-fast-usdc.js';
'../packages/builders/scripts/fast-usdc/start-fast-usdc.build.js';
const LP_DEPOSIT_AMOUNT = 8_000n * 10n ** 6n;

test.before(async t => {
Expand Down
53 changes: 50 additions & 3 deletions packages/boot/test/fast-usdc/fast-usdc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ test.serial(
bridgeUtils.setBech32Prefix('noble');

const materials = buildProposal(
'@agoric/builders/scripts/fast-usdc/init-fast-usdc.js',
'@agoric/builders/scripts/fast-usdc/start-fast-usdc.build.js',
['--net', 'MAINNET'],
);
await evalProposal(materials);
Expand Down Expand Up @@ -469,6 +469,8 @@ test.serial('restart contract', async t => {
test.serial('replace operators', async t => {
const {
agoricNamesRemotes,
buildProposal,
evalProposal,
storage,
runUtils: { EV },
walletFactoryDriver: wfd,
Expand Down Expand Up @@ -521,6 +523,51 @@ test.serial('replace operators', async t => {
}
}

// TODO test adding new operators
// The naive approach is failing under XS. A new CoreEval may be necessary.
if (defaultManagerType === 'xs-worker') {
// XXX for some reason the code after this when run under XS fails with:
// message: 'unsettled value for "kp2526"',
return;
}

// Add some new oracle operator
const {
// any one would do
oracles: { gov1: address },
} = configurations.A3P_INTEGRATION;
const wallet = await wfd.provideSmartWallet(address);

const addOperators = buildProposal(
'@agoric/builders/scripts/fast-usdc/add-operators.build.js',
['--oracle', `gov1a3p:${address}`],
);
await evalProposal(addOperators);

await wallet.sendOffer({
id: 'claim-oracle-invitation',
invitationSpec: {
source: 'purse',
instance: agoricNamesRemotes.instance.fastUsdc,
description: 'oracle operator invitation',
},
proposal: {},
});
console.log('accepted invitation');

await wallet.sendOffer({
id: 'submit',
invitationSpec: {
source: 'continuing',
previousOffer: 'claim-oracle-invitation',
invitationMakerName: 'SubmitEvidence',
invitationArgs: [evidence],
},
proposal: {},
});
console.log('submitted price');
t.like(wallet.getLatestUpdateRecord(), {
status: {
id: 'submit',
result: 'inert; nothing should be expected from this offer',
},
});
});
2 changes: 1 addition & 1 deletion packages/boot/tools/supports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import type { SwingsetController } from '@agoric/swingset-vat/src/controller/con
import type { BridgeHandler, IBCDowncallMethod, IBCMethod } from '@agoric/vats';
import type { BootstrapRootObject } from '@agoric/vats/src/core/lib-boot.js';
import type { EProxy } from '@endo/eventual-send';
import type { FastUSDCCorePowers } from '@agoric/fast-usdc/src/fast-usdc.start.js';
import type { FastUSDCCorePowers } from '@agoric/fast-usdc/src/start-fast-usdc.core.js';
import {
defaultBeansPerVatCreation,
defaultBeansPerXsnapComputron,
Expand Down
83 changes: 83 additions & 0 deletions packages/builders/scripts/fast-usdc/add-operators.build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// @ts-check
import { makeHelpers } from '@agoric/deploy-script-support';
import { getManifestForAddOperators } from '@agoric/fast-usdc/src/add-operators.core.js';
import { toExternalConfig } from '@agoric/fast-usdc/src/utils/config-marshal.js';
import { configurations } from '@agoric/fast-usdc/src/utils/deploy-config.js';
import { Far } from '@endo/far';
import { parseArgs } from 'node:util';

/**
* @import {CoreEvalBuilder, DeployScriptFunction} from '@agoric/deploy-script-support/src/externalTypes.js';
* @import {ParseArgsConfig} from 'node:util';
* @import {FastUSDCConfig, FeedPolicy} from '@agoric/fast-usdc/src/types.js';
* @import {FastUSDCOpts} from './start-fast-usdc.build.js';
*/

const { keys } = Object;

/** @type {ParseArgsConfig['options']} */
const options = {
net: { type: 'string' },
oracle: { type: 'string', multiple: true },
};
const oraclesUsage = 'use --oracle name:address ...';

const crossVatContext = /** @type {const} */ ({
/** @type {Brand<'nat'>} */
USDC: Far('USDC Brand'),
});

/** @type {CoreEvalBuilder} */
export const defaultProposalBuilder = async (
powers,
/** @type {FastUSDCConfig} */ config,
) => {
return harden({
sourceSpec: '@agoric/fast-usdc/src/add-operators.core.js',
/** @type {[string, Parameters<typeof getManifestForAddOperators>[1]]} */
getManifestCall: [
getManifestForAddOperators.name,
{
options: toExternalConfig(config, crossVatContext),
},
],
});
};

/** @type {DeployScriptFunction} */
export default async (homeP, endowments) => {
const { writeCoreEval } = await makeHelpers(homeP, endowments);
const { scriptArgs } = endowments;

/** @type {{ values: FastUSDCOpts }} */
// @ts-expect-error ensured by options
const {
values: { oracle: oracleArgs, net },
} = parseArgs({ args: scriptArgs, options });

const parseOracleArgs = () => {
if (net) {
if (!(net in configurations)) {
throw Error(`${net} not in ${keys(configurations)}`);
}
return configurations[net].oracles;
}
if (!oracleArgs) throw Error(oraclesUsage);
return Object.fromEntries(
oracleArgs.map(arg => {
const result = arg.match(/(?<name>[^:]+):(?<address>.+)/);
if (!(result && result.groups)) throw Error(oraclesUsage);
const { name, address } = result.groups;
return [name, address];
}),
);
};

const config = harden({
oracles: parseOracleArgs(),
});

await writeCoreEval('add-operators', utils =>
defaultProposalBuilder(utils, config),
);
};
10 changes: 7 additions & 3 deletions packages/builders/scripts/fast-usdc/fast-usdc-update.build.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,14 @@ const feedPolicyUsage = 'use --feedPolicy <policy> ...';
* }} FastUSDCUpdateOpts
*/

/** @type {CoreEvalBuilder} */
/**
* @param {Parameters<CoreEvalBuilder>[0]} powers
* @param {FastUSDCConfig} config
* @satisfies {CoreEvalBuilder}
*/
export const updateProposalBuilder = async (
_utils,
/** @type {FastUSDCConfig} */ config,
powers,
/** @type {Pick<FastUSDCConfig, 'feedPolicy'>} */ config,
) => {
return harden({
sourceSpec: '@agoric/fast-usdc/src/fast-usdc-policy.core.js',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
// @ts-check
import { makeHelpers } from '@agoric/deploy-script-support';
import { AmountMath } from '@agoric/ertp';
import {
FastUSDCConfigShape,
getManifestForFastUSDC,
} from '@agoric/fast-usdc/src/fast-usdc.start.js';
import { getManifestForFastUSDC } from '@agoric/fast-usdc/src/start-fast-usdc.core.js';
import { FastUSDCConfigShape } from '@agoric/fast-usdc/src/type-guards.js';
import { toExternalConfig } from '@agoric/fast-usdc/src/utils/config-marshal.js';
import { configurations } from '@agoric/fast-usdc/src/utils/deploy-config.js';
import {
Expand Down Expand Up @@ -72,13 +70,17 @@ const { USDC } = crossVatContext;
const USDC_DECIMALS = 6;
const unit = AmountMath.make(USDC, 10n ** BigInt(USDC_DECIMALS));

/** @type {CoreEvalBuilder} */
/**
* @param {Parameters<CoreEvalBuilder>[0]} powers
* @param {FastUSDCConfig} config
* @satisfies {CoreEvalBuilder}
*/
export const defaultProposalBuilder = async (
{ publishRef, install },
/** @type {FastUSDCConfig} */ config,
config,
) => {
return harden({
sourceSpec: '@agoric/fast-usdc/src/fast-usdc.start.js',
sourceSpec: '@agoric/fast-usdc/src/start-fast-usdc.core.js',
/** @type {[string, Parameters<typeof getManifestForFastUSDC>[1]]} */
getManifestCall: [
getManifestForFastUSDC.name,
Expand Down
Loading

0 comments on commit 7e9048c

Please sign in to comment.