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

add (dummy) dispatch.dropExports to liveslots, test that it can be called #2656

Merged
merged 1 commit into from
Mar 22, 2021
Merged
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
1 change: 1 addition & 0 deletions packages/SwingSet/docs/vat-worker.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ The `Delivery` object is a hardened Array of data (Objects, Arrays, and Strings,

* `['message', targetSlot, msg]`
* `['notify', resolutions]`
* `['dropExports', vrefs]`

In the `message` form, `targetSlot` is a object/promise reference (a string like `o+13` or `p-24`), which identifies the object or promise to which the message is being sent. This target can be a promise if the message is being pipelined to the result of some earlier message.

Expand Down
9 changes: 8 additions & 1 deletion packages/SwingSet/src/kernel/liveSlots.js
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,13 @@ function build(
}
}

function dropExports(vrefs) {
assert(Array.isArray(vrefs));
vrefs.map(vref => insistVatType('object', vref));
vrefs.map(vref => assert(parseVatSlot(vref).allocatedByVat));
console.log(`-- liveslots ignoring dropExports`);
}

// TODO: when we add notifyForward, guard against cycles

function exitVat(completion) {
Expand Down Expand Up @@ -676,7 +683,7 @@ function build(
slotToVal.set(rootSlot, rootObject);
}

const dispatch = harden({ deliver, notify });
const dispatch = harden({ deliver, notify, dropExports });
return harden({ vatGlobals, setBuildRootObject, dispatch, m });
}

Expand Down
7 changes: 7 additions & 0 deletions packages/SwingSet/src/kernel/vatManager/deliver.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ export function makeDeliver(tools, dispatch) {
return doProcess(['notify', resolutions], errmsg);
}

async function deliverOneDropExports(vrefs) {
const errmsg = `vat[${vatID}].dropExports failed`;
return doProcess(['dropExports', vrefs], errmsg);
}

// vatDeliverObject is:
// ['message', target, msg]
// target is vid
Expand All @@ -109,6 +114,8 @@ export function makeDeliver(tools, dispatch) {
return deliverOneMessage(...args);
case 'notify':
return deliverOneNotification(...args);
case 'dropExports':
return deliverOneDropExports(...args);
default:
assert.fail(X`unknown delivery type ${type}`);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ function doNotify(resolutions) {
return doProcess(['notify', resolutions], errmsg);
}

function doDropExports(vrefs) {
const errmsg = `vat.doDropExport failed`;
return doProcess(['dropExports', vrefs], errmsg);
}

parentPort.on('message', ([type, ...margs]) => {
workerLog(`received`, type);
if (type === 'start') {
Expand Down Expand Up @@ -143,6 +148,8 @@ parentPort.on('message', ([type, ...margs]) => {
doMessage(...dargs).then(res => sendUplink(['deliverDone', ...res]));
} else if (dtype === 'notify') {
doNotify(...dargs).then(res => sendUplink(['deliverDone', ...res]));
} else if (dtype === 'dropExports') {
doDropExports(...dargs).then(res => sendUplink(['deliverDone', ...res]));
} else {
assert.fail(X`bad delivery type ${dtype}`);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ function doNotify(resolutions) {
return doProcess(['notify', resolutions], errmsg);
}

function doDropExports(vrefs) {
const errmsg = `vat.doDropExport failed`;
return doProcess(['dropExports', vrefs], errmsg);
}

const toParent = arrayEncoderStream();
toParent
.pipe(netstringEncoderStream())
Expand Down Expand Up @@ -163,6 +168,8 @@ fromParent.on('data', ([type, ...margs]) => {
doMessage(...dargs).then(res => sendUplink(['deliverDone', ...res]));
} else if (dtype === 'notify') {
doNotify(...dargs).then(res => sendUplink(['deliverDone', ...res]));
} else if (dtype === 'dropExports') {
doDropExports(...dargs).then(res => sendUplink(['deliverDone', ...res]));
} else {
assert.fail(X`bad delivery type ${dtype}`);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@ function makeWorker(port) {
return doProcess(['notify', resolutions], errmsg);
}

/** @type { (rs: unknown) => Promise<Tagged> } */
function doDropExports(vrefs) {
const errmsg = `vat.dropExports failed`;
return doProcess(['dropExports', vrefs], errmsg);
}

/**
* TODO: consider other methods per SES VirtualConsole.
* See https://github.com/Agoric/agoric-sdk/issues/2146
Expand Down Expand Up @@ -277,6 +283,8 @@ function makeWorker(port) {
return doMessage(dargs[0], dargs[1]);
case 'notify':
return doNotify(dargs[0]);
case 'dropExports':
return doDropExports(dargs[0]);
default:
assert.fail(X`bad delivery type ${dtype}`);
}
Expand Down
11 changes: 9 additions & 2 deletions packages/SwingSet/src/vats/comms/dispatch.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { assert, details as X } from '@agoric/assert';
import { makeVatSlot } from '../../parseVatSlots';
import { makeVatSlot, insistVatType, parseVatSlot } from '../../parseVatSlots';
import { getRemote } from './remote';
import { makeState, makeStateKit } from './state';
import { deliverToController } from './controller';
Expand Down Expand Up @@ -109,7 +109,14 @@ export function buildCommsDispatch(
// comms vat version of it) here?
}

const dispatch = harden({ deliver, notify });
function dropExports(vrefs) {
assert(Array.isArray(vrefs));
vrefs.map(vref => insistVatType('object', vref));
vrefs.map(vref => assert(parseVatSlot(vref).allocatedByVat));
console.log(`-- comms ignoring dropExports`);
}

const dispatch = harden({ deliver, notify, dropExports });
debugState.set(dispatch, { state, clistKit });

return dispatch;
Expand Down
17 changes: 11 additions & 6 deletions packages/SwingSet/test/test-comms.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,18 +155,19 @@ test('receive', t => {
encodeArgs(`deliver:${bobRemote}:bar::ro-20:${bobRemote};argsbytes`),
null,
);
const expectedAliceKernel = 'o+31';
t.deepEqual(sends.shift(), [
bobKernel,
'bar',
capdata('argsbytes', ['o+31', bobKernel]),
capdata('argsbytes', [expectedAliceKernel, bobKernel]),
]);
// if we were to send o+31/lo11, the other side should get ro+20, which is alice
t.is(getRemoteForLocal(remoteID, 'lo11'), 'ro+20');
t.is(getLocalForRemote(remoteID, 'ro-20'), 'lo11');
t.is(getKernelForLocal('lo11'), 'o+31');
t.is(getLocalForKernel('o+31'), 'lo11');
t.is(getKernelForLocal('lo11'), expectedAliceKernel);
t.is(getLocalForKernel(expectedAliceKernel), 'lo11');

// bob!bar(alice, bob)
// bob!bar(alice, bob), again, to test stability
d.deliver(
receiverID,
'receive',
Expand All @@ -176,10 +177,11 @@ test('receive', t => {
t.deepEqual(sends.shift(), [
bobKernel,
'bar',
capdata('argsbytes', ['o+31', bobKernel]),
capdata('argsbytes', [expectedAliceKernel, bobKernel]),
]);

// bob!cat(alice, bob, ayana)
const expectedAyanaKernel = 'o+32';
d.deliver(
receiverID,
'receive',
Expand All @@ -189,6 +191,9 @@ test('receive', t => {
t.deepEqual(sends.shift(), [
bobKernel,
'cat',
capdata('argsbytes', ['o+31', bobKernel, 'o+32']),
capdata('argsbytes', [expectedAliceKernel, bobKernel, expectedAyanaKernel]),
]);

// make sure comms can tolerate dropExports, even if it's a no-op
d.dropExports([expectedAliceKernel, expectedAyanaKernel]);
});
49 changes: 46 additions & 3 deletions packages/SwingSet/test/test-liveslots.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,17 @@ function capargs(args, slots = []) {
return capdata(JSON.stringify(args), slots);
}

function caponeslot(slot) {
return capargs([{ '@qclass': 'slot', index: 0 }], [slot]);
function capdataOneSlot(slot) {
return capargs({ '@qclass': 'slot', iface: 'Alleged: export', index: 0 }, [
slot,
]);
}

function capargsOneSlot(slot) {
return capargs(
[{ '@qclass': 'slot', iface: 'Alleged: export', index: 0 }],
[slot],
);
}

function oneResolution(promiseID, rejected, data) {
Expand Down Expand Up @@ -639,7 +648,7 @@ test('disavow', async t => {
const import1 = 'o-1';

// root~.one(import1) // sendOnly
dispatch.deliver(rootA, 'one', caponeslot(import1), undefined);
dispatch.deliver(rootA, 'one', capargsOneSlot(import1), undefined);
await waitUntilQuiescent();
t.deepEqual(log.shift(), { type: 'dropImports', slots: [import1] });
t.deepEqual(log.shift(), 'disavowed pres1');
Expand Down Expand Up @@ -672,3 +681,37 @@ test('disavow', async t => {
t.deepEqual(log.shift(), 'tried to send to disavowed');
t.deepEqual(log, []);
});

test('dropExports', async t => {
const { log, syscall } = buildSyscall();

function build(_vatPowers) {
const ex1 = Far('export', {});
const root = Far('root', {
one() {
return ex1;
},
});
return root;
}
const dispatch = makeDispatch(syscall, build, true);
t.deepEqual(log, []);
const rootA = 'o+0';

// rp1 = root~.one()
// ex1 = await rp1
const rp1 = 'p-1';
dispatch.deliver(rootA, 'one', capargs([]), rp1);
await waitUntilQuiescent();
const l1 = log.shift();
const ex1 = l1.resolutions[0][2].slots[0];
t.deepEqual(l1, {
type: 'resolve',
resolutions: [[rp1, false, capdataOneSlot(ex1)]],
});
t.deepEqual(log, []);

// now tell the vat to drop that export
dispatch.dropExports([ex1]);
// for now, all that we care about is that liveslots doesn't crash
});