From 6ba171fb2aec659683c911b5aa4f97dfa8e2f20a Mon Sep 17 00:00:00 2001 From: Kate Sills Date: Tue, 15 Sep 2020 18:30:01 -0700 Subject: [PATCH] fix: stop accepting offers if zcf.shutdown is called (#1772) --- packages/zoe/src/internal-types.js | 2 ++ packages/zoe/src/zoeService/zoe.js | 23 +++++++++++++-------- packages/zoe/test/unitTests/zcf/test-zcf.js | 4 +--- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/packages/zoe/src/internal-types.js b/packages/zoe/src/internal-types.js index f3102dba3ce..a837bec14e4 100644 --- a/packages/zoe/src/internal-types.js +++ b/packages/zoe/src/internal-types.js @@ -96,6 +96,8 @@ * @property {() => IssuerKeywordRecord} getIssuers * @property {() => BrandKeywordRecord} getBrands * @property {() => Object} getTerms + * @property {() => boolean} hasShutdown + * @property {() => void} shutdown */ /** diff --git a/packages/zoe/src/zoeService/zoe.js b/packages/zoe/src/zoeService/zoe.js index 2de29d59d43..19d4ae8f851 100644 --- a/packages/zoe/src/zoeService/zoe.js +++ b/packages/zoe/src/zoeService/zoe.js @@ -212,6 +212,7 @@ function makeZoe(vatAdminSvc, zcfBundleName = undefined) { const makeInstanceAdmin = () => { /** @type {Set} */ const zoeSeatAdmins = new Set(); + let hasShutdown = false; /** @type {InstanceAdmin} */ return { @@ -234,8 +235,11 @@ function makeZoe(vatAdminSvc, zcfBundleName = undefined) { getIssuers: () => instanceRecord.terms.issuers, getBrands: () => instanceRecord.terms.brands, getInstance: () => instance, - exitAllSeats: () => - zoeSeatAdmins.forEach(zoeSeatAdmin => zoeSeatAdmin.exit()), + hasShutdown: () => hasShutdown, + shutdown: () => { + hasShutdown = true; + zoeSeatAdmins.forEach(zoeSeatAdmin => zoeSeatAdmin.exit()); + }, }; }; @@ -246,8 +250,8 @@ function makeZoe(vatAdminSvc, zcfBundleName = undefined) { E(adminNode) .done() .then( - () => instanceAdmin.exitAllSeats(), - () => instanceAdmin.exitAllSeats(), + () => instanceAdmin.shutdown(), + () => instanceAdmin.shutdown(), ); // Unpack the invitationKit. @@ -303,7 +307,7 @@ function makeZoe(vatAdminSvc, zcfBundleName = undefined) { return { userSeat, notifier, zoeSeatAdmin }; }, shutdown: () => { - instanceAdmin.exitAllSeats(); + instanceAdmin.shutdown(); E(adminNode).terminate(); }, makeZoeMint, @@ -368,6 +372,11 @@ function makeZoe(vatAdminSvc, zcfBundleName = undefined) { invitationAmount.value.length === 1, 'Only one invitation can be redeemed at a time', ); + const { + value: [{ instance, handle: invitationHandle }], + } = invitationAmount; + const instanceAdmin = instanceToInstanceAdmin.get(instance); + assert(!instanceAdmin.hasShutdown(), `No further offers are accepted`); const proposal = cleanProposal(getAmountMath, uncleanProposal); const { give, want } = proposal; @@ -390,9 +399,6 @@ function makeZoe(vatAdminSvc, zcfBundleName = undefined) { return getAmountMath(proposal.want[keyword].brand).getEmpty(); } }); - const { - value: [{ instance, handle: invitationHandle }], - } = invitationAmount; return Promise.all(paymentDepositedPs).then(amountsArray => { const initialAllocation = arrayToObj(amountsArray, proposalKeywords); @@ -403,7 +409,6 @@ function makeZoe(vatAdminSvc, zcfBundleName = undefined) { const exitObjPromiseKit = makePromiseKit(); // Don't trigger Node.js's UnhandledPromiseRejectionWarning exitObjPromiseKit.promise.catch(_ => {}); - const instanceAdmin = instanceToInstanceAdmin.get(instance); const seatHandle = makeHandle('SeatHandle'); const { userSeat, notifier, zoeSeatAdmin } = makeZoeSeatAdminKit( diff --git a/packages/zoe/test/unitTests/zcf/test-zcf.js b/packages/zoe/test/unitTests/zcf/test-zcf.js index e4e2d2b9f38..2df466fc814 100644 --- a/packages/zoe/test/unitTests/zcf/test-zcf.js +++ b/packages/zoe/test/unitTests/zcf/test-zcf.js @@ -1218,9 +1218,7 @@ test(`zcf.shutdown - zcfSeat exits`, async t => { t.truthy(await E(userSeat).hasExited()); }); -// TODO: Any new offers should throw after zcf.shutdown() is called -// https://github.com/Agoric/agoric-sdk/issues/1756 -test.failing(`zcf.shutdown - no further offers accepted`, async t => { +test(`zcf.shutdown - no further offers accepted`, async t => { const { zoe, zcf } = await setupZCFTest({}); const invitation = await zcf.makeInvitation(() => {}, 'seat'); zcf.shutdown();