diff --git a/packages/vats/src/vat-zoe.js b/packages/vats/src/vat-zoe.js index cb9973e628c..6ee24cc21c0 100644 --- a/packages/vats/src/vat-zoe.js +++ b/packages/vats/src/vat-zoe.js @@ -6,15 +6,20 @@ 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({ + // The return value is `{ zoeService, zoeConfigFacet, feeMintAccess }`. This + // call only needs zoeConfigFacet because the others have been returned. + // zoeConfigFacet was added after the first release of Zoe on-chain. + ({ zoeConfigFacet } = makeDurableZoeKit({ // For now Zoe will rewire vatAdminSvc on its own shutdownZoeVat, feeIssuerConfig, zcfSpec, zoeBaggage, - }); + })); } return Far('root', { @@ -44,5 +49,6 @@ export function buildRootObject(vatPowers, _vatParams, zoeBaggage) { feeMintAccess, }); }, + getZoeConfigFacet: () => zoeConfigFacet, }); } diff --git a/packages/zoe/src/zoeService/startInstance.js b/packages/zoe/src/zoeService/startInstance.js index d7333d9b724..5754f58d05b 100644 --- a/packages/zoe/src/zoeService/startInstance.js +++ b/packages/zoe/src/zoeService/startInstance.js @@ -50,6 +50,12 @@ export const makeStartInstance = ( seatHandleToZoeSeatAdmin, ); + const getFreshZcfBundleCap = async () => { + const settledBundleCap = await getZcfBundleCapP(); + settledBundleCap !== undefined || Fail`the ZCF bundle cap was broken`; + return settledBundleCap; + }; + const InstanceAdminStateShape = harden({ instanceStorage: M.remotable('ZoeInstanceStorageManager'), instanceAdmin: M.remotable('InstanceAdmin'), @@ -225,12 +231,10 @@ export const makeStartInstance = ( /** * * @param {import('@agoric/swingset-vat').VatAdminFacet} adminNode - * @param {*} zcfBundleCap * @param {*} contractBundleCap */ - (adminNode, zcfBundleCap, contractBundleCap) => ({ + (adminNode, contractBundleCap) => ({ adminNode, - zcfBundleCap, contractBundleCap, }), { @@ -247,12 +251,13 @@ export const makeStartInstance = ( privateArgs: newPrivateArgs, }; - return E(state.adminNode).upgrade(state.zcfBundleCap, { - vatParameters, - }); + return E.when(getFreshZcfBundleCap(), bCap => + E(state.adminNode).upgrade(bCap, { vatParameters }), + ); }, async upgradeContract(contractBundleId, newPrivateArgs = undefined) { const { state } = this; + const newContractBundleCap = await getBundleCapByIdNow( contractBundleId, ); @@ -260,9 +265,9 @@ export const makeStartInstance = ( contractBundleCap: newContractBundleCap, privateArgs: newPrivateArgs, }; - return E(state.adminNode).upgrade(state.zcfBundleCap, { - vatParameters, - }); + return E.when(getFreshZcfBundleCap(), bCap => + E(state.adminNode).upgrade(bCap, { vatParameters }), + ); }, }, ); @@ -347,9 +352,6 @@ export const makeStartInstance = ( instanceAdmin.initDelayedState(handleOfferObj, publicFacet); - const settledBundleCap = await getZcfBundleCapP(); - settledBundleCap !== undefined || Fail`the bundle cap was broken`; - // creatorInvitation can be undefined, but if it is defined, // let's make sure it is an invitation. return E.when( @@ -365,11 +367,7 @@ export const makeStartInstance = ( isLiveResult || Fail`The contract did not correctly return a creatorInvitation`; - const adminFacet = makeAdminFacet( - adminNode, - harden(settledBundleCap), - contractBundleCap, - ); + const adminFacet = makeAdminFacet(adminNode, contractBundleCap); // Actually returned to the user. return harden({ diff --git a/packages/zoe/src/zoeService/zoe.js b/packages/zoe/src/zoeService/zoe.js index 3be3b3df349..d28dc9192de 100644 --- a/packages/zoe/src/zoeService/zoe.js +++ b/packages/zoe/src/zoeService/zoe.js @@ -18,6 +18,7 @@ import '../internal-types.js'; import { E } from '@endo/eventual-send'; import { Far } from '@endo/marshal'; import { makeScalarBigMapStore, prepareExo } from '@agoric/vat-data'; +import { M } from '@agoric/store'; import { makeZoeStorageManager } from './zoeStorageManager.js'; import { makeStartInstance } from './startInstance.js'; @@ -32,7 +33,7 @@ import { ZoeServiceI } from '../typeGuards.js'; const { Fail } = assert; /** - * Create an durable instance of Zoe. + * Create a durable instance of Zoe. * * @param {object} options * @param {Baggage} options.zoeBaggage - the baggage for Zoe durability. Must be provided by caller @@ -52,6 +53,7 @@ const makeDurableZoeKit = ({ feeIssuerConfig = defaultFeeIssuerConfig, zcfSpec = { name: 'zcf' }, }) => { + /** @type {BundleCap} */ let zcfBundleCap; const saveBundleCap = () => { @@ -168,6 +170,25 @@ const makeDurableZoeKit = ({ }); }; + const ZoeConfigI = M.interface('ZoeConfigFacet', { + updateZcfBundleId: M.call(M.string()).returns(), + }); + + const zoeConfigFacet = prepareExo(zoeBaggage, 'ZoeConfigFacet', ZoeConfigI, { + updateZcfBundleId(bundleId) { + E.when( + getZcfBundleCap({ id: bundleId }, vatAdminSvc), + bundleCap => { + zcfBundleCap = bundleCap; + }, + e => { + console.error(`'🚨 unable to update ZCF Bundle: `, e); + throw e; + }, + ); + }, + }); + /** @type {ZoeService} */ const zoeService = prepareExo(zoeBaggage, 'ZoeService', ZoeServiceI, { install(bundleId, bundleLabel) { @@ -223,6 +244,7 @@ const makeDurableZoeKit = ({ return harden({ zoeService, + zoeConfigFacet, /** @type {FeeMintAccess} */ // @ts-expect-error cast feeMintAccess: feeMintKit.feeMintAccess, diff --git a/packages/zoe/src/zoeService/zoeStorageManager.js b/packages/zoe/src/zoeService/zoeStorageManager.js index ba4b16e4dcf..9f2d8d36d11 100644 --- a/packages/zoe/src/zoeService/zoeStorageManager.js +++ b/packages/zoe/src/zoeService/zoeStorageManager.js @@ -1,5 +1,10 @@ import { E } from '@endo/far'; -import { AssetKind, makeDurableIssuerKit, AmountMath } from '@agoric/ertp'; +import { + AssetKind, + makeDurableIssuerKit, + AmountMath, + prepareIssuerKit, +} from '@agoric/ertp'; import { makeScalarBigMapStore, provideDurableWeakMapStore, @@ -117,7 +122,7 @@ export const makeZoeStorageManager = ( 'zoeMintBaggageSet', ); for (const issuerBaggage of zoeMintBaggageSet.values()) { - zoeMintBaggageSet(issuerBaggage); + prepareIssuerKit(issuerBaggage); } const makeZoeMint = prepareExoClass(