From 9ac09b1291a62f519d0c8b43849698b2ec19dd3b Mon Sep 17 00:00:00 2001 From: Chris Hibbert Date: Fri, 16 Jun 2023 16:20:28 -0700 Subject: [PATCH 1/5] fix: make zoeStorageModule correctly restart with zcfMints present. --- packages/zoe/src/zoeService/zoeStorageManager.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) 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( From 7e2c8d77b38ce069e17ba98fd6757987998cbdf6 Mon Sep 17 00:00:00 2001 From: Chris Hibbert Date: Tue, 20 Jun 2023 16:58:34 -0700 Subject: [PATCH 2/5] chore: use a fresh zcfBundleCap from inside startInstance makeStartInstance was being passed an accessor to retrieve zcfBundleCap from zoe's state. The accessor was being called once and the result re-used rather than calling the accessor every time in case there was a new value. --- packages/zoe/src/zoeService/startInstance.js | 32 +++++++++----------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/packages/zoe/src/zoeService/startInstance.js b/packages/zoe/src/zoeService/startInstance.js index a176f972c30..fb1eb213413 100644 --- a/packages/zoe/src/zoeService/startInstance.js +++ b/packages/zoe/src/zoeService/startInstance.js @@ -43,6 +43,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'), @@ -178,12 +184,10 @@ export const makeStartInstance = ( /** * * @param {import('@agoric/swingset-vat').VatAdminFacet} adminNode - * @param {*} zcfBundleCap * @param {*} contractBundleCap */ - (adminNode, zcfBundleCap, contractBundleCap) => ({ + (adminNode, contractBundleCap) => ({ adminNode, - zcfBundleCap, contractBundleCap, }), { @@ -200,12 +204,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, ); @@ -213,9 +218,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 }), + ); }, }, ); @@ -306,9 +311,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( @@ -324,11 +326,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({ From c4f6e85b12837b94b479d5bdf351f44bef9e1967 Mon Sep 17 00:00:00 2001 From: Chris Hibbert Date: Wed, 21 Jun 2023 11:27:12 -0700 Subject: [PATCH 3/5] feat(zoe!):add a config facet to Zoe so the zcfBundle can be updated --- packages/vats/src/vat-zoe.js | 7 +++++-- packages/zoe/src/zoeService/zoe.js | 23 ++++++++++++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/packages/vats/src/vat-zoe.js b/packages/vats/src/vat-zoe.js index cb9973e628c..7591b2837b5 100644 --- a/packages/vats/src/vat-zoe.js +++ b/packages/vats/src/vat-zoe.js @@ -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', { @@ -44,5 +46,6 @@ export function buildRootObject(vatPowers, _vatParams, zoeBaggage) { feeMintAccess, }); }, + getZoeConfigFacet: () => zoeConfigFacet, }); } diff --git a/packages/zoe/src/zoeService/zoe.js b/packages/zoe/src/zoeService/zoe.js index 3be3b3df349..8364cc6b5ae 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,24 @@ 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.warn(`unable to update ZCF Bundle: `, e); + }, + ); + }, + }); + /** @type {ZoeService} */ const zoeService = prepareExo(zoeBaggage, 'ZoeService', ZoeServiceI, { install(bundleId, bundleLabel) { @@ -223,6 +243,7 @@ const makeDurableZoeKit = ({ return harden({ zoeService, + zoeConfigFacet, /** @type {FeeMintAccess} */ // @ts-expect-error cast feeMintAccess: feeMintKit.feeMintAccess, From 948709500467018d25c79e60fdbfd13e94325682 Mon Sep 17 00:00:00 2001 From: Chris Hibbert Date: Fri, 23 Jun 2023 16:58:39 -0700 Subject: [PATCH 4/5] chore: add a comment explaining why only zoeConfigFacet is used --- packages/vats/src/vat-zoe.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/vats/src/vat-zoe.js b/packages/vats/src/vat-zoe.js index 7591b2837b5..6ee24cc21c0 100644 --- a/packages/vats/src/vat-zoe.js +++ b/packages/vats/src/vat-zoe.js @@ -10,6 +10,9 @@ export function buildRootObject(vatPowers, _vatParams, zoeBaggage) { if (zoeBaggage.has(BUILD_PARAMS_KEY)) { const { feeIssuerConfig, zcfSpec } = zoeBaggage.get(BUILD_PARAMS_KEY); + // 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, From 3b65d039166d3ff4120c9f978486c1dd8f18a54e Mon Sep 17 00:00:00 2001 From: Chris Hibbert Date: Mon, 17 Jul 2023 16:21:57 -0700 Subject: [PATCH 5/5] chore: upgrade warning on inabilty to upgrade to error, and throw --- packages/zoe/src/zoeService/zoe.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/zoe/src/zoeService/zoe.js b/packages/zoe/src/zoeService/zoe.js index 8364cc6b5ae..d28dc9192de 100644 --- a/packages/zoe/src/zoeService/zoe.js +++ b/packages/zoe/src/zoeService/zoe.js @@ -182,7 +182,8 @@ const makeDurableZoeKit = ({ zcfBundleCap = bundleCap; }, e => { - console.warn(`unable to update ZCF Bundle: `, e); + console.error(`'🚨 unable to update ZCF Bundle: `, e); + throw e; }, ); },