Skip to content

Commit

Permalink
vstorage published types mapping (#10422)
Browse files Browse the repository at this point in the history
refs: #9109

## Description

The new `@agoric/client-utils` package provides a place to hang a type mapping of what's published in vstorage to the JS type one should have after unmarshalling.

This adds:
- a `PublishedType` utility type mapper to the package
- a `readPublished` helper to RpcUtils (and passed through WalletUtils)
- a `readPublished` help in the SwingsetToolkit for boot tests
- uses the above through agoric CLI and bootstrap tests

I don't think I got everywhere this could be used. Looking for feedback on,

- Should we have a `readPublished` abstraction or continue to use `published.` everywhere? I opted for the latter thinking it would be a proxy for whether the stores values were CapData
- Should WalletUtils pass through readPublished or provide a reference to RpcUtils ? 

### Security Considerations


### Scaling Considerations


### Documentation Considerations


### Testing Considerations


### Upgrade Considerations
  • Loading branch information
mergify[bot] authored Nov 11, 2024
2 parents e7af58f + 0dfecae commit a82d636
Show file tree
Hide file tree
Showing 19 changed files with 172 additions and 147 deletions.
1 change: 1 addition & 0 deletions packages/boot/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"dependencies": {
"@endo/errors": "^1.2.7",
"@agoric/builders": "^0.1.0",
"@agoric/client-utils": "^0.1.0",
"@agoric/cosmic-proto": "^0.4.0",
"@agoric/cosmic-swingset": "^0.41.3",
"@agoric/ertp": "^0.16.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ test.serial(

test.serial('Update reserve metrics', async t => {
// Need to update metrics before membership upgrade for tests related to vault params later
const { advanceTimeTo, setupVaults, priceFeedDrivers, readLatest } =
const { advanceTimeTo, setupVaults, priceFeedDrivers, readPublished } =
t.context;
const setup = {
vaults: [
Expand Down Expand Up @@ -225,7 +225,7 @@ test.serial('Update reserve metrics', async t => {

await setupVaults('ATOM', 0, setup);
await priceFeedDrivers.ATOM.setPrice(setup.price.trigger);
const liveSchedule = readLatest('published.auction.schedule');
const liveSchedule = readPublished('auction.schedule');
await advanceTimeTo(NonNullish(liveSchedule.nextDescendingStepTime));
t.pass();
});
Expand Down
33 changes: 16 additions & 17 deletions packages/boot/test/bootstrapTests/liquidation-1.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,14 @@ const checkFlow1 = async (
check,
priceFeedDrivers,
readLatest,
readPublished,
walletFactoryDriver,
setupVaults,
placeBids,
} = t.context;

const metricsPath = `published.vaultFactory.managers.manager${managerIndex}.metrics`;
const metricsSubpath =
`vaultFactory.managers.manager${managerIndex}.metrics` as const;

await setupVaults(collateralBrandKey, managerIndex, setup);

Expand All @@ -166,19 +168,17 @@ const checkFlow1 = async (
await priceFeedDrivers[collateralBrandKey].setPrice(9.99);

// check nothing liquidating yet
const liveSchedule: ScheduleNotification = readLatest(
'published.auction.schedule',
);
const liveSchedule = readPublished('auction.schedule');
t.is(liveSchedule.activeStartTime, null);
t.like(readLatest(metricsPath), {
t.like(readPublished(metricsSubpath), {
numActiveVaults: setup.vaults.length,
numLiquidatingVaults: 0,
});

// advance time to start an auction
console.log(collateralBrandKey, 'step 1 of 10');
await advanceTimeTo(NonNullish(liveSchedule.nextDescendingStepTime));
t.like(readLatest(metricsPath), {
t.like(readPublished(metricsSubpath), {
numActiveVaults: 0,
numLiquidatingVaults: setup.vaults.length,
liquidatingCollateral: {
Expand All @@ -190,7 +190,7 @@ const checkFlow1 = async (

console.log(collateralBrandKey, 'step 2 of 10');
await advanceTimeBy(3, 'minutes');
t.like(readLatest(`published.auction.book${managerIndex}`), {
t.like(readPublished(`auction.book${managerIndex}`), {
collateralAvailable: { value: scale6(setup.auction.start.collateral) },
startCollateral: { value: scale6(setup.auction.start.collateral) },
startProceedsGoal: { value: scale6(setup.auction.start.debt) },
Expand All @@ -203,7 +203,7 @@ const checkFlow1 = async (
await advanceTimeBy(3, 'minutes');
// XXX updates for bid1 and bid2 are appended in the same turn so readLatest gives bid2
// NB: console output shows 8897786n payout which matches spec 8.897ATOM
// t.like(readLatest('published.wallet.agoric1buyer'), {
// t.like(readPublished('wallet.agoric1buyer'), {
// status: {
// id: `${collateralBrandKey}-bid1`,
// payouts: {
Expand All @@ -213,7 +213,7 @@ const checkFlow1 = async (
// },
// });

t.like(readLatest('published.wallet.agoric1buyer'), {
t.like(readPublished('wallet.agoric1buyer'), {
status: {
id: `${collateralBrandKey}-bid2`,
payouts: likePayouts(outcome.bids[1].payouts),
Expand All @@ -225,7 +225,7 @@ const checkFlow1 = async (

console.log(collateralBrandKey, 'step 6 of 10');
await advanceTimeBy(3, 'minutes');
t.like(readLatest(`published.auction.book${managerIndex}`), {
t.like(readPublished(`auction.book${managerIndex}`), {
collateralAvailable: { value: 9659301n },
});

Expand All @@ -238,7 +238,7 @@ const checkFlow1 = async (
console.log(collateralBrandKey, 'step 9 of 10');
await advanceTimeBy(3, 'minutes');
// Not part of product spec
t.like(readLatest(metricsPath), {
t.like(readPublished(metricsSubpath), {
numActiveVaults: 0,
numLiquidationsCompleted: setup.vaults.length,
numLiquidatingVaults: 0,
Expand All @@ -254,18 +254,17 @@ const checkFlow1 = async (
console.log(collateralBrandKey, 'step 10 of 10');
// continuing after now would start a new auction
{
const { nextDescendingStepTime, nextStartTime } = readLatest(
'published.auction.schedule',
) as Record<string, import('@agoric/time').TimestampRecord>;
const { nextDescendingStepTime, nextStartTime } =
readPublished('auction.schedule');
t.is(nextDescendingStepTime.absValue, nextStartTime.absValue);
}

// bid3 still live because it's not fully satisfied
const { liveOffers } = readLatest('published.wallet.agoric1buyer.current');
const { liveOffers } = readPublished('wallet.agoric1buyer.current');
t.is(liveOffers[0][1].id, `${collateralBrandKey}-bid3`);
// exit to get payouts
await buyer.tryExitOffer(`${collateralBrandKey}-bid3`);
t.like(readLatest('published.wallet.agoric1buyer'), {
t.like(readPublished('wallet.agoric1buyer'), {
status: {
id: `${collateralBrandKey}-bid3`,
payouts: likePayouts(outcome.bids[2].payouts),
Expand All @@ -290,7 +289,7 @@ const checkFlow1 = async (
}

// check reserve balances
t.like(readLatest('published.reserve.metrics'), {
t.like(readPublished('reserve.metrics'), {
allocations: {
[collateralBrandKey]: {
value: scale6(outcome.reserve.allocations[collateralBrandKey]),
Expand Down
19 changes: 9 additions & 10 deletions packages/boot/test/bootstrapTests/liquidation-2b.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,13 @@ test.serial('scenario: Flow 2b', async t => {
check,
priceFeedDrivers,
readLatest,
readPublished,
setupVaults,
placeBids,
} = t.context;

const managerIndex = 0;
const metricPath = `published.vaultFactory.managers.manager${managerIndex}.metrics`;
const publishedMetrics = `vaultFactory.managers.manager${managerIndex}.metrics`;

await setupVaults(collateralBrandKey, managerIndex, setup);
await placeBids(collateralBrandKey, 'agoric1buyer', setup);
Expand All @@ -150,19 +151,17 @@ test.serial('scenario: Flow 2b', async t => {
await priceFeedDrivers.ATOM.setPrice(setup.price.trigger);

// check nothing liquidating yet
const liveSchedule: ScheduleNotification = readLatest(
'published.auction.schedule',
);
const liveSchedule = readPublished('auction.schedule');
t.is(liveSchedule.activeStartTime, null);
t.like(readLatest(metricPath), {
t.like(readPublished(publishedMetrics), {
numActiveVaults: setup.vaults.length,
numLiquidatingVaults: 0,
});

// advance time to start an auction
console.log('step 0 of 10');
await advanceTimeTo(NonNullish(liveSchedule.nextDescendingStepTime));
t.like(readLatest(metricPath), {
t.like(readPublished(publishedMetrics), {
numActiveVaults: 0,
numLiquidatingVaults: setup.vaults.length,
liquidatingCollateral: {
Expand All @@ -173,7 +172,7 @@ test.serial('scenario: Flow 2b', async t => {

console.log('step 1 of 10');
await advanceTimeBy(3, 'minutes');
t.like(readLatest(`published.auction.book${managerIndex}`), {
t.like(readPublished(`auction.book${managerIndex}`), {
collateralAvailable: { value: scale6(setup.auction.start.collateral) },
startCollateral: { value: scale6(setup.auction.start.collateral) },
startProceedsGoal: { value: scale6(setup.auction.start.debt) },
Expand All @@ -190,7 +189,7 @@ test.serial('scenario: Flow 2b', async t => {

console.log('step 5 of 10');
await advanceTimeBy(3, 'minutes');
t.like(readLatest(`published.auction.book${managerIndex}`), {
t.like(readPublished(`auction.book${managerIndex}`), {
collateralAvailable: { value: scale6(45) },
});

Expand Down Expand Up @@ -237,14 +236,14 @@ test.serial('scenario: Flow 2b', async t => {
}

// check reserve balances
t.like(readLatest('published.reserve.metrics'), {
t.like(readPublished('reserve.metrics'), {
allocations: {
ATOM: { value: scale6(outcome.reserve.allocations.ATOM) },
},
shortfallBalance: { value: scale6(outcome.reserve.shortfall) },
});

t.like(readLatest(metricPath), {
t.like(readPublished(publishedMetrics), {
// reconstituted
numActiveVaults: 2,
numLiquidationsCompleted: 1,
Expand Down
26 changes: 10 additions & 16 deletions packages/boot/test/bootstrapTests/liquidation-concurrent-1.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ test('concurrent flow 1', async t => {
check,
priceFeedDrivers,
readLatest,
readPublished,
walletFactoryDriver,
setupVaults,
placeBids,
Expand Down Expand Up @@ -305,7 +306,7 @@ test('concurrent flow 1', async t => {
setups[collateralBrandKeySt].price.trigger,
);

const liveSchedule = readLatest('published.auction.schedule');
const liveSchedule = readPublished('auction.schedule');

for (const { collateralBrandKey, managerIndex } of cases) {
// check nothing liquidating yet
Expand Down Expand Up @@ -339,7 +340,7 @@ test('concurrent flow 1', async t => {
await advanceTimeBy(3, 'minutes');

for (const { collateralBrandKey, managerIndex } of cases) {
t.like(readLatest(`published.auction.book${managerIndex}`), {
t.like(readPublished(`auction.book${managerIndex}`), {
collateralAvailable: {
value: scale6(setups[collateralBrandKey].auction.start.collateral),
},
Expand All @@ -360,7 +361,7 @@ test('concurrent flow 1', async t => {

// updates for bid1 and bid2 are appended in the same turn so readLatest gives bid2
// updates for ATOM and STARS are appended in the same turn so readLatest gives STARS
t.like(readLatest('published.wallet.agoric1buyer'), {
t.like(readPublished('wallet.agoric1buyer'), {
status: {
id: `${collateralBrandKeySt}-bid2`,
payouts: likePayouts(outcomes[collateralBrandKeySt].bids[1].payouts),
Expand All @@ -374,7 +375,7 @@ test('concurrent flow 1', async t => {
await advanceTimeBy(3, 'minutes');

for (const { collateralBrandKey, managerIndex } of cases) {
t.like(readLatest(`published.auction.book${managerIndex}`), {
t.like(readPublished(`auction.book${managerIndex}`), {
collateralAvailable: {
value: scale6(setups[collateralBrandKey].auction.end.collateral),
},
Expand All @@ -393,15 +394,8 @@ test('concurrent flow 1', async t => {
console.log('step 10 of 10');
// continuing after now would start a new auction
{
/**
* @type {Record<
* string,
* import('@agoric/time').TimestampRecord
* >}
*/
const { nextDescendingStepTime, nextStartTime } = readLatest(
'published.auction.schedule',
);
const { nextDescendingStepTime, nextStartTime } =
readPublished('auction.schedule');
t.is(nextDescendingStepTime.absValue, nextStartTime.absValue);
}

Expand All @@ -422,7 +416,7 @@ test('concurrent flow 1', async t => {
});

// check reserve balances
t.like(readLatest('published.reserve.metrics'), {
t.like(readPublished('reserve.metrics'), {
allocations: {
[collateralBrandKey]: {
value: scale6(
Expand Down Expand Up @@ -459,11 +453,11 @@ test('concurrent flow 1', async t => {
});

// bid3 still live because it's not fully satisfied
const { liveOffers } = readLatest('published.wallet.agoric1buyer.current');
const { liveOffers } = readPublished('wallet.agoric1buyer.current');
t.is(liveOffers[0][1].id, `${collateralBrandKeyA}-bid3`);
// exit to get payouts
await buyer.tryExitOffer(`${collateralBrandKeyA}-bid3`);
t.like(readLatest('published.wallet.agoric1buyer'), {
t.like(readPublished('wallet.agoric1buyer'), {
status: {
id: `${collateralBrandKeyA}-bid3`,
payouts: likePayouts(outcomes[collateralBrandKeyA].bids[2].payouts),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ test.serial(
check,
priceFeedDrivers,
readLatest,
readPublished,
setupVaults,
placeBids,
} = t.context;
Expand Down Expand Up @@ -266,7 +267,7 @@ test.serial(
setups[collateralBrandKeySt].price.trigger,
);

const liveSchedule = readLatest('published.auction.schedule');
const liveSchedule = readPublished('auction.schedule');

for (const { collateralBrandKey, managerIndex } of cases) {
// check nothing liquidating yet
Expand Down Expand Up @@ -298,7 +299,7 @@ test.serial(
await advanceTimeBy(3, 'minutes');

for (const { collateralBrandKey, managerIndex } of cases) {
t.like(readLatest(`published.auction.book${managerIndex}`), {
t.like(readPublished(`auction.book${managerIndex}`), {
collateralAvailable: {
value: scale6(setups[collateralBrandKey].auction.start.collateral),
},
Expand All @@ -324,7 +325,7 @@ test.serial(
await advanceTimeBy(3, 'minutes');

for (const { collateralBrandKey, managerIndex } of cases) {
t.like(readLatest(`published.auction.book${managerIndex}`), {
t.like(readPublished(`auction.book${managerIndex}`), {
collateralAvailable: {
value: scale6(setups[collateralBrandKey].auction.start.collateral),
},
Expand Down
Loading

0 comments on commit a82d636

Please sign in to comment.