-
Notifications
You must be signed in to change notification settings - Fork 207
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
unnest defineDurableKind relax for promises too use seatHandle rather than zoeSeatAdmin notifiers not stored make the zcfSeatMint durable pass bundleCap to createZcfVat and rename to zcfBundleCapP
- Loading branch information
1 parent
3a856b6
commit bf46bdb
Showing
24 changed files
with
496 additions
and
266 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// @ts-check | ||
|
||
import { makeScalarBigWeakMapStore } from '@agoric/vat-data'; | ||
import { provide } from '@agoric/store'; | ||
import { makeNotifierKit } from '@agoric/notifier'; | ||
|
||
// Note: Virtual for high cardinality, but *not* durable, and so | ||
// broken across an upgrade. | ||
export const makeTransientNotifierKit = () => { | ||
/** @type {WeakMapStore<Purse, NotifierRecord<any>>} */ | ||
const transientNotiferKits = makeScalarBigWeakMapStore( | ||
'transientNotiferKits', | ||
); | ||
|
||
const provideNotifierKit = key => | ||
provide(transientNotiferKits, key, () => | ||
makeNotifierKit(key.getCurrentAmount()), | ||
); | ||
|
||
const provideNotifier = key => provideNotifierKit(key).notifier; | ||
const update = (key, newValue) => { | ||
if (transientNotiferKits.has(key)) { | ||
const { updater } = transientNotiferKits.get(key); | ||
updater.updateState(newValue); | ||
} | ||
}; | ||
|
||
return { provideNotifier, update }; | ||
}; | ||
harden(makeTransientNotifierKit); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
// @ts-check | ||
|
||
import { E } from '@endo/eventual-send'; | ||
import { AmountMath } from '@agoric/ertp'; | ||
import { | ||
provideDurableSingleton, | ||
provideDurableSetStore, | ||
makeScalarBigMapStore, | ||
} from '@agoric/vat-data'; | ||
|
||
import { coerceAmountKeywordRecord } from '../cleanProposal.js'; | ||
import { makeIssuerRecord } from '../issuerRecord.js'; | ||
import { addToAllocation, subtractFromAllocation } from './allocationMath.js'; | ||
|
||
import '../../exported.js'; | ||
import '../internal-types.js'; | ||
import './internal-types.js'; | ||
|
||
import '@agoric/swingset-vat/src/types-ambient.js'; | ||
|
||
// helpers for the code shared between MakeZCFMint and RegisterZCFMint | ||
|
||
export const makeZCFMintFactory = async ( | ||
zcfBaggage, | ||
recordIssuer, | ||
getAssetKindByBrand, | ||
makeEmptySeatKit, | ||
reallocateForZCFMint, | ||
) => { | ||
// The set of baggages for zcfMints | ||
const zcfMintBaggageSet = provideDurableSetStore(zcfBaggage, 'baggageSet'); | ||
|
||
/** | ||
* retrieve the state of the zcfMint from the baggage, and create a durable | ||
* singleton reflecting that state. | ||
* | ||
* @param {MapStore<string,any>} zcfMintBaggage | ||
*/ | ||
const provideDurableZcfMint = async zcfMintBaggage => { | ||
const keyword = zcfMintBaggage.get('keyword'); | ||
const zoeMintP = zcfMintBaggage.get('zoeMintP'); | ||
const { | ||
brand: mintyBrand, | ||
issuer: mintyIssuer, | ||
displayInfo: mintyDisplayInfo, | ||
} = await E(zoeMintP).getIssuerRecord(); | ||
// AWAIT | ||
const mintyIssuerRecord = makeIssuerRecord( | ||
mintyBrand, | ||
mintyIssuer, | ||
mintyDisplayInfo, | ||
); | ||
recordIssuer(keyword, mintyIssuerRecord); | ||
|
||
const empty = AmountMath.makeEmpty(mintyBrand, mintyDisplayInfo.assetKind); | ||
const add = (total, amountToAdd) => { | ||
return AmountMath.add(total, amountToAdd, mintyBrand); | ||
}; | ||
|
||
return provideDurableSingleton( | ||
zcfMintBaggage, | ||
'zcfMint', | ||
/** @type {ZCFMint} */ | ||
{ | ||
getIssuerRecord: _context => { | ||
return mintyIssuerRecord; | ||
}, | ||
mintGains: (_context, gains, zcfSeat = undefined) => { | ||
gains = coerceAmountKeywordRecord(gains, getAssetKindByBrand); | ||
if (zcfSeat === undefined) { | ||
zcfSeat = makeEmptySeatKit().zcfSeat; | ||
} | ||
const totalToMint = Object.values(gains).reduce(add, empty); | ||
assert( | ||
// @ts-expect-error It's non-null | ||
!zcfSeat.hasExited(), | ||
`zcfSeat must be active to mint gains for the zcfSeat`, | ||
); | ||
const allocationPlusGains = addToAllocation( | ||
// @ts-expect-error It's non-null | ||
zcfSeat.getCurrentAllocation(), | ||
gains, | ||
); | ||
|
||
// Increment the stagedAllocation if it exists so that the | ||
// stagedAllocation is kept up to the currentAllocation | ||
// @ts-expect-error It's non-null | ||
if (zcfSeat.hasStagedAllocation()) { | ||
// @ts-expect-error It's non-null | ||
zcfSeat.incrementBy(gains); | ||
} | ||
|
||
// Offer safety should never be able to be violated here, as | ||
// we are adding assets. However, we keep this check so that | ||
// all reallocations are covered by offer safety checks, and | ||
// that any bug within Zoe that may affect this is caught. | ||
assert( | ||
// @ts-expect-error It's non-null | ||
zcfSeat.isOfferSafe(allocationPlusGains), | ||
`The allocation after minting gains ${allocationPlusGains} for the zcfSeat was not offer safe`, | ||
); | ||
// No effects above, apart from incrementBy. Note COMMIT POINT within | ||
// reallocateForZCFMint. The following two steps *should* be | ||
// committed atomically, but it is not a disaster if they are | ||
// not. If we minted only, no one would ever get those | ||
// invisibly-minted assets. | ||
E(zoeMintP).mintAndEscrow(totalToMint); | ||
reallocateForZCFMint(zcfSeat, allocationPlusGains); | ||
return zcfSeat; | ||
}, | ||
burnLosses: (_context, losses, zcfSeat) => { | ||
losses = coerceAmountKeywordRecord(losses, getAssetKindByBrand); | ||
const totalToBurn = Object.values(losses).reduce(add, empty); | ||
assert( | ||
!zcfSeat.hasExited(), | ||
`zcfSeat must be active to burn losses from the zcfSeat`, | ||
); | ||
const allocationMinusLosses = subtractFromAllocation( | ||
zcfSeat.getCurrentAllocation(), | ||
losses, | ||
); | ||
|
||
// verifies offer safety | ||
assert( | ||
zcfSeat.isOfferSafe(allocationMinusLosses), | ||
`The allocation after burning losses ${allocationMinusLosses}for the zcfSeat was not offer safe`, | ||
); | ||
|
||
// Decrement the stagedAllocation if it exists so that the | ||
// stagedAllocation is kept up to the currentAllocation | ||
if (zcfSeat.hasStagedAllocation()) { | ||
zcfSeat.decrementBy(losses); | ||
} | ||
|
||
// No effects above, apart from decrementBy. Note COMMIT POINT within | ||
// reallocateForZCFMint. The following two steps *should* be | ||
// committed atomically, but it is not a disaster if they are | ||
// not. If we only commit the allocationMinusLosses no one would | ||
// ever get the unburned assets. | ||
reallocateForZCFMint(zcfSeat, allocationMinusLosses); | ||
E(zoeMintP).withdrawAndBurn(totalToBurn); | ||
}, | ||
}, | ||
); | ||
}; | ||
|
||
const makeDurableZcfMint = async (keyword, zoeMintP, zcfMintBaggage) => { | ||
zcfMintBaggage.init('keyword', keyword); | ||
zcfMintBaggage.init('zoeMintP', zoeMintP); | ||
return provideDurableZcfMint(zcfMintBaggage); | ||
}; | ||
|
||
/** | ||
* zcfMintFactory has a method makeZcfMint() that takes a keyword and the | ||
* promise returned by a makeZoeMint() call. makeZcfMint() creates a new | ||
* baggage for the state of the zcfMint, makes a durableZcfMint from that | ||
* baggage, and registers that baggage to be revived with the factory. | ||
*/ | ||
const zcfMintFactory = provideDurableSingleton(zcfBaggage, 'zcfMintFactory', { | ||
makeZcfMint: (keyword, zoeMintP) => { | ||
const zcfMintBaggage = makeScalarBigMapStore('zcfMintBaggage', { | ||
durable: true, | ||
}); | ||
const zcfMint = makeDurableZcfMint(keyword, zoeMintP, zcfMintBaggage); | ||
zcfMintBaggageSet.add(zcfMint); | ||
return zcfMint; | ||
}, | ||
}); | ||
|
||
for (const zcfMintBaggage of zcfMintBaggageSet.values()) { | ||
provideDurableZcfMint(zcfMintBaggage); | ||
} | ||
|
||
return zcfMintFactory; | ||
}; | ||
harden(makeZCFMintFactory); |
Oops, something went wrong.