@agoric/swingset-vat 0.33.0-upgrade-19-dev-0754752.0 → 0.33.0-upgrade-18a-dev-4ee0508.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -128,10 +128,8 @@ export function makeXsSubprocessFactory({
128
128
 
129
129
  const vatKeeper = kernelKeeper.provideVatKeeper(vatID);
130
130
  const snapshotInfo = vatKeeper.getSnapshotInfo();
131
- let uncompressedSizeLoaded = null;
132
131
  if (snapshotInfo) {
133
132
  kernelSlog.write({ type: 'heap-snapshot-load', vatID, ...snapshotInfo });
134
- uncompressedSizeLoaded = snapshotInfo.uncompressedSize;
135
133
  }
136
134
 
137
135
  // `startXSnap` adds `nameDisplayArg` as a dummy argument so that 'ps'
@@ -242,31 +240,9 @@ export function makeXsSubprocessFactory({
242
240
  async function makeSnapshot(snapPos, snapStore, restartWorker) {
243
241
  const snapshotDescription = `${vatID}-${snapPos}`;
244
242
  const snapshotStream = worker.makeSnapshotStream(snapshotDescription);
245
- const saveSnapshot = async saveStream => {
246
- const results = await snapStore.saveSnapshot(
247
- vatID,
248
- snapPos,
249
- saveStream,
250
- );
251
- const { hash: snapshotID, ...metrics } = results;
252
- const uncompressedSizeDelta =
253
- uncompressedSizeLoaded &&
254
- metrics.uncompressedSize - uncompressedSizeLoaded;
255
- uncompressedSizeLoaded = results.uncompressedSize;
256
- kernelSlog.write({
257
- type: 'heap-snapshot-save',
258
- vatID,
259
- snapshotID,
260
- endPosition: snapPos,
261
- ...metrics,
262
- uncompressedSizeDelta,
263
- restartWorker,
264
- });
265
- return results;
266
- };
267
243
 
268
244
  if (!restartWorker) {
269
- return saveSnapshot(snapshotStream);
245
+ return snapStore.saveSnapshot(vatID, snapPos, snapshotStream);
270
246
  }
271
247
 
272
248
  /** @type {AsyncGenerator<Uint8Array, void, void>[]} */
@@ -292,7 +268,7 @@ export function makeXsSubprocessFactory({
292
268
  snapshotDescription,
293
269
  },
294
270
  }),
295
- saveSnapshot(snapStoreSaveStream),
271
+ snapStore.saveSnapshot(vatID, snapPos, snapStoreSaveStream),
296
272
  ]);
297
273
  await closeP;
298
274
 
@@ -9,7 +9,7 @@ export function makeVatRootObjectSlot() {
9
9
  export function makeVatLoader(stuff) {
10
10
  const {
11
11
  overrideVatManagerOptions = {},
12
- makeVatManager,
12
+ vatManagerFactory,
13
13
  kernelSlog,
14
14
  makeSourcedConsole,
15
15
  kernelKeeper,
@@ -127,7 +127,7 @@ export function makeVatLoader(stuff) {
127
127
  };
128
128
 
129
129
  const finish = starting && kernelSlog.startup(vatID);
130
- const manager = await makeVatManager(vatID, {
130
+ const manager = await vatManagerFactory(vatID, {
131
131
  managerOptions,
132
132
  liveSlotsOptions,
133
133
  });
@@ -150,7 +150,7 @@ export function makeVatLoader(stuff) {
150
150
  ...overrideVatManagerOptions,
151
151
  };
152
152
  const liveSlotsOptions = {};
153
- const manager = await makeVatManager(vatID, {
153
+ const manager = await vatManagerFactory(vatID, {
154
154
  managerOptions,
155
155
  liveSlotsOptions,
156
156
  });
@@ -32,15 +32,16 @@ function makeSupervisorDispatch(dispatch) {
32
32
  async function dispatchToVat(delivery) {
33
33
  // the (low-level) vat is responsible for giving up agency, but we still
34
34
  // protect against exceptions
35
- await null;
36
- try {
37
- const res = await dispatch(delivery);
38
- return harden(['ok', res, null]);
39
- } catch (err) {
40
- // TODO react more thoughtfully, maybe terminate the vat
41
- console.warn(`error during vat dispatch() of ${delivery}`, err);
42
- return harden(['error', `${err}`, null]);
43
- }
35
+ return Promise.resolve(delivery)
36
+ .then(dispatch)
37
+ .then(
38
+ res => harden(['ok', res, null]),
39
+ err => {
40
+ // TODO react more thoughtfully, maybe terminate the vat
41
+ console.warn(`error during vat dispatch() of ${delivery}`, err);
42
+ return harden(['error', `${err}`, null]);
43
+ },
44
+ );
44
45
  }
45
46
 
46
47
  return harden(dispatchToVat);
package/src/typeGuards.js CHANGED
@@ -10,40 +10,38 @@ export const ManagerType = M.or(
10
10
 
11
11
  const Bundle = M.splitRecord({ moduleType: M.string() });
12
12
 
13
- const VatConfigOptions = harden({
13
+ const SwingsetConfigOptions = {
14
14
  creationOptions: M.splitRecord({}, { critical: M.boolean() }),
15
15
  parameters: M.recordOf(M.string(), M.any()),
16
- });
16
+ };
17
+ harden(SwingsetConfigOptions);
17
18
 
18
- const makeSwingSetConfigProperties = (required = {}, optional = {}, rest) =>
19
- M.or(
20
- M.splitRecord({ sourceSpec: M.string(), ...required }, optional, rest),
21
- M.splitRecord({ bundleSpec: M.string(), ...required }, optional, rest),
22
- M.splitRecord({ bundle: Bundle, ...required }, optional, rest),
23
- );
24
- const makeSwingSetConfigDescriptor = (required, optional, rest) =>
25
- M.recordOf(
26
- M.string(),
27
- makeSwingSetConfigProperties(required, optional, rest),
28
- );
19
+ const SwingSetConfigProperties = M.or(
20
+ M.splitRecord({ sourceSpec: M.string() }, SwingsetConfigOptions),
21
+ M.splitRecord({ bundleSpec: M.string() }, SwingsetConfigOptions),
22
+ M.splitRecord({ bundle: Bundle }, SwingsetConfigOptions),
23
+ );
24
+ const SwingSetConfigDescriptor = M.recordOf(
25
+ M.string(),
26
+ SwingSetConfigProperties,
27
+ );
29
28
 
30
29
  /**
31
30
  * NOTE: this pattern suffices for PSM bootstrap,
32
31
  * but does not cover the whole SwingSet config syntax.
33
32
  *
34
33
  * {@link ./docs/configuration.md}
34
+ * TODO: move this to swingset?
35
35
  *
36
36
  * @see SwingSetConfig
37
37
  * in ./types-external.js
38
38
  */
39
- export const SwingSetConfig = M.splitRecord(
40
- { vats: makeSwingSetConfigDescriptor(undefined, VatConfigOptions) },
41
- {
42
- defaultManagerType: ManagerType,
43
- includeDevDependencies: M.boolean(),
44
- defaultReapInterval: M.number(),
45
- snapshotInterval: M.number(),
46
- bootstrap: M.string(),
47
- bundles: makeSwingSetConfigDescriptor(undefined, undefined, {}),
48
- },
39
+ export const SwingSetConfig = M.and(
40
+ M.splitRecord({}, { defaultManagerType: ManagerType }),
41
+ M.splitRecord({}, { includeDevDependencies: M.boolean() }),
42
+ M.splitRecord({}, { defaultReapInterval: M.number() }), // not in type decl
43
+ M.splitRecord({}, { snapshotInterval: M.number() }),
44
+ M.splitRecord({}, { vats: SwingSetConfigDescriptor }),
45
+ M.splitRecord({}, { bootstrap: M.string() }),
46
+ M.splitRecord({}, { bundles: SwingSetConfigDescriptor }),
49
47
  );
@@ -1,10 +1,10 @@
1
+ /** @import { ERef } from '@endo/far'; */
2
+
1
3
  export {};
2
4
 
3
5
  /**
4
6
  * @import {Guarded} from '@endo/exo';
5
- * @import {ERef} from '@endo/far';
6
7
  * @import {Passable, RemotableObject} from '@endo/pass-style';
7
- * @import {LimitedConsole} from '@agoric/internal/src/js-utils.js';
8
8
  */
9
9
 
10
10
  /* This file defines types that part of the external API of swingset. That
@@ -129,15 +129,7 @@ export {};
129
129
  * @typedef { (dr: VatDeliveryResult) => void } SlogFinishDelivery
130
130
  * @typedef { (ksr: KernelSyscallResult, vsr: VatSyscallResult) => void } SlogFinishSyscall
131
131
  * @typedef { { write: ({}) => void,
132
- * provideVatSlogger: (vatID: string,
133
- * dynamic?: boolean,
134
- * description?: string,
135
- * name?: string,
136
- * vatSourceBundle?: unknown,
137
- * managerType?: string,
138
- * vatParameters?: unknown) => { vatSlog: VatSlog },
139
- * vatConsole: (vatID: string, origConsole: LimitedConsole) => LimitedConsole,
140
- * startup: (vatID: string) => () => void,
132
+ * vatConsole: (vatID: string, origConsole: {}) => {},
141
133
  * delivery: (vatID: string,
142
134
  * newCrankNum: BigInt, newDeliveryNum: BigInt,
143
135
  * kd: KernelDeliveryObject, vd: VatDeliveryObject,
@@ -145,11 +137,13 @@ export {};
145
137
  * syscall: (vatID: string,
146
138
  * ksc: KernelSyscallObject | undefined,
147
139
  * vsc: VatSyscallObject) => SlogFinishSyscall,
148
- * changeCList: (vatID: string,
149
- * crankNum: BigInt,
150
- * mode: 'import' | 'export' | 'drop',
151
- * kernelSlot: string,
152
- * vatSlot: string) => void,
140
+ * provideVatSlogger: (vatID: string,
141
+ * dynamic?: boolean,
142
+ * description?: string,
143
+ * name?: string,
144
+ * vatSourceBundle?: unknown,
145
+ * managerType?: string,
146
+ * vatParameters?: unknown) => { vatSlog: VatSlog },
153
147
  * terminateVat: (vatID: string, shouldReject: boolean, info: SwingSetCapData) => void,
154
148
  * } } KernelSlog
155
149
  * @typedef {{
@@ -160,25 +154,27 @@ export {};
160
154
  */
161
155
 
162
156
  /**
163
- * @typedef {{ bundle: Bundle }} BundleRef a bundle object
164
- * @typedef {{ bundleName: string }} BundleName a name identifying a property in the `bundles` of a SwingSetOptions object
165
- * @typedef {{ bundleSpec: string }} BundleSpec a path to a bundle file
166
- * @typedef {{ sourceSpec: string }} SourceSpec a package specifier such as "@agoric/swingset-vat/tools/vat-puppet.js"
167
- *
168
157
  * @typedef {{
158
+ * sourceSpec: string // path to pre-bundled root
159
+ * }} SourceSpec
160
+ * @typedef {{
161
+ * bundleSpec: string // path to bundled code
162
+ * }} BundleSpec
163
+ * @typedef {{
164
+ * bundle: Bundle
165
+ * }} BundleRef
166
+ * @typedef {{
167
+ * bundleName: string
168
+ * }} BundleName
169
+ * @typedef {(SourceSpec | BundleSpec | BundleRef | BundleName ) & {
169
170
  * bundleID?: BundleID,
170
- * creationOptions?: StaticVatOptions,
171
+ * creationOptions?: Record<string, any>,
171
172
  * parameters?: Record<string, any>,
172
- * }} VatConfigOptions
173
- */
174
- /**
175
- * @template [Fields=object]
176
- * @typedef {(SourceSpec | BundleSpec | BundleName | BundleRef) & Fields} SwingSetConfigProperties
173
+ * }} SwingSetConfigProperties
177
174
  */
178
175
 
179
176
  /**
180
- * @template [Fields=object]
181
- * @typedef {Record<string, SwingSetConfigProperties<Fields>>} SwingSetConfigDescriptor
177
+ * @typedef {Record<string, SwingSetConfigProperties>} SwingSetConfigDescriptor
182
178
  * Where the property name is the name of the vat. Note that
183
179
  * the `bootstrap` property names the vat that should be used as the bootstrap vat. Although a swingset
184
180
  * configuration can designate any vat as its bootstrap vat, `loadBasedir` will always look for a file named
@@ -192,7 +188,7 @@ export {};
192
188
  * `devDependencies` of the surrounding `package.json` should be accessible to
193
189
  * bundles.
194
190
  * @property {string} [bundleCachePath] if present, SwingSet will use a bundle cache at this path
195
- * @property {SwingSetConfigDescriptor<VatConfigOptions>} vats
191
+ * @property {SwingSetConfigDescriptor} vats
196
192
  * @property {SwingSetConfigDescriptor} [bundles]
197
193
  * @property {BundleFormat} [bundleFormat] the bundle source / import bundle
198
194
  * format.
@@ -210,7 +206,7 @@ export {};
210
206
  */
211
207
 
212
208
  /**
213
- * @typedef {BundleName | BundleRef | {bundleID: BundleID}} SourceOfBundle
209
+ * @typedef {{ bundleName: string} | { bundle: Bundle } | { bundleID: BundleID } } SourceOfBundle
214
210
  */
215
211
  /**
216
212
  * @typedef { import('@agoric/swing-store').KVStore } KVStore
@@ -299,8 +295,12 @@ export {};
299
295
  * Vat Creation and Management
300
296
  *
301
297
  * @typedef { string } BundleID
302
- * @typedef { any } BundleCap
298
+ * @typedef {any} BundleCap
303
299
  * @typedef { { moduleFormat: 'endoZipBase64', endoZipBase64: string, endoZipBase64Sha512: string } } EndoZipBase64Bundle
300
+ *
301
+ * @typedef { unknown } Meter
302
+ *
303
+ * E(vatAdminService).createVat(bundle, options: DynamicVatOptions)
304
304
  */
305
305
 
306
306
  /**
@@ -326,6 +326,8 @@ export {};
326
326
  * types are then defined as amendments to this base type.
327
327
  *
328
328
  * @typedef { object } BaseVatOptions
329
+ * @property { string } name
330
+ * @property { * } [vatParameters]
329
331
  * @property { boolean } [enableSetup]
330
332
  * If true, permits the vat to construct itself using the
331
333
  * `setup()` API, which bypasses the imposition of LiveSlots but
@@ -344,10 +346,6 @@ export {};
344
346
  * outbound syscalls so that the vat's internal state can be
345
347
  * reconstructed via replay. If false, no such record is kept.
346
348
  * Defaults to true.
347
- * @property { ManagerType } [managerType]
348
- * @property { boolean } [neverReap]
349
- * If true, disables automatic bringOutYourDead deliveries to a vat.
350
- * Defaults to false.
351
349
  * @property { number | 'never' } [reapInterval]
352
350
  * Trigger a bringOutYourDead after the vat has received
353
351
  * this many deliveries. If the value is 'never',
@@ -362,7 +360,7 @@ export {};
362
360
  */
363
361
 
364
362
  /**
365
- * @typedef { { meter?: unknown } } OptMeter
363
+ * @typedef { { meter?: Meter } } OptMeter
366
364
  * If a meter is provided, the new dynamic vat is limited to a fixed
367
365
  * amount of computation and allocation that can occur during any
368
366
  * given crank. Peak stack frames are limited as well. In addition,
@@ -372,13 +370,14 @@ export {};
372
370
  * terminated. If undefined, the vat is unmetered. Static vats
373
371
  * cannot be metered.
374
372
  *
375
- * @typedef { BaseVatOptions & { name: string, vatParameters?: object } & OptMeter } DynamicVatOptions
373
+ * @typedef { { managerType?: ManagerType } } OptManagerType
374
+ * @typedef { BaseVatOptions & OptMeter & OptManagerType } DynamicVatOptions
376
375
  *
377
376
  * config.vats[name].creationOptions: StaticVatOptions
378
377
  *
379
378
  * @typedef { { enableDisavow?: boolean } } OptEnableDisavow
380
379
  * @typedef { { nodeOptions?: string[] } } OptNodeOptions
381
- * @typedef { BaseVatOptions & OptEnableDisavow & OptNodeOptions } StaticVatOptions
380
+ * @typedef { BaseVatOptions & OptManagerType & OptEnableDisavow & OptNodeOptions } StaticVatOptions
382
381
  *
383
382
  * @typedef { { vatParameters?: object, upgradeMessage?: string } } VatUpgradeOptions
384
383
  * @typedef { { incarnationNumber: number } } VatUpgradeResults
@@ -29,6 +29,7 @@ export {};
29
29
  * @typedef { string } MeterID
30
30
  * @typedef { { meterID?: MeterID } } OptMeterID
31
31
  * @typedef { import('./types-external.js').BaseVatOptions } BaseVatOptions
32
+ * @typedef { import('./types-external.js').OptManagerType } OptManagerType
32
33
  * @typedef { import('@agoric/swingset-liveslots').VatDeliveryObject } VatDeliveryObject
33
34
  * @typedef { import('@agoric/swingset-liveslots').VatDeliveryResult } VatDeliveryResult
34
35
  * @typedef { import('@agoric/swingset-liveslots').VatSyscallObject } VatSyscallObject
@@ -37,7 +38,7 @@ export {};
37
38
  *
38
39
  * // used by vatKeeper.setSourceAndOptions(source, RecordedVatOptions)
39
40
  *
40
- * @typedef { BaseVatOptions & OptMeterID } InternalDynamicVatOptions
41
+ * @typedef { BaseVatOptions & OptMeterID & OptManagerType } InternalDynamicVatOptions
41
42
  *
42
43
  * RecordedVatOptions is fully-specified, no optional fields
43
44
  *
@@ -111,7 +112,7 @@ export {};
111
112
  * enableDisavow: boolean,
112
113
  * useTranscript: boolean,
113
114
  * name: string,
114
- * sourcedConsole: import('@agoric/internal/src/js-utils.js').LimitedConsole,
115
+ * sourcedConsole: Pick<Console, 'debug' | 'log' | 'info' | 'warn' | 'error'>,
115
116
  * enableSetup: boolean,
116
117
  * setup?: unknown,
117
118
  * retainSyscall?: boolean
@@ -14,8 +14,6 @@ import { makeScalarWeakMapStore } from '@agoric/store';
14
14
  import { TimeMath } from '@agoric/time';
15
15
 
16
16
  /**
17
- * @import {LegacyWeakMap, WeakMapStore} from '@agoric/store';
18
- * @import {MapStore} from '@agoric/swingset-liveslots';
19
17
  * @import {Passable, RemotableObject} from '@endo/pass-style';
20
18
  * @import {Key} from '@endo/patterns';
21
19
  */
@@ -1,10 +1,6 @@
1
1
  import { makeNodeBundleCache as wrappedMaker } from '@endo/bundle-source/cache.js';
2
2
  import styles from 'ansi-styles'; // less authority than 'chalk'
3
3
 
4
- /**
5
- * @import {EReturn} from '@endo/far';
6
- */
7
-
8
4
  /** @type {typeof wrappedMaker} */
9
5
  export const makeNodeBundleCache = async (dest, options, loadModule, pid) => {
10
6
  const log = (...args) => {
@@ -21,7 +17,7 @@ export const makeNodeBundleCache = async (dest, options, loadModule, pid) => {
21
17
  };
22
18
  return wrappedMaker(dest, { log, ...options }, loadModule, pid);
23
19
  };
24
- /** @typedef {EReturn<typeof makeNodeBundleCache>} BundleCache */
20
+ /** @typedef {Awaited<ReturnType<typeof makeNodeBundleCache>>} BundleCache */
25
21
 
26
22
  /** @type {Map<string, Promise<BundleCache>>} */
27
23
  const providedCaches = new Map();
@@ -53,25 +53,10 @@ export const makeRunUtils = (controller, harness) => {
53
53
  };
54
54
 
55
55
  /**
56
- * @typedef EVProxyMethods
57
- * @property {(presence: unknown) => Record<string, (...args: any) => Promise<void>>} sendOnly
58
- * Returns a "methods proxy" for the presence that ignores the results of
59
- * each method invocation.
60
- * @property {(name: string) => Record<string, (...args: any) => Promise<any>>} vat
61
- * Returns a "methods proxy" for the root object of the specified vat.
62
- * So e.g. `EV.vat('foo').m(0)` becomes
63
- * `controller.queueToVatRoot('foo', 'm', [0])`.
64
- * @property {(presence: unknown) => Record<string, Promise<any>>} get
65
- * Returns a "values proxy" for the presence for which each requested
66
- * property manifests as a promise.
67
- */
68
- /**
69
- * @typedef {import('@endo/eventual-send').EProxy & EVProxyMethods} EVProxy
70
- * Given a presence, return a "methods proxy" for which each requested
71
- * property manifests as a method that forwards its invocation through the
72
- * controller to the presence as an invocation of an identically-named method
73
- * with identical arguments (modulo passable translation).
74
- * So e.g. `EV(x).m(0)` becomes `controller.queueToVatObject(x, 'm', [0])`.
56
+ * @typedef {import('@endo/eventual-send').EProxy & {
57
+ * sendOnly: (presence: unknown) => Record<string, (...args: any) => void>;
58
+ * vat: (name: string) => Record<string, (...args: any) => Promise<any>>;
59
+ * }} EVProxy
75
60
  */
76
61
 
77
62
  // IMPORTANT WARNING TO USERS OF `EV`
@@ -118,39 +103,52 @@ export const makeRunUtils = (controller, harness) => {
118
103
  // promise that can remain pending indefinitely, possibly to be settled by a
119
104
  // future message delivery.
120
105
 
121
- /**
122
- * @template {(typeof controller.queueToVatObject) | (typeof controller.queueToVatRoot)} T
123
- * @param {T} invoker
124
- * @param {Parameters<T>[0]} target
125
- * @param {boolean} [voidResult]
126
- */
127
- const makeMethodsProxy = (invoker, target, voidResult = false) =>
128
- new Proxy(harden({}), {
129
- get: (_t, method, _rx) => {
130
- const resultPolicy = voidResult ? 'none' : undefined;
131
- const boundMethod = (...args) =>
132
- queueAndRun(
133
- () => invoker(target, method, args, resultPolicy),
134
- voidResult,
135
- );
136
- return harden(boundMethod);
137
- },
138
- });
139
-
140
- const EV = /** @type {EVProxy} */ (
141
- Object.assign(
142
- presence => makeMethodsProxy(controller.queueToVatObject, presence),
143
- {
144
- vat: vatName => makeMethodsProxy(controller.queueToVatRoot, vatName),
145
- sendOnly: presence =>
146
- makeMethodsProxy(controller.queueToVatObject, presence, true),
147
- get: presence =>
148
- new Proxy(harden({}), {
149
- get: (_t, key, _rx) =>
150
- EV.vat('bootstrap').awaitVatObject(presence, [key]),
151
- }),
152
- },
153
- )
106
+ /** @type {EVProxy} */
107
+ // @ts-expect-error cast, approximate
108
+ const EV = Object.assign(
109
+ presence =>
110
+ new Proxy(harden({}), {
111
+ get: (_t, method, _rx) => {
112
+ const boundMethod = (...args) =>
113
+ queueAndRun(() =>
114
+ controller.queueToVatObject(presence, method, args),
115
+ );
116
+ return harden(boundMethod);
117
+ },
118
+ }),
119
+ {
120
+ vat: vatName =>
121
+ new Proxy(harden({}), {
122
+ get: (_t, method, _rx) => {
123
+ const boundMethod = (...args) =>
124
+ queueAndRun(() =>
125
+ controller.queueToVatRoot(vatName, method, args),
126
+ );
127
+ return harden(boundMethod);
128
+ },
129
+ }),
130
+ sendOnly: presence =>
131
+ new Proxy(harden({}), {
132
+ get: (_t, method, _rx) => {
133
+ const boundMethod = (...args) =>
134
+ queueAndRun(
135
+ () => controller.queueToVatObject(presence, method, args),
136
+ true,
137
+ );
138
+ return harden(boundMethod);
139
+ },
140
+ }),
141
+ get: presence =>
142
+ new Proxy(harden({}), {
143
+ get: (_t, pathElement, _rx) =>
144
+ queueAndRun(() =>
145
+ controller.queueToVatRoot('bootstrap', 'awaitVatObject', [
146
+ presence,
147
+ [pathElement],
148
+ ]),
149
+ ),
150
+ }),
151
+ },
154
152
  );
155
153
  return harden({ queueAndRun, EV });
156
154
  };