diff --git a/packages/SwingSet/src/kernel/state/kernelKeeper.js b/packages/SwingSet/src/kernel/state/kernelKeeper.js index 656fcae1974..f230a6b41d0 100644 --- a/packages/SwingSet/src/kernel/state/kernelKeeper.js +++ b/packages/SwingSet/src/kernel/state/kernelKeeper.js @@ -548,6 +548,7 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) { } } } + harden(enumerateNonDurableObjectExports); /** * Allocate a new koid. @@ -936,6 +937,7 @@ export default function makeKernelKeeper(kernelStorage, kernelSlog) { } } } + harden(enumeratePromisesByDecider); function addSubscriberToPromise(kernelSlot, vatID) { insistKernelType('promise', kernelSlot); diff --git a/packages/SwingSet/src/kernel/state/storageHelper.js b/packages/SwingSet/src/kernel/state/storageHelper.js index 86b2b0d4dfa..cad0a907a39 100644 --- a/packages/SwingSet/src/kernel/state/storageHelper.js +++ b/packages/SwingSet/src/kernel/state/storageHelper.js @@ -25,6 +25,7 @@ export function* enumeratePrefixedKeys(kvStore, prefix, exclusiveEnd) { yield key; } } +harden(enumeratePrefixedKeys); /** * @param {KVStore} kvStore @@ -45,6 +46,7 @@ function* enumerateNumericPrefixedKeys(kvStore, prefix) { } } } +harden(enumerateNumericPrefixedKeys); /** * @param {KVStore} kvStore @@ -55,6 +57,7 @@ export function* getPrefixedValues(kvStore, prefix) { yield kvStore.get(key) || Fail`enumerate ensures get`; } } +harden(getPrefixedValues); /** * @param {KVStore} kvStore diff --git a/packages/SwingSet/src/kernel/state/vatKeeper.js b/packages/SwingSet/src/kernel/state/vatKeeper.js index fe15e7d746e..59a2040ad30 100644 --- a/packages/SwingSet/src/kernel/state/vatKeeper.js +++ b/packages/SwingSet/src/kernel/state/vatKeeper.js @@ -487,6 +487,7 @@ export function makeVatKeeper( deliveryNum += 1; } } + harden(getTranscript); /** * Append an entry to the vat's transcript. diff --git a/packages/casting/src/follower-cosmjs.js b/packages/casting/src/follower-cosmjs.js index ffe7b26e372..5792b6c8ede 100644 --- a/packages/casting/src/follower-cosmjs.js +++ b/packages/casting/src/follower-cosmjs.js @@ -10,6 +10,15 @@ import { MAKE_DEFAULT_DECODER, MAKE_DEFAULT_UNSERIALIZER } from './defaults.js'; import { makeCastingSpec } from './casting-spec.js'; import { makeLeader as defaultMakeLeader } from './leader-netconfig.js'; +// A lot of cosmjs classes end up hardened through instances shared by this +// package so preemptively harden them all. +// However we cannot directly harden a module namespace object (exotic behavior +// for bindings) so spread the namespace instead +harden({ + tendermint34: { ...tendermint34 }, + stargateStar: { ...stargateStar }, +}); + const { QueryClient } = stargateStar; const { Tendermint34Client } = tendermint34; const { details: X, quote: q, Fail } = assert; @@ -357,6 +366,7 @@ export const makeCosmjsFollower = ( ); } } + harden(allValuesFromCell); /** * @param {import('./types.js').StreamCell} streamCell @@ -372,6 +382,7 @@ export const makeCosmjsFollower = ( ); } } + harden(reverseValuesFromCell); /** * @param {import('./types.js').StreamCell} streamCell @@ -389,6 +400,7 @@ export const makeCosmjsFollower = ( ); } } + harden(lastValueFromCell); /** * @yields {ValueFollowerElement} @@ -434,6 +446,7 @@ export const makeCosmjsFollower = ( lastValue = latest.value; } } + harden(getLatestIterable); /** * @param {number} [cursorBlockHeight] @@ -552,6 +565,7 @@ export const makeCosmjsFollower = ( cursorData = currentData; } } + harden(getEachIterableAtHeight); /** * @param {number} [cursorBlockHeight] @@ -575,6 +589,7 @@ export const makeCosmjsFollower = ( cursorBlockHeight = cursorStreamCell.blockHeight - 1; } } + harden(getReverseIterableAtHeight); /** @type {ValueFollower} */ return Far('chain follower', { diff --git a/packages/casting/src/iterable.js b/packages/casting/src/iterable.js index 392a0c48227..e97fa8e3fc6 100644 --- a/packages/casting/src/iterable.js +++ b/packages/casting/src/iterable.js @@ -15,6 +15,7 @@ export const mapAsyncIterable = (iterable, transform) => { yield transform(value); } } + harden(transformGenerator); return transformGenerator(); }; diff --git a/packages/internal/test/test-utils.js b/packages/internal/test/test-utils.js index e81b6ae7e4d..ffced4aa0ed 100644 --- a/packages/internal/test/test-utils.js +++ b/packages/internal/test/test-utils.js @@ -182,6 +182,7 @@ const consumeStreamInto = async (stream, output, maxItems) => { const generateStream = async function* generateStream(items) { yield* items; }; +harden(generateStream); test('synchronizedTee - consumeAll - 1 reader', async t => { const sourceData = [1, 2, 3]; @@ -251,6 +252,7 @@ test('synchronizedTee - consume synchronized', async t => { } } } + harden(generate); const source = generate(); const [reader1, reader2] = synchronizedTee(source, 2); await Promise.all([ diff --git a/packages/swing-store/src/bundleStore.js b/packages/swing-store/src/bundleStore.js index fe74b9d53ad..6482d696757 100644 --- a/packages/swing-store/src/bundleStore.js +++ b/packages/swing-store/src/bundleStore.js @@ -267,6 +267,7 @@ export function makeBundleStore(db, ensureTxn, noteExport = () => {}) { const rawBundle = row.bundle || Fail`bundle ${q(bundleID)} pruned`; yield* Readable.from(Buffer.from(rawBundle)); } + harden(exportBundle); const sqlGetBundleIDs = db.prepare(` SELECT bundleID @@ -286,12 +287,14 @@ export function makeBundleStore(db, ensureTxn, noteExport = () => {}) { yield [bundleArtifactName(bundleID), bundleID]; } } + harden(getExportRecords); async function* getArtifactNames() { for (const bundleID of sqlGetBundleIDs.iterate()) { yield bundleArtifactName(bundleID); } } + harden(getArtifactNames); function computeSha512(bytes) { const hash = createHash('sha512'); @@ -364,6 +367,7 @@ export function makeBundleStore(db, ensureTxn, noteExport = () => {}) { function* getBundleIDs() { yield* sqlListBundleIDs.iterate(); } + harden(getBundleIDs); return harden({ importBundleRecord, diff --git a/packages/swing-store/src/exporter.js b/packages/swing-store/src/exporter.js index 5d74bb92dd4..42fe2d8d452 100644 --- a/packages/swing-store/src/exporter.js +++ b/packages/swing-store/src/exporter.js @@ -164,6 +164,7 @@ export function makeSwingStoreExporter(dirPath, options = {}) { yield* transcriptStore.getExportRecords(true); yield* bundleStore.getExportRecords(); } + harden(getExportData); /** * @returns {AsyncIterableIterator} @@ -174,6 +175,7 @@ export function makeSwingStoreExporter(dirPath, options = {}) { yield* transcriptStore.getArtifactNames(artifactMode); yield* bundleStore.getArtifactNames(); } + harden(getArtifactNames); /** * @param {string} name diff --git a/packages/swing-store/src/snapStore.js b/packages/swing-store/src/snapStore.js index 9df9a4a20bb..3d1ac29f743 100644 --- a/packages/swing-store/src/snapStore.js +++ b/packages/swing-store/src/snapStore.js @@ -306,6 +306,7 @@ export function makeSnapStore( const snapshotReader = gzReader.pipe(unzipper); yield* snapshotReader; } + harden(exporter); return exporter(); } @@ -344,6 +345,7 @@ export function makeSnapStore( Fail`actual hash ${q(hash)} !== expected ${q(snapshotID)}`; } } + harden(loadSnapshot); const sqlDeleteVatSnapshots = db.prepare(` DELETE FROM snapshots @@ -481,6 +483,7 @@ export function makeSnapStore( } } } + harden(getExportRecords); async function* getArtifactNames(artifactMode) { for (const rec of sqlGetAvailableSnapshots.iterate(1)) { @@ -492,6 +495,7 @@ export function makeSnapStore( } } } + harden(getArtifactNames); const sqlAddSnapshotRecord = db.prepare(` INSERT INTO snapshots (vatID, snapPos, hash, inUse) @@ -640,6 +644,7 @@ export function makeSnapStore( function* listAllSnapshots() { yield* sqlListAllSnapshots.iterate(); } + harden(listAllSnapshots); const sqlDumpCurrentSnapshots = db.prepare(` SELECT vatID, snapPos, hash, compressedSnapshot, inUse diff --git a/packages/swing-store/src/transcriptStore.js b/packages/swing-store/src/transcriptStore.js index ee30af5d4d6..b3797d73ec3 100644 --- a/packages/swing-store/src/transcriptStore.js +++ b/packages/swing-store/src/transcriptStore.js @@ -43,6 +43,7 @@ import { createSHA256 } from './hasher.js'; function* empty() { // Yield nothing } +harden(empty); /** * @param {number} position @@ -158,6 +159,7 @@ export function makeTranscriptStore( } } } + harden(readFullVatTranscript); function spanArtifactName(rec) { return `transcript.${rec.vatID}.${rec.startPos}.${rec.endPos}`; @@ -393,6 +395,7 @@ export function makeTranscriptStore( } } } + harden(getExportRecords); const sqlCountSpanItems = db.prepare(` SELECT COUNT(*) FROM transcriptItems @@ -447,6 +450,7 @@ export function makeTranscriptStore( } } } + harden(getArtifactNames); const sqlGetSpanEndPos = db.prepare(` SELECT endPos @@ -501,6 +505,7 @@ export function makeTranscriptStore( expectedCount, )})`; } + harden(reader); if (startPos === endPos) { return empty(); @@ -541,6 +546,7 @@ export function makeTranscriptStore( yield Buffer.from(`${entry}\n`); } } + harden(exportSpan); const sqlAddItem = db.prepare(` INSERT INTO transcriptItems (vatID, item, position, incarnation) diff --git a/packages/swing-store/test/test-deletion.js b/packages/swing-store/test/test-deletion.js index a6bbe32b560..58e08bf727b 100644 --- a/packages/swing-store/test/test-deletion.js +++ b/packages/swing-store/test/test-deletion.js @@ -6,6 +6,7 @@ import { initSwingStore } from '../src/swingStore.js'; async function* getSnapshotStream() { yield Buffer.from('abc'); } +harden(getSnapshotStream); test('delete snapshots with export callback', async t => { const exportLog = []; diff --git a/packages/swing-store/test/test-exportImport.js b/packages/swing-store/test/test-exportImport.js index bf01d2271c4..11579aec66d 100644 --- a/packages/swing-store/test/test-exportImport.js +++ b/packages/swing-store/test/test-exportImport.js @@ -83,6 +83,7 @@ async function fakeAVatSnapshot(vat, ks) { async function* getSnapshotStream() { yield Buffer.from(`snapshot of vat ${vat.vatID} as of ${vat.endPos}`); } + harden(getSnapshotStream); await ks.snapStore.saveSnapshot(vat.vatID, vat.endPos, getSnapshotStream()); ks.transcriptStore.addItem(vat.vatID, 'save-snapshot'); vat.endPos += 1; diff --git a/packages/swing-store/test/test-snapstore.js b/packages/swing-store/test/test-snapstore.js index 2e725d18479..584e0160653 100644 --- a/packages/swing-store/test/test-snapstore.js +++ b/packages/swing-store/test/test-snapstore.js @@ -26,6 +26,7 @@ function ensureTxn() {} async function* getSnapshotStream(payload) { yield Buffer.from(payload); } +harden(getSnapshotStream); test('compress to cache file; closes snapshot stream', async t => { const db = sqlite3(':memory:'); diff --git a/packages/swing-store/test/test-state.js b/packages/swing-store/test/test-state.js index 11b3c7d8b76..490f7953035 100644 --- a/packages/swing-store/test/test-state.js +++ b/packages/swing-store/test/test-state.js @@ -47,6 +47,7 @@ function* iterate(kvStore, start, end) { prev = next; } } +harden(iterate); function makeExportLog() { const exportLog = []; diff --git a/packages/swing-store/test/util.js b/packages/swing-store/test/util.js index 615cd3af567..967bc53609c 100644 --- a/packages/swing-store/test/util.js +++ b/packages/swing-store/test/util.js @@ -20,6 +20,7 @@ export const tmpDir = prefix => export async function* getSnapshotStream(contents) { yield Buffer.from(contents); } +harden(getSnapshotStream); export function makeB0ID(bundle) { return `b0-${createSHA256(JSON.stringify(bundle)).finish()}`; diff --git a/packages/swingset-liveslots/src/collectionManager.js b/packages/swingset-liveslots/src/collectionManager.js index 0840fea135a..aa9a465f695 100644 --- a/packages/swingset-liveslots/src/collectionManager.js +++ b/packages/swingset-liveslots/src/collectionManager.js @@ -518,7 +518,7 @@ export function makeCollectionManager( yield [yieldKeys ? key : undefined, yieldValues ? value : undefined]; } } - + harden(iter); return iter(); } @@ -528,6 +528,7 @@ export function makeCollectionManager( yield entry[0]; } } + harden(iter); return iter(); } @@ -592,6 +593,7 @@ export function makeCollectionManager( yield entry[1]; } } + harden(iter); return iter(); } @@ -601,6 +603,7 @@ export function makeCollectionManager( yield entry; } } + harden(iter); return iter(); } diff --git a/packages/swingset-liveslots/src/vatstore-iterators.js b/packages/swingset-liveslots/src/vatstore-iterators.js index 1dde103ea55..e51f4ed259c 100644 --- a/packages/swingset-liveslots/src/vatstore-iterators.js +++ b/packages/swingset-liveslots/src/vatstore-iterators.js @@ -18,6 +18,7 @@ export function* enumerateKeysStartEnd(syscall, start, end, checkF) { dbKey = syscall.vatstoreGetNextKey(dbKey); } } +harden(enumerateKeysStartEnd); // return an iterator of all existing keys that start with 'prefix' // (excluding the prefix itself) @@ -32,6 +33,7 @@ export function* enumerateKeysWithPrefix(syscall, prefix) { yield key; } } +harden(enumerateKeysWithPrefix); export function prefixedKeysExist(syscall, prefix) { const nextKey = syscall.vatstoreGetNextKey(prefix); diff --git a/packages/swingset-liveslots/test/gc-helpers.js b/packages/swingset-liveslots/test/gc-helpers.js index 376ac94365b..2cd32a78319 100644 --- a/packages/swingset-liveslots/test/gc-helpers.js +++ b/packages/swingset-liveslots/test/gc-helpers.js @@ -168,6 +168,7 @@ export function* enumerateKeysWithPrefix(fakestore, prefix) { } } } +harden(enumerateKeysWithPrefix); export function recognizersOf(v, baseref) { // the | is followed by the collectionID that can recognize baseref diff --git a/packages/vats/src/vat-bank.js b/packages/vats/src/vat-bank.js index d0d0ffa0a9a..7263c9a8687 100644 --- a/packages/vats/src/vat-bank.js +++ b/packages/vats/src/vat-bank.js @@ -229,6 +229,7 @@ async function* concatAsyncIterables(iterables) { yield* asyncIterable; } } +harden(concatAsyncIterables); /** * TODO: This should be absorbed and zone-ified into the existing publish kit. diff --git a/packages/wallet/api/src/wallet.js b/packages/wallet/api/src/wallet.js index dcad8f0b3bc..a37de6fd49f 100644 --- a/packages/wallet/api/src/wallet.js +++ b/packages/wallet/api/src/wallet.js @@ -165,6 +165,7 @@ export function buildRootObject(vatPowers) { yield state; } } + harden(makeApprovedNotifier); /** @type {WalletBridge} */ const bridge = Far('bridge', { diff --git a/packages/xsnap/api.js b/packages/xsnap/api.js index 94434428a5b..d8973d0590d 100644 --- a/packages/xsnap/api.js +++ b/packages/xsnap/api.js @@ -43,6 +43,7 @@ export class ErrorSignal extends Error { this.code = signal; } } +harden(ErrorSignal); export class ErrorCode extends Error { /** @@ -55,3 +56,4 @@ export class ErrorCode extends Error { this.code = code; } } +harden(ErrorCode); diff --git a/packages/xsnap/src/xsnap.js b/packages/xsnap/src/xsnap.js index d2b46e95755..a5a0978ef36 100644 --- a/packages/xsnap/src/xsnap.js +++ b/packages/xsnap/src/xsnap.js @@ -525,6 +525,7 @@ export async function xsnap(options) { )}`; } } + harden(makeSnapshotInternal); /** * @param {string} [description] diff --git a/packages/zoe/tools/fakePriceAuthority.js b/packages/zoe/tools/fakePriceAuthority.js index e08492e8341..625f3cf5b2a 100644 --- a/packages/zoe/tools/fakePriceAuthority.js +++ b/packages/zoe/tools/fakePriceAuthority.js @@ -259,6 +259,7 @@ export async function makeFakePriceAuthority(options) { record = await ticker.getUpdateSince(record.updateCount); } } + harden(generateQuotes); /** @type {PriceAuthority} */ const priceAuthority = Far('fake price authority', {