From e1b781a8cf9ba46618711ce3cd34327a8169dff2 Mon Sep 17 00:00:00 2001 From: "Mark S. Miller" Date: Sun, 5 Mar 2023 15:21:43 -0800 Subject: [PATCH] fix: start on zonifying ertp --- packages/ERTP/package.json | 1 + packages/ERTP/src/issuerKit.js | 14 +++++++----- packages/ERTP/src/payment.js | 10 ++++----- packages/ERTP/src/paymentLedger.js | 30 +++++++++++--------------- packages/ERTP/src/purse.js | 22 +++++++++++++------ packages/ERTP/src/transientNotifier.js | 2 ++ 6 files changed, 43 insertions(+), 36 deletions(-) diff --git a/packages/ERTP/package.json b/packages/ERTP/package.json index 6df65905d988..19ee76c4578a 100644 --- a/packages/ERTP/package.json +++ b/packages/ERTP/package.json @@ -45,6 +45,7 @@ "@agoric/store": "^0.8.3", "@agoric/swingset-vat": "^0.30.2", "@agoric/vat-data": "^0.4.3", + "@agoric/zone": "^0.1.0", "@endo/eventual-send": "^0.16.8", "@endo/far": "^0.2.14", "@endo/marshal": "^0.8.1", diff --git a/packages/ERTP/src/issuerKit.js b/packages/ERTP/src/issuerKit.js index 187917d67e4e..ddfc3ee86025 100644 --- a/packages/ERTP/src/issuerKit.js +++ b/packages/ERTP/src/issuerKit.js @@ -3,6 +3,7 @@ import { assert } from '@agoric/assert'; import { assertPattern } from '@agoric/store'; import { makeScalarBigMapStore } from '@agoric/vat-data'; +import { makeDurableZone } from '@agoric/zone/durable.js'; import { AssetKind, assertAssetKind } from './amountMath.js'; import { coerceDisplayInfo } from './displayInfo.js'; @@ -10,6 +11,7 @@ import { preparePaymentLedger } from './paymentLedger.js'; import './types-ambient.js'; +/** @typedef {import('@agoric/zone').Zone} Zone */ /** @typedef {import('@agoric/vat-data').Baggage} Baggage */ /** @@ -24,7 +26,7 @@ import './types-ambient.js'; /** * @template {AssetKind} K * @param {IssuerRecord} issuerRecord - * @param {Baggage} issuerBaggage + * @param {Zone} issuerZone * @param {ShutdownWithFailure} [optShutdownWithFailure] If this issuer fails * in the middle of an atomic action (which btw should never happen), it * potentially leaves its ledger in a corrupted state. If this function was @@ -36,7 +38,7 @@ import './types-ambient.js'; */ const setupIssuerKit = ( { name, assetKind, displayInfo, elementShape }, - issuerBaggage, + issuerZone, optShutdownWithFailure = undefined, ) => { assert.typeof(name, 'string'); @@ -56,7 +58,7 @@ const setupIssuerKit = ( /** @type {PaymentLedger} */ // @ts-expect-error could be instantiated with different subtype of AssetKind const { issuer, mint, brand } = preparePaymentLedger( - issuerBaggage, + issuerZone, name, assetKind, cleanDisplayInfo, @@ -93,7 +95,8 @@ export const prepareIssuerKit = ( optShutdownWithFailure = undefined, ) => { const issuerRecord = issuerBaggage.get(INSTANCE_KEY); - return setupIssuerKit(issuerRecord, issuerBaggage, optShutdownWithFailure); + const issuerZone = makeDurableZone(issuerBaggage); + return setupIssuerKit(issuerRecord, issuerZone, optShutdownWithFailure); }; harden(prepareIssuerKit); @@ -149,7 +152,8 @@ export const makeDurableIssuerKit = ( ) => { const issuerData = harden({ name, assetKind, displayInfo, elementShape }); issuerBaggage.init(INSTANCE_KEY, issuerData); - return setupIssuerKit(issuerData, issuerBaggage, optShutdownWithFailure); + const issuerZone = makeDurableZone(issuerBaggage); + return setupIssuerKit(issuerData, issuerZone, optShutdownWithFailure); }; harden(makeDurableIssuerKit); diff --git a/packages/ERTP/src/payment.js b/packages/ERTP/src/payment.js index 34d19db81dfb..bcde7abe2bab 100644 --- a/packages/ERTP/src/payment.js +++ b/packages/ERTP/src/payment.js @@ -1,19 +1,17 @@ import { initEmpty } from '@agoric/store'; -import { prepareExoClass } from '@agoric/vat-data'; -/** @typedef {import('@agoric/vat-data').Baggage} Baggage */ +/** @typedef {import('@agoric/zone').Zone} Zone */ /** * @template {AssetKind} K - * @param {Baggage} issuerBaggage + * @param {Zone} issuerZone * @param {string} name * @param {Brand} brand * @param {InterfaceGuard} PaymentI * @returns {() => Payment} */ -export const preparePaymentKind = (issuerBaggage, name, brand, PaymentI) => { - const makePayment = prepareExoClass( - issuerBaggage, +export const preparePaymentKind = (issuerZone, name, brand, PaymentI) => { + const makePayment = issuerZone.exoClass( `${name} payment`, PaymentI, initEmpty, diff --git a/packages/ERTP/src/paymentLedger.js b/packages/ERTP/src/paymentLedger.js index 48f6380ce54f..f4bf8ee701f1 100644 --- a/packages/ERTP/src/paymentLedger.js +++ b/packages/ERTP/src/paymentLedger.js @@ -2,7 +2,6 @@ import { isPromise } from '@endo/promise-kit'; import { assertCopyArray } from '@endo/marshal'; import { mustMatch, M } from '@agoric/store'; -import { provideDurableWeakMapStore, prepareExo } from '@agoric/vat-data'; import { AmountMath } from './amountMath.js'; import { preparePaymentKind } from './payment.js'; import { preparePurseKind } from './purse.js'; @@ -10,7 +9,7 @@ import { preparePurseKind } from './purse.js'; import '@agoric/store/exported.js'; import { BrandI, makeIssuerInterfaces } from './typeGuards.js'; -/** @typedef {import('@agoric/vat-data').Baggage} Baggage */ +/** @typedef {import('@agoric/zone').Zone} Zone */ const { details: X, quote: q, Fail } = assert; @@ -69,7 +68,7 @@ const amountShapeFromElementShape = (brand, assetKind, elementShape) => { * payments. All minting and transfer authority originates here. * * @template {AssetKind} K - * @param {Baggage} issuerBaggage + * @param {Zone} issuerZone * @param {string} name * @param {K} assetKind * @param {DisplayInfo} displayInfo @@ -78,7 +77,7 @@ const amountShapeFromElementShape = (brand, assetKind, elementShape) => { * @returns {PaymentLedger} */ export const preparePaymentLedger = ( - issuerBaggage, + issuerZone, name, assetKind, displayInfo, @@ -87,7 +86,7 @@ export const preparePaymentLedger = ( ) => { /** @type {Brand} */ // @ts-expect-error XXX callWhen - const brand = prepareExo(issuerBaggage, `${name} brand`, BrandI, { + const brand = issuerZone.exo(`${name} brand`, BrandI, { isMyIssuer(allegedIssuer) { // BrandI delays calling this method until `allegedIssuer` is a Remotable return allegedIssuer === issuer; @@ -117,7 +116,7 @@ export const preparePaymentLedger = ( amountShape, ); - const makePayment = preparePaymentKind(issuerBaggage, name, brand, PaymentI); + const makePayment = preparePaymentKind(issuerZone, name, brand, PaymentI); /** @type {ShutdownWithFailure} */ const shutdownLedgerWithFailure = reason => { @@ -135,11 +134,9 @@ export const preparePaymentLedger = ( }; /** @type {WeakMapStore} */ - const paymentLedger = provideDurableWeakMapStore( - issuerBaggage, - 'paymentLedger', - { valueShape: amountShape }, - ); + const paymentLedger = issuerZone.weakMapStore('paymentLedger', { + valueShape: amountShape, + }); /** * A withdrawn live payment is associated with the recovery set of @@ -161,10 +158,7 @@ export const preparePaymentLedger = ( * * @type {WeakMapStore>} */ - const paymentRecoverySets = provideDurableWeakMapStore( - issuerBaggage, - 'paymentRecoverySets', - ); + const paymentRecoverySets = issuerZone.weakMapStore('paymentRecoverySets'); /** * To maintain the invariants listed in the `paymentRecoverySets` comment, @@ -371,7 +365,7 @@ export const preparePaymentLedger = ( }; const makeEmptyPurse = preparePurseKind( - issuerBaggage, + issuerZone, name, assetKind, brand, @@ -384,7 +378,7 @@ export const preparePaymentLedger = ( /** @type {Issuer} */ // @ts-expect-error cast due to callWhen discrepancy - const issuer = prepareExo(issuerBaggage, `${name} issuer`, IssuerI, { + const issuer = issuerZone.exo(`${name} issuer`, IssuerI, { getBrand() { return brand; }, @@ -499,7 +493,7 @@ export const preparePaymentLedger = ( }); /** @type {Mint} */ - const mint = prepareExo(issuerBaggage, `${name} mint`, MintI, { + const mint = issuerZone.exo(`${name} mint`, MintI, { getIssuer() { return issuer; }, diff --git a/packages/ERTP/src/purse.js b/packages/ERTP/src/purse.js index d218887c8dc2..04d04ebfefbf 100644 --- a/packages/ERTP/src/purse.js +++ b/packages/ERTP/src/purse.js @@ -1,12 +1,22 @@ import { M } from '@agoric/store'; -import { prepareExoClassKit, makeScalarBigSetStore } from '@agoric/vat-data'; import { AmountMath } from './amountMath.js'; import { makeTransientNotifierKit } from './transientNotifier.js'; +/** @typedef {import('@endo/eventual-send').Callable} Callable */ +/** @typedef {import('@agoric/zone').Zone} Zone */ + const { Fail } = assert; +/** + * @param {Zone} issuerZone + * @param {string} name + * @param {AssetKind} assetKind + * @param {Brand} brand + * @param {Record} PurseIKit + * @param {Record} purseMethods + */ export const preparePurseKind = ( - issuerBaggage, + issuerZone, name, assetKind, brand, @@ -17,6 +27,7 @@ export const preparePurseKind = ( // Note: Virtual for high cardinality, but *not* durable, and so // broken across an upgrade. + // TODO propagate zonifying to notifiers, maybe? const { provideNotifier, update: updateBalance } = makeTransientNotifierKit(); const updatePurseBalance = (state, newPurseBalance, purse) => { @@ -31,17 +42,14 @@ export const preparePurseKind = ( // that created depositFacet as needed. But this approach ensures a constant // identity for the facet and exercises the multi-faceted object style. const { depositInternal, withdrawInternal } = purseMethods; - const makePurseKit = prepareExoClassKit( - issuerBaggage, + const makePurseKit = issuerZone.exoClassKit( `${name} Purse`, PurseIKit, () => { const currentBalance = AmountMath.makeEmpty(brand, assetKind); /** @type {SetStore} */ - const recoverySet = makeScalarBigSetStore('recovery set', { - durable: true, - }); + const recoverySet = issuerZone.detached().setStore('recovery set'); return { currentBalance, diff --git a/packages/ERTP/src/transientNotifier.js b/packages/ERTP/src/transientNotifier.js index 0e612cf78b6c..0354a35dd458 100644 --- a/packages/ERTP/src/transientNotifier.js +++ b/packages/ERTP/src/transientNotifier.js @@ -2,6 +2,8 @@ import { makeScalarBigWeakMapStore } from '@agoric/vat-data'; import { provideLazy } from '@agoric/store'; import { makeNotifierKit } from '@agoric/notifier'; +// TODO propagate zonifying to notifiers, maybe? + // Note: Virtual for high cardinality, but *not* durable, and so // broken across an upgrade. export const makeTransientNotifierKit = () => {