@agoric/swingset-vat 0.32.2 → 0.32.3-calypso-dev-84eb287.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.
Files changed (77) hide show
  1. package/README.md +2 -2
  2. package/package.json +45 -35
  3. package/src/controller/controller.js +64 -25
  4. package/src/controller/initializeKernel.js +5 -3
  5. package/src/controller/initializeSwingset.js +10 -12
  6. package/src/controller/startNodeSubprocess.js +35 -0
  7. package/src/controller/startXSnap.js +14 -5
  8. package/src/devices/bundle/device-bundle.js +1 -0
  9. package/src/devices/lib/deviceTools.js +1 -1
  10. package/src/devices/mailbox/device-mailbox.js +2 -2
  11. package/src/devices/mailbox/mailbox.js +6 -6
  12. package/src/devices/plugin/device-plugin.js +3 -3
  13. package/src/devices/timer/device-timer.js +3 -3
  14. package/src/devices/vat-admin/device-vat-admin.js +8 -1
  15. package/src/kernel/deviceManager.js +1 -1
  16. package/src/kernel/deviceSlots.js +1 -1
  17. package/src/kernel/kernel.js +43 -30
  18. package/src/kernel/kernelQueue.js +5 -3
  19. package/src/kernel/kernelSyscall.js +0 -2
  20. package/src/kernel/notifyTermination.js +1 -1
  21. package/src/kernel/slogger.js +4 -0
  22. package/src/kernel/state/kernelKeeper.js +15 -8
  23. package/src/kernel/state/storageHelper.js +15 -1
  24. package/src/kernel/state/vatKeeper.js +3 -2
  25. package/src/kernel/vat-admin-hooks.js +1 -1
  26. package/src/kernel/vat-loader/manager-factory.js +18 -0
  27. package/src/kernel/vat-loader/manager-helper.js +6 -6
  28. package/src/kernel/vat-loader/manager-local.js +3 -2
  29. package/src/kernel/vat-loader/manager-subprocess-node.js +120 -0
  30. package/src/kernel/vat-loader/manager-subprocess-xsnap.js +22 -21
  31. package/src/kernel/vat-loader/types.js +2 -0
  32. package/src/kernel/vat-loader/vat-loader.js +1 -1
  33. package/src/kernel/vat-warehouse.js +18 -21
  34. package/src/kernel/vatTranslator.js +17 -15
  35. package/src/lib/capdata.js +1 -2
  36. package/src/lib/kdebug.js +2 -1
  37. package/src/lib/makeUndeliverableError.js +1 -1
  38. package/src/lib/recordVatOptions.js +6 -1
  39. package/src/lib/workerOptions.js +21 -7
  40. package/src/supervisors/subprocess-node/supervisor-subprocess-node.js +209 -0
  41. package/src/supervisors/supervisor-helper.js +4 -4
  42. package/src/typeGuards.js +7 -2
  43. package/src/types-ambient.js +4 -117
  44. package/src/types-external.js +29 -19
  45. package/src/types-internal.js +5 -4
  46. package/src/vats/comms/controller.js +1 -1
  47. package/src/vats/comms/delivery.js +1 -1
  48. package/src/vats/comms/dispatch.js +5 -6
  49. package/src/vats/plugin-manager.js +1 -3
  50. package/src/vats/timer/vat-timer.js +20 -11
  51. package/src/vats/vat-admin/vat-vat-admin.js +8 -8
  52. package/src/vats/vattp/vat-vattp.js +0 -2
  53. package/tools/baggage-check.js +205 -0
  54. package/tools/bootstrap-relay.js +111 -0
  55. package/tools/bundleTool.js +5 -5
  56. package/tools/dvo-test-harness.js +1 -2
  57. package/tools/manual-timer.js +3 -3
  58. package/tools/prepare-test-env-ava.js +1 -6
  59. package/tools/run-utils.js +151 -0
  60. package/CHANGELOG.md +0 -1677
  61. package/exported.js +0 -0
  62. package/src/lib/kmarshal.js +0 -97
  63. package/src/lib/netstring.js +0 -119
  64. package/src/lib-nodejs/engine-gc.js +0 -22
  65. package/src/lib-nodejs/gc-and-finalize.js +0 -91
  66. package/src/lib-nodejs/waitUntilQuiescent.js +0 -18
  67. package/src/lib-nodejs/worker-protocol.js +0 -56
  68. package/src/vats/network/bytes.js +0 -63
  69. package/src/vats/network/index.js +0 -4
  70. package/src/vats/network/multiaddr.js +0 -65
  71. package/src/vats/network/network.js +0 -610
  72. package/src/vats/network/router.js +0 -115
  73. package/src/vats/network/types.js +0 -85
  74. package/src/vats/timer/types.js +0 -2
  75. package/tools/install-ses-debug.js +0 -6
  76. package/tools/passableEncoding.js +0 -81
  77. package/tools/prepare-test-env.js +0 -49
package/README.md CHANGED
@@ -15,7 +15,7 @@ this is insufficient to provide persistence across restarts.
15
15
 
16
16
  More docs are in the works. For now, try:
17
17
 
18
- ```
18
+ ```console
19
19
  $ npm install
20
20
  $ npm test
21
21
  $ bin/vat run demo/encouragementBot
@@ -26,7 +26,7 @@ expected to stabilize for a while.
26
26
 
27
27
  ## REPL Shell
28
28
 
29
- ```
29
+ ```console
30
30
  $ bin/vat shell demo/encouragementBot
31
31
  vat>
32
32
  ```
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@agoric/swingset-vat",
3
- "version": "0.32.2",
3
+ "version": "0.32.3-calypso-dev-84eb287.0+84eb287",
4
4
  "description": "Vat/Container Launcher",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
7
7
  "engines": {
8
- "node": ">=14.15.0"
8
+ "node": "^18.12 || ^20.9"
9
9
  },
10
10
  "bin": {
11
11
  "vat": "bin/vat"
@@ -14,53 +14,57 @@
14
14
  "build": "exit 0",
15
15
  "test": "ava",
16
16
  "test:xs": "SWINGSET_WORKER_TYPE=xs-worker ava",
17
- "test:xs-worker": "ava test/workers/test-worker.js -m 'xsnap vat manager'",
17
+ "test:xs-worker": "ava test/workers -m 'xsnap vat manager'",
18
18
  "lint-fix": "yarn lint:eslint --fix",
19
19
  "lint": "run-s --continue-on-error lint:*",
20
- "lint:types": "tsc -p jsconfig.json",
20
+ "lint:types": "tsc",
21
21
  "lint:eslint": "eslint ."
22
22
  },
23
23
  "devDependencies": {
24
- "@types/better-sqlite3": "^7.5.0",
24
+ "@types/better-sqlite3": "^7.6.9",
25
25
  "@types/microtime": "^2.1.0",
26
26
  "@types/tmp": "^0.2.0",
27
- "better-sqlite3": "^8.2.0",
28
- "yargs-parser": "^21.1.1"
27
+ "@types/yargs-parser": "^21.0.0"
29
28
  },
30
29
  "dependencies": {
31
- "@agoric/assert": "^0.6.0",
32
- "@agoric/internal": "^0.3.2",
33
- "@agoric/store": "^0.9.2",
34
- "@agoric/swing-store": "^0.9.1",
35
- "@agoric/swingset-liveslots": "^0.10.2",
36
- "@agoric/swingset-xsnap-supervisor": "^0.10.2",
37
- "@agoric/time": "^0.3.2",
38
- "@agoric/vat-data": "^0.5.2",
39
- "@agoric/xsnap": "^0.14.2",
40
- "@agoric/xsnap-lockdown": "^0.14.0",
41
- "@endo/base64": "^0.2.31",
42
- "@endo/bundle-source": "^2.5.1",
43
- "@endo/captp": "^3.1.1",
44
- "@endo/check-bundle": "^0.2.18",
45
- "@endo/compartment-mapper": "^0.8.4",
46
- "@endo/eventual-send": "^0.17.2",
47
- "@endo/far": "^0.2.18",
48
- "@endo/import-bundle": "^0.3.4",
49
- "@endo/init": "^0.5.56",
50
- "@endo/marshal": "^0.8.5",
51
- "@endo/nat": "^4.1.27",
52
- "@endo/promise-kit": "^0.2.56",
53
- "@endo/zip": "^0.2.31",
30
+ "@agoric/assert": "0.6.1-calypso-dev-84eb287.0+84eb287",
31
+ "@agoric/internal": "0.3.3-calypso-dev-84eb287.0+84eb287",
32
+ "@agoric/kmarshal": "0.1.1-calypso-dev-84eb287.0+84eb287",
33
+ "@agoric/store": "0.9.3-calypso-dev-84eb287.0+84eb287",
34
+ "@agoric/swing-store": "0.9.2-calypso-dev-84eb287.0+84eb287",
35
+ "@agoric/swingset-liveslots": "0.10.3-calypso-dev-84eb287.0+84eb287",
36
+ "@agoric/swingset-xsnap-supervisor": "0.10.3-calypso-dev-84eb287.0+84eb287",
37
+ "@agoric/time": "0.3.3-calypso-dev-84eb287.0+84eb287",
38
+ "@agoric/vat-data": "0.5.3-calypso-dev-84eb287.0+84eb287",
39
+ "@agoric/xsnap": "0.14.3-calypso-dev-84eb287.0+84eb287",
40
+ "@agoric/xsnap-lockdown": "0.14.1-calypso-dev-84eb287.0+84eb287",
41
+ "@endo/base64": "^1.0.5",
42
+ "@endo/bundle-source": "^3.2.3",
43
+ "@endo/captp": "^4.2.0",
44
+ "@endo/check-bundle": "^1.0.7",
45
+ "@endo/compartment-mapper": "^1.1.5",
46
+ "@endo/eventual-send": "^1.2.2",
47
+ "@endo/far": "^1.1.2",
48
+ "@endo/import-bundle": "^1.1.2",
49
+ "@endo/init": "^1.1.2",
50
+ "@endo/marshal": "^1.5.0",
51
+ "@endo/nat": "^5.0.7",
52
+ "@endo/patterns": "^1.4.0",
53
+ "@endo/promise-kit": "^1.1.2",
54
+ "@endo/ses-ava": "^1.2.2",
55
+ "@endo/stream": "^1.2.2",
56
+ "@endo/zip": "^1.0.5",
54
57
  "ansi-styles": "^6.2.1",
55
58
  "anylogger": "^0.21.0",
59
+ "better-sqlite3": "^9.1.1",
56
60
  "import-meta-resolve": "^2.2.1",
57
61
  "microtime": "^3.1.0",
58
62
  "semver": "^6.3.0",
59
- "tmp": "^0.2.1"
63
+ "tmp": "^0.2.1",
64
+ "yargs-parser": "^21.1.1"
60
65
  },
61
66
  "peerDependencies": {
62
- "@endo/ses-ava": "^0.2.40",
63
- "ava": "^5.2.0"
67
+ "ava": "^5.3.0"
64
68
  },
65
69
  "files": [
66
70
  "bin/vat",
@@ -84,7 +88,10 @@
84
88
  },
85
89
  "ava": {
86
90
  "files": [
87
- "test/**/test-*.js"
91
+ "test/**/*.test.*"
92
+ ],
93
+ "require": [
94
+ "@endo/init/debug.js"
88
95
  ],
89
96
  "timeout": "20m",
90
97
  "workerThreads": false
@@ -92,5 +99,8 @@
92
99
  "publishConfig": {
93
100
  "access": "public"
94
101
  },
95
- "gitHead": "b66bf7c881ae462fcb617cd6e8d41b5c40ec58ef"
102
+ "typeCoverage": {
103
+ "atLeast": 75.02
104
+ },
105
+ "gitHead": "84eb287915c8255d68e845a9b6e10c790f0d54cb"
96
106
  }
@@ -1,5 +1,4 @@
1
1
  /* global globalThis, WeakRef, FinalizationRegistry */
2
- /* eslint-disable @typescript-eslint/prefer-ts-expect-error -- https://github.com/Agoric/agoric-sdk/issues/4620 */
3
2
 
4
3
  import process from 'process';
5
4
  import crypto from 'crypto';
@@ -10,15 +9,17 @@ import { tmpName } from 'tmp';
10
9
  import anylogger from 'anylogger';
11
10
  import microtime from 'microtime';
12
11
 
13
- import { assert, Fail, q } from '@agoric/assert';
12
+ import { assert, Fail } from '@agoric/assert';
14
13
  import { importBundle } from '@endo/import-bundle';
15
14
  import { initSwingStore } from '@agoric/swing-store';
16
15
 
16
+ import { mustMatch, M } from '@endo/patterns';
17
17
  import { checkBundle } from '@endo/check-bundle/lite.js';
18
- import engineGC from '../lib-nodejs/engine-gc.js';
19
- import { waitUntilQuiescent } from '../lib-nodejs/waitUntilQuiescent.js';
20
- import { makeGcAndFinalize } from '../lib-nodejs/gc-and-finalize.js';
21
- import { kslot } from '../lib/kmarshal.js';
18
+ import engineGC from '@agoric/internal/src/lib-nodejs/engine-gc.js';
19
+ import { startSubprocessWorker } from '@agoric/internal/src/lib-nodejs/spawnSubprocessWorker.js';
20
+ import { waitUntilQuiescent } from '@agoric/internal/src/lib-nodejs/waitUntilQuiescent.js';
21
+ import { makeGcAndFinalize } from '@agoric/internal/src/lib-nodejs/gc-and-finalize.js';
22
+ import { kslot, krefOf } from '@agoric/kmarshal';
22
23
  import { insistStorageAPI } from '../lib/storageAPI.js';
23
24
  import {
24
25
  buildKernelBundle,
@@ -30,6 +31,13 @@ import {
30
31
  makeXsnapBundleData,
31
32
  } from './bundle-handler.js';
32
33
  import { makeStartXSnap } from './startXSnap.js';
34
+ import { makeStartSubprocessWorkerNode } from './startNodeSubprocess.js';
35
+
36
+ const endoZipBase64Sha512Shape = harden({
37
+ moduleFormat: 'endoZipBase64',
38
+ endoZipBase64: M.string(harden({ stringLengthLimit: Infinity })),
39
+ endoZipBase64Sha512: M.string(),
40
+ });
33
41
 
34
42
  /** @param {Uint8Array} bytes */
35
43
  export function computeSha512(bytes) {
@@ -94,6 +102,8 @@ function unhandledRejectionHandler(e, pr) {
94
102
  * kernelBundle?: Bundle
95
103
  * xsnapBundleData?: ReturnType<import('./bundle-handler.js').makeXsnapBundleData>,
96
104
  * bundleHandler?: import('./bundle-handler.js').BundleHandler,
105
+ * profileVats?: string[],
106
+ * debugVats?: string[],
97
107
  * }} runtimeOptions
98
108
  */
99
109
  export async function makeSwingsetController(
@@ -117,6 +127,8 @@ export async function makeSwingsetController(
117
127
  warehousePolicy = {},
118
128
  overrideVatManagerOptions = {},
119
129
  xsnapBundleData = makeXsnapBundleData(),
130
+ profileVats = [],
131
+ debugVats = [],
120
132
  } = runtimeOptions;
121
133
  const {
122
134
  bundleHandler = makeWorkerBundleHandler(
@@ -137,7 +149,14 @@ export async function makeSwingsetController(
137
149
  tmpName,
138
150
  debug: !!env.XSNAP_DEBUG,
139
151
  workerTraceRootPath: env.XSNAP_TEST_RECORD,
152
+ profileVats,
153
+ debugVats,
140
154
  });
155
+ const startSubprocessWorkerNode = makeStartSubprocessWorkerNode(
156
+ startSubprocessWorker,
157
+ profileVats,
158
+ debugVats,
159
+ );
141
160
 
142
161
  function writeSlogObject(obj) {
143
162
  if (!slogSender) {
@@ -157,7 +176,6 @@ export async function makeSwingsetController(
157
176
  slogSender(timedObj);
158
177
  }
159
178
 
160
- // eslint-disable-next-line no-shadow
161
179
  const console = makeConsole(`${debugPrefix}SwingSet:controller`);
162
180
  // We can harden this 'console' because it's new, but if we were using the
163
181
  // original 'console' object (which has a unique prototype), we'd have to
@@ -168,7 +186,7 @@ export async function makeSwingsetController(
168
186
  writeSlogObject({ type: 'kernel-init-start' });
169
187
 
170
188
  writeSlogObject({ type: 'bundle-kernel-start' });
171
- // eslint-disable-next-line @jessie.js/no-nested-await
189
+ await null;
172
190
  const { kernelBundle = await buildKernelBundle() } = runtimeOptions;
173
191
  writeSlogObject({ type: 'bundle-kernel-finish' });
174
192
 
@@ -193,7 +211,8 @@ export async function makeSwingsetController(
193
211
  filePrefix: 'kernel/...',
194
212
  endowments: {
195
213
  console: makeConsole(`${debugPrefix}SwingSet:kernel`),
196
- assert,
214
+ // See https://github.com/Agoric/agoric-sdk/issues/9515
215
+ assert: globalThis.assert,
197
216
  require: kernelRequire,
198
217
  URL: globalThis.Base64, // Unavailable only on XSnap
199
218
  Base64: globalThis.Base64, // Available only on XSnap
@@ -211,6 +230,7 @@ export async function makeSwingsetController(
211
230
  debugPrefix,
212
231
  vatEndowments,
213
232
  makeConsole,
233
+ startSubprocessWorkerNode,
214
234
  startXSnap,
215
235
  slogCallbacks,
216
236
  writeSlogObject,
@@ -225,7 +245,7 @@ export async function makeSwingsetController(
225
245
  warehousePolicy,
226
246
  overrideVatManagerOptions,
227
247
  };
228
- /** @type { ReturnType<typeof import('../kernel').default> } */
248
+ /** @type { ReturnType<typeof import('../kernel/kernel.js').default> } */
229
249
  const kernel = buildKernel(
230
250
  kernelEndowments,
231
251
  deviceEndowments,
@@ -252,21 +272,11 @@ export async function makeSwingsetController(
252
272
  * @param {BundleID} [allegedBundleID]
253
273
  * @returns {Promise<BundleID>}
254
274
  */
255
- async function validateAndInstallBundle(bundle, allegedBundleID) {
275
+ async function validateAndInstallBundle(bundle, allegedBundleID = undefined) {
256
276
  // TODO The following assertion may be removed when checkBundle subsumes
257
277
  // the responsibility to verify the permanence of a bundle's properties.
258
278
  // https://github.com/endojs/endo/issues/1106
259
-
260
- Object.values(Object.getOwnPropertyDescriptors(bundle)).every(
261
- ({ value, get, writable, configurable }) =>
262
- typeof value === 'string' &&
263
- get === undefined &&
264
- // @ts-ignore `isFake` purposely omitted from type
265
- (harden.isFake || (writable === false && configurable === false)),
266
- ) ||
267
- Fail`Bundle with alleged ID ${q(
268
- allegedBundleID,
269
- )} must be a frozen object with only string value properties, no accessors`;
279
+ mustMatch(bundle, endoZipBase64Sha512Shape);
270
280
  await checkBundle(bundle, computeSha512, allegedBundleID);
271
281
  const { endoZipBase64Sha512 } = bundle;
272
282
  assert.typeof(endoZipBase64Sha512, 'string');
@@ -316,6 +326,10 @@ export async function makeSwingsetController(
316
326
  return kernel.shutdown();
317
327
  },
318
328
 
329
+ reapAllVats() {
330
+ kernel.reapAllVats();
331
+ },
332
+
319
333
  changeKernelOptions(options) {
320
334
  kernel.changeKernelOptions(options);
321
335
  },
@@ -357,6 +371,7 @@ export async function makeSwingsetController(
357
371
  kernelStorage.emitCrankHashes();
358
372
  return result;
359
373
  },
374
+
360
375
  vatNameToID(vatName) {
361
376
  return kernel.vatNameToID(vatName);
362
377
  },
@@ -368,13 +383,15 @@ export async function makeSwingsetController(
368
383
  * Queue a method call into the named vat
369
384
  *
370
385
  * @param {string} vatName
371
- * @param {string} method
386
+ * @param {string|symbol} method
372
387
  * @param {unknown[]} args
373
388
  * @param {ResolutionPolicy} resultPolicy
374
389
  */
375
390
  queueToVatRoot(vatName, method, args = [], resultPolicy = 'ignore') {
376
391
  const vatID = kernel.vatNameToID(vatName);
377
- assert.typeof(method, 'string');
392
+ if (typeof method !== 'symbol') {
393
+ assert.typeof(method, 'string');
394
+ }
378
395
  const kref = kernel.getRootObject(vatID);
379
396
  const kpid = kernel.queueToKref(kref, method, args, resultPolicy);
380
397
  if (kpid) {
@@ -384,6 +401,28 @@ export async function makeSwingsetController(
384
401
  return kpid;
385
402
  },
386
403
 
404
+ /**
405
+ * Queue a method call to an object represented by a kmarshal token
406
+ *
407
+ * @param {any} target
408
+ * @param {string|symbol} method
409
+ * @param {unknown[]} args
410
+ * @param {ResolutionPolicy} resultPolicy
411
+ */
412
+ queueToVatObject(target, method, args = [], resultPolicy = 'ignore') {
413
+ const targetKref = krefOf(target);
414
+ assert.typeof(targetKref, 'string');
415
+ if (typeof method !== 'symbol') {
416
+ assert.typeof(method, 'string');
417
+ }
418
+ const kpid = kernel.queueToKref(targetKref, method, args, resultPolicy);
419
+ if (kpid) {
420
+ kernel.kpRegisterInterest(kpid);
421
+ }
422
+ kernelStorage.emitCrankHashes();
423
+ return kpid;
424
+ },
425
+
387
426
  upgradeStaticVat(vatName, shouldPauseFirst, bundleID, options = {}) {
388
427
  const vatID = kernel.vatNameToID(vatName);
389
428
  let pauseTarget = null;
@@ -473,8 +512,8 @@ export async function buildVatController(
473
512
  };
474
513
  const initializationOptions = { verbose, kernelBundles };
475
514
  let bootstrapResult;
515
+ await null;
476
516
  if (!swingsetIsInitialized(kernelStorage)) {
477
- // eslint-disable-next-line @jessie.js/no-nested-await
478
517
  bootstrapResult = await initializeSwingset(
479
518
  config,
480
519
  argv,
@@ -3,9 +3,9 @@
3
3
  import { makeMarshal } from '@endo/marshal';
4
4
  import { Far } from '@endo/far';
5
5
  import { assert, Fail } from '@agoric/assert';
6
+ import { kser, kunser } from '@agoric/kmarshal';
6
7
  import { assertKnownOptions } from '../lib/assertOptions.js';
7
8
  import { insistVatID } from '../lib/id.js';
8
- import { kser, kunser } from '../lib/kmarshal.js';
9
9
  import { makeVatSlot } from '../lib/parseVatSlots.js';
10
10
  import { insistStorageAPI } from '../lib/storageAPI.js';
11
11
  import { makeVatOptionRecorder } from '../lib/recordVatOptions.js';
@@ -63,6 +63,7 @@ export async function initializeKernel(config, kernelStorage, options = {}) {
63
63
  let gotVatAdminRootKref;
64
64
 
65
65
  // generate the genesis vats
66
+ await null;
66
67
  if (config.vats) {
67
68
  for (const name of Object.keys(config.vats)) {
68
69
  const {
@@ -85,13 +86,13 @@ export async function initializeKernel(config, kernelStorage, options = {}) {
85
86
  'useTranscript',
86
87
  'critical',
87
88
  'reapInterval',
89
+ 'nodeOptions',
88
90
  ]);
89
91
  const vatID = kernelKeeper.allocateVatIDForNameIfNeeded(name);
90
92
  logStartup(`assigned VatID ${vatID} for genesis vat ${name}`);
91
93
 
92
94
  const source = { bundleID };
93
95
  const staticOptions = { name, ...creationOptions };
94
- // eslint-disable-next-line @jessie.js/no-nested-await,no-await-in-loop
95
96
  await optionRecorder.recordStatic(vatID, source, staticOptions);
96
97
 
97
98
  kernelKeeper.addToAcceptanceQueue(
@@ -209,8 +210,9 @@ export async function initializeKernel(config, kernelStorage, options = {}) {
209
210
  serializeBodyFormat: 'smallcaps',
210
211
  // TODO Temporary hack.
211
212
  // See https://github.com/Agoric/agoric-sdk/issues/2780
212
- errorIdNum: 60000,
213
+ errorIdNum: 60_000,
213
214
  });
215
+ // @ts-expect-error xxx
214
216
  const args = kunser(m.serialize(harden([vatObj0s, deviceObj0s])));
215
217
  const rootKref = exportRootObject(kernelKeeper, bootstrapVatID);
216
218
  const resultKpid = queueToKref(rootKref, 'bootstrap', args, 'panic');
@@ -34,9 +34,10 @@ const { keys, values, fromEntries } = Object;
34
34
  * @returns {Promise<Record<string, V>>}
35
35
  * @template V
36
36
  */
37
- const allValues = async obj =>
38
- // eslint-disable-next-line @jessie.js/no-nested-await
39
- fromEntries(zip(keys(obj), await Promise.all(values(obj))));
37
+ const allValues = async obj => {
38
+ const vs = await Promise.all(values(obj));
39
+ return fromEntries(zip(keys(obj), vs));
40
+ };
40
41
 
41
42
  const bundleRelative = rel =>
42
43
  bundleSource(new URL(rel, import.meta.url).pathname);
@@ -127,7 +128,7 @@ export function loadBasedir(basedir, options = {}) {
127
128
  const vats = {};
128
129
  const subs = fs.readdirSync(basedir, { withFileTypes: true });
129
130
  subs.sort(byName);
130
- subs.forEach(dirent => {
131
+ for (const dirent of subs) {
131
132
  if (
132
133
  dirent.name.startsWith('vat-') &&
133
134
  dirent.name.endsWith('.js') &&
@@ -137,7 +138,7 @@ export function loadBasedir(basedir, options = {}) {
137
138
  const vatSourcePath = path.resolve(basedir, dirent.name);
138
139
  vats[name] = { sourceSpec: vatSourcePath, parameters: {} };
139
140
  }
140
- });
141
+ }
141
142
  /** @type {string | void} */
142
143
  let bootstrapPath = path.resolve(basedir, 'bootstrap.js');
143
144
  try {
@@ -172,8 +173,8 @@ export function loadBasedir(basedir, options = {}) {
172
173
  * determined.
173
174
  */
174
175
  async function resolveSpecFromConfig(referrer, specPath) {
176
+ await null;
175
177
  try {
176
- // eslint-disable-next-line @jessie.js/no-nested-await
177
178
  return new URL(await resolveModuleSpecifier(specPath, referrer)).pathname;
178
179
  } catch (e) {
179
180
  if (e.code !== 'MODULE_NOT_FOUND' && e.code !== 'ERR_MODULE_NOT_FOUND') {
@@ -233,15 +234,11 @@ async function normalizeConfigDescriptor(desc, referrer, expectParameters) {
233
234
  * invalid.
234
235
  */
235
236
  export async function loadSwingsetConfigFile(configPath) {
237
+ await null;
236
238
  try {
237
239
  const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
238
- const referrer = new URL(
239
- configPath,
240
- `file:///${process.cwd()}/`,
241
- ).toString();
242
- // eslint-disable-next-line @jessie.js/no-nested-await
240
+ const referrer = new URL(configPath, `file://${process.cwd()}/`).toString();
243
241
  await normalizeConfigDescriptor(config.vats, referrer, true);
244
- // eslint-disable-next-line @jessie.js/no-nested-await
245
242
  await normalizeConfigDescriptor(config.bundles, referrer, false);
246
243
  // await normalizeConfigDescriptor(config.devices, referrer, true); // TODO: represent devices
247
244
  config.bootstrap || Fail`no designated bootstrap vat in ${configPath}`;
@@ -249,6 +246,7 @@ export async function loadSwingsetConfigFile(configPath) {
249
246
  Fail`bootstrap vat ${config.bootstrap} not found in ${configPath}`;
250
247
  return config;
251
248
  } catch (e) {
249
+ console.error(`failed to load ${configPath}`);
252
250
  if (e.code === 'ENOENT') {
253
251
  return null;
254
252
  } else {
@@ -0,0 +1,35 @@
1
+ import process from 'process';
2
+
3
+ export function makeStartSubprocessWorkerNode(
4
+ startSubprocessWorker,
5
+ profileVats,
6
+ debugVats,
7
+ ) {
8
+ // launch a worker in a subprocess (which runs Node.js)
9
+ function startSubprocessWorkerNode(nameDisplayArg, vatID, nodeOptions) {
10
+ const supervisorCodePath = new URL(
11
+ '../supervisors/subprocess-node/supervisor-subprocess-node.js',
12
+ import.meta.url,
13
+ ).pathname;
14
+ const args = nodeOptions ? [...nodeOptions] : [];
15
+ if (profileVats.includes(vatID)) {
16
+ args.push('--cpu-prof');
17
+ args.push('--cpu-prof-interval');
18
+ args.push('1');
19
+ args.push('--cpu-prof-name');
20
+ // cf. https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282
21
+ nameDisplayArg = nameDisplayArg
22
+ .replaceAll(':', '-')
23
+ .replaceAll(/[^a-z0-9._-]/gi, '_');
24
+ args.push(`CPU.${nameDisplayArg}.cpuprofile`);
25
+ }
26
+ if (debugVats.includes(vatID)) {
27
+ args.push('--inspect-brk');
28
+ }
29
+ args.push(supervisorCodePath);
30
+ args.push(nameDisplayArg);
31
+ return startSubprocessWorker(process.execPath, args);
32
+ }
33
+
34
+ return startSubprocessWorkerNode;
35
+ }
@@ -41,6 +41,8 @@ const NETSTRING_MAX_CHUNK_SIZE = 12_000_000;
41
41
  * debug?: boolean,
42
42
  * workerTraceRootPath?: string,
43
43
  * overrideBundles?: import('../types-external.js').Bundle[],
44
+ * profileVats?: string[],
45
+ * debugVats?: string[],
44
46
  * }} options
45
47
  */
46
48
  export function makeStartXSnap(options) {
@@ -54,6 +56,8 @@ export function makeStartXSnap(options) {
54
56
  snapStore,
55
57
  workerTraceRootPath,
56
58
  overrideBundles,
59
+ profileVats = [],
60
+ debugVats = [],
57
61
  debug = false,
58
62
  } = options;
59
63
 
@@ -77,7 +81,7 @@ export function makeStartXSnap(options) {
77
81
  };
78
82
  }
79
83
 
80
- /** @type { import('@agoric/xsnap/src/xsnap').XSnapOptions } */
84
+ /** @type { import('@agoric/xsnap/src/xsnap.js').XSnapOptions } */
81
85
  const xsnapOpts = {
82
86
  os: osType(),
83
87
  fs: { ...fs, ...fs.promises, tmpName },
@@ -123,6 +127,7 @@ export function makeStartXSnap(options) {
123
127
  * @param {string} name
124
128
  * @param {object} details
125
129
  * @param {import('../types-external.js').BundleID[]} details.bundleIDs
130
+ * @param {string} details.vatID
126
131
  * @param {(request: Uint8Array) => Promise<Uint8Array>} details.handleCommand
127
132
  * @param {boolean} [details.metered]
128
133
  * @param {StartXSnapInitDetails} [details.init]
@@ -131,15 +136,22 @@ export function makeStartXSnap(options) {
131
136
  name,
132
137
  {
133
138
  bundleIDs,
139
+ vatID,
134
140
  handleCommand,
135
141
  metered,
136
142
  init: initDetails = { from: 'bundles' },
137
143
  },
138
144
  ) {
145
+ if (profileVats.includes(vatID)) {
146
+ Fail`startXSnap: not yet supporting profiling for vat ${vatID}`;
147
+ }
148
+ if (debugVats.includes(vatID)) {
149
+ Fail`startXSnap: not yet supporting debugging for vat ${vatID}`;
150
+ }
139
151
  const meterOpts = metered ? {} : { meteringLimit: 0 };
140
152
  const snapshotLoadOpts = getSnapshotLoadOptions(initDetails);
153
+ await null;
141
154
  if (snapshotLoadOpts) {
142
- // eslint-disable-next-line @jessie.js/no-nested-await
143
155
  const xs = await doXSnap({
144
156
  name,
145
157
  handleCommand,
@@ -147,7 +159,6 @@ export function makeStartXSnap(options) {
147
159
  ...meterOpts,
148
160
  ...xsnapOpts,
149
161
  });
150
- // eslint-disable-next-line @jessie.js/no-nested-await
151
162
  await xs.isReady();
152
163
  return xs;
153
164
  }
@@ -164,7 +175,6 @@ export function makeStartXSnap(options) {
164
175
  bundles = overrideBundles; // ignore the usual bundles
165
176
  } else {
166
177
  const bundlePs = bundleIDs.map(id => bundleHandler.getBundle(id));
167
- // eslint-disable-next-line @jessie.js/no-nested-await
168
178
  bundles = await Promise.all(bundlePs);
169
179
  }
170
180
 
@@ -173,7 +183,6 @@ export function makeStartXSnap(options) {
173
183
  if (moduleFormat !== 'getExport' && moduleFormat !== 'nestedEvaluate') {
174
184
  throw Fail`unexpected moduleFormat: ${moduleFormat}`;
175
185
  }
176
- // eslint-disable-next-line no-await-in-loop, @jessie.js/no-nested-await
177
186
  await worker.evaluate(`(${bundle.source}\n)()`.trim());
178
187
  }
179
188
  return worker;
@@ -103,6 +103,7 @@ export function buildDevice(tools, endowments) {
103
103
 
104
104
  const dispatch = {
105
105
  invoke: (dnid, method, argsCapdata) => {
106
+ /** @type {any} */
106
107
  const args = unserialize(argsCapdata);
107
108
 
108
109
  if (dnid === ROOT) {
@@ -78,7 +78,7 @@ export function buildSerializationTools(syscall, deviceName) {
78
78
  serializeBodyFormat: 'smallcaps',
79
79
  // TODO Temporary hack.
80
80
  // See https://github.com/Agoric/agoric-sdk/issues/2780
81
- errorIdNum: 60000,
81
+ errorIdNum: 60_000,
82
82
  });
83
83
 
84
84
  // for invoke(), these will unserialize the arguments, and serialize the
@@ -16,10 +16,10 @@ export function buildRootDeviceNode(tools) {
16
16
  );
17
17
  }
18
18
  assert.typeof(peer, 'string');
19
- messages.forEach(m => {
19
+ for (const m of messages) {
20
20
  Nat(m[0]);
21
21
  assert.typeof(m[1], 'string');
22
- });
22
+ }
23
23
  Nat(ack);
24
24
  if (messages.length) {
25
25
  deliverInboundMessages(peer, harden(messages));
@@ -74,9 +74,9 @@ import { Fail } from '@agoric/assert';
74
74
 
75
75
  export function importMailbox(data, inout = {}) {
76
76
  const outbox = new Map();
77
- data.outbox.forEach(m => {
77
+ for (const m of data.outbox) {
78
78
  outbox.set(Nat(m[0]), m[1]);
79
- });
79
+ }
80
80
  inout.ack = Nat(data.ack);
81
81
  inout.outbox = outbox;
82
82
  return inout;
@@ -84,9 +84,9 @@ export function importMailbox(data, inout = {}) {
84
84
 
85
85
  export function exportMailbox(inout) {
86
86
  const messages = [];
87
- inout.outbox.forEach((body, msgnum) => {
87
+ for (const [msgnum, body] of inout.outbox) {
88
88
  messages.push([Number(msgnum), body]);
89
- });
89
+ }
90
90
  messages.sort((a, b) => a[0] - b[0]);
91
91
  return {
92
92
  ack: Number(inout.ack),
@@ -121,13 +121,13 @@ export function buildMailboxStateMap(state = harden(new Map())) {
121
121
 
122
122
  function exportToData() {
123
123
  const data = {};
124
- state.forEach((inout, peer) => {
124
+ for (const [peer, inout] of state.entries()) {
125
125
  const exported = exportMailbox(inout);
126
126
  data[peer] = {
127
127
  inboundAck: exported.ack,
128
128
  outbox: exported.outbox,
129
129
  };
130
- });
130
+ }
131
131
  return harden(data);
132
132
  }
133
133