Skip to content

Commit

Permalink
test(bootstrap): restart all contracts
Browse files Browse the repository at this point in the history
  • Loading branch information
turadg committed May 11, 2023
1 parent 30f5405 commit b9f677c
Show file tree
Hide file tree
Showing 9 changed files with 448 additions and 15 deletions.
1 change: 1 addition & 0 deletions packages/inter-protocol/src/proposals/core-proposal.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ const SHARED_MAIN_MANIFEST = harden({
consume: {
board: 'board',
chainStorage: true,
diagnostics: true,
feeMintAccess: 'zoe',
chainTimerService: 'timer',
zoe: 'zoe',
Expand Down
25 changes: 16 additions & 9 deletions packages/inter-protocol/src/proposals/econ-behaviors.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export const setupReserve = async ({
feeMintAccess: feeMintAccessP,
chainStorage,
chainTimerService,
diagnostics,
zoe,
economicCommitteeCreatorFacet: committeeCreator,
},
Expand Down Expand Up @@ -120,19 +121,20 @@ export const setupReserve = async ({
},
}),
);
const privateArgs = {
governed: {
feeMintAccess,
initialPoserInvitation: poserInvitation,
marshaller,
storageNode,
},
};
/** @type {GovernorStartedInstallationKit<typeof reserveInstallation>} */
const g = await E(zoe).startInstance(
governorInstallation,
{},
reserveGovernorTerms,
{
governed: {
feeMintAccess,
initialPoserInvitation: poserInvitation,
marshaller,
storageNode,
},
},
privateArgs,
'reserve.governor',
);

Expand All @@ -155,6 +157,9 @@ export const setupReserve = async ({
governorAdminFacet: g.adminFacet,
}),
);
const { instancePrivateArgs } = await diagnostics;
instancePrivateArgs.set(instance, privateArgs.governed);
instancePrivateArgs.set(g.instance, privateArgs);

reserveInstanceProducer.resolve(instance);
reserveGovernor.resolve(g.instance);
Expand Down Expand Up @@ -454,7 +459,9 @@ export const startRewardDistributor = async ({
),
});

feeDistributorKit.resolve(instanceKit);
feeDistributorKit.resolve(
harden({ ...instanceKit, label: 'feeDistributor' }),
);
feeDistributorP.resolve(instanceKit.instance);

// Initialize the periodic collectors list if we don't have one.
Expand Down
20 changes: 14 additions & 6 deletions packages/inter-protocol/src/proposals/startEconCommittee.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const sanitizePathSegment = name => {
*/
export const startEconomicCommittee = async (
{
consume: { board, chainStorage, zoe },
consume: { board, chainStorage, diagnostics, zoe },
produce: { economicCommitteeKit, economicCommitteeCreatorFacet },
installation: {
consume: { committee },
Expand Down Expand Up @@ -59,19 +59,26 @@ export const startEconomicCommittee = async (
// NB: committee must only publish what it intended to be public
const marshaller = await E(board).getPublishingMarshaller();

const privateArgs = {
storageNode,
marshaller,
};
const startResult = await E(zoe).startInstance(
committee,
{},
{ committeeName, committeeSize, ...rest },
{
storageNode,
marshaller,
},
privateArgs,
'economicCommittee',
);
const { creatorFacet, instance } = startResult;

economicCommitteeKit.resolve(startResult);
economicCommitteeKit.resolve(
// XXX should startInstance return its label?
harden({ ...startResult, label: 'economicCommittee' }),
);
const { instancePrivateArgs } = await diagnostics;
instancePrivateArgs.set(startResult.instance, privateArgs);

economicCommitteeCreatorFacet.resolve(creatorFacet);
economicCommittee.resolve(instance);
};
Expand All @@ -82,6 +89,7 @@ export const ECON_COMMITTEE_MANIFEST = harden({
consume: {
board: true,
chainStorage: true,
diagnostics: true,
zoe: true,
},
produce: {
Expand Down
1 change: 1 addition & 0 deletions packages/inter-protocol/src/proposals/startPSM.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ export const startPSM = async (
/** @type {MapStore<Brand,psmKit>} */
const psmKitMap = await psmKit;

// TODO init into governedContractKits too to simplify testing
psmKitMap.init(anchorBrand, newpsmKit);
const instanceAdmin = E(agoricNamesAdmin).lookupAdmin('instance');

Expand Down
1 change: 1 addition & 0 deletions packages/vats/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"build:boot-viz-gov": "node src/authorityViz.js --gov>docs/boot-gov.dot && dot -Tsvg docs/boot-gov.dot >docs/boot-gov.dot.svg",
"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",
"prepack": "tsc --build jsconfig.build.json",
"postpack": "git clean -f '*.d.ts*'",
"test": "ava",
Expand Down
23 changes: 23 additions & 0 deletions packages/vats/scripts/restart-vats.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { makeHelpers } from '@agoric/deploy-script-support';

/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').ProposalBuilder} */
export const defaultProposalBuilder = async () => {
// An includelist isn't necessary because the collections are known to be complete (tested in test-vaults-upgrade.js)
const skip = [
// can be replaced instead of upgraded
'auctioneer',
'feeDistributor',
// skip so vaultManager can have prices upon restart; these have been tested as restartable
'scaledPriceAuthority-ATOM',
];

return harden({
sourceSpec: '../src/proposals/restart-vats-proposal.js',
getManifestCall: ['getManifestForRestart', harden({ skip })],
});
};

export default async (homeP, endowments) => {
const { writeCoreProposal } = await makeHelpers(homeP, endowments);
await writeCoreProposal('restart-vats', defaultProposalBuilder);
};
133 changes: 133 additions & 0 deletions packages/vats/src/proposals/restart-vats-proposal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/* eslint-disable no-await-in-loop */
// @ts-check

import { Fail } from '@agoric/assert';
import { deeplyFulfilledObject, makeTracer } from '@agoric/internal';
import { M, mustMatch } from '@agoric/store';
import { E, getInterfaceOf } from '@endo/far';

const trace = makeTracer('RV');

const HR = '----------------';

/**
* TODO cover each of these collections
* - [x] contractKits
* - [ ] psmKit
* - [x] governedContractKits
* - [ ] vatStore
*/

/**
* @param {BootstrapPowers & import('@agoric/inter-protocol/src/proposals/econ-behaviors.js').EconomyBootstrapSpace} space
* @param {object} config
* @param {{ skip: Array<string>}} config.options
*/
export const restartVats = async ({ consume }, { options }) => {
console.log(HR);
console.log(HR);
trace('restartVats start', options);
mustMatch(options, harden({ skip: M.arrayOf(M.string()) }));

trace('awaiting VaultFactorKit as a proxy for "bootstrap done"');
await consume.vaultFactoryKit;

trace('testing restarts');
const { contractKits, governedContractKits } = await deeplyFulfilledObject(
harden({
contractKits: consume.contractKits,
governedContractKits: consume.governedContractKits,
}),
);

const { instancePrivateArgs } = await consume.diagnostics;

const failures = [];
/**
*
* @param {string} debugName
* @param {Instance} instance
* @param {ERef<AdminFacet>} adminFacet
*/
const tryRestart = async (debugName, instance, adminFacet) => {
// TODO document that privateArgs cannot contain promises
// TODO try making all the contract starts take resolved values
const privateArgs = await deeplyFulfilledObject(
// @ts-expect-error cast
harden(instancePrivateArgs.get(instance) || {}),
);

console.log(HR);
console.log(HR);
console.log(HR);
console.log(HR);
trace('tryRestart', debugName, privateArgs);

if (options.skip.includes(debugName)) {
trace('SKIPPED', debugName);
return;
}
try {
await E(adminFacet).restartContract(privateArgs);
trace('RESTARTED', debugName);
} catch (err) {
trace('🚨 RESTART FAILED', debugName, err);
failures.push(debugName);
}
};

// iterate over the two contractKits and use the adminFacet to restartContract
for (const kit of contractKits.values()) {
const debugName =
kit.label || getInterfaceOf(kit.publicFacet) || 'UNLABELED';
if (debugName !== kit.label) {
console.warn('MISSING LABEL:', kit);
}
await tryRestart(debugName, kit.instance, kit.adminFacet);
}

for (const kit of governedContractKits.values()) {
const debugName =
kit.label || getInterfaceOf(kit.publicFacet) || 'UNLABELED';
if (debugName !== kit.label) {
console.warn('MISSING LABEL:', kit);
}

trace('restarting governed', debugName);
await tryRestart(debugName, kit.instance, kit.adminFacet);

trace('restarting governor of', debugName);
await tryRestart(
`${debugName} [Governor]`,
kit.governor,
kit.governorAdminFacet,
);
}

trace('restartVats done with ', failures.length, 'failures');
console.log(HR);
if (failures.length) {
Fail`restart failed for ${failures.join(',')}`;
}
console.log(HR);
};
harden(restartVats);

export const getManifestForRestart = (_powers, options) => ({
manifest: {
[restartVats.name]: {
consume: {
contractKits: true,
diagnostics: true,
governedContractKits: true,
loadCriticalVat: true,
zoe: 'zoe',
provisioning: 'provisioning',
vaultFactoryKit: true,
},
produce: {},
},
},
options,
});
harden(getManifestForRestart);
Loading

0 comments on commit b9f677c

Please sign in to comment.