Skip to content

Commit

Permalink
test: a test framework for verifying upgrade of Zoe and ZCF
Browse files Browse the repository at this point in the history
It starts from the currently installed version of Zoe and ZCF. First
it verifies that reallocation via staging and via the helper work and
that the version internal to ZCF is not present. It then upgrades Zoe
and ZCF as necessary to introduce the new behavior. Finally, it
re-runs the initial verification to show that the ZCF internal version
works.

This currently fails on the first step since it runs in a state in
which the new Zoe/ZCF code has already replaced the old.
  • Loading branch information
Chris-Hibbert committed Jun 21, 2023
1 parent b8f88d7 commit 63fc6fa
Show file tree
Hide file tree
Showing 11 changed files with 597 additions and 156 deletions.
1 change: 1 addition & 0 deletions packages/vats/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"build:boot-viz-sim": "node src/authorityViz.js --sim-chain >docs/boot-sim.dot && dot -Tsvg docs/boot-sim.dot >docs/boot-sim.dot.svg",
"build:boot-viz-sim-gov": "node src/authorityViz.js --sim-chain --gov >docs/boot-sim-gov.dot && dot -Tsvg docs/boot-sim-gov.dot >docs/boot-sim-gov.dot.svg",
"build:restart-vats-proposal": "agoric run scripts/restart-vats.js",
"build:zcf-proposal": "agoric run scripts/replace-zoe.js",
"prepack": "tsc --build jsconfig.build.json",
"postpack": "git clean -f '*.d.ts*'",
"test": "ava",
Expand Down
19 changes: 19 additions & 0 deletions packages/vats/scripts/replace-zoe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { makeHelpers } from '@agoric/deploy-script-support';

/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').ProposalBuilder} */
export const defaultProposalBuilder = async ({ publishRef, install }) =>
harden({
sourceSpec: '../src/proposals/zcf-proposal.js',
getManifestCall: [
'getManifestForZoe',
{
zoeRef: publishRef(install('../src/vat-zoe.js')),
zcfRef: publishRef(install('../../zoe/src/contractFacet/vatRoot.js')),
},
],
});

export default async (homeP, endowments) => {
const { writeCoreProposal } = await makeHelpers(homeP, endowments);
await writeCoreProposal('replace-zcf', defaultProposalBuilder);
};
44 changes: 44 additions & 0 deletions packages/vats/src/proposals/zcf-proposal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { E } from '@endo/far';

/**
* @param { BootstrapPowers & {
* consume: {
* vatAdminSvc: VatAdminSve,
* vatStore: MapStore<string, CreateVatResults>,
* }
* }} powers
*
* @param {object} options
* @param {{zoeRef: VatSourceRef, zcfRef: VatSourceRef}} options.options
*/
export const upgradeZcf = async (
{ consume: { vatAdminSvc, vatStore } },
options,
) => {
const { zoeRef, zcfRef } = options.options;

const zoeBundleCap = await E(vatAdminSvc).getBundleCap(zoeRef.bundleID);

const { adminNode, root: zoeRoot } = await E(vatStore).get('zoe');

await E(adminNode).upgrade(zoeBundleCap, {});

const zoeConfigFacet = await E(zoeRoot).getZoeConfigFacet();
await E(zoeConfigFacet).updateZcfBundleId(zcfRef.bundleID);
};

export const getManifestForZoe = (_powers, { zoeRef, zcfRef }) => ({
manifest: {
[upgradeZcf.name]: {
consume: {
vatAdminSvc: 'vatAdminSvc',
vatStore: 'vatStore',
},
produce: {},
},
},
options: {
zoeRef,
zcfRef,
},
});
7 changes: 5 additions & 2 deletions packages/vats/src/vat-zoe.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ const BUILD_PARAMS_KEY = 'buildZoeParams';
export function buildRootObject(vatPowers, _vatParams, zoeBaggage) {
const shutdownZoeVat = vatPowers.exitVatWithFailure;

let zoeConfigFacet;

if (zoeBaggage.has(BUILD_PARAMS_KEY)) {
const { feeIssuerConfig, zcfSpec } = zoeBaggage.get(BUILD_PARAMS_KEY);
makeDurableZoeKit({
({ zoeConfigFacet } = makeDurableZoeKit({
// For now Zoe will rewire vatAdminSvc on its own
shutdownZoeVat,
feeIssuerConfig,
zcfSpec,
zoeBaggage,
});
}));
}

return Far('root', {
Expand Down Expand Up @@ -44,5 +46,6 @@ export function buildRootObject(vatPowers, _vatParams, zoeBaggage) {
feeMintAccess,
});
},
getZoeConfigFacet: () => zoeConfigFacet,
});
}
71 changes: 71 additions & 0 deletions packages/vats/test/bootstrapTests/drivers.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Offers } from '@agoric/inter-protocol/src/clientSupport.js';
import { SECONDS_PER_MINUTE } from '@agoric/inter-protocol/src/proposals/econ-behaviors.js';
import { unmarshalFromVstorage } from '@agoric/internal/src/lib-chainStorage.js';
import { slotToRemotable } from '@agoric/internal/src/storage-test-utils.js';

import { boardSlottingMarshaller } from '../../tools/board-utils.js';

/**
Expand Down Expand Up @@ -339,3 +340,73 @@ export const makeGovernanceDriver = async (
},
};
};

/**
* @param {import('./supports.js').SwingsetTestKit} testKit
*/
export const makeZoeDriver = async testKit => {
const { EV } = testKit.runUtils;
const zoe = await EV.vat('bootstrap').consumeItem('zoe');
let creatorFacet;
let brand;
const sub = (a, v) => {
return { brand: a.brand, value: a.value - v };
};

return {
async instantiateProbeContract(probeContractBundle) {
const installation = await EV(zoe).install(probeContractBundle);
const startResults = await EV(zoe).startInstance(installation);
({ creatorFacet } = startResults);

const issuers = await EV(zoe).getIssuers(startResults.instance);
const brands = await EV(zoe).getBrands(startResults.instance);
brand = brands.Ducats;
return { creatorFacet, issuer: issuers.Ducats, brand };
},

verifyRealloc() {
const alloc = EV(creatorFacet).getAllocation();
return alloc;
},
async probeReallocation(value, payment) {
const stagingInv = await EV(creatorFacet).makeProbeStagingInvitation();

const stagingSeat = await EV(zoe).offer(
stagingInv,
{ give: { Ducats: value } },
{ Ducats: payment },
);
const helperPayments = await EV(stagingSeat).getPayouts();

const helperInv = await EV(creatorFacet).makeProbeHelperInvitation();
const helperSeat = await EV(zoe).offer(
helperInv,
{ give: { Ducats: sub(value, 1n) } },
{ Ducats: helperPayments.Ducats },
);
const internalPayments = await EV(helperSeat).getPayouts();

const internalInv = await EV(creatorFacet).makeProbeInternalInvitation();
const internalSeat = await EV(zoe).offer(
internalInv,
{ give: { Ducats: sub(value, 2n) } },
{ Ducats: internalPayments.Ducats },
);
const leftoverPayments = await EV(internalSeat).getPayouts();

return {
stagingResult: await EV(stagingSeat).getOfferResult(),
helperResult: await EV(helperSeat).getOfferResult(),
internalResult: await EV(internalSeat).getOfferResult(),
leftoverPayments,
};
},
async faucet() {
const faucetInv = await EV(creatorFacet).makeFaucetInvitation();
const seat = await EV(zoe).offer(faucetInv);

return EV(seat).getPayout('Ducats');
},
};
};
Loading

0 comments on commit 63fc6fa

Please sign in to comment.