Skip to content

Commit

Permalink
test: move vault upgrade from test to use phase
Browse files Browse the repository at this point in the history
refactor oracle registration to make it simpler to push prices later
  • Loading branch information
Chris-Hibbert authored and mhofman committed Jun 21, 2024
1 parent b6bbb79 commit 9686fb7
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 37 deletions.
55 changes: 44 additions & 11 deletions a3p-integration/proposals/a:upgrade-next/agd-tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,30 +48,63 @@ export const checkForOracle = async (t, name) => {
t.truthy(instance);
};

export const addOraclesForBrand = async (brandIn, oraclesByBrand) => {
export const registerOraclesForBrand = async (brandIn, oraclesByBrand) => {
await null;
const promiseArray = [];

const oraclesWithID = [];
// newOfferId() waits 1 second
const offerIdBase = await newOfferId();
for (let i = 0; i < ORACLE_ADDRESSES.length; i += 1) {
const oracleAddress = ORACLE_ADDRESSES[i];
const offerId = `${offerIdBase}.${i}`;
oraclesWithID.push({ address: oracleAddress, offerId });

const oraclesWithID = oraclesByBrand.get(brandIn);
for (const oracle of oraclesWithID) {
const { address, offerId } = oracle;
promiseArray.push(
executeOffer(
oracleAddress,
address,
agops.oracle('accept', '--offerId', offerId, `--pair ${brandIn}.USD`),
),
);
}
oraclesByBrand.set(brandIn, oraclesWithID);

return Promise.all(promiseArray);
};

/**
* Generate a consistent map of oracleIDs for a brand that can be used to
* register oracles or to push prices. The baseID changes each time new
* invitations are sent/accepted, and need to be maintained as constants in
* scripts that use the oracles. Each oracleAddress and brand needs a unique
* offerId, so we create recoverable IDs using the brandName and oracle id,
* mixed with the upgrade at which the invitations were accepted.
*
* @param {string} baseId
* @param {string} brandName
*/
const addOraclesForBrand = (baseId, brandName) => {
const oraclesWithID = [];
for (let i = 0; i < ORACLE_ADDRESSES.length; i += 1) {
const oracleAddress = ORACLE_ADDRESSES[i];
const offerId = `${brandName}.${baseId}.${i}`;
oraclesWithID.push({ address: oracleAddress, offerId });
}
return oraclesWithID;
};

/**
* Generate a consistent map of oracleIDs and brands that can be used to
* register oracles or to push prices. The baseID changes each time new
* invitations are sent/accepted, and need to be maintained as constants in
* scripts that use these records to push prices.
*
* @param {string} baseId
* @param {string[]} brandNames
*/
export const generateOracleMap = (baseId, brandNames) => {
const oraclesByBrand = new Map();
for (const brandName of brandNames) {
const oraclesWithID = addOraclesForBrand(baseId, brandName);
oraclesByBrand.set(brandName, oraclesWithID);
}
return oraclesByBrand;
};

export const pushPrices = (price, brandIn, oraclesByBrand) => {
const promiseArray = [];

Expand Down
30 changes: 30 additions & 0 deletions a3p-integration/proposals/a:upgrade-next/upgradeVaults.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env node

import assert from 'node:assert/strict';
import {
generateOracleMap,
getPriceQuote,
pushPrices,
registerOraclesForBrand,
} from './agd-tools.js';

const BRANDNAMES = ['ATOM', 'stATOM', 'stTIA', 'stOSMO', 'stkATOM'];
const oraclesByBrand = generateOracleMap('u16', BRANDNAMES);

// There are no old prices for the other currencies.
const atomOutPre = await getPriceQuote('ATOM');
assert.equal(atomOutPre, '+12010000');

console.log('adding oracle for each brand');
await registerOraclesForBrand('ATOM', oraclesByBrand);
await registerOraclesForBrand('stATOM', oraclesByBrand);
await registerOraclesForBrand('stTIA', oraclesByBrand);
await registerOraclesForBrand('stOSMO', oraclesByBrand);
await registerOraclesForBrand('stkATOM', oraclesByBrand);

console.log('pushing new prices');
await pushPrices(11.2, 'ATOM', oraclesByBrand);
await pushPrices(11.3, 'stTIA', oraclesByBrand);
await pushPrices(11.4, 'stATOM', oraclesByBrand);
await pushPrices(11.5, 'stOSMO', oraclesByBrand);
await pushPrices(11.6, 'stkATOM', oraclesByBrand);
35 changes: 9 additions & 26 deletions a3p-integration/proposals/a:upgrade-next/upgradeVaults.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import {
} from '@agoric/synthetic-chain';

import {
addOraclesForBrand,
bankSend,
BID_OFFER_ID,
checkForOracle,
createBid,
generateOracleMap,
getLiveOffers,
getPriceQuote,
pushPrices,
Expand All @@ -40,27 +40,10 @@ const checkPriceFeedVatsUpdated = async t => {
]);
};

const oraclesByBrand = new Map();

const tryPushPrices = async t => {
// There are no old prices for the other currencies.
const atomOutPre = await getPriceQuote('ATOM');
t.is(atomOutPre, '+12010000');

t.log('adding oracle for each brand');
await addOraclesForBrand('ATOM', oraclesByBrand);
await addOraclesForBrand('stATOM', oraclesByBrand);
await addOraclesForBrand('stTIA', oraclesByBrand);
await addOraclesForBrand('stOSMO', oraclesByBrand);
await addOraclesForBrand('stkATOM', oraclesByBrand);

t.log('pushing new prices');
await pushPrices(11.2, 'ATOM', oraclesByBrand);
await pushPrices(11.3, 'stTIA', oraclesByBrand);
await pushPrices(11.4, 'stATOM', oraclesByBrand);
await pushPrices(11.5, 'stOSMO', oraclesByBrand);
await pushPrices(11.6, 'stkATOM', oraclesByBrand);
const BRANDNAMES = ['ATOM', 'stATOM', 'stTIA', 'stOSMO', 'stkATOM'];
const oraclesByBrand = generateOracleMap('u16', BRANDNAMES);

const checkNewQuotes = async t => {
t.log('awaiting new quotes');
const atomOut = await getPriceQuote('ATOM');
t.is(atomOut, '+11200000');
Expand All @@ -71,7 +54,7 @@ const tryPushPrices = async t => {
const osmoOut = await getPriceQuote('stOSMO');
t.is(osmoOut, '+11500000');
const stkAtomOut = await getPriceQuote('stkATOM');
t.is(stkAtomOut, '+11600000');
await t.is(stkAtomOut, '+11600000');
};

const createNewBid = async t => {
Expand Down Expand Up @@ -106,7 +89,7 @@ const triggerAuction = async t => {
t.is(atomOut, '+5200000');
};

const makeNewAuctionVat = async t => {
const checkAuctionVat = async t => {
const details = await getDetailsMatchingVats('auctioneer');
// This query matches both the auction and its governor, so double the count
t.true(Object.keys(details).length > 2);
Expand All @@ -117,8 +100,8 @@ test('liquidation post upgrade', async t => {
t.log('starting upgrade vaults test');
await checkPriceFeedVatsUpdated(t);

t.log('starting pushPrices');
await tryPushPrices(t);
t.log('check new price quotes');
await checkNewQuotes(t);

t.log('create a new Bid for the auction');
await createNewBid(t);
Expand All @@ -130,5 +113,5 @@ test('liquidation post upgrade', async t => {
await triggerAuction(t);

t.log('make new auction');
await makeNewAuctionVat(t);
await checkAuctionVat(t);
});
2 changes: 2 additions & 0 deletions a3p-integration/proposals/a:upgrade-next/use.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
# actions are executed in the upgraded chain software and the effects are
# persisted in the generated image for the upgrade, so they can be used in
# later steps, such as the "test" step, or further proposal layers.

./upgradeVaults.js

0 comments on commit 9686fb7

Please sign in to comment.