@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
|
@@ -10,13 +10,38 @@ import {
|
|
|
10
10
|
import { enumeratePrefixedKeys } from '../kernel/state/storageHelper.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
* @import {RunQueueEvent} from '../types-internal.js';
|
|
13
|
+
* @import {ReapDirtThreshold, RunQueueEvent} from '../types-internal.js';
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Parse a string of decimal digits into a number.
|
|
18
|
+
*
|
|
19
|
+
* @param {string} digits
|
|
20
|
+
* @param {string} label
|
|
21
|
+
* @returns {number}
|
|
22
|
+
*/
|
|
23
|
+
const mustParseInt = (digits, label) => {
|
|
24
|
+
assert(
|
|
25
|
+
digits.match(/^\d+$/),
|
|
26
|
+
`expected ${label}=${digits} to be a decimal integer`,
|
|
27
|
+
);
|
|
28
|
+
return Number(digits);
|
|
29
|
+
};
|
|
19
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Called for each vat when upgradeSwingset migrates from v0 to v1.
|
|
33
|
+
*
|
|
34
|
+
* @param {KVStore} kvStore
|
|
35
|
+
* @param {(key: string) => string} getRequired
|
|
36
|
+
* @param {ReapDirtThreshold} defaultReapDirtThreshold
|
|
37
|
+
* @param {string} vatID
|
|
38
|
+
*/
|
|
39
|
+
const upgradeVatV0toV1 = (
|
|
40
|
+
kvStore,
|
|
41
|
+
getRequired,
|
|
42
|
+
defaultReapDirtThreshold,
|
|
43
|
+
vatID,
|
|
44
|
+
) => {
|
|
20
45
|
// schema v0:
|
|
21
46
|
// Each vat has a `vNN.reapInterval` and `vNN.reapCountdown`.
|
|
22
47
|
// vNN.options has a `.reapInterval` property (however it was not
|
|
@@ -33,15 +58,10 @@ const upgradeVatV0toV1 = (kvStore, defaultReapDirtThreshold, vatID) => {
|
|
|
33
58
|
// `defaultReapDirtThreshold`)
|
|
34
59
|
|
|
35
60
|
const reapDirtKey = `${vatID}.reapDirt`;
|
|
36
|
-
|
|
37
|
-
assert(kvStore.has(oldReapIntervalKey), oldReapIntervalKey);
|
|
38
|
-
assert(kvStore.has(oldReapCountdownKey), oldReapCountdownKey);
|
|
39
61
|
assert(!kvStore.has(reapDirtKey), reapDirtKey);
|
|
40
62
|
|
|
41
|
-
const reapIntervalString =
|
|
42
|
-
const reapCountdownString =
|
|
43
|
-
assert(reapIntervalString !== undefined);
|
|
44
|
-
assert(reapCountdownString !== undefined);
|
|
63
|
+
const reapIntervalString = getRequired(oldReapIntervalKey);
|
|
64
|
+
const reapCountdownString = getRequired(oldReapCountdownKey);
|
|
45
65
|
|
|
46
66
|
const intervalIsNever = reapIntervalString === 'never';
|
|
47
67
|
const countdownIsNever = reapCountdownString === 'never';
|
|
@@ -62,8 +82,11 @@ const upgradeVatV0toV1 = (kvStore, defaultReapDirtThreshold, vatID) => {
|
|
|
62
82
|
threshold.never = true;
|
|
63
83
|
} else {
|
|
64
84
|
// deduce delivery count from old countdown values
|
|
65
|
-
const reapInterval =
|
|
66
|
-
const reapCountdown =
|
|
85
|
+
const reapInterval = mustParseInt(reapIntervalString, oldReapIntervalKey);
|
|
86
|
+
const reapCountdown = mustParseInt(
|
|
87
|
+
reapCountdownString,
|
|
88
|
+
oldReapCountdownKey,
|
|
89
|
+
);
|
|
67
90
|
const deliveries = reapInterval - reapCountdown;
|
|
68
91
|
reapDirt.deliveries = Math.max(deliveries, 0); // just in case
|
|
69
92
|
if (reapInterval !== defaultReapDirtThreshold.deliveries) {
|
|
@@ -76,7 +99,7 @@ const upgradeVatV0toV1 = (kvStore, defaultReapDirtThreshold, vatID) => {
|
|
|
76
99
|
kvStore.set(reapDirtKey, JSON.stringify(reapDirt));
|
|
77
100
|
|
|
78
101
|
// Update options to use the new schema.
|
|
79
|
-
const options = JSON.parse(
|
|
102
|
+
const options = JSON.parse(getRequired(vatOptionsKey));
|
|
80
103
|
delete options.reapInterval;
|
|
81
104
|
options.reapDirtThreshold = threshold;
|
|
82
105
|
kvStore.set(vatOptionsKey, JSON.stringify(options));
|
|
@@ -104,14 +127,11 @@ const upgradeVatV0toV1 = (kvStore, defaultReapDirtThreshold, vatID) => {
|
|
|
104
127
|
*/
|
|
105
128
|
export const upgradeSwingset = kernelStorage => {
|
|
106
129
|
const { kvStore } = kernelStorage;
|
|
107
|
-
let modified = false;
|
|
108
130
|
/** @type {RunQueueEvent[]} */
|
|
109
131
|
const upgradeEvents = [];
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
let version = Number(vstring);
|
|
132
|
+
const vstring = kvStore.get('version');
|
|
133
|
+
const version = Number(vstring) || 0;
|
|
134
|
+
let newVersion;
|
|
115
135
|
|
|
116
136
|
/**
|
|
117
137
|
* @param {string} key
|
|
@@ -166,11 +186,7 @@ export const upgradeSwingset = kernelStorage => {
|
|
|
166
186
|
assert(kvStore.has(oldDefaultReapIntervalKey));
|
|
167
187
|
assert(!kvStore.has(DEFAULT_REAP_DIRT_THRESHOLD_KEY));
|
|
168
188
|
|
|
169
|
-
/**
|
|
170
|
-
* @typedef { import('../types-internal.js').ReapDirtThreshold } ReapDirtThreshold
|
|
171
|
-
*/
|
|
172
|
-
|
|
173
|
-
/** @type ReapDirtThreshold */
|
|
189
|
+
/** @type {ReapDirtThreshold} */
|
|
174
190
|
const threshold = {
|
|
175
191
|
deliveries: 'never',
|
|
176
192
|
gcKrefs: 'never',
|
|
@@ -179,9 +195,7 @@ export const upgradeSwingset = kernelStorage => {
|
|
|
179
195
|
|
|
180
196
|
const oldValue = getRequired(oldDefaultReapIntervalKey);
|
|
181
197
|
if (oldValue !== 'never') {
|
|
182
|
-
|
|
183
|
-
assert.typeof(value, 'number');
|
|
184
|
-
threshold.deliveries = value;
|
|
198
|
+
threshold.deliveries = mustParseInt(oldValue, oldDefaultReapIntervalKey);
|
|
185
199
|
// if BOYD wasn't turned off entirely (eg
|
|
186
200
|
// defaultReapInterval='never', which only happens in unit
|
|
187
201
|
// tests), then pretend we wanted a gcKrefs= threshold all
|
|
@@ -196,22 +210,20 @@ export const upgradeSwingset = kernelStorage => {
|
|
|
196
210
|
|
|
197
211
|
// now upgrade all vats
|
|
198
212
|
for (const [_name, vatID] of getAllStaticVats(kvStore)) {
|
|
199
|
-
upgradeVatV0toV1(kvStore, threshold, vatID);
|
|
213
|
+
upgradeVatV0toV1(kvStore, getRequired, threshold, vatID);
|
|
200
214
|
}
|
|
201
215
|
for (const vatID of getAllDynamicVats(getRequired)) {
|
|
202
|
-
upgradeVatV0toV1(kvStore, threshold, vatID);
|
|
216
|
+
upgradeVatV0toV1(kvStore, getRequired, threshold, vatID);
|
|
203
217
|
}
|
|
204
218
|
|
|
205
|
-
|
|
206
|
-
version = 1;
|
|
219
|
+
newVersion = 1;
|
|
207
220
|
}
|
|
208
221
|
|
|
209
222
|
if (version < 2) {
|
|
210
223
|
// schema v2: add vats.terminated = []
|
|
211
224
|
assert(!kvStore.has('vats.terminated'));
|
|
212
225
|
kvStore.set('vats.terminated', JSON.stringify([]));
|
|
213
|
-
|
|
214
|
-
version = 2;
|
|
226
|
+
newVersion = 2;
|
|
215
227
|
}
|
|
216
228
|
|
|
217
229
|
if (version < 3) {
|
|
@@ -322,10 +334,11 @@ export const upgradeSwingset = kernelStorage => {
|
|
|
322
334
|
}
|
|
323
335
|
|
|
324
336
|
console.log(` - #9039 remediation complete, ${count} notifies to inject`);
|
|
325
|
-
|
|
326
|
-
version = 3;
|
|
337
|
+
newVersion = 3;
|
|
327
338
|
}
|
|
328
339
|
|
|
340
|
+
const modified = newVersion !== undefined;
|
|
341
|
+
|
|
329
342
|
if (upgradeEvents.length) {
|
|
330
343
|
assert(modified);
|
|
331
344
|
// stash until host calls controller.injectQueuedUpgradeEvents()
|
|
@@ -335,7 +348,7 @@ export const upgradeSwingset = kernelStorage => {
|
|
|
335
348
|
}
|
|
336
349
|
|
|
337
350
|
if (modified) {
|
|
338
|
-
kvStore.set('version', `${
|
|
351
|
+
kvStore.set('version', `${newVersion}`);
|
|
339
352
|
}
|
|
340
353
|
return harden({ modified });
|
|
341
354
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Fail } from '@endo/errors';
|
|
2
2
|
import { Far } from '@endo/far';
|
|
3
|
+
import { deepCopyJsonable } from '@agoric/internal/src/js-utils.js';
|
|
3
4
|
|
|
4
5
|
function sanitize(data) {
|
|
5
6
|
if (data === undefined) {
|
|
@@ -8,7 +9,7 @@ function sanitize(data) {
|
|
|
8
9
|
if (data instanceof Error) {
|
|
9
10
|
data = data.stack;
|
|
10
11
|
}
|
|
11
|
-
return
|
|
12
|
+
return deepCopyJsonable(data);
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
/**
|
|
@@ -32,7 +33,7 @@ export function buildRootDeviceNode(tools) {
|
|
|
32
33
|
|
|
33
34
|
function inboundCallback(...args) {
|
|
34
35
|
inboundHandler || Fail`inboundHandler not yet registered`;
|
|
35
|
-
const safeArgs =
|
|
36
|
+
const safeArgs = deepCopyJsonable(args);
|
|
36
37
|
try {
|
|
37
38
|
SO(inboundHandler).inbound(...harden(safeArgs));
|
|
38
39
|
} catch (e) {
|
|
@@ -24,7 +24,6 @@ export function buildSerializationTools(syscall, deviceName) {
|
|
|
24
24
|
send(method, args) {
|
|
25
25
|
assert.typeof(method, 'string');
|
|
26
26
|
assert(Array.isArray(args), args);
|
|
27
|
-
// eslint-disable-next-line no-use-before-define
|
|
28
27
|
const capdata = serialize([method, args]);
|
|
29
28
|
syscall.sendOnly(slot, capdata);
|
|
30
29
|
},
|
package/src/index.js
CHANGED
package/src/kernel/kernel.js
CHANGED
|
@@ -9,7 +9,7 @@ import { makeUpgradeDisconnection } from '@agoric/internal/src/upgrade-api.js';
|
|
|
9
9
|
import { kser, kslot, makeError } from '@agoric/kmarshal';
|
|
10
10
|
import { assertKnownOptions } from '../lib/assertOptions.js';
|
|
11
11
|
import { foreverPolicy } from '../lib/runPolicies.js';
|
|
12
|
-
import {
|
|
12
|
+
import { makeVatManagerMaker } from './vat-loader/manager-factory.js';
|
|
13
13
|
import { makeVatWarehouse } from './vat-warehouse.js';
|
|
14
14
|
import makeDeviceManager from './deviceManager.js';
|
|
15
15
|
import makeKernelKeeper, {
|
|
@@ -110,11 +110,10 @@ export default function buildKernel(
|
|
|
110
110
|
warehousePolicy,
|
|
111
111
|
overrideVatManagerOptions = {},
|
|
112
112
|
} = kernelRuntimeOptions;
|
|
113
|
-
const logStartup = verbose ? console.debug : () =>
|
|
113
|
+
const logStartup = verbose ? console.debug : () => {};
|
|
114
114
|
|
|
115
115
|
const vatAdminRootKref = kernelStorage.kvStore.get('vatAdminRootKref');
|
|
116
116
|
|
|
117
|
-
/** @type { KernelSlog } */
|
|
118
117
|
const kernelSlog = writeSlogObject
|
|
119
118
|
? makeSlogger(slogCallbacks, writeSlogObject)
|
|
120
119
|
: makeDummySlogger(slogCallbacks, makeConsole('disabled slogger'));
|
|
@@ -167,10 +166,9 @@ export default function buildKernel(
|
|
|
167
166
|
harden(testLog);
|
|
168
167
|
|
|
169
168
|
function makeSourcedConsole(vatID) {
|
|
170
|
-
const origConsole = makeConsole(
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
});
|
|
169
|
+
const origConsole = makeConsole(
|
|
170
|
+
source => `${debugPrefix}SwingSet:${source}:${vatID}`,
|
|
171
|
+
);
|
|
174
172
|
return kernelSlog.vatConsole(vatID, origConsole);
|
|
175
173
|
}
|
|
176
174
|
|
|
@@ -1128,7 +1126,6 @@ export default function buildKernel(
|
|
|
1128
1126
|
} else if (message.type === 'changeVatOptions') {
|
|
1129
1127
|
// prettier-ignore
|
|
1130
1128
|
return `changeVatOptions ${message.vatID} options: ${JSON.stringify(message.options)}`;
|
|
1131
|
-
// eslint-disable-next-line no-use-before-define
|
|
1132
1129
|
} else if (gcMessages.includes(message.type)) {
|
|
1133
1130
|
// prettier-ignore
|
|
1134
1131
|
return `${message.type} ${message.vatID} ${message.krefs.map(e=>`@${e}`).join(' ')}`;
|
|
@@ -1558,7 +1555,7 @@ export default function buildKernel(
|
|
|
1558
1555
|
gcAndFinalize,
|
|
1559
1556
|
meterControl: makeDummyMeterControl(),
|
|
1560
1557
|
});
|
|
1561
|
-
const
|
|
1558
|
+
const makeVatManager = makeVatManagerMaker({
|
|
1562
1559
|
allVatPowers,
|
|
1563
1560
|
kernelKeeper,
|
|
1564
1561
|
vatEndowments,
|
|
@@ -1653,7 +1650,7 @@ export default function buildKernel(
|
|
|
1653
1650
|
}
|
|
1654
1651
|
|
|
1655
1652
|
const vatLoader = makeVatLoader({
|
|
1656
|
-
|
|
1653
|
+
makeVatManager,
|
|
1657
1654
|
kernelSlog,
|
|
1658
1655
|
makeSourcedConsole,
|
|
1659
1656
|
kernelKeeper,
|
package/src/kernel/slogger.js
CHANGED
|
@@ -1,120 +1,127 @@
|
|
|
1
1
|
import { q } from '@endo/errors';
|
|
2
|
+
import { makeLimitedConsole } from '@agoric/internal/src/ses-utils.js';
|
|
3
|
+
|
|
4
|
+
/** @import {LimitedConsole} from '@agoric/internal/src/js-utils.js'; */
|
|
2
5
|
|
|
3
6
|
const IDLE = 'idle';
|
|
4
7
|
const STARTUP = 'startup';
|
|
5
8
|
const DELIVERY = 'delivery';
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
const noopFinisher = harden(() => {});
|
|
11
|
+
|
|
12
|
+
/** @typedef {(...finishArgs: unknown[]) => unknown} AnyFinisher */
|
|
13
|
+
/** @typedef {Partial<Record<Exclude<keyof KernelSlog, 'write'>, (methodName: string, args: unknown[], finisher: AnyFinisher) => unknown>>} SlogWrappers */
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Support composition of asynchronous callbacks that are invoked at the start
|
|
17
|
+
* of an operation and return either a non-function result or a "finisher"
|
|
18
|
+
* function to be invoked upon operation completion.
|
|
19
|
+
* This maker accepts a collection of wrapper functions that receive the same
|
|
20
|
+
* arguments as the method they wrap, along with the result of that method
|
|
21
|
+
* (e.g., its finisher), and are expected to return a finisher of their own that
|
|
22
|
+
* will invoke that wrapped finisher.
|
|
23
|
+
*
|
|
24
|
+
* @param {SlogWrappers} wrappers
|
|
25
|
+
*/
|
|
26
|
+
function makeFinishersKit(wrappers) {
|
|
27
|
+
const unused = new Set(Object.keys(wrappers));
|
|
9
28
|
return harden({
|
|
10
29
|
/**
|
|
11
|
-
* Robustly wrap a method
|
|
12
|
-
* incur no runtime overhead if the given callback method isn't defined.
|
|
30
|
+
* Robustly wrap a method if a wrapper is defined.
|
|
13
31
|
*
|
|
14
|
-
* @
|
|
15
|
-
* @
|
|
16
|
-
*
|
|
17
|
-
* @
|
|
18
|
-
*
|
|
32
|
+
* @template {(...args: unknown[]) => (Finisher | unknown)} F
|
|
33
|
+
* @template {AnyFinisher} [Finisher=AnyFinisher]
|
|
34
|
+
* @param {string} method name
|
|
35
|
+
* @param {F} impl the original implementation
|
|
36
|
+
* @returns {F} the wrapped method
|
|
19
37
|
*/
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return impl;
|
|
27
|
-
}
|
|
38
|
+
wrap(method, impl) {
|
|
39
|
+
unused.delete(method);
|
|
40
|
+
const wrapper = wrappers[method];
|
|
41
|
+
|
|
42
|
+
// If there is no registered wrapper, return the implementation directly.
|
|
43
|
+
if (!wrapper) return impl;
|
|
28
44
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const ret = impl(...args);
|
|
45
|
+
const wrapped = (...args) => {
|
|
46
|
+
const maybeFinisher = /** @type {Finisher} */ (impl(...args));
|
|
32
47
|
try {
|
|
33
|
-
// Allow the callback to observe the call synchronously, and
|
|
34
|
-
// the finisher function, but not to throw an exception.
|
|
35
|
-
const
|
|
36
|
-
if (typeof
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
return ret(...args);
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
// We just return the callback's return value.
|
|
51
|
-
return cbRet;
|
|
48
|
+
// Allow the callback to observe the call synchronously, and replace
|
|
49
|
+
// the implementation's finisher function, but not to throw an exception.
|
|
50
|
+
const wrapperFinisher = wrapper(method, args, maybeFinisher);
|
|
51
|
+
if (typeof maybeFinisher !== 'function') return wrapperFinisher;
|
|
52
|
+
|
|
53
|
+
// We wrap the finisher in the callback's return value.
|
|
54
|
+
return (...finishArgs) => {
|
|
55
|
+
try {
|
|
56
|
+
return /** @type {Finisher} */ (wrapperFinisher)(...finishArgs);
|
|
57
|
+
} catch (e) {
|
|
58
|
+
console.error(`${method} wrapper finisher failed:`, e);
|
|
59
|
+
return maybeFinisher(...finishArgs);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
52
62
|
} catch (e) {
|
|
53
|
-
console.error(
|
|
63
|
+
console.error(`${method} wrapper failed:`, e);
|
|
64
|
+
return maybeFinisher;
|
|
54
65
|
}
|
|
55
|
-
return ret;
|
|
56
66
|
};
|
|
67
|
+
return /** @type {F} */ (wrapped);
|
|
57
68
|
},
|
|
58
69
|
/**
|
|
59
|
-
* Declare that all
|
|
70
|
+
* Declare that all wrapping is done.
|
|
60
71
|
*
|
|
61
|
-
* @param {string}
|
|
62
|
-
* names that don't correspond to a registration
|
|
72
|
+
* @param {string} msg message to display if there are unused wrappers
|
|
63
73
|
*/
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
console.warn(errorUnusedMsg, cbNames.map(q).sort().join(', '));
|
|
74
|
+
done(msg = 'Unused wrappers') {
|
|
75
|
+
if (!unused.size) return;
|
|
76
|
+
console.warn(msg, ...[...unused.keys()].sort().map(q));
|
|
70
77
|
},
|
|
71
78
|
});
|
|
72
79
|
}
|
|
73
80
|
|
|
81
|
+
export const badConsole = makeLimitedConsole(level => () => {
|
|
82
|
+
throw Error(`unexpected use of badConsole.${level}`);
|
|
83
|
+
});
|
|
84
|
+
export const noopConsole = makeLimitedConsole(_level => () => {});
|
|
85
|
+
|
|
74
86
|
/**
|
|
75
|
-
* @param {
|
|
76
|
-
* @param {
|
|
87
|
+
* @param {SlogWrappers} slogCallbacks
|
|
88
|
+
* @param {LimitedConsole} [dummyConsole]
|
|
77
89
|
* @returns {KernelSlog}
|
|
78
90
|
*/
|
|
79
|
-
export function makeDummySlogger(slogCallbacks, dummyConsole) {
|
|
80
|
-
const {
|
|
81
|
-
makeCallbackRegistry(slogCallbacks);
|
|
91
|
+
export function makeDummySlogger(slogCallbacks, dummyConsole = badConsole) {
|
|
92
|
+
const { wrap, done } = makeFinishersKit(slogCallbacks);
|
|
82
93
|
const dummySlogger = harden({
|
|
83
|
-
provideVatSlogger:
|
|
84
|
-
harden({
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
),
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
syscall: reg('syscall', () => () => 0),
|
|
95
|
-
changeCList: reg('changeCList', () => () => 0),
|
|
96
|
-
terminateVat: reg('terminateVat', () => () => 0),
|
|
97
|
-
write: () => 0,
|
|
94
|
+
provideVatSlogger: wrap('provideVatSlogger', () => {
|
|
95
|
+
return harden({ vatSlog: { delivery: () => noopFinisher } });
|
|
96
|
+
}),
|
|
97
|
+
vatConsole: wrap('vatConsole', () => dummyConsole),
|
|
98
|
+
startup: wrap('startup', () => noopFinisher),
|
|
99
|
+
replayVatTranscript: wrap('replayVatTranscript', () => noopFinisher),
|
|
100
|
+
delivery: wrap('delivery', () => noopFinisher),
|
|
101
|
+
syscall: wrap('syscall', () => noopFinisher),
|
|
102
|
+
changeCList: wrap('changeCList', () => noopFinisher),
|
|
103
|
+
terminateVat: wrap('terminateVat', () => noopFinisher),
|
|
104
|
+
write: noopFinisher,
|
|
98
105
|
});
|
|
99
|
-
|
|
100
|
-
// @ts-expect-error xxx
|
|
106
|
+
done('Unused makeDummySlogger slogCallbacks method names');
|
|
101
107
|
return dummySlogger;
|
|
102
108
|
}
|
|
103
109
|
|
|
104
110
|
/**
|
|
105
|
-
* @param {
|
|
106
|
-
* @param {
|
|
111
|
+
* @param {SlogWrappers} slogCallbacks
|
|
112
|
+
* @param {(obj: object) => void} [writeObj]
|
|
107
113
|
* @returns {KernelSlog}
|
|
108
114
|
*/
|
|
109
115
|
export function makeSlogger(slogCallbacks, writeObj) {
|
|
110
|
-
const safeWrite =
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
const safeWrite = writeObj
|
|
117
|
+
? obj => {
|
|
118
|
+
try {
|
|
119
|
+
writeObj(obj);
|
|
120
|
+
} catch (err) {
|
|
121
|
+
console.error('WARNING: slogger write error', err);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
: () => {};
|
|
118
125
|
|
|
119
126
|
const vatSlogs = new Map(); // vatID -> vatSlog
|
|
120
127
|
|
|
@@ -130,36 +137,33 @@ export function makeSlogger(slogCallbacks, writeObj) {
|
|
|
130
137
|
console.error(
|
|
131
138
|
`WARNING: slogger state confused: vat ${vatID} in ${state}, not ${exp}: ${msg}`,
|
|
132
139
|
);
|
|
133
|
-
|
|
140
|
+
safeWrite({ type: 'slogger-confused', vatID, state, exp, msg });
|
|
134
141
|
}
|
|
135
142
|
}
|
|
136
143
|
|
|
137
144
|
function vatConsole(sourcedConsole) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
return harden(vc);
|
|
145
|
+
return makeLimitedConsole(level => (source, ...args) => {
|
|
146
|
+
// Don't duplicate stale output.
|
|
147
|
+
if (replay) return;
|
|
148
|
+
|
|
149
|
+
// Write to the console, then to the slog.
|
|
150
|
+
sourcedConsole[level](source, ...args);
|
|
151
|
+
// TODO: Just use "liveslots" rather than "ls"?
|
|
152
|
+
if (source === 'ls') source = 'liveslots';
|
|
153
|
+
const when = { state, crankNum, vatID, deliveryNum };
|
|
154
|
+
safeWrite({ type: 'console', source, ...when, level, args });
|
|
155
|
+
});
|
|
152
156
|
}
|
|
153
157
|
|
|
154
158
|
function startup() {
|
|
155
159
|
// provide a context for console calls during startup
|
|
156
160
|
checkOldState(IDLE, 'did startup get called twice?');
|
|
157
161
|
state = STARTUP;
|
|
158
|
-
|
|
162
|
+
safeWrite({ type: 'vat-startup-start', vatID });
|
|
159
163
|
function finish() {
|
|
160
164
|
checkOldState(STARTUP, 'startup-finish called twice?');
|
|
161
165
|
state = IDLE;
|
|
162
|
-
|
|
166
|
+
safeWrite({ type: 'vat-startup-finish', vatID });
|
|
163
167
|
}
|
|
164
168
|
return harden(finish);
|
|
165
169
|
}
|
|
@@ -172,13 +176,13 @@ export function makeSlogger(slogCallbacks, writeObj) {
|
|
|
172
176
|
deliveryNum = newDeliveryNum;
|
|
173
177
|
replay = inReplay;
|
|
174
178
|
const when = { crankNum, vatID, deliveryNum, replay };
|
|
175
|
-
|
|
179
|
+
safeWrite({ type: 'deliver', ...when, kd, vd });
|
|
176
180
|
syscallNum = 0;
|
|
177
181
|
|
|
178
182
|
// dr: deliveryResult
|
|
179
183
|
function finish(dr) {
|
|
180
184
|
checkOldState(DELIVERY, 'delivery-finish called twice?');
|
|
181
|
-
|
|
185
|
+
safeWrite({ type: 'deliver-result', ...when, dr });
|
|
182
186
|
state = IDLE;
|
|
183
187
|
}
|
|
184
188
|
return harden(finish);
|
|
@@ -188,24 +192,24 @@ export function makeSlogger(slogCallbacks, writeObj) {
|
|
|
188
192
|
function syscall(ksc, vsc) {
|
|
189
193
|
checkOldState(DELIVERY, 'syscall invoked outside of delivery');
|
|
190
194
|
const when = { crankNum, vatID, deliveryNum, syscallNum, replay };
|
|
191
|
-
|
|
195
|
+
safeWrite({ type: 'syscall', ...when, ksc, vsc });
|
|
192
196
|
syscallNum += 1;
|
|
193
197
|
|
|
194
198
|
// ksr: kernelSyscallResult, vsr: vatSyscallResult
|
|
195
199
|
function finish(ksr, vsr) {
|
|
196
200
|
checkOldState(DELIVERY, 'syscall finished after delivery?');
|
|
197
|
-
|
|
201
|
+
safeWrite({ type: 'syscall-result', ...when, ksr, vsr });
|
|
198
202
|
}
|
|
199
203
|
return harden(finish);
|
|
200
204
|
}
|
|
201
205
|
|
|
202
206
|
// mode: 'import' | 'export' | 'drop'
|
|
203
207
|
function changeCList(crank, mode, kobj, vobj) {
|
|
204
|
-
|
|
208
|
+
safeWrite({ type: 'clist', crankNum: crank, mode, vatID, kobj, vobj });
|
|
205
209
|
}
|
|
206
210
|
|
|
207
211
|
function terminateVat(shouldReject, info) {
|
|
208
|
-
|
|
212
|
+
safeWrite({ type: 'terminate', vatID, shouldReject, info });
|
|
209
213
|
}
|
|
210
214
|
|
|
211
215
|
return harden({
|
|
@@ -233,7 +237,7 @@ export function makeSlogger(slogCallbacks, writeObj) {
|
|
|
233
237
|
}
|
|
234
238
|
const vatSlog = makeVatSlog(vatID);
|
|
235
239
|
vatSlogs.set(vatID, vatSlog);
|
|
236
|
-
|
|
240
|
+
safeWrite({
|
|
237
241
|
type: 'create-vat',
|
|
238
242
|
vatID,
|
|
239
243
|
dynamic,
|
|
@@ -247,43 +251,42 @@ export function makeSlogger(slogCallbacks, writeObj) {
|
|
|
247
251
|
}
|
|
248
252
|
|
|
249
253
|
function replayVatTranscript(vatID) {
|
|
250
|
-
|
|
254
|
+
safeWrite({ type: 'replay-transcript-start', vatID });
|
|
251
255
|
function finish() {
|
|
252
|
-
|
|
256
|
+
safeWrite({ type: 'replay-transcript-finish', vatID });
|
|
253
257
|
}
|
|
254
258
|
return harden(finish);
|
|
255
259
|
}
|
|
256
260
|
|
|
257
261
|
// function annotateVat(vatID, data) {
|
|
258
|
-
//
|
|
262
|
+
// safeWrite({ type: 'annotate-vat', vatID, data });
|
|
259
263
|
// }
|
|
260
264
|
|
|
261
|
-
const {
|
|
262
|
-
makeCallbackRegistry(slogCallbacks);
|
|
265
|
+
const { wrap, done } = makeFinishersKit(slogCallbacks);
|
|
263
266
|
const slogger = harden({
|
|
264
|
-
provideVatSlogger:
|
|
265
|
-
vatConsole:
|
|
267
|
+
provideVatSlogger: wrap('provideVatSlogger', provideVatSlogger),
|
|
268
|
+
vatConsole: wrap('vatConsole', (vatID, ...args) =>
|
|
266
269
|
provideVatSlogger(vatID).vatSlog.vatConsole(...args),
|
|
267
270
|
),
|
|
268
|
-
startup:
|
|
271
|
+
startup: wrap('startup', (vatID, ...args) =>
|
|
269
272
|
provideVatSlogger(vatID).vatSlog.startup(...args),
|
|
270
273
|
),
|
|
274
|
+
// TODO: Remove this seemingly dead code.
|
|
271
275
|
replayVatTranscript,
|
|
272
|
-
delivery:
|
|
276
|
+
delivery: wrap('delivery', (vatID, ...args) =>
|
|
273
277
|
provideVatSlogger(vatID).vatSlog.delivery(...args),
|
|
274
278
|
),
|
|
275
|
-
syscall:
|
|
279
|
+
syscall: wrap('syscall', (vatID, ...args) =>
|
|
276
280
|
provideVatSlogger(vatID).vatSlog.syscall(...args),
|
|
277
281
|
),
|
|
278
|
-
changeCList:
|
|
282
|
+
changeCList: wrap('changeCList', (vatID, ...args) =>
|
|
279
283
|
provideVatSlogger(vatID).vatSlog.changeCList(...args),
|
|
280
284
|
),
|
|
281
|
-
terminateVat:
|
|
285
|
+
terminateVat: wrap('terminateVat', (vatID, ...args) =>
|
|
282
286
|
provideVatSlogger(vatID).vatSlog.terminateVat(...args),
|
|
283
287
|
),
|
|
284
|
-
write,
|
|
288
|
+
write: safeWrite,
|
|
285
289
|
});
|
|
286
|
-
|
|
287
|
-
// @ts-expect-error xxx
|
|
290
|
+
done('Unused makeSlogger slogCallbacks method names');
|
|
288
291
|
return slogger;
|
|
289
292
|
}
|