Skip to content

Commit

Permalink
feat: support vats without transcripts, notably the comms vat (to sta…
Browse files Browse the repository at this point in the history
…rt with)

Implements #3217
  • Loading branch information
FUDCo committed Jun 9, 2021
1 parent e8bab9b commit 18d6050
Show file tree
Hide file tree
Showing 13 changed files with 75 additions and 26 deletions.
1 change: 1 addition & 0 deletions packages/SwingSet/src/initializeSwingset.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ export async function initializeSwingset(
// non-local workers any time soon.
enableSetup: true,
managerType: 'local',
useTranscript: false,
},
};

Expand Down
1 change: 1 addition & 0 deletions packages/SwingSet/src/kernel/initializeKernel.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export function initializeKernel(config, hostStorage, verbose = false) {
'enableDisavow',
'enableSetup',
'virtualObjectCacheSize',
'useTranscript',
]);
creationOptions.vatParameters = vatParameters;
creationOptions.description = `static name=${name}`;
Expand Down
10 changes: 10 additions & 0 deletions packages/SwingSet/src/kernel/loadVat.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export function makeVatLoader(stuff) {
'enableSetup',
'enablePipelining',
'virtualObjectCacheSize',
'useTranscript',
];

const allowedStaticOptions = [
Expand All @@ -96,6 +97,7 @@ export function makeVatLoader(stuff) {
'enableSetup',
'enablePipelining',
'virtualObjectCacheSize',
'useTranscript',
];

/**
Expand Down Expand Up @@ -139,6 +141,11 @@ export function makeVatLoader(stuff) {
* without waiting for the promises to be resolved. If false, such
* messages will be queued inside the kernel. Defaults to false.
*
* 'useTranscript' If true, saves a transcript of a vat's inbound
* deliveries and outbound syscalls so that the vat's internal state
* can be reconstructed via replay. If false, no such record is kept.
* Defaults to true.
*
* @param {boolean} isDynamic If true, the vat being created is a dynamic vat;
* if false, it's a static vat (these have differences in their allowed
* options and some of their option defaults).
Expand Down Expand Up @@ -169,6 +176,7 @@ export function makeVatLoader(stuff) {
enableDisavow = false,
enablePipelining = false,
virtualObjectCacheSize,
useTranscript = true,
name,
} = options;

Expand Down Expand Up @@ -199,6 +207,7 @@ export function makeVatLoader(stuff) {
liveSlotsConsole: makeVatConsole('ls', vatID),
vatParameters,
virtualObjectCacheSize,
useTranscript,
name,
};

Expand All @@ -220,6 +229,7 @@ export function makeVatLoader(stuff) {
setup,
enableSetup: true,
managerType: 'local',
useTranscript: true,
};
const translators = makeVatTranslators(vatID, kernelKeeper);
const vatSyscallHandler = buildVatSyscallHandler(vatID, translators);
Expand Down
1 change: 1 addition & 0 deletions packages/SwingSet/src/kernel/vatManager/factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export function makeVatManagerFactory({
'enableSetup',
'liveSlotsConsole',
'virtualObjectCacheSize',
'useTranscript',
'vatParameters',
'vatConsole',
'name',
Expand Down
57 changes: 35 additions & 22 deletions packages/SwingSet/src/kernel/vatManager/manager-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,18 @@ function makeManagerKit(
vatSyscallHandler,
workerCanBlock,
compareSyscalls,
useTranscript,
) {
assert(kernelSlog);
const vatKeeper = kernelKeeper.getVatKeeper(vatID);
const transcriptManager = makeTranscriptManager(
vatKeeper,
vatID,
compareSyscalls,
);
let transcriptManager;
if (useTranscript) {
transcriptManager = makeTranscriptManager(
vatKeeper,
vatID,
compareSyscalls,
);
}

/** @type { (delivery: VatDeliveryObject) => Promise<VatDeliveryResult> } */
let deliverToWorker;
Expand All @@ -138,19 +142,24 @@ function makeManagerKit(
* @returns { Promise<VatDeliveryResult> }
*/
async function deliver(delivery) {
transcriptManager.startDispatch(delivery);
if (transcriptManager) {
transcriptManager.startDispatch(delivery);
}
/** @type { VatDeliveryResult } */
const status = await deliverToWorker(delivery).catch(err =>
harden(['error', err.message, null]),
);
insistVatDeliveryResult(status);
// TODO: if the dispatch failed for whatever reason, and we choose to
// destroy the vat, change what we do with the transcript here.
transcriptManager.finishDispatch();
if (transcriptManager) {
transcriptManager.finishDispatch();
}
return status;
}

async function replayOneDelivery(delivery, expectedSyscalls, deliveryNum) {
assert(transcriptManager, `delivery replay with no transcript`);
transcriptManager.startReplay();
transcriptManager.startReplayDelivery(expectedSyscalls);
kernelSlog.write({
Expand All @@ -167,20 +176,22 @@ function makeManagerKit(
}

async function replayTranscript() {
const total = vatKeeper.vatStats().transcriptCount;
kernelSlog.write({ type: 'start-replay', vatID, deliveries: total });
let deliveryNum = 0;
for (const t of vatKeeper.getTranscript()) {
// if (deliveryNum % 100 === 0) {
// console.debug(`replay vatID:${vatID} deliveryNum:${deliveryNum} / ${total}`);
// }
//
// eslint-disable-next-line no-await-in-loop
await replayOneDelivery(t.d, t.syscalls, deliveryNum);
deliveryNum += 1;
if (transcriptManager) {
const total = vatKeeper.vatStats().transcriptCount;
kernelSlog.write({ type: 'start-replay', vatID, deliveries: total });
let deliveryNum = 0;
for (const t of vatKeeper.getTranscript()) {
// if (deliveryNum % 100 === 0) {
// console.debug(`replay vatID:${vatID} deliveryNum:${deliveryNum} / ${total}`);
// }
//
// eslint-disable-next-line no-await-in-loop
await replayOneDelivery(t.d, t.syscalls, deliveryNum);
deliveryNum += 1;
}
transcriptManager.checkReplayError();
kernelSlog.write({ type: 'finish-replay', vatID });
}
transcriptManager.checkReplayError();
kernelSlog.write({ type: 'finish-replay', vatID });
}

/**
Expand All @@ -194,7 +205,7 @@ function makeManagerKit(
* @returns { VatSyscallResult }
*/
function syscallFromWorker(vso) {
if (transcriptManager.inReplay()) {
if (transcriptManager && transcriptManager.inReplay()) {
// We're replaying old messages to bring the vat's internal state
// up-to-date. It will make syscalls like a puppy chasing rabbits in
// its sleep. Gently prevent their twitching paws from doing anything.
Expand All @@ -211,7 +222,9 @@ function makeManagerKit(
if (data && !workerCanBlock) {
console.log(`warning: syscall returns data, but worker cannot get it`);
}
transcriptManager.addSyscall(vso, data);
if (transcriptManager) {
transcriptManager.addSyscall(vso, data);
}
}
return vres;
}
Expand Down
14 changes: 12 additions & 2 deletions packages/SwingSet/src/kernel/vatManager/manager-local.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,13 @@ export function makeLocalVatManagerFactory(tools) {
};
// testLog is also a vatPower, only for unit tests

function prepare(vatID, vatSyscallHandler, meterRecord, compareSyscalls) {
function prepare(
vatID,
vatSyscallHandler,
meterRecord,
compareSyscalls,
useTranscript,
) {
const mtools = harden({ stopGlobalMeter, meterRecord, refillAllMeters });
const mk = makeManagerKit(
vatID,
Expand All @@ -35,6 +41,7 @@ export function makeLocalVatManagerFactory(tools) {
vatSyscallHandler,
true,
compareSyscalls,
useTranscript,
);

function finish(dispatch) {
Expand All @@ -60,12 +67,13 @@ export function makeLocalVatManagerFactory(tools) {
assert(!managerOptions.metered, X`unsupported`);
assert(setup instanceof Function, 'setup is not an in-realm function');

const { vatParameters, compareSyscalls } = managerOptions;
const { vatParameters, compareSyscalls, useTranscript } = managerOptions;
const { syscall, finish } = prepare(
vatID,
vatSyscallHandler,
null,
compareSyscalls,
useTranscript,
);
const { testLog } = allVatPowers;
const helpers = harden({}); // DEPRECATED, todo remove from setup()
Expand All @@ -91,6 +99,7 @@ export function makeLocalVatManagerFactory(tools) {
liveSlotsConsole,
virtualObjectCacheSize,
compareSyscalls,
useTranscript,
} = managerOptions;
assert(vatConsole, 'vats need managerOptions.vatConsole');

Expand All @@ -112,6 +121,7 @@ export function makeLocalVatManagerFactory(tools) {
vatSyscallHandler,
meterRecord,
compareSyscalls,
useTranscript,
);

const vatPowers = harden({
Expand Down
2 changes: 2 additions & 0 deletions packages/SwingSet/src/kernel/vatManager/manager-nodeworker.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export function makeNodeWorkerVatManagerFactory(tools) {
virtualObjectCacheSize,
enableDisavow,
compareSyscalls,
useTranscript,
} = managerOptions;
assert(!managerOptions.metered, 'not supported yet');
assert(!managerOptions.enableSetup, 'not supported at all');
Expand All @@ -55,6 +56,7 @@ export function makeNodeWorkerVatManagerFactory(tools) {
vatSyscallHandler,
false,
compareSyscalls,
useTranscript,
);

// start the worker and establish a connection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export function makeNodeSubprocessFactory(tools) {
virtualObjectCacheSize,
enableDisavow,
compareSyscalls,
useTranscript,
} = managerOptions;
assert(!managerOptions.metered, 'not supported yet');
assert(!managerOptions.enableSetup, 'not supported at all');
Expand All @@ -32,6 +33,7 @@ export function makeNodeSubprocessFactory(tools) {
vatSyscallHandler,
false,
compareSyscalls,
useTranscript,
);

// start the worker and establish a connection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export function makeXsSubprocessFactory({
name,
metered,
compareSyscalls,
useTranscript,
} = managerOptions;
assert(
!managerOptions.enableSetup,
Expand All @@ -67,6 +68,7 @@ export function makeXsSubprocessFactory({
vatSyscallHandler,
true,
compareSyscalls,
useTranscript,
);

/** @type { (item: Tagged) => unknown } */
Expand Down
2 changes: 2 additions & 0 deletions packages/SwingSet/src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
* managerType: ManagerType,
* metered?: boolean,
* enableDisavow?: boolean,
* useTranscript?: boolean,
* vatParameters: Record<string, unknown>,
* virtualObjectCacheSize: number,
* vatParameters: Record<string, unknown>,
* name: string,
Expand Down
2 changes: 2 additions & 0 deletions packages/SwingSet/test/test-gc-transcript.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ function setup(storedTranscript = []) {
kernelKeeper,
vatSyscallHandler,
workerCanBlock,
undefined,
true,
);
const { syscallFromWorker } = mk;
function deliver(_delivery) {
Expand Down
1 change: 1 addition & 0 deletions packages/SwingSet/test/test-message-patterns.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ test.before(async t => {
enablePipelining: true,
enableSetup: true,
managerType: 'local',
useTranscript: false,
},
};
const moreVatTP = { bundle: kernelBundles.vattp };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"botcomms": {
"bundleName": "commsvat",
"creationOptions": {
"enableSetup": true
"enableSetup": true,
"useTranscript": false
}
},
"botvattp": {
Expand All @@ -31,7 +32,8 @@
"usercomms": {
"bundleName": "commsvat",
"creationOptions": {
"enableSetup": true
"enableSetup": true,
"useTranscript": false
}
},
"uservattp": {
Expand Down

0 comments on commit 18d6050

Please sign in to comment.