Skip to content

Commit

Permalink
test: test mostly works. need to wait for auction to finish
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris-Hibbert committed Apr 17, 2024
1 parent e84e5e0 commit 7d3191e
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import { getDetailsMatchingVats } from './vatDetails.js';

test('new auction vat', async t => {
const details = await getDetailsMatchingVats('auctioneer');
// This query matches both the auction and its governor
// This query matches both the auction and its governor, so double the count
t.true(Object.keys(details).length > 2);
});
97 changes: 79 additions & 18 deletions a3p-integration/proposals/a:upgrade-next/priceFeed.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,32 @@ import test from 'ava';
import {
agd,
agops,
agopsLocation,
executeCommand,
executeOffer,
getVatDetails,
GOV1ADDR,
GOV2ADDR,
GOV3ADDR,
newOfferId,
openVault,
USER1ADDR,
} from '@agoric/synthetic-chain';

const ORACLE_ADDRESSES = [GOV1ADDR, GOV2ADDR, GOV3ADDR];

const agdQuery = path =>
agd.query('vstorage', 'data', '--output', 'json', path);

async function getQuoteBody(path) {
const queryout = await agdQuery(path);

const body = JSON.parse(JSON.parse(queryout.value).values[0]);
return JSON.parse(body.body.substring(1));
}

const getOracleInstance = async price => {
const instanceRec = await agd.query(
'vstorage',
'data',
'--output',
'json',
`published.agoricNames.instance`,
);
const instanceRec = await agdQuery(`published.agoricNames.instance`);

// agd query -o json vstorage data published.agoricNames.instance
// |& jq '.value | fromjson | .values[-1] | fromjson | .body[1:]
Expand Down Expand Up @@ -105,17 +113,9 @@ const pushPrices = (price = 10.0, brandIn) => {
};

const getPriceQuote = async price => {
const priceQuote = await agd.query(
'vstorage',
'data',
'--output',
'json',
`published.priceFeed.${price}-USD_price_feed`,
);

const body = JSON.parse(JSON.parse(priceQuote.value).values[0]);
const bodyTruncated = JSON.parse(body.body.substring(1));
return bodyTruncated.amountOut.value;
const path = `published.priceFeed.${price}-USD_price_feed`;
const body = await getQuoteBody(path);
return body.amountOut.value;
};

test.serial('push prices', async t => {
Expand Down Expand Up @@ -148,3 +148,64 @@ test.serial('push prices', async t => {
const osmoOut = await getPriceQuote('stOSMO');
t.is(osmoOut, '+11500000');
});

export const agopsInter = (...params) => {
const newParams = ['inter', ...params];
return executeCommand(agopsLocation, newParams);
};

// agops inter bid by-price --price 1 --give 1.0IST --from $GOV1ADDR --keyring-backend test
test.serial('create new bid', async t => {
const offerId = 'bid-vaultUpgrade-test';
/* const interCmd = */ await agopsInter(
'bid',
'by-price',
'--price 20',
`--give 1.0IST`,
'--from',
USER1ADDR,
'--keyring-backend test',
`--offer-id ${offerId}`,
);

const walletPath = `published.wallet.${USER1ADDR}.current`;
const walletOffer = await getQuoteBody(walletPath);
// | fromjson | .liveOffers[0][1].id '
t.is(walletOffer.liveOffers[0][1].id, offerId);
});

test.serial('open a marginal vault', async t => {
const currentVaults = await agops.vaults('list', '--from', USER1ADDR);

openVault(USER1ADDR, 20, 10);

const activeVaultsAfter = await agops.vaults('list', '--from', USER1ADDR);
t.log(currentVaults, activeVaultsAfter);
t.true(
activeVaultsAfter.length > currentVaults.length,
'vaults count increased',
);
});

// This test needs to wait longer than ava will allow, so it will only be
// invoked manually
test.serial.skip('trigger auction', async t => {
const startVaults = await agops.vaults('list', '--from', USER1ADDR);
await pushPrices(5.2, 'ATOM');

// agd query -o json vstorage data published.priceFeed.stOSMO-USD_price_feed |&
// jq '.value | fromjson | .values[0] | fromjson | .body[1:] | fromjson | .amountOut.value'
const atomOut = await getPriceQuote('ATOM');
t.is(atomOut, '+5200000');

const book0Data = await getQuoteBody(`published.auction.book0`);

const finishVaults = await agops.vaults('list', '--from', USER1ADDR);
t.log(startVaults, finishVaults);
t.true(finishVaults.length < startVaults.length, 'vaults count fell');

console.log(`auction raised`, book0Data.proceedsRaised);

// TODO check USER1 purse for proceeds
// TODO check auction records for trade
});
Empty file.
100 changes: 100 additions & 0 deletions a3p-integration/proposals/a:upgrade-next/vatDetails.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import dbOpenAmbient from 'better-sqlite3';

const HOME = process.env.HOME;

/** @type {<T>(val: T | undefined) => T} */
export const NonNullish = val => {
if (!val) throw Error('required');
return val;
};

/**
* @file look up vat incarnation from kernel DB
* @see {getIncarnation}
*/

const swingstorePath = `${HOME}/.agoric/data/agoric/swingstore.sqlite`;

/**
* SQL short-hand
*
* @param {import('better-sqlite3').Database} db
*/
export const dbTool = db => {
const prepare = (strings, ...params) => {
const dml = strings.join('?');
return { stmt: db.prepare(dml), params };
};
const sql = (strings, ...args) => {
const { stmt, params } = prepare(strings, ...args);
return stmt.all(...params);
};
sql.get = (strings, ...args) => {
const { stmt, params } = prepare(strings, ...args);
return stmt.get(...params);
};
return sql;
};

/**
* @param {import('better-sqlite3').Database} db
*/
const makeSwingstore = db => {
const sql = dbTool(db);

/** @param {string} key */
const kvGet = key => sql.get`select * from kvStore where key = ${key}`.value;
/** @param {string} key */
const kvGetJSON = key => JSON.parse(kvGet(key));

/** @param {string} vatID */
const lookupVat = vatID => {
return Object.freeze({
source: () => kvGetJSON(`${vatID}.source`),
options: () => kvGetJSON(`${vatID}.options`),
currentSpan: () =>
sql.get`select * from transcriptSpans where isCurrent = 1 and vatID = ${vatID}`,
});
};

return Object.freeze({
/** @param {string} vatName */
findVat: vatName => {
/** @type {string[]} */
const dynamicIDs = kvGetJSON('vat.dynamicIDs');
const targetVat = dynamicIDs.find(vatID =>
lookupVat(vatID).options().name.includes(vatName),
);
if (!targetVat) throw Error(`vat not found: ${vatName}`);
return targetVat;
},
/** @param {string} vatName */
findVats: vatName => {
/** @type {string[]} */
const dynamicIDs = kvGetJSON('vat.dynamicIDs');
return dynamicIDs.filter(vatID =>
lookupVat(vatID).options().name.includes(vatName),
);
},
lookupVat,
});
};

/** @param {string} vatName */
export const getDetailsMatchingVats = async vatName => {
const kStore = makeSwingstore(
dbOpenAmbient(swingstorePath, { readonly: true }),
);

const vatIDs = kStore.findVats(vatName);
const infos = [];
for (const vatID of vatIDs) {
const vatInfo = kStore.lookupVat(vatID);
const source = vatInfo.source();
// @ts-expect-error cast
const { incarnation } = vatInfo.currentSpan();
infos.push({ vatName, vatID, incarnation, ...source });
}

return infos;
};
2 changes: 1 addition & 1 deletion packages/inter-protocol/src/proposals/econ-behaviors.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export const SECONDS_PER_WEEK = 7n * SECONDS_PER_DAY;
* >;
* vaultFactoryKit: GovernanceFacetKit<VFStart>;
* auctioneerKit: AuctioneerKit;
* newAuctioneerKit: AuctioneerKit;
* newAuctioneerKit: AuctioneerKit | undefined;
* minInitialDebt: NatValue;
* }>} EconomyBootstrapSpace
*/
Expand Down
12 changes: 10 additions & 2 deletions packages/inter-protocol/src/proposals/upgrade-vaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ export const upgradeVaults = async (powers, { options }) => {
economicCommitteeCreatorFacet: electorateCreatorFacet,
reserveKit,
},
produce: { auctioneerKit: auctioneerKitProducer },
produce: {
auctioneerKit: auctioneerKitProducer,
newAuctioneerKit: tempAuctioneerKit,
},
instance: {
produce: { auctioneer: auctioneerProducer },
},
Expand Down Expand Up @@ -119,6 +122,7 @@ export const upgradeVaults = async (powers, { options }) => {
/** @type {import('../../src/vaultFactory/vaultFactory').VaultFactoryContract['privateArgs']} */
const newPrivateArgs = harden({
...privateArgs,
// @ts-expect-error It has a value until reset after the upgrade
auctioneerInstance: auctioneerKit.instance,
initialPoserInvitation: poserInvitation,
initialShortfallInvitation: shortfallInvitation,
Expand All @@ -144,9 +148,13 @@ export const upgradeVaults = async (powers, { options }) => {
trace(`upgrading after delay`);
await upgradeVaultFactory();
auctioneerKitProducer.reset();
// @ts-expect-error It has a value until reset just below
auctioneerKitProducer.resolve(auctioneerKit);
auctioneerProducer.reset();
// @ts-expect-error It has a value until reset just below
auctioneerProducer.resolve(auctioneerKit.instance);
// We wanted it to be valid for only a short while.
tempAuctioneerKit.reset();
},
);

Expand Down Expand Up @@ -177,7 +185,7 @@ export const getManifestForUpgradeVaults = async (
zoe: t,
},
produce: { auctioneerKit: t },
instance: { produce: { auctioneer: t } },
instance: { produce: { auctioneer: t, newAuctioneerKit: t } },
},
},
options: { ...vaultUpgradeOptions },
Expand Down

0 comments on commit 7d3191e

Please sign in to comment.