@agoric/swingset-vat 0.32.3-upgrade-18-dev-6ddbef0.0 → 0.32.3-upgrade-19-dev-c605745.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.
- package/package.json +33 -34
- package/src/controller/controller.js +47 -44
- package/src/controller/initializeKernel.js +0 -3
- package/src/controller/initializeSwingset.js +86 -80
- package/src/controller/upgradeSwingset.js +50 -37
- package/src/devices/bridge/device-bridge.js +3 -2
- package/src/devices/lib/deviceTools.js +0 -1
- package/src/index.js +1 -0
- package/src/kernel/kernel.js +7 -10
- package/src/kernel/slogger.js +124 -121
- package/src/kernel/state/kernelKeeper.js +65 -59
- package/src/kernel/state/vatKeeper.js +64 -84
- package/src/kernel/vat-loader/manager-factory.js +26 -45
- package/src/kernel/vat-loader/manager-subprocess-xsnap.js +26 -2
- package/src/kernel/vat-loader/vat-loader.js +3 -3
- package/src/kernel/vat-warehouse.js +22 -16
- package/src/supervisors/subprocess-node/supervisor-subprocess-node.js +1 -0
- package/src/supervisors/supervisor-helper.js +9 -10
- package/src/typeGuards.js +22 -19
- package/src/types-external.js +39 -38
- package/src/types-internal.js +2 -3
- package/src/vats/comms/delivery.js +0 -2
- package/src/vats/comms/state.js +0 -4
- package/src/vats/timer/vat-timer.js +2 -2
- package/src/vats/vat-admin/vat-vat-admin.js +0 -4
- package/tools/baggage-check.js +0 -2
- package/tools/bootstrap-dvo-test.js +0 -1
- package/tools/bootstrap-relay.js +9 -0
- package/tools/bundleTool.js +5 -1
- package/tools/run-utils.js +63 -54
- package/tools/vat-puppet.js +111 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/swingset-vat",
|
|
3
|
-
"version": "0.32.3-upgrade-
|
|
3
|
+
"version": "0.32.3-upgrade-19-dev-c605745.0+c605745",
|
|
4
4
|
"description": "Vat/Container Launcher",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -27,44 +27,44 @@
|
|
|
27
27
|
"@types/yargs-parser": "^21.0.0"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@agoric/internal": "0.3.3-upgrade-
|
|
31
|
-
"@agoric/kmarshal": "0.1.1-upgrade-
|
|
32
|
-
"@agoric/store": "0.9.3-upgrade-
|
|
33
|
-
"@agoric/swing-store": "0.9.2-upgrade-
|
|
34
|
-
"@agoric/swingset-liveslots": "0.10.3-upgrade-
|
|
35
|
-
"@agoric/swingset-xsnap-supervisor": "0.10.3-upgrade-
|
|
36
|
-
"@agoric/time": "0.3.3-upgrade-
|
|
37
|
-
"@agoric/vat-data": "0.5.3-upgrade-
|
|
38
|
-
"@agoric/xsnap": "0.14.
|
|
39
|
-
"@
|
|
40
|
-
"@endo/
|
|
41
|
-
"@endo/
|
|
42
|
-
"@endo/
|
|
43
|
-
"@endo/
|
|
44
|
-
"@endo/
|
|
45
|
-
"@endo/
|
|
46
|
-
"@endo/
|
|
47
|
-
"@endo/
|
|
48
|
-
"@endo/
|
|
49
|
-
"@endo/
|
|
50
|
-
"@endo/
|
|
51
|
-
"@endo/
|
|
52
|
-
"@endo/
|
|
53
|
-
"@endo/
|
|
54
|
-
"@endo/
|
|
55
|
-
"@endo/
|
|
56
|
-
"@endo/
|
|
57
|
-
"@endo/zip": "^1.0.8",
|
|
30
|
+
"@agoric/internal": "0.3.3-upgrade-19-dev-c605745.0+c605745",
|
|
31
|
+
"@agoric/kmarshal": "0.1.1-upgrade-19-dev-c605745.0+c605745",
|
|
32
|
+
"@agoric/store": "0.9.3-upgrade-19-dev-c605745.0+c605745",
|
|
33
|
+
"@agoric/swing-store": "0.9.2-upgrade-19-dev-c605745.0+c605745",
|
|
34
|
+
"@agoric/swingset-liveslots": "0.10.3-upgrade-19-dev-c605745.0+c605745",
|
|
35
|
+
"@agoric/swingset-xsnap-supervisor": "0.10.3-upgrade-19-dev-c605745.0+c605745",
|
|
36
|
+
"@agoric/time": "0.3.3-upgrade-19-dev-c605745.0+c605745",
|
|
37
|
+
"@agoric/vat-data": "0.5.3-upgrade-19-dev-c605745.0+c605745",
|
|
38
|
+
"@agoric/xsnap-lockdown": "0.14.1-upgrade-19-dev-c605745.0+c605745",
|
|
39
|
+
"@endo/base64": "^1.0.9",
|
|
40
|
+
"@endo/bundle-source": "^3.5.1",
|
|
41
|
+
"@endo/captp": "^4.4.4",
|
|
42
|
+
"@endo/check-bundle": "^1.0.13",
|
|
43
|
+
"@endo/compartment-mapper": "^1.5.0",
|
|
44
|
+
"@endo/errors": "^1.2.9",
|
|
45
|
+
"@endo/eventual-send": "^1.3.0",
|
|
46
|
+
"@endo/far": "^1.1.10",
|
|
47
|
+
"@endo/import-bundle": "^1.3.3",
|
|
48
|
+
"@endo/init": "^1.1.8",
|
|
49
|
+
"@endo/marshal": "^1.6.3",
|
|
50
|
+
"@endo/nat": "^5.0.14",
|
|
51
|
+
"@endo/pass-style": "^1.4.8",
|
|
52
|
+
"@endo/patterns": "^1.4.8",
|
|
53
|
+
"@endo/promise-kit": "^1.1.9",
|
|
54
|
+
"@endo/ses-ava": "^1.2.9",
|
|
55
|
+
"@endo/stream": "^1.2.9",
|
|
56
|
+
"@endo/zip": "^1.0.9",
|
|
58
57
|
"ansi-styles": "^6.2.1",
|
|
59
58
|
"anylogger": "^0.21.0",
|
|
60
59
|
"better-sqlite3": "^9.1.1",
|
|
61
|
-
"import-meta-resolve": "^
|
|
60
|
+
"import-meta-resolve": "^4.1.0",
|
|
62
61
|
"microtime": "^3.1.0",
|
|
63
62
|
"semver": "^6.3.0",
|
|
64
63
|
"tmp": "^0.2.1",
|
|
65
64
|
"yargs-parser": "^21.1.1"
|
|
66
65
|
},
|
|
67
66
|
"peerDependencies": {
|
|
67
|
+
"@agoric/xsnap": "^0.14.2",
|
|
68
68
|
"ava": "^5.3.0"
|
|
69
69
|
},
|
|
70
70
|
"files": [
|
|
@@ -94,14 +94,13 @@
|
|
|
94
94
|
"require": [
|
|
95
95
|
"@endo/init/debug.js"
|
|
96
96
|
],
|
|
97
|
-
"timeout": "20m"
|
|
98
|
-
"workerThreads": false
|
|
97
|
+
"timeout": "20m"
|
|
99
98
|
},
|
|
100
99
|
"publishConfig": {
|
|
101
100
|
"access": "public"
|
|
102
101
|
},
|
|
103
102
|
"typeCoverage": {
|
|
104
|
-
"atLeast":
|
|
103
|
+
"atLeast": 76.28
|
|
105
104
|
},
|
|
106
|
-
"gitHead": "
|
|
105
|
+
"gitHead": "c605745ee6619292b51cec5fc0db0a25ff1b203c"
|
|
107
106
|
}
|
|
@@ -15,6 +15,8 @@ import { initSwingStore } from '@agoric/swing-store';
|
|
|
15
15
|
|
|
16
16
|
import { mustMatch, M } from '@endo/patterns';
|
|
17
17
|
import { checkBundle } from '@endo/check-bundle/lite.js';
|
|
18
|
+
import { deepCopyJsonable } from '@agoric/internal/src/js-utils.js';
|
|
19
|
+
import { makeLimitedConsole } from '@agoric/internal/src/ses-utils.js';
|
|
18
20
|
import engineGC from '@agoric/internal/src/lib-nodejs/engine-gc.js';
|
|
19
21
|
import { startSubprocessWorker } from '@agoric/internal/src/lib-nodejs/spawnSubprocessWorker.js';
|
|
20
22
|
import { waitUntilQuiescent } from '@agoric/internal/src/lib-nodejs/waitUntilQuiescent.js';
|
|
@@ -34,6 +36,10 @@ import {
|
|
|
34
36
|
import { makeStartXSnap } from './startXSnap.js';
|
|
35
37
|
import { makeStartSubprocessWorkerNode } from './startNodeSubprocess.js';
|
|
36
38
|
|
|
39
|
+
/**
|
|
40
|
+
* @import {EReturn} from '@endo/far';
|
|
41
|
+
*/
|
|
42
|
+
|
|
37
43
|
/**
|
|
38
44
|
* @typedef { import('../types-internal.js').VatID } VatID
|
|
39
45
|
*/
|
|
@@ -51,34 +57,32 @@ export function computeSha512(bytes) {
|
|
|
51
57
|
return hash.digest().toString('hex');
|
|
52
58
|
}
|
|
53
59
|
|
|
54
|
-
/**
|
|
55
|
-
function
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
let logger = tagToLogger.get(tag);
|
|
66
|
-
if (!logger) {
|
|
67
|
-
logger = anylogger(tag);
|
|
68
|
-
tagToLogger.set(tag, logger);
|
|
69
|
-
}
|
|
70
|
-
// Actually log the message.
|
|
71
|
-
return logger[level](...args);
|
|
72
|
-
};
|
|
73
|
-
} else {
|
|
74
|
-
const logger = anylogger(tagOrTagCreator);
|
|
75
|
-
makeLoggerForLevel = level => logger[level];
|
|
76
|
-
}
|
|
77
|
-
const cons = {};
|
|
78
|
-
for (const level of ['debug', 'log', 'info', 'warn', 'error']) {
|
|
79
|
-
cons[level] = makeLoggerForLevel(level);
|
|
60
|
+
/**
|
|
61
|
+
* Make logger functions from either a prefix string or a function that receives
|
|
62
|
+
* the first argument of a log-method invocation and returns a replacement that
|
|
63
|
+
* provides more detail for source identification.
|
|
64
|
+
*
|
|
65
|
+
* @param {string | ((originalSource: unknown) => string)} prefixer
|
|
66
|
+
*/
|
|
67
|
+
function makeConsole(prefixer) {
|
|
68
|
+
if (typeof prefixer !== 'function') {
|
|
69
|
+
const logger = anylogger(prefixer);
|
|
70
|
+
return makeLimitedConsole(level => logger[level]);
|
|
80
71
|
}
|
|
81
|
-
|
|
72
|
+
|
|
73
|
+
const prefixToLogger = new Map();
|
|
74
|
+
return makeLimitedConsole(level => {
|
|
75
|
+
return (source, ...args) => {
|
|
76
|
+
const prefix = prefixer(source);
|
|
77
|
+
let logger = prefixToLogger.get(prefix);
|
|
78
|
+
if (!logger) {
|
|
79
|
+
logger = anylogger(prefix);
|
|
80
|
+
prefixToLogger.set(prefix, logger);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return logger[level](...args);
|
|
84
|
+
};
|
|
85
|
+
});
|
|
82
86
|
}
|
|
83
87
|
|
|
84
88
|
/**
|
|
@@ -208,17 +212,23 @@ export async function makeSwingsetController(
|
|
|
208
212
|
process.on('unhandledRejection', unhandledRejectionHandler);
|
|
209
213
|
}
|
|
210
214
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
215
|
+
const kernelConsole = makeConsole(`${debugPrefix}SwingSet:kernel`);
|
|
216
|
+
const sloggingKernelConsole = makeLimitedConsole(level => {
|
|
217
|
+
return (...args) => {
|
|
218
|
+
kernelConsole[level](...args);
|
|
219
|
+
writeSlogObject({ type: 'console', source: 'kernel', args });
|
|
220
|
+
};
|
|
221
|
+
});
|
|
214
222
|
writeSlogObject({ type: 'import-kernel-start' });
|
|
215
223
|
const kernelNS = await importBundle(kernelBundle, {
|
|
216
224
|
filePrefix: 'kernel/...',
|
|
217
225
|
endowments: {
|
|
218
|
-
console:
|
|
226
|
+
console: sloggingKernelConsole,
|
|
219
227
|
// See https://github.com/Agoric/agoric-sdk/issues/9515
|
|
220
228
|
assert: globalThis.assert,
|
|
221
|
-
require:
|
|
229
|
+
require: harden(
|
|
230
|
+
what => Fail`kernelRequire unprepared to satisfy require(${what})`,
|
|
231
|
+
),
|
|
222
232
|
URL: globalThis.Base64, // Unavailable only on XSnap
|
|
223
233
|
Base64: globalThis.Base64, // Available only on XSnap
|
|
224
234
|
},
|
|
@@ -263,13 +273,6 @@ export async function makeSwingsetController(
|
|
|
263
273
|
|
|
264
274
|
await kernel.start();
|
|
265
275
|
|
|
266
|
-
/**
|
|
267
|
-
* @param {T} x
|
|
268
|
-
* @returns {T}
|
|
269
|
-
* @template T
|
|
270
|
-
*/
|
|
271
|
-
const defensiveCopy = x => JSON.parse(JSON.stringify(x));
|
|
272
|
-
|
|
273
276
|
/**
|
|
274
277
|
* Validate and install a code bundle.
|
|
275
278
|
*
|
|
@@ -304,7 +307,7 @@ export async function makeSwingsetController(
|
|
|
304
307
|
writeSlogObject,
|
|
305
308
|
|
|
306
309
|
dump() {
|
|
307
|
-
return
|
|
310
|
+
return deepCopyJsonable(kernel.dump());
|
|
308
311
|
},
|
|
309
312
|
|
|
310
313
|
verboseDebugMode(flag) {
|
|
@@ -340,11 +343,11 @@ export async function makeSwingsetController(
|
|
|
340
343
|
},
|
|
341
344
|
|
|
342
345
|
getStats() {
|
|
343
|
-
return
|
|
346
|
+
return deepCopyJsonable(kernel.getStats());
|
|
344
347
|
},
|
|
345
348
|
|
|
346
349
|
getStatus() {
|
|
347
|
-
return
|
|
350
|
+
return deepCopyJsonable(kernel.getStatus());
|
|
348
351
|
},
|
|
349
352
|
|
|
350
353
|
getActivityhash() {
|
|
@@ -483,7 +486,7 @@ export async function makeSwingsetController(
|
|
|
483
486
|
*
|
|
484
487
|
* The first `controller.run()` after this call will delete all
|
|
485
488
|
* the old vat's state at once, unless you use a
|
|
486
|
-
* [`runPolicy`](
|
|
489
|
+
* [`runPolicy`](../../docs/run-policy.md) to rate-limit cleanups.
|
|
487
490
|
*
|
|
488
491
|
* @param {VatID} vatID
|
|
489
492
|
* @param {SwingSetCapData} reasonCD
|
|
@@ -500,7 +503,7 @@ export async function makeSwingsetController(
|
|
|
500
503
|
|
|
501
504
|
return controller;
|
|
502
505
|
}
|
|
503
|
-
/** @typedef {
|
|
506
|
+
/** @typedef {EReturn<typeof makeSwingsetController>} SwingsetController */
|
|
504
507
|
|
|
505
508
|
/**
|
|
506
509
|
* NB: To be used only in tests. An app with this may not survive a reboot.
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/* eslint-disable no-use-before-define */
|
|
2
|
-
|
|
3
1
|
import { assert, Fail } from '@endo/errors';
|
|
4
2
|
import { makeMarshal } from '@endo/marshal';
|
|
5
3
|
import { Far } from '@endo/far';
|
|
@@ -102,7 +100,6 @@ export async function initializeKernel(config, kernelStorage, options = {}) {
|
|
|
102
100
|
// the VatManager, since it isn't available until the bundle is evaluated
|
|
103
101
|
assertKnownOptions(creationOptions, [
|
|
104
102
|
'enablePipelining',
|
|
105
|
-
'metered',
|
|
106
103
|
'managerType',
|
|
107
104
|
'enableDisavow',
|
|
108
105
|
'enableSetup',
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
|
|
5
|
-
import { assert, Fail } from '@endo/errors';
|
|
6
|
-
import { makeTracer } from '@agoric/internal';
|
|
5
|
+
import { assert, b, Fail } from '@endo/errors';
|
|
6
|
+
import { deepCopyJsonable, makeTracer } from '@agoric/internal';
|
|
7
7
|
import { mustMatch } from '@agoric/store';
|
|
8
8
|
import bundleSource from '@endo/bundle-source';
|
|
9
9
|
import { resolve as resolveModuleSpecifier } from 'import-meta-resolve';
|
|
@@ -86,16 +86,6 @@ export async function buildKernelBundles() {
|
|
|
86
86
|
return harden({ kernel: kernelBundle, ...vdBundles });
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
function byName(a, b) {
|
|
90
|
-
if (a.name < b.name) {
|
|
91
|
-
return -1;
|
|
92
|
-
}
|
|
93
|
-
if (a.name > b.name) {
|
|
94
|
-
return 1;
|
|
95
|
-
}
|
|
96
|
-
return 0;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
89
|
/**
|
|
100
90
|
* Scan a directory for files defining the vats to bootstrap for a swingset, and
|
|
101
91
|
* produce a swingset config object for what was found there. Looks for files
|
|
@@ -126,18 +116,18 @@ export function loadBasedir(basedir, options = {}) {
|
|
|
126
116
|
const { includeDevDependencies = false, bundleFormat = undefined } = options;
|
|
127
117
|
/** @type { SwingSetConfigDescriptor } */
|
|
128
118
|
const vats = {};
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
119
|
+
const rVatName = /^vat-(.*)\.js$/s;
|
|
120
|
+
const files = fs.readdirSync(basedir, { withFileTypes: true });
|
|
121
|
+
const vatFiles = files.flatMap(dirent => {
|
|
122
|
+
const file = dirent.name;
|
|
123
|
+
const m = rVatName.exec(file);
|
|
124
|
+
return m && dirent.isFile() ? [{ file, label: m[1] }] : [];
|
|
125
|
+
});
|
|
126
|
+
// eslint-disable-next-line no-shadow,no-nested-ternary
|
|
127
|
+
vatFiles.sort((a, b) => (a.label < b.label ? -1 : a.label > b.label ? 1 : 0));
|
|
128
|
+
for (const { file, label } of vatFiles) {
|
|
129
|
+
const vatSourcePath = path.resolve(basedir, file);
|
|
130
|
+
vats[label] = { sourceSpec: vatSourcePath, parameters: {} };
|
|
141
131
|
}
|
|
142
132
|
/** @type {string | void} */
|
|
143
133
|
let bootstrapPath = path.resolve(basedir, 'bootstrap.js');
|
|
@@ -185,37 +175,42 @@ async function resolveSpecFromConfig(referrer, specPath) {
|
|
|
185
175
|
}
|
|
186
176
|
|
|
187
177
|
/**
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
178
|
+
* Convert each entry in a config descriptor group (`vats`/`bundles`/etc.) to
|
|
179
|
+
* normal form: resolve each pathname to a context-insensitive absolute path and
|
|
180
|
+
* run any other appropriate fixup.
|
|
191
181
|
*
|
|
192
|
-
* @param {
|
|
193
|
-
* @param {
|
|
194
|
-
* config file
|
|
195
|
-
* @param {
|
|
196
|
-
*
|
|
182
|
+
* @param {SwingSetConfig} config
|
|
183
|
+
* @param {'vats' | 'bundles' | 'devices'} groupName
|
|
184
|
+
* @param {string | undefined} configPath of the containing config file
|
|
185
|
+
* @param {string} referrer URL
|
|
186
|
+
* @param {(entry: SwingSetConfigProperties, name?: string) => void} [fixupEntry]
|
|
187
|
+
* A function to call on each entry to e.g. add defaults for missing fields
|
|
188
|
+
* such as vat `parameters`.
|
|
197
189
|
*/
|
|
198
|
-
async function normalizeConfigDescriptor(
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
190
|
+
async function normalizeConfigDescriptor(
|
|
191
|
+
config,
|
|
192
|
+
groupName,
|
|
193
|
+
configPath,
|
|
194
|
+
referrer,
|
|
195
|
+
fixupEntry,
|
|
196
|
+
) {
|
|
197
|
+
const normalizeSpec = async (entry, specKey, name) => {
|
|
198
|
+
const sourcePath = await resolveSpecFromConfig(referrer, entry[specKey]);
|
|
199
|
+
fs.existsSync(sourcePath) ||
|
|
200
|
+
Fail`${sourcePath} for ${b(groupName)}[${name}].${b(specKey)} in ${configPath} config file does not exist`;
|
|
201
|
+
entry[specKey] = sourcePath;
|
|
205
202
|
};
|
|
206
203
|
|
|
207
204
|
const jobs = [];
|
|
205
|
+
const desc = config[groupName];
|
|
208
206
|
if (desc) {
|
|
209
|
-
for (const name of Object.
|
|
210
|
-
|
|
207
|
+
for (const [name, entry] of Object.entries(desc)) {
|
|
208
|
+
fixupEntry?.(entry, name);
|
|
211
209
|
if ('sourceSpec' in entry) {
|
|
212
|
-
jobs.push(normalizeSpec(entry, 'sourceSpec'));
|
|
210
|
+
jobs.push(normalizeSpec(entry, 'sourceSpec', name));
|
|
213
211
|
}
|
|
214
212
|
if ('bundleSpec' in entry) {
|
|
215
|
-
jobs.push(normalizeSpec(entry, 'bundleSpec'));
|
|
216
|
-
}
|
|
217
|
-
if (expectParameters && !entry.parameters) {
|
|
218
|
-
entry.parameters = {};
|
|
213
|
+
jobs.push(normalizeSpec(entry, 'bundleSpec', name));
|
|
219
214
|
}
|
|
220
215
|
}
|
|
221
216
|
}
|
|
@@ -223,27 +218,41 @@ async function normalizeConfigDescriptor(desc, referrer, expectParameters) {
|
|
|
223
218
|
}
|
|
224
219
|
|
|
225
220
|
/**
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
* @
|
|
229
|
-
*
|
|
230
|
-
|
|
231
|
-
|
|
221
|
+
* @param {SwingSetConfig} config
|
|
222
|
+
* @param {string} [configPath]
|
|
223
|
+
* @returns {Promise<void>}
|
|
224
|
+
* @throws {Error} if the config is invalid
|
|
225
|
+
*/
|
|
226
|
+
export async function normalizeConfig(config, configPath) {
|
|
227
|
+
const base = `file://${process.cwd()}/`;
|
|
228
|
+
const referrer = configPath
|
|
229
|
+
? new URL(configPath, base).href
|
|
230
|
+
: new URL(base).href;
|
|
231
|
+
const fixupVat = vat => (vat.parameters ||= {});
|
|
232
|
+
await Promise.all([
|
|
233
|
+
normalizeConfigDescriptor(config, 'vats', configPath, referrer, fixupVat),
|
|
234
|
+
normalizeConfigDescriptor(config, 'bundles', configPath, referrer),
|
|
235
|
+
// TODO: represent devices
|
|
236
|
+
// normalizeConfigDescriptor(config, 'devices', configPath, referrer),
|
|
237
|
+
]);
|
|
238
|
+
config.bootstrap ||
|
|
239
|
+
Fail`no designated bootstrap vat in ${configPath} config file`;
|
|
240
|
+
(config.vats && config.vats[/** @type {string} */ (config.bootstrap)]) ||
|
|
241
|
+
Fail`bootstrap vat ${config.bootstrap} not found in ${configPath} config file`;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Read and normalize a swingset config file.
|
|
232
246
|
*
|
|
233
|
-
* @
|
|
234
|
-
*
|
|
247
|
+
* @param {string} configPath
|
|
248
|
+
* @returns {Promise<SwingSetConfig | null>} the normalized config,
|
|
249
|
+
* or null if the file did not exist
|
|
235
250
|
*/
|
|
236
251
|
export async function loadSwingsetConfigFile(configPath) {
|
|
237
252
|
await null;
|
|
238
253
|
try {
|
|
239
254
|
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
240
|
-
|
|
241
|
-
await normalizeConfigDescriptor(config.vats, referrer, true);
|
|
242
|
-
await normalizeConfigDescriptor(config.bundles, referrer, false);
|
|
243
|
-
// await normalizeConfigDescriptor(config.devices, referrer, true); // TODO: represent devices
|
|
244
|
-
config.bootstrap || Fail`no designated bootstrap vat in ${configPath}`;
|
|
245
|
-
(config.vats && config.vats[config.bootstrap]) ||
|
|
246
|
-
Fail`bootstrap vat ${config.bootstrap} not found in ${configPath}`;
|
|
255
|
+
await normalizeConfig(config, configPath);
|
|
247
256
|
return config;
|
|
248
257
|
} catch (e) {
|
|
249
258
|
console.error(`failed to load ${configPath}`);
|
|
@@ -314,7 +323,7 @@ export async function initializeSwingset(
|
|
|
314
323
|
} = runtimeOptions;
|
|
315
324
|
|
|
316
325
|
// copy config so we can safely mess with it even if it's shared or hardened
|
|
317
|
-
config =
|
|
326
|
+
config = deepCopyJsonable(config);
|
|
318
327
|
if (!config.bundles) {
|
|
319
328
|
config.bundles = {};
|
|
320
329
|
}
|
|
@@ -433,26 +442,24 @@ export async function initializeSwingset(
|
|
|
433
442
|
* The host application gives us
|
|
434
443
|
* config.[vats|devices].NAME.[bundle|bundleSpec|sourceSpec|bundleName] .
|
|
435
444
|
* The 'bundleName' option points into
|
|
436
|
-
* config.bundles.BUNDLENAME.[bundle|bundleSpec|sourceSpec]
|
|
445
|
+
* config.bundles.BUNDLENAME.[bundle|bundleSpec|sourceSpec], which can
|
|
437
446
|
* also include arbitrary named bundles that will be made available to
|
|
438
|
-
* E(vatAdminService).getNamedBundleCap(bundleName)
|
|
447
|
+
* E(vatAdminService).getNamedBundleCap(bundleName), and temporarily as
|
|
439
448
|
* E(vatAdminService).createVatByName(bundleName)
|
|
440
449
|
*
|
|
441
450
|
* The 'kconfig' we pass through to initializeKernel has
|
|
442
451
|
* kconfig.[vats|devices].NAME.bundleID and
|
|
443
|
-
* kconfig.namedBundleIDs.BUNDLENAME=bundleID
|
|
452
|
+
* kconfig.namedBundleIDs.BUNDLENAME=bundleID, which both point into
|
|
444
453
|
* kconfig.idToBundle.BUNDLEID=bundle
|
|
445
454
|
*
|
|
446
|
-
* @param {SwingSetConfigProperties
|
|
455
|
+
* @param {SwingSetConfigProperties} desc
|
|
447
456
|
* @param {Record<string, *>} [nameToBundle]
|
|
448
457
|
*/
|
|
449
458
|
async function getBundle(desc, nameToBundle) {
|
|
450
459
|
trace(
|
|
451
460
|
'getBundle',
|
|
452
461
|
Object.keys(desc),
|
|
453
|
-
// @ts-expect-error optional
|
|
454
462
|
desc.moduleFormat,
|
|
455
|
-
// @ts-expect-error optional
|
|
456
463
|
desc.endoZipBase64Sha512 || desc.sourceSpec,
|
|
457
464
|
);
|
|
458
465
|
|
|
@@ -480,8 +487,9 @@ export async function initializeSwingset(
|
|
|
480
487
|
throw Error(`unknown mode in desc`, desc);
|
|
481
488
|
}
|
|
482
489
|
|
|
483
|
-
// fires with BundleWithID: { ...bundle, id }
|
|
484
490
|
/**
|
|
491
|
+
* Returns a bundle record with an "id" property from an input that might be missing it.
|
|
492
|
+
*
|
|
485
493
|
* @param {EndoZipBase64Bundle & {id?: string}} bundle
|
|
486
494
|
* @returns {Promise<EndoZipBase64Bundle & {id: string}>} bundle
|
|
487
495
|
*/
|
|
@@ -499,11 +507,9 @@ export async function initializeSwingset(
|
|
|
499
507
|
};
|
|
500
508
|
}
|
|
501
509
|
|
|
502
|
-
// fires with BundleWithID: { ...bundle, id }
|
|
503
|
-
|
|
504
510
|
/**
|
|
505
511
|
*
|
|
506
|
-
* @param {
|
|
512
|
+
* @param {SwingSetConfigProperties & {bundleID?: string}} desc
|
|
507
513
|
* @param {Record<string, EndoZipBase64Bundle>} [nameToBundle]
|
|
508
514
|
*/
|
|
509
515
|
async function processDesc(desc, nameToBundle) {
|
|
@@ -517,14 +523,14 @@ export async function initializeSwingset(
|
|
|
517
523
|
modes.length === 1 ||
|
|
518
524
|
Fail`need =1 of bundle/bundleSpec/sourceSpec/bundleName, got ${modes}`;
|
|
519
525
|
const mode = modes[0];
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
526
|
+
|
|
527
|
+
// Remove the original mode in favor of a uniform "bundleID" property.
|
|
528
|
+
const bundle = await getBundle(desc, nameToBundle);
|
|
529
|
+
const bundleWithID = await addBundleID(bundle);
|
|
530
|
+
delete desc[mode];
|
|
531
|
+
desc.bundleID = bundleWithID.id;
|
|
532
|
+
|
|
533
|
+
return bundleWithID;
|
|
528
534
|
}
|
|
529
535
|
|
|
530
536
|
/**
|