Skip to content

Commit

Permalink
feat(swingset)!: remove support for non-XS metering
Browse files Browse the repository at this point in the history
We no longer care about injected (Node.js) -based metering: XS is the only
platform where we can reasonably+efficiently meter code.

This removes support for passing `{ managerType: 'local', metered: true }` to
`createVat()`. Doing so will throw an exception when the vatManager is
invoked. Using just `{ metered: true }` is also an error when the swingset
`config.defaultManagerType` is not set to `xs-worker`. Applications that want
metered dynamic vats (i.e. all of them) should set `config.defaultManagerType
= 'xs-worker'` to avoid this.

This commit removes support throughout swingset:
* `transformMetering` is no longer passed from controller to kernel to the
local vatManager, and the transform is no longer applied to
`inescapableTransforms` to ensure sub-Compartments are also transformed
* `getMeter` is no longer placed on `inescapableLexicals`
* `replaceGlobalMeter` is no longer passed through to `supervisor-helper`,
where it was used to disable metering at the end of each crank
* the kernel `meterManager` facilities were removed
* all tests of metering non-XS workers are removed, including a test that
exercised sub-Compartments (which was specific to the injection approach)

Some tests have been modernized slightly, to use `controller.kpResolution`
instead of appending strings to testLog, and to use `prepare-test-env-ava`
instead of `@agoric/install-ses`.

Dependency updates:

Swingset no longer uses `@agoric/install-metering-and-ses`, or the
`tame-metering`/`transform-metering` packages. A vestigal dependency on
`babel-parser` (left over from the transform-tildot days) was removed.
Swingset still depends upon `babel-standalone`, to pre-load before `lockdown`
in `prepare-test-env-ava`.

closes #3518
  • Loading branch information
warner committed Jul 24, 2021
1 parent c73dd8d commit 5b95638
Show file tree
Hide file tree
Showing 19 changed files with 99 additions and 677 deletions.
2 changes: 0 additions & 2 deletions packages/SwingSet/bin/replay-transcript.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@ async function replay(transcriptFile, worker = 'xs-worker') {
allVatPowers,
kernelKeeper: fakeKernelKeeper,
vatEndowments: {},
meterManager: {},
transformMetering: undefined,
gcTools,
kernelSlog,
});
Expand Down
4 changes: 0 additions & 4 deletions packages/SwingSet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,11 @@
"lint:eslint": "eslint '**/*.js'"
},
"devDependencies": {
"@agoric/install-metering-and-ses": "^0.2.20",
"@endo/ses-ava": "^0.2.4",
"ava": "^3.12.1"
},
"dependencies": {
"@agoric/assert": "^0.3.6",
"@agoric/babel-parser": "^7.6.4",
"@agoric/babel-standalone": "^7.14.3",
"@agoric/bundle-source": "^1.4.4",
"@agoric/captp": "^1.7.20",
Expand All @@ -47,8 +45,6 @@
"@agoric/store": "^0.4.22",
"@agoric/swing-store-lmdb": "^0.5.6",
"@agoric/swing-store-simple": "^0.4.6",
"@agoric/tame-metering": "^2.0.6",
"@agoric/transform-metering": "^1.4.19",
"@agoric/xsnap": "^0.6.9",
"@endo/base64": "^0.2.4",
"@types/tmp": "^0.2.0",
Expand Down
36 changes: 0 additions & 36 deletions packages/SwingSet/src/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import { Worker } from 'worker_threads';
import anylogger from 'anylogger';

import { assert, details as X } from '@agoric/assert';
import { isTamed, tameMetering } from '@agoric/tame-metering';
import { importBundle } from '@agoric/import-bundle';
import { makeMeteringTransformer } from '@agoric/transform-metering';
import { xsnap, recordXSnap } from '@agoric/xsnap';

import engineGC from './engine-gc.js';
Expand Down Expand Up @@ -220,45 +218,13 @@ export async function makeSwingsetController(
const buildKernel = kernelNS.default;
writeSlogObject({ type: 'import-kernel-finish' });

// transformMetering() requires Babel, which imports 'fs' and 'path', so it
// cannot be implemented within a non-start-Compartment. We build it out
// here and pass it to the kernel, which then passes it to vats. This is
// intended to be powerless.
const mt = makeMeteringTransformer();
function transformMetering(src, getMeter) {
// 'getMeter' provides the meter to which the transformation itself is
// billed (the COMPUTE meter is charged the length of the source string).
// The endowment must be present and truthy, otherwise the transformation
// is disabled. TODO: rethink that, and have @agoric/transform-metering
// export a simpler function (without 'endowments' or .rewrite).
const ss = mt.rewrite({ src, endowments: { getMeter } });
return ss.src;
}
harden(transformMetering);

// all vats get these in their global scope, plus a vat-specific 'console'
const vatEndowments = harden({
// re2 is a RegExp work-a-like that disables backtracking expressions for
// safer memory consumption
RegExp: re2,
});

// It is important that tameMetering() was called by application startup,
// before install-ses. Rather than ask applications to capture the return
// value and pass it all the way through to here, we just run
// tameMetering() again (and rely upon its only-once behavior) to get the
// control facet (replaceGlobalMeter), and pass it in through
// kernelEndowments. If our enclosing application decided to not tame the
// globals, we detect that and refrain from touching it later.
const replaceGlobalMeter = isTamed() ? tameMetering() : undefined;
if (verbose) {
console.log(
`SwingSet global metering is ${
isTamed() ? 'enabled' : 'disabled (no replaceGlobalMeter)'
}`,
);
}

// this launches a worker in a Node.js thread (aka "Worker")
function makeNodeWorker() {
// TODO: after we move away from `-r esm` and use real ES6 modules, point
Expand Down Expand Up @@ -296,8 +262,6 @@ export async function makeSwingsetController(
debugPrefix,
vatEndowments,
makeConsole,
replaceGlobalMeter,
transformMetering,
makeNodeWorker,
startSubprocessWorkerNode,
startXSnap,
Expand Down
7 changes: 0 additions & 7 deletions packages/SwingSet/src/kernel/kernel.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { insistStorageAPI } from '../storageAPI.js';
import { insistCapData } from '../capdata.js';
import { insistMessage, insistVatDeliveryResult } from '../message.js';
import { insistDeviceID, insistVatID } from './id.js';
import { makeMeterManager } from './metering.js';
import { makeKernelSyscallHandler, doSend } from './kernelSyscall.js';
import { makeSlogger, makeDummySlogger } from './slogger.js';
import { getKpidsToRetire } from './cleanup.js';
Expand Down Expand Up @@ -120,8 +119,6 @@ export default function buildKernel(
vatEndowments,
slogCallbacks = {},
makeConsole,
replaceGlobalMeter,
transformMetering,
makeNodeWorker,
startSubprocessWorkerNode,
startXSnap,
Expand Down Expand Up @@ -159,8 +156,6 @@ export default function buildKernel(
snapStore,
);

const meterManager = makeMeterManager(replaceGlobalMeter);

let started = false;

/**
Expand Down Expand Up @@ -717,8 +712,6 @@ export default function buildKernel(
allVatPowers,
kernelKeeper,
vatEndowments,
meterManager,
transformMetering,
makeNodeWorker,
startSubprocessWorkerNode,
startXSnap,
Expand Down
118 changes: 0 additions & 118 deletions packages/SwingSet/src/kernel/metering.js

This file was deleted.

4 changes: 0 additions & 4 deletions packages/SwingSet/src/kernel/vatManager/factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ export function makeVatManagerFactory({
allVatPowers,
kernelKeeper,
vatEndowments,
meterManager,
transformMetering,
makeNodeWorker,
startSubprocessWorkerNode,
startXSnap,
Expand All @@ -22,8 +20,6 @@ export function makeVatManagerFactory({
allVatPowers,
kernelKeeper,
vatEndowments,
meterManager,
transformMetering,
gcTools,
kernelSlog,
});
Expand Down
47 changes: 4 additions & 43 deletions packages/SwingSet/src/kernel/vatManager/manager-local.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { makeLiveSlots } from '../liveSlots.js';
import { makeManagerKit } from './manager-helper.js';
import {
makeSupervisorDispatch,
makeMeteredDispatch,
makeSupervisorSyscall,
makeVatConsole,
} from './supervisor-helper.js';
Expand All @@ -15,26 +14,16 @@ export function makeLocalVatManagerFactory(tools) {
allVatPowers,
kernelKeeper,
vatEndowments,
meterManager,
transformMetering,
gcTools,
kernelSlog,
} = tools;

const { makeGetMeter, refillAllMeters, stopGlobalMeter } = meterManager;
const baseVP = {
makeMarshal: allVatPowers.makeMarshal,
};
// testLog is also a vatPower, only for unit tests

function prepare(
vatID,
vatSyscallHandler,
meterRecord,
compareSyscalls,
useTranscript,
) {
const mtools = harden({ stopGlobalMeter, meterRecord, refillAllMeters });
function prepare(vatID, vatSyscallHandler, compareSyscalls, useTranscript) {
const mk = makeManagerKit(
vatID,
kernelSlog,
Expand All @@ -48,11 +37,7 @@ export function makeLocalVatManagerFactory(tools) {
function finish(dispatch) {
assert.typeof(dispatch, 'function');
// this 'deliverToWorker' never throws, even if liveslots has an internal error
const deliverToWorker = makeMeteredDispatch(
makeSupervisorDispatch(dispatch),
mtools,
);
mk.setDeliverToWorker(deliverToWorker);
mk.setDeliverToWorker(makeSupervisorDispatch(dispatch));

async function shutdown() {
// local workers don't need anything special to shut down between turns
Expand All @@ -65,14 +50,13 @@ export function makeLocalVatManagerFactory(tools) {
}

function createFromSetup(vatID, setup, managerOptions, vatSyscallHandler) {
assert(!managerOptions.metered, X`unsupported`);
assert(!managerOptions.metered, `metering unsupported on 'local' workers`);
assert(setup instanceof Function, 'setup is not an in-realm function');

const { vatParameters, compareSyscalls, useTranscript } = managerOptions;
const { syscall, finish } = prepare(
vatID,
vatSyscallHandler,
null,
compareSyscalls,
useTranscript,
);
Expand All @@ -91,9 +75,9 @@ export function makeLocalVatManagerFactory(tools) {
managerOptions,
vatSyscallHandler,
) {
assert(!managerOptions.metered, `metering unsupported on 'local' workers`);
const {
consensusMode,
metered = false,
enableDisavow = false,
enableSetup = false,
vatParameters = {},
Expand All @@ -106,23 +90,9 @@ export function makeLocalVatManagerFactory(tools) {
} = managerOptions;
assert(vatConsole, 'vats need managerOptions.vatConsole');

let meterRecord = null;
if (metered) {
// fail-stop: we refill the meter after each crank (in vatManager
// doProcess()), but if the vat exhausts its meter within a single
// crank, it will never run again. We set refillEachCrank:false because
// we want doProcess to do the refilling itself, so it can count the
// usage
meterRecord = makeGetMeter({
refillEachCrank: false,
refillIfExhausted: false,
});
}

const { syscall, finish } = prepare(
vatID,
vatSyscallHandler,
meterRecord,
compareSyscalls,
useTranscript,
);
Expand Down Expand Up @@ -155,20 +125,11 @@ export function makeLocalVatManagerFactory(tools) {
}),
assert,
});
const inescapableTransforms = [];
const inescapableGlobalProperties = { ...ls.inescapableGlobalProperties };
const inescapableGlobalLexicals = {};
if (metered) {
const getMeter = meterRecord.getMeter;
inescapableTransforms.push(src => transformMetering(src, getMeter));
inescapableGlobalLexicals.getMeter = getMeter;
}

const vatNS = await importBundle(bundle, {
filePrefix: `vat-${vatID}/...`,
endowments,
inescapableTransforms,
inescapableGlobalLexicals,
inescapableGlobalProperties,
});

Expand Down
Loading

0 comments on commit 5b95638

Please sign in to comment.