@agoric/swingset-vat 0.32.3-dev-dc77e16.0 → 0.32.3-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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/swingset-vat",
3
- "version": "0.32.3-dev-dc77e16.0+dc77e16",
3
+ "version": "0.32.3-dev-c605745.0+c605745",
4
4
  "description": "Vat/Container Launcher",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -27,15 +27,15 @@
27
27
  "@types/yargs-parser": "^21.0.0"
28
28
  },
29
29
  "dependencies": {
30
- "@agoric/internal": "0.3.3-dev-dc77e16.0+dc77e16",
31
- "@agoric/kmarshal": "0.1.1-dev-dc77e16.0+dc77e16",
32
- "@agoric/store": "0.9.3-dev-dc77e16.0+dc77e16",
33
- "@agoric/swing-store": "0.9.2-dev-dc77e16.0+dc77e16",
34
- "@agoric/swingset-liveslots": "0.10.3-dev-dc77e16.0+dc77e16",
35
- "@agoric/swingset-xsnap-supervisor": "0.10.3-dev-dc77e16.0+dc77e16",
36
- "@agoric/time": "0.3.3-dev-dc77e16.0+dc77e16",
37
- "@agoric/vat-data": "0.5.3-dev-dc77e16.0+dc77e16",
38
- "@agoric/xsnap-lockdown": "0.14.1-dev-dc77e16.0+dc77e16",
30
+ "@agoric/internal": "0.3.3-dev-c605745.0+c605745",
31
+ "@agoric/kmarshal": "0.1.1-dev-c605745.0+c605745",
32
+ "@agoric/store": "0.9.3-dev-c605745.0+c605745",
33
+ "@agoric/swing-store": "0.9.2-dev-c605745.0+c605745",
34
+ "@agoric/swingset-liveslots": "0.10.3-dev-c605745.0+c605745",
35
+ "@agoric/swingset-xsnap-supervisor": "0.10.3-dev-c605745.0+c605745",
36
+ "@agoric/time": "0.3.3-dev-c605745.0+c605745",
37
+ "@agoric/vat-data": "0.5.3-dev-c605745.0+c605745",
38
+ "@agoric/xsnap-lockdown": "0.14.1-dev-c605745.0+c605745",
39
39
  "@endo/base64": "^1.0.9",
40
40
  "@endo/bundle-source": "^3.5.1",
41
41
  "@endo/captp": "^4.4.4",
@@ -102,5 +102,5 @@
102
102
  "typeCoverage": {
103
103
  "atLeast": 76.28
104
104
  },
105
- "gitHead": "dc77e169321b8c2cf4d6c81699dbe7cc4cba0177"
105
+ "gitHead": "c605745ee6619292b51cec5fc0db0a25ff1b203c"
106
106
  }
@@ -16,6 +16,7 @@ import { initSwingStore } from '@agoric/swing-store';
16
16
  import { mustMatch, M } from '@endo/patterns';
17
17
  import { checkBundle } from '@endo/check-bundle/lite.js';
18
18
  import { deepCopyJsonable } from '@agoric/internal/src/js-utils.js';
19
+ import { makeLimitedConsole } from '@agoric/internal/src/ses-utils.js';
19
20
  import engineGC from '@agoric/internal/src/lib-nodejs/engine-gc.js';
20
21
  import { startSubprocessWorker } from '@agoric/internal/src/lib-nodejs/spawnSubprocessWorker.js';
21
22
  import { waitUntilQuiescent } from '@agoric/internal/src/lib-nodejs/waitUntilQuiescent.js';
@@ -56,34 +57,32 @@ export function computeSha512(bytes) {
56
57
  return hash.digest().toString('hex');
57
58
  }
58
59
 
59
- /** @param {string | ((args: unknown[]) => string)} tagOrTagCreator */
60
- function makeConsole(tagOrTagCreator) {
61
- /** @type {(level: string) => (args: unknown[]) => void} */
62
- let makeLoggerForLevel;
63
- if (typeof tagOrTagCreator === 'function') {
64
- const tagToLogger = new Map();
65
- makeLoggerForLevel =
66
- level =>
67
- (...args) => {
68
- // Retrieve the logger from cache.
69
- const tag = tagOrTagCreator(args);
70
- let logger = tagToLogger.get(tag);
71
- if (!logger) {
72
- logger = anylogger(tag);
73
- tagToLogger.set(tag, logger);
74
- }
75
- // Actually log the message.
76
- return logger[level](...args);
77
- };
78
- } else {
79
- const logger = anylogger(tagOrTagCreator);
80
- makeLoggerForLevel = level => logger[level];
81
- }
82
- const cons = {};
83
- for (const level of ['debug', 'log', 'info', 'warn', 'error']) {
84
- 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]);
85
71
  }
86
- return harden(cons);
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
+ });
87
86
  }
88
87
 
89
88
  /**
@@ -213,17 +212,23 @@ export async function makeSwingsetController(
213
212
  process.on('unhandledRejection', unhandledRejectionHandler);
214
213
  }
215
214
 
216
- function kernelRequire(what) {
217
- Fail`kernelRequire unprepared to satisfy require(${what})`;
218
- }
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
+ });
219
222
  writeSlogObject({ type: 'import-kernel-start' });
220
223
  const kernelNS = await importBundle(kernelBundle, {
221
224
  filePrefix: 'kernel/...',
222
225
  endowments: {
223
- console: makeConsole(`${debugPrefix}SwingSet:kernel`),
226
+ console: sloggingKernelConsole,
224
227
  // See https://github.com/Agoric/agoric-sdk/issues/9515
225
228
  assert: globalThis.assert,
226
- require: kernelRequire,
229
+ require: harden(
230
+ what => Fail`kernelRequire unprepared to satisfy require(${what})`,
231
+ ),
227
232
  URL: globalThis.Base64, // Unavailable only on XSnap
228
233
  Base64: globalThis.Base64, // Available only on XSnap
229
234
  },
@@ -110,11 +110,10 @@ export default function buildKernel(
110
110
  warehousePolicy,
111
111
  overrideVatManagerOptions = {},
112
112
  } = kernelRuntimeOptions;
113
- const logStartup = verbose ? console.debug : () => 0;
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(args => {
171
- const source = args.shift();
172
- return `${debugPrefix}SwingSet:${source}:${vatID}`;
173
- });
169
+ const origConsole = makeConsole(
170
+ source => `${debugPrefix}SwingSet:${source}:${vatID}`,
171
+ );
174
172
  return kernelSlog.vatConsole(vatID, origConsole);
175
173
  }
176
174
 
@@ -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
- function makeCallbackRegistry(callbacks) {
8
- const todo = new Set(Object.keys(callbacks));
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 with a callbacks[method] function, if defined. We
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
- * @param {string} method wrap with callbacks[method]
15
- * @param {(...args: Array<unknown>) => unknown} impl the original
16
- * implementation of the method
17
- * @returns {(...args: Array<unknown>) => unknown} the wrapped method if the
18
- * callback is defined, or original method if not
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
- registerCallback(method, impl) {
21
- todo.delete(method);
22
- const cb = callbacks[method];
23
- if (!cb) {
24
- // No registered callback, just use the implementation directly.
25
- // console.error('no registered callback for', method);
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
- return (...args) => {
30
- // Invoke the implementation first.
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 affect
34
- // the finisher function, but not to throw an exception.
35
- const cbRet = cb(method, args, ret);
36
- if (typeof ret === 'function') {
37
- // We wrap the finisher in the callback's return value.
38
- return (...finishArgs) => {
39
- try {
40
- return cbRet(...finishArgs);
41
- } catch (e) {
42
- console.error(
43
- `failed to call registered ${method}.finish function:`,
44
- e,
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('failed to call registered', method, 'callback:', e);
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 the methods have been registered.
70
+ * Declare that all wrapping is done.
60
71
  *
61
- * @param {string} errorUnusedMsg message to display if there are callback
62
- * names that don't correspond to a registration
72
+ * @param {string} msg message to display if there are unused wrappers
63
73
  */
64
- doneRegistering(errorUnusedMsg = `Unrecognized callback names:`) {
65
- const cbNames = [...todo.keys()];
66
- if (!cbNames.length) {
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 {*} slogCallbacks
76
- * @param {Pick<Console, 'debug'|'log'|'info'|'warn'|'error'>} dummyConsole
87
+ * @param {SlogWrappers} slogCallbacks
88
+ * @param {LimitedConsole} [dummyConsole]
77
89
  * @returns {KernelSlog}
78
90
  */
79
- export function makeDummySlogger(slogCallbacks, dummyConsole) {
80
- const { registerCallback: reg, doneRegistering } =
81
- makeCallbackRegistry(slogCallbacks);
91
+ export function makeDummySlogger(slogCallbacks, dummyConsole = badConsole) {
92
+ const { wrap, done } = makeFinishersKit(slogCallbacks);
82
93
  const dummySlogger = harden({
83
- provideVatSlogger: reg('provideVatSlogger', () =>
84
- harden({
85
- vatSlog: {
86
- delivery: () => () => 0,
87
- },
88
- }),
89
- ),
90
- vatConsole: reg('vatConsole', () => dummyConsole),
91
- startup: reg('startup', () => () => 0), // returns nop finish() function
92
- replayVatTranscript: reg('replayVatTranscript', () => () => 0),
93
- delivery: reg('delivery', () => () => 0),
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
- doneRegistering(`Unrecognized makeDummySlogger slogCallbacks names:`);
100
- // @ts-expect-error xxx
106
+ done('Unused makeDummySlogger slogCallbacks method names');
101
107
  return dummySlogger;
102
108
  }
103
109
 
104
110
  /**
105
- * @param {*} slogCallbacks
106
- * @param {*} writeObj
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 = e => {
111
- try {
112
- writeObj(e);
113
- } catch (err) {
114
- console.error('WARNING: slogger write error', err);
115
- }
116
- };
117
- const write = writeObj ? safeWrite : () => 0;
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
- write({ type: 'slogger-confused', vatID, state, exp, msg });
140
+ safeWrite({ type: 'slogger-confused', vatID, state, exp, msg });
134
141
  }
135
142
  }
136
143
 
137
144
  function vatConsole(sourcedConsole) {
138
- const vc = {};
139
- for (const level of ['debug', 'log', 'info', 'warn', 'error']) {
140
- vc[level] = (sourceTag, ...args) => {
141
- if (replay) {
142
- // Don't duplicate stale console output.
143
- return;
144
- }
145
- sourcedConsole[level](sourceTag, ...args);
146
- const when = { state, crankNum, vatID, deliveryNum };
147
- const source = sourceTag === 'ls' ? 'liveslots' : sourceTag;
148
- write({ type: 'console', source, ...when, level, args });
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
- write({ type: 'vat-startup-start', vatID });
162
+ safeWrite({ type: 'vat-startup-start', vatID });
159
163
  function finish() {
160
164
  checkOldState(STARTUP, 'startup-finish called twice?');
161
165
  state = IDLE;
162
- write({ type: 'vat-startup-finish', vatID });
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
- write({ type: 'deliver', ...when, kd, vd });
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
- write({ type: 'deliver-result', ...when, dr });
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
- write({ type: 'syscall', ...when, ksc, vsc });
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
- write({ type: 'syscall-result', ...when, ksr, vsr });
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
- write({ type: 'clist', crankNum: crank, mode, vatID, kobj, vobj });
208
+ safeWrite({ type: 'clist', crankNum: crank, mode, vatID, kobj, vobj });
205
209
  }
206
210
 
207
211
  function terminateVat(shouldReject, info) {
208
- write({ type: 'terminate', vatID, shouldReject, info });
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
- write({
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
- write({ type: 'replay-transcript-start', vatID });
254
+ safeWrite({ type: 'replay-transcript-start', vatID });
251
255
  function finish() {
252
- write({ type: 'replay-transcript-finish', vatID });
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
- // write({ type: 'annotate-vat', vatID, data });
262
+ // safeWrite({ type: 'annotate-vat', vatID, data });
259
263
  // }
260
264
 
261
- const { registerCallback: reg, doneRegistering } =
262
- makeCallbackRegistry(slogCallbacks);
265
+ const { wrap, done } = makeFinishersKit(slogCallbacks);
263
266
  const slogger = harden({
264
- provideVatSlogger: reg('provideVatSlogger', provideVatSlogger),
265
- vatConsole: reg('vatConsole', (vatID, ...args) =>
267
+ provideVatSlogger: wrap('provideVatSlogger', provideVatSlogger),
268
+ vatConsole: wrap('vatConsole', (vatID, ...args) =>
266
269
  provideVatSlogger(vatID).vatSlog.vatConsole(...args),
267
270
  ),
268
- startup: reg('startup', (vatID, ...args) =>
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: reg('delivery', (vatID, ...args) =>
276
+ delivery: wrap('delivery', (vatID, ...args) =>
273
277
  provideVatSlogger(vatID).vatSlog.delivery(...args),
274
278
  ),
275
- syscall: reg('syscall', (vatID, ...args) =>
279
+ syscall: wrap('syscall', (vatID, ...args) =>
276
280
  provideVatSlogger(vatID).vatSlog.syscall(...args),
277
281
  ),
278
- changeCList: reg('changeCList', (vatID, ...args) =>
282
+ changeCList: wrap('changeCList', (vatID, ...args) =>
279
283
  provideVatSlogger(vatID).vatSlog.changeCList(...args),
280
284
  ),
281
- terminateVat: reg('terminateVat', (vatID, ...args) =>
285
+ terminateVat: wrap('terminateVat', (vatID, ...args) =>
282
286
  provideVatSlogger(vatID).vatSlog.terminateVat(...args),
283
287
  ),
284
- write,
288
+ write: safeWrite,
285
289
  });
286
- doneRegistering(`Unrecognized makeSlogger slogCallbacks names:`);
287
- // @ts-expect-error xxx
290
+ done('Unused makeSlogger slogCallbacks method names');
288
291
  return slogger;
289
292
  }
@@ -1,6 +1,7 @@
1
1
  import { Nat, isNat } from '@endo/nat';
2
2
  import { assert, Fail } from '@endo/errors';
3
3
  import { naturalCompare } from '@agoric/internal/src/natural-sort.js';
4
+ import { makeDummySlogger, noopConsole } from '../slogger.js';
4
5
  import {
5
6
  initializeVatState,
6
7
  makeVatKeeper,
@@ -330,7 +331,7 @@ export const DEFAULT_GC_KREFS_PER_BOYD = 20;
330
331
  /**
331
332
  * @param {SwingStoreKernelStorage} kernelStorage
332
333
  * @param {number | 'uninitialized'} expectedVersion
333
- * @param {KernelSlog} [kernelSlog]
334
+ * @param {KernelSlog} [kernelSlog] optional only for expectedVersion 'uninitialized'
334
335
  */
335
336
  export default function makeKernelKeeper(
336
337
  kernelStorage,
@@ -356,10 +357,13 @@ export default function makeKernelKeeper(
356
357
  if (versionString) {
357
358
  throw Error(`kernel DB already initialized (v${versionString})`);
358
359
  }
360
+ kernelSlog ||= makeDummySlogger({}, noopConsole);
359
361
  } else if (expectedVersion !== version) {
360
362
  throw Error(
361
363
  `kernel DB is too old: has version v${version}, but expected v${expectedVersion}`,
362
364
  );
365
+ } else if (!kernelSlog) {
366
+ throw Error('kernelSlog is required for an already-initialized kernel DB');
363
367
  } else {
364
368
  // DB is up-to-date, so populate any caches we use
365
369
  terminatedVats = JSON.parse(getRequired('vats.terminated'));
@@ -86,7 +86,7 @@ export function initializeVatState(
86
86
  /**
87
87
  * @typedef {object} VatKeeperPowers
88
88
  * @property {TranscriptStore} transcriptStore Accompanying transcript store, for the transcripts
89
- * @property {*} kernelSlog
89
+ * @property {KernelSlog} kernelSlog
90
90
  * @property {*} addKernelObject Kernel function to add a new object to the kernel's mapping tables.
91
91
  * @property {*} addKernelPromiseForVat Kernel function to add a new promise to the kernel's mapping tables.
92
92
  * @property {(kernelSlot: string) => boolean} kernelObjectExists
@@ -411,15 +411,13 @@ export function makeVatKeeper(
411
411
  // update any necessary refcounts consistently
412
412
  kvStore.set(kernelKey, buildReachableAndVatSlot(false, vatSlot));
413
413
  kvStore.set(vatKey, kernelSlot);
414
- if (kernelSlog) {
415
- kernelSlog.changeCList(
416
- vatID,
417
- getCrankNumber(),
418
- 'export',
419
- kernelSlot,
420
- vatSlot,
421
- );
422
- }
414
+ kernelSlog.changeCList(
415
+ vatID,
416
+ getCrankNumber(),
417
+ 'export',
418
+ kernelSlot,
419
+ vatSlot,
420
+ );
423
421
  kdebug(`Add mapping v->k ${kernelKey}<=>${vatKey}`);
424
422
  } else {
425
423
  // the vat didn't allocate it, and the kernel didn't allocate it
@@ -486,15 +484,13 @@ export function makeVatKeeper(
486
484
  incStat('clistEntries');
487
485
  kvStore.set(vatKey, kernelSlot);
488
486
  kvStore.set(kernelKey, buildReachableAndVatSlot(false, vatSlot));
489
- if (kernelSlog) {
490
- kernelSlog.changeCList(
491
- vatID,
492
- getCrankNumber(),
493
- 'import',
494
- kernelSlot,
495
- vatSlot,
496
- );
497
- }
487
+ kernelSlog.changeCList(
488
+ vatID,
489
+ getCrankNumber(),
490
+ 'import',
491
+ kernelSlot,
492
+ vatSlot,
493
+ );
498
494
  kdebug(`Add mapping k->v ${kernelKey}<=>${vatKey}`);
499
495
  }
500
496
 
@@ -537,15 +533,13 @@ export function makeVatKeeper(
537
533
  const vatKey = `${vatID}.c.${vatSlot}`;
538
534
  assert(kvStore.has(kernelKey));
539
535
  kdebug(`Delete mapping ${kernelKey}<=>${vatKey}`);
540
- if (kernelSlog) {
541
- kernelSlog.changeCList(
542
- vatID,
543
- getCrankNumber(),
544
- 'drop',
545
- kernelSlot,
546
- vatSlot,
547
- );
548
- }
536
+ kernelSlog.changeCList(
537
+ vatID,
538
+ getCrankNumber(),
539
+ 'drop',
540
+ kernelSlot,
541
+ vatSlot,
542
+ );
549
543
  const isExport = allocatedByVat;
550
544
  // We tolerate the object kref not being present in the kernel object
551
545
  // table, either because we're being called during the translation of
@@ -1,10 +1,10 @@
1
- /** @import { ERef } from '@endo/far'; */
2
-
3
1
  export {};
4
2
 
5
3
  /**
6
4
  * @import {Guarded} from '@endo/exo';
5
+ * @import {ERef} from '@endo/far';
7
6
  * @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,14 +129,6 @@ export {};
129
129
  * @typedef { (dr: VatDeliveryResult) => void } SlogFinishDelivery
130
130
  * @typedef { (ksr: KernelSyscallResult, vsr: VatSyscallResult) => void } SlogFinishSyscall
131
131
  * @typedef { { write: ({}) => void,
132
- * vatConsole: (vatID: string, origConsole: {}) => {},
133
- * delivery: (vatID: string,
134
- * newCrankNum: BigInt, newDeliveryNum: BigInt,
135
- * kd: KernelDeliveryObject, vd: VatDeliveryObject,
136
- * replay?: boolean) => SlogFinishDelivery,
137
- * syscall: (vatID: string,
138
- * ksc: KernelSyscallObject | undefined,
139
- * vsc: VatSyscallObject) => SlogFinishSyscall,
140
132
  * provideVatSlogger: (vatID: string,
141
133
  * dynamic?: boolean,
142
134
  * description?: string,
@@ -144,6 +136,20 @@ export {};
144
136
  * vatSourceBundle?: unknown,
145
137
  * managerType?: string,
146
138
  * vatParameters?: unknown) => { vatSlog: VatSlog },
139
+ * vatConsole: (vatID: string, origConsole: LimitedConsole) => LimitedConsole,
140
+ * startup: (vatID: string) => () => void,
141
+ * delivery: (vatID: string,
142
+ * newCrankNum: BigInt, newDeliveryNum: BigInt,
143
+ * kd: KernelDeliveryObject, vd: VatDeliveryObject,
144
+ * replay?: boolean) => SlogFinishDelivery,
145
+ * syscall: (vatID: string,
146
+ * ksc: KernelSyscallObject | undefined,
147
+ * vsc: VatSyscallObject) => SlogFinishSyscall,
148
+ * changeCList: (vatID: string,
149
+ * crankNum: BigInt,
150
+ * mode: 'import' | 'export' | 'drop',
151
+ * kernelSlot: string,
152
+ * vatSlot: string) => void,
147
153
  * terminateVat: (vatID: string, shouldReject: boolean, info: SwingSetCapData) => void,
148
154
  * } } KernelSlog
149
155
  * @typedef {{
@@ -111,7 +111,7 @@ export {};
111
111
  * enableDisavow: boolean,
112
112
  * useTranscript: boolean,
113
113
  * name: string,
114
- * sourcedConsole: Pick<Console, 'debug' | 'log' | 'info' | 'warn' | 'error'>,
114
+ * sourcedConsole: import('@agoric/internal/src/js-utils.js').LimitedConsole,
115
115
  * enableSetup: boolean,
116
116
  * setup?: unknown,
117
117
  * retainSyscall?: boolean