diff --git a/packages/ERTP/package.json b/packages/ERTP/package.json index 84d49f7dede1..dc8316e291b7 100644 --- a/packages/ERTP/package.json +++ b/packages/ERTP/package.json @@ -43,6 +43,7 @@ "@agoric/notifier": "^0.6.2", "@agoric/store": "^0.9.2", "@agoric/vat-data": "^0.5.2", + "@agoric/zone": "^0.2.2", "@endo/eventual-send": "^1.1.0", "@endo/far": "^1.0.2", "@endo/marshal": "^1.1.0", diff --git a/packages/ERTP/src/issuerKit.js b/packages/ERTP/src/issuerKit.js index 028ba4fbcd60..fa6b15d30441 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'; @@ -13,6 +14,7 @@ import './types-ambient.js'; // TODO Why does TypeScript lose the `MapStore` typing of `Baggage` here, even // though it knows the correct type at the exporting `@agoric/vat-data` /** @typedef {import('@agoric/vat-data').Baggage} Baggage */ +/** @typedef {import('@agoric/zone').Zone} Zone */ /** * @template {AssetKind} K @@ -28,7 +30,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 @@ -40,7 +42,7 @@ import './types-ambient.js'; */ const setupIssuerKit = ( { name, assetKind, displayInfo, elementShape }, - issuerBaggage, + issuerZone, optShutdownWithFailure = undefined, ) => { assert.typeof(name, 'string'); @@ -60,7 +62,7 @@ const setupIssuerKit = ( /** @type {PaymentLedger} */ // @ts-expect-error could be instantiated with different subtype of AssetKind const { issuer, mint, brand, mintRecoveryPurse } = preparePaymentLedger( - issuerBaggage, + issuerZone, name, assetKind, cleanDisplayInfo, @@ -101,7 +103,8 @@ export const upgradeIssuerKit = ( optShutdownWithFailure = undefined, ) => { const issuerRecord = issuerBaggage.get(INSTANCE_KEY); - return setupIssuerKit(issuerRecord, issuerBaggage, optShutdownWithFailure); + const issuerZone = makeDurableZone(issuerBaggage); + return setupIssuerKit(issuerRecord, issuerZone, optShutdownWithFailure); }; harden(upgradeIssuerKit); @@ -167,7 +170,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 809be8cc965b..499151966f82 100644 --- a/packages/ERTP/src/payment.js +++ b/packages/ERTP/src/payment.js @@ -1,26 +1,24 @@ // @jessie-check import { initEmpty } from '@agoric/store'; -import { prepareExoClass } from '@agoric/vat-data'; /** @typedef {import('@endo/patterns').MethodGuard} MethodGuard */ /** * @template {Record} [T=Record] * @typedef {import('@endo/patterns').InterfaceGuard} InterfaceGuard */ -/** @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 a20f6e4be5e3..4bb674124cf4 100644 --- a/packages/ERTP/src/paymentLedger.js +++ b/packages/ERTP/src/paymentLedger.js @@ -3,11 +3,6 @@ /* eslint-disable no-use-before-define */ import { isPromise } from '@endo/promise-kit'; import { mustMatch, M, keyEQ } from '@agoric/store'; -import { - provideDurableWeakMapStore, - prepareExo, - provide, -} from '@agoric/vat-data'; import { AmountMath } from './amountMath.js'; import { preparePaymentKind } from './payment.js'; import { preparePurseKind } from './purse.js'; @@ -15,7 +10,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; @@ -74,7 +69,7 @@ const amountShapeFromElementShape = (brand, assetKind, elementShape) => { * minting and transfer authority originates here. * * @template {AssetKind} K - * @param {Baggage} issuerBaggage + * @param {Zone} issuerZone * @param {string} name * @param {K} assetKind * @param {DisplayInfo} displayInfo @@ -83,7 +78,7 @@ const amountShapeFromElementShape = (brand, assetKind, elementShape) => { * @returns {PaymentLedger} */ export const preparePaymentLedger = ( - issuerBaggage, + issuerZone, name, assetKind, displayInfo, @@ -91,8 +86,12 @@ export const preparePaymentLedger = ( optShutdownWithFailure = undefined, ) => { /** @type {Brand} */ - // @ts-expect-error XXX callWhen - const brand = prepareExo(issuerBaggage, `${name} brand`, BrandI, { + // Should be + // at-ts-expect-error XXX callWhen + // but ran into the usual disagreement between local lint and CI + // eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error + // @ts-ignore + const brand = issuerZone.exo(`${name} brand`, BrandI, { isMyIssuer(allegedIssuer) { // BrandI delays calling this method until `allegedIssuer` is a Remotable return allegedIssuer === issuer; @@ -121,7 +120,7 @@ export const preparePaymentLedger = ( amountShape, ); - const makePayment = preparePaymentKind(issuerBaggage, name, brand, PaymentI); + const makePayment = preparePaymentKind(issuerZone, name, brand, PaymentI); /** @type {ShutdownWithFailure} */ const shutdownLedgerWithFailure = reason => { @@ -139,11 +138,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 the purse @@ -164,10 +161,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, @@ -293,7 +287,7 @@ export const preparePaymentLedger = ( /** @type {() => Purse} */ // @ts-expect-error type parameter confusion const makeEmptyPurse = preparePurseKind( - issuerBaggage, + issuerZone, name, assetKind, brand, @@ -305,8 +299,12 @@ export const preparePaymentLedger = ( ); /** @type {Issuer} */ - // @ts-expect-error cast due to callWhen discrepancy - const issuer = prepareExo(issuerBaggage, `${name} issuer`, IssuerI, { + // Should be + // at-ts-expect-error cast due to callWhen discrepancy + // but ran into the usual disagreement between local lint and CI + // eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error + // @ts-ignore + const issuer = issuerZone.exo(`${name} issuer`, IssuerI, { getBrand() { return brand; }, @@ -359,20 +357,28 @@ export const preparePaymentLedger = ( * Because the `mintRecoveryPurse` is placed in baggage, even if the caller of * `makeIssuerKit` drops it on the floor, it can still be recovered in an * emergency upgrade. - * - * @type {Purse} */ - const mintRecoveryPurse = provide(issuerBaggage, 'mintRecoveryPurse', () => - makeEmptyPurse(), + // Should be + // at-ts-expect-error checked cast + // but ran into the usual disagreement between local lint and IDE lint. + // Don't know yet about lint under CI. + // eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error + // @ts-ignore + const mintRecoveryPurse = /** @type {Purse} */ ( + issuerZone.makeOnce('mintRecoveryPurse', () => makeEmptyPurse()) ); /** @type {Mint} */ - const mint = prepareExo(issuerBaggage, `${name} mint`, MintI, { + const mint = issuerZone.exo(`${name} mint`, MintI, { getIssuer() { return issuer; }, mintPayment(newAmount) { - // @ts-expect-error checked cast + // Should be + // at-ts-expect-error checked cast + // but ran into the usual disagreement between local lint and CI + // eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error + // @ts-ignore newAmount = coerce(newAmount); mustMatch(newAmount, amountShape, 'minted amount'); // `rawPayment` is not associated with any recovery set, and diff --git a/packages/ERTP/src/purse.js b/packages/ERTP/src/purse.js index 52fc1ca11e3a..acc7080acc97 100644 --- a/packages/ERTP/src/purse.js +++ b/packages/ERTP/src/purse.js @@ -1,17 +1,16 @@ import { M } from '@agoric/store'; -import { prepareExoClassKit, makeScalarBigSetStore } from '@agoric/vat-data'; import { AmountMath } from './amountMath.js'; import { makeTransientNotifierKit } from './transientNotifier.js'; import { makeAmountStore } from './amountStore.js'; // TODO `InterfaceGuard` type parameter /** @typedef {import('@endo/patterns').InterfaceGuard} InterfaceGuard */ -/** @typedef {import('@agoric/vat-data').Baggage} Baggage */ +/** @typedef {import('@agoric/zone').Zone} Zone */ const { Fail } = assert; /** - * @param {Baggage} issuerBaggage + * @param {Zone} issuerZone * @param {string} name * @param {AssetKind} assetKind * @param {Brand} brand @@ -25,7 +24,7 @@ const { Fail } = assert; * }} purseMethods */ export const preparePurseKind = ( - issuerBaggage, + issuerZone, name, assetKind, brand, @@ -36,6 +35,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(); // - This kind is a pair of purse and depositFacet that have a 1:1 @@ -45,17 +45,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,