Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DO NOT MERGE: test 10795 against endo#2684 sham non-trapping #10796

Draft
wants to merge 2 commits into
base: markm-prepare-for-non-trapping
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { $ } from 'execa';

const waitForBootstrap = async () => {
const endpoint = 'localhost';
// eslint-disable-next-line no-constant-condition
while (true) {
const { stdout: json } = await $({
reject: false,
Expand Down Expand Up @@ -37,6 +38,7 @@ export const waitForBlock = async (n = 1) => {
const h0 = await waitForBootstrap();
let lastHeight = h0;
for (let i = 0; i < n; i += 1) {
// eslint-disable-next-line no-constant-condition
while (true) {
await new Promise(r => setTimeout(r, 1000));
const currentHeight = await waitForBootstrap();
Expand Down
13 changes: 12 additions & 1 deletion packages/SwingSet/src/kernel/deviceSlots.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@ import {
} from '../lib/parseVatSlots.js';
import { insistCapData } from '../lib/capdata.js';

const { freeze } = Object;

/**
* `freeze` but not `harden` the proxy target so it remains trapping.
* Although a frozen-only object will not be defensive, since it could still
* be made non-trapping, these are encapsulated only within proxies that
* will refuse to be made non-trapping, and so can safely be shared.
* @see /~https://github.com/endojs/endo/blob/master/packages/ses/docs/preparing-for-stabilize.md
*/
const target = freeze({});

// 'makeDeviceSlots' is a subset of makeLiveSlots, for device code

export function makeDeviceSlots(
Expand Down Expand Up @@ -142,7 +153,7 @@ export function makeDeviceSlots(
(slot && parseVatSlot(slot).type === 'object') ||
Fail`SO(x) must be called on a Presence, not ${x}`;
const handler = PresenceHandler(slot);
const p = harden(new Proxy({}, handler));
const p = new Proxy(target, handler);
outstandingProxies.add(p);
return p;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/SwingSet/test/metering/metered-code.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function meterMe(log2, explode = 'no') {
}
try {
if (explode === 'compute') {
// eslint-disable-next-line no-empty
// eslint-disable-next-line no-empty, no-constant-condition
while (true) {}
} else if (explode === 'stack') {
delveForeverIntoTheRecursiveDepths();
Expand Down
2 changes: 2 additions & 0 deletions packages/SwingSet/test/upgrade/upgrade.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ const initKernelForTest = async (t, bundleData, config, options = {}) => {
};
};

// Gratuitous change so I can create an otherwise identical PR

const testNullUpgrade = async (t, defaultManagerType) => {
const config = makeConfigFromPaths('../../tools/bootstrap-relay.js', {
defaultManagerType,
Expand Down
28 changes: 24 additions & 4 deletions packages/SwingSet/tools/run-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { makeQueue } from '@endo/stream';
* @import { RunPolicy } from '../src/types-external.js'
*/

const { freeze } = Object;

/** @typedef {{ provideRunPolicy: () => RunPolicy | undefined }} RunHarness */

/**
Expand Down Expand Up @@ -103,11 +105,29 @@ export const makeRunUtils = (controller, harness) => {
// promise that can remain pending indefinitely, possibly to be settled by a
// future message delivery.

/**
* `freeze` but not `harden` the proxy target so it remains trapping.
* Although a frozen-only object will not be defensive, since it could still
* be made non-trapping, these are encapsulated only within proxies that
* will refuse to be made non-trapping, and so can safely be shared.
* @see /~https://github.com/endojs/endo/blob/master/packages/ses/docs/preparing-for-stabilize.md
*/
const objTarget = freeze({});

/**
* `freeze` but not `harden` the proxy target so it remains trapping.
* Although a frozen-only object will not be defensive, since it could still
* be made non-trapping, these are encapsulated only within proxies that
* will refuse to be made non-trapping, and so can safely be shared.
* @see /~https://github.com/endojs/endo/blob/master/packages/ses/docs/preparing-for-stabilize.md
*/
const funcTarget = freeze(() => {});

/** @type {EVProxy} */
// @ts-expect-error cast, approximate
const EV = Object.assign(
presence =>
new Proxy(harden({}), {
new Proxy(funcTarget, {
get: (_t, method, _rx) => {
const boundMethod = (...args) =>
queueAndRun(() =>
Expand All @@ -118,7 +138,7 @@ export const makeRunUtils = (controller, harness) => {
}),
{
vat: vatName =>
new Proxy(harden({}), {
new Proxy(funcTarget, {
get: (_t, method, _rx) => {
const boundMethod = (...args) =>
queueAndRun(() =>
Expand All @@ -128,7 +148,7 @@ export const makeRunUtils = (controller, harness) => {
},
}),
sendOnly: presence =>
new Proxy(harden({}), {
new Proxy(funcTarget, {
get: (_t, method, _rx) => {
const boundMethod = (...args) =>
queueAndRun(
Expand All @@ -139,7 +159,7 @@ export const makeRunUtils = (controller, harness) => {
},
}),
get: presence =>
new Proxy(harden({}), {
new Proxy(objTarget, {
get: (_t, pathElement, _rx) =>
queueAndRun(() =>
controller.queueToVatRoot('bootstrap', 'awaitVatObject', [
Expand Down
9 changes: 8 additions & 1 deletion packages/swingset-liveslots/src/liveslots.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { makeCollectionManager } from './collectionManager.js';
import { makeWatchedPromiseManager } from './watchedPromises.js';
import { makeBOYDKit } from './boyd-gc.js';

const { freeze } = Object;

const SYSCALL_CAPDATA_BODY_SIZE_LIMIT = 10_000_000;
const SYSCALL_CAPDATA_SLOTS_LENGTH_LIMIT = 10_000;

Expand Down Expand Up @@ -864,8 +866,13 @@ function build(
if (!slot || parseVatSlot(slot).type !== 'device') {
throw Error('D() must be given a device node');
}
/**
* `freeze` but not `harden` the proxy target so it remains trapping.
* @see /~https://github.com/endojs/endo/blob/master/packages/ses/docs/preparing-for-stabilize.md
*/
const target = freeze({});
const handler = DeviceHandler(slot);
const pr = harden(new Proxy({}, handler));
const pr = new Proxy(target, handler);
outstandingProxies.add(pr);
return pr;
}
Expand Down
16 changes: 14 additions & 2 deletions packages/vats/src/core/promise-space.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { assertKey } from '@agoric/store';
import { canBeDurable } from '@agoric/vat-data';
import { makePromiseKit } from '@endo/promise-kit';

const { freeze } = Object;

/**
* @typedef {{
* onAddKey: (key: string) => void;
Expand All @@ -14,6 +16,16 @@ import { makePromiseKit } from '@endo/promise-kit';

const noop = harden(() => {});

/**
* `freeze` but not `harden` the proxy target so it remains trapping. Although a
* frozen-only object will not be defensive, since it could still be made
* non-trapping, these are encapsulated only within proxies that will refuse to
* be made non-trapping, and so can safely be shared.
*
* @see /~https://github.com/endojs/endo/blob/master/packages/ses/docs/preparing-for-stabilize.md
*/
const target = freeze({});

/**
* @param {typeof console.log} log
* @returns {PromiseSpaceHooks}
Expand Down Expand Up @@ -167,7 +179,7 @@ export const makePromiseSpace = (optsOrLog = {}) => {

/** @type {PromiseSpaceOf<T>['consume']} */
// @ts-expect-error cast
const consume = new Proxy(harden({}), {
const consume = new Proxy(target, {
get: (_target, name) => {
assert.typeof(name, 'string');
return provideState(name).pk.promise;
Expand All @@ -176,7 +188,7 @@ export const makePromiseSpace = (optsOrLog = {}) => {

/** @type {PromiseSpaceOf<T>['produce']} */
// @ts-expect-error cast
const produce = new Proxy(harden({}), {
const produce = new Proxy(target, {
get: (_target, name) => {
assert.typeof(name, 'string');
return makeProducer(name);
Expand Down
9 changes: 7 additions & 2 deletions packages/vats/src/core/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { makeLogHooks, makePromiseSpace } from './promise-space.js';

import './types-ambient.js';

const { entries, fromEntries, keys } = Object;
const { entries, fromEntries, keys, freeze } = Object;

/**
* Used in bootstrap to reserve names in the agoricNames namespace before any
Expand Down Expand Up @@ -130,7 +130,12 @@ export const extract = (template, specimen, path = []) => {
specimen,
)}`;
}
const target = harden(
/**
* `freeze` but not `harden` the proxy target so it remains trapping.
*
* @see /~https://github.com/endojs/endo/blob/master/packages/ses/docs/preparing-for-stabilize.md
*/
const target = freeze(
fromEntries(
entries(template).map(([propName, subTemplate]) => [
propName,
Expand Down
40 changes: 24 additions & 16 deletions packages/vow/src/E.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { X, q, Fail, makeError } from '@endo/errors';
import { trackTurns } from './track-turns.js';
import { makeMessageBreakpointTester } from './message-breakpoints.js';

const { assign, create } = Object;
const { assign, create, freeze } = Object;

const onSend = makeMessageBreakpointTester('ENDO_SEND_BREAKPOINTS');

Expand Down Expand Up @@ -200,6 +200,24 @@ const makeEGetProxyHandler = (x, HandledPromise, unwrap) =>
/** @param {any} x */
const resolve = x => HandledPromise.resolve(x);

/**
* `freeze` but not `harden` the proxy target so it remains trapping.
* Although a frozen-only object will not be defensive, since it could still
* be made non-trapping, these are encapsulated only within proxies that
* will refuse to be made non-trapping, and so can safely be shared.
* @see /~https://github.com/endojs/endo/blob/master/packages/ses/docs/preparing-for-stabilize.md
*/
const objTarget = freeze(create(null));

/**
* `freeze` but not `harden` the proxy target so it remains trapping.
* Although a frozen-only object will not be defensive, since it could still
* be made non-trapping, these are encapsulated only within proxies that
* will refuse to be made non-trapping, and so can safely be shared.
* @see /~https://github.com/endojs/endo/blob/master/packages/ses/docs/preparing-for-stabilize.md
*/
const funcTarget = freeze(() => {});

/**
* @template [A={}]
* @param {HandledPromiseConstructor} HandledPromise
Expand All @@ -224,10 +242,7 @@ const makeE = (HandledPromise, powers = {}) => {
* @param {T} x target for method/function call
* @returns {ECallableOrMethods<RemoteFunctions<T>>} method/function call proxy
*/
x =>
harden(
new Proxy(() => {}, makeEProxyHandler(x, HandledPromise, unwrap)),
),
x => new Proxy(funcTarget, makeEProxyHandler(x, HandledPromise, unwrap)),
{
/**
* E.get(x) returns a proxy on which you can get arbitrary properties.
Expand All @@ -241,12 +256,7 @@ const makeE = (HandledPromise, powers = {}) => {
* @readonly
*/
get: x =>
harden(
new Proxy(
create(null),
makeEGetProxyHandler(x, HandledPromise, unwrap),
),
),
new Proxy(objTarget, makeEGetProxyHandler(x, HandledPromise, unwrap)),

/**
* E.resolve(x) converts x to a handled promise. It is
Expand All @@ -269,11 +279,9 @@ const makeE = (HandledPromise, powers = {}) => {
* @readonly
*/
sendOnly: x =>
harden(
new Proxy(
() => {},
makeESendOnlyProxyHandler(x, HandledPromise, unwrap),
),
new Proxy(
funcTarget,
makeESendOnlyProxyHandler(x, HandledPromise, unwrap),
),

/**
Expand Down
Loading