@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.
@@ -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
- const upgradeVatV0toV1 = (kvStore, defaultReapDirtThreshold, vatID) => {
17
- // This is called, once per vat, when upgradeSwingset migrates from
18
- // v0 to v1
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 = kvStore.get(oldReapIntervalKey);
42
- const reapCountdownString = kvStore.get(oldReapCountdownKey);
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 = Number.parseInt(reapIntervalString, 10);
66
- const reapCountdown = Number.parseInt(reapCountdownString, 10);
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(kvStore.get(vatOptionsKey));
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
- let vstring = kvStore.get('version');
111
- if (vstring === undefined) {
112
- vstring = '0';
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
- const value = Number.parseInt(oldValue, 10);
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
- modified = true;
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
- modified = true;
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
- modified = true;
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', `${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 JSON.parse(JSON.stringify(data));
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 = JSON.parse(JSON.stringify(args));
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
@@ -8,6 +8,7 @@ export {
8
8
  buildKernelBundles,
9
9
  loadBasedir,
10
10
  loadSwingsetConfigFile,
11
+ normalizeConfig,
11
12
  } from './controller/initializeSwingset.js';
12
13
  export { upgradeSwingset } from './controller/upgradeSwingset.js';
13
14
  export {
@@ -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 { makeVatManagerFactory } from './vat-loader/manager-factory.js';
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 : () => 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
 
@@ -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 vatManagerFactory = makeVatManagerFactory({
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
- vatManagerFactory,
1653
+ makeVatManager,
1657
1654
  kernelSlog,
1658
1655
  makeSourcedConsole,
1659
1656
  kernelKeeper,
@@ -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
  }