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

fake virtual watched promises for upgrade 14 #8772

Merged
merged 1 commit into from
Jan 19, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -587,12 +587,12 @@ test('durable kind IDs can be reanimated', t => {

// Store it in the store without having used it
placeToPutIt.init('savedKindID', kindHandle);
t.is(log.shift(), 'get vc.1.ssavedKindID => undefined');
t.is(log.shift(), 'get vc.4.ssavedKindID => undefined');
t.is(log.shift(), `get vom.rc.${khid} => undefined`);
t.is(log.shift(), `set vom.rc.${khid} 1`);
t.is(log.shift(), `set vc.1.ssavedKindID ${vstr(kind)}`);
t.is(log.shift(), 'get vc.1.|entryCount => 0');
t.is(log.shift(), 'set vc.1.|entryCount 1');
t.is(log.shift(), `set vc.4.ssavedKindID ${vstr(kind)}`);
t.is(log.shift(), 'get vc.4.|entryCount => 0');
t.is(log.shift(), 'set vc.4.|entryCount 1');
t.deepEqual(log, []);

// Forget its Representative
Expand All @@ -606,7 +606,7 @@ test('durable kind IDs can be reanimated', t => {

// Fetch it from the store, which should reanimate it
const fetchedKindID = placeToPutIt.get('savedKindID');
t.is(log.shift(), `get vc.1.ssavedKindID => ${vstr(kind)}`);
t.is(log.shift(), `get vc.4.ssavedKindID => ${vstr(kind)}`);
t.is(
log.shift(),
'get vom.dkind.10.descriptor => {"kindID":"10","tag":"testkind"}',
Expand Down Expand Up @@ -654,9 +654,23 @@ test('virtual object gc', t => {
];
t.is(log.shift(), `get storeKindIDTable => undefined`);
t.is(log.shift(), `set ${skit[0]} ${skit[1]}`);
t.is(log.shift(), 'set vc.1.|nextOrdinal 1');
t.is(log.shift(), 'set vc.1.|entryCount 0');
t.is(log.shift(), 'get watcherTableID => undefined');
t.is(log.shift(), 'set vc.2.|nextOrdinal 1');
t.is(log.shift(), 'set vc.2.|entryCount 0');
t.is(log.shift(), 'set watcherTableID o+d6/2');
t.is(log.shift(), 'get vom.rc.o+d6/2 => undefined');
t.is(log.shift(), 'set vom.rc.o+d6/2 1');
t.is(log.shift(), 'get watchedPromiseTableID => undefined');
t.is(log.shift(), 'set vc.3.|nextOrdinal 1');
t.is(log.shift(), 'set vc.3.|entryCount 0');
t.is(log.shift(), 'set watchedPromiseTableID o+d6/3');
t.is(log.shift(), 'get vom.rc.o+d6/3 => undefined');
t.is(log.shift(), 'set vom.rc.o+d6/3 1');
t.is(
log.shift(),
`set vom.vkind.10.descriptor {"kindID":"10","tag":"thing"}`,
'set vom.vkind.10.descriptor {"kindID":"10","tag":"thing"}',
);
t.is(log.shift(), `set vom.vkind.11.descriptor {"kindID":"11","tag":"ref"}`);
t.deepEqual(log, []);
Expand All @@ -682,6 +696,12 @@ test('virtual object gc', t => {
t.deepEqual(dumpStore(), [
['kindIDID', '1'],
skit,
['vc.1.|entryCount', '0'],
['vc.1.|nextOrdinal', '1'],
['vc.2.|entryCount', '0'],
['vc.2.|nextOrdinal', '1'],
['vc.3.|entryCount', '0'],
['vc.3.|nextOrdinal', '1'],
[`vom.${tbase}/1`, minThing('thing #1')],
[`vom.${tbase}/2`, minThing('thing #2')],
[`vom.${tbase}/3`, minThing('thing #3')],
Expand All @@ -691,8 +711,12 @@ test('virtual object gc', t => {
[`vom.${tbase}/7`, minThing('thing #7')],
[`vom.${tbase}/8`, minThing('thing #8')],
[`vom.${tbase}/9`, minThing('thing #9')],
['vom.rc.o+d6/2', '1'],
['vom.rc.o+d6/3', '1'],
['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
['watchedPromiseTableID', 'o+d6/3'],
['watcherTableID', 'o+d6/2'],
]);

// This is what the finalizer would do if the local reference was dropped and GC'd
Expand All @@ -718,6 +742,12 @@ test('virtual object gc', t => {
t.deepEqual(dumpStore(), [
['kindIDID', '1'],
skit,
['vc.1.|entryCount', '0'],
['vc.1.|nextOrdinal', '1'],
['vc.2.|entryCount', '0'],
['vc.2.|nextOrdinal', '1'],
['vc.3.|entryCount', '0'],
['vc.3.|nextOrdinal', '1'],
[`vom.es.${tbase}/1`, 'r'],
[`vom.${tbase}/1`, minThing('thing #1')],
[`vom.${tbase}/2`, minThing('thing #2')],
Expand All @@ -728,8 +758,12 @@ test('virtual object gc', t => {
[`vom.${tbase}/7`, minThing('thing #7')],
[`vom.${tbase}/8`, minThing('thing #8')],
[`vom.${tbase}/9`, minThing('thing #9')],
['vom.rc.o+d6/2', '1'],
['vom.rc.o+d6/3', '1'],
['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
['watchedPromiseTableID', 'o+d6/3'],
['watcherTableID', 'o+d6/2'],
]);

// drop export -- should delete
Expand Down Expand Up @@ -759,6 +793,12 @@ test('virtual object gc', t => {
t.deepEqual(dumpStore(), [
['kindIDID', '1'],
skit,
['vc.1.|entryCount', '0'],
['vc.1.|nextOrdinal', '1'],
['vc.2.|entryCount', '0'],
['vc.2.|nextOrdinal', '1'],
['vc.3.|entryCount', '0'],
['vc.3.|nextOrdinal', '1'],
[`vom.${tbase}/2`, minThing('thing #2')],
[`vom.${tbase}/3`, minThing('thing #3')],
[`vom.${tbase}/4`, minThing('thing #4')],
Expand All @@ -767,8 +807,12 @@ test('virtual object gc', t => {
[`vom.${tbase}/7`, minThing('thing #7')],
[`vom.${tbase}/8`, minThing('thing #8')],
[`vom.${tbase}/9`, minThing('thing #9')],
['vom.rc.o+d6/2', '1'],
['vom.rc.o+d6/3', '1'],
['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
['watchedPromiseTableID', 'o+d6/3'],
['watcherTableID', 'o+d6/2'],
]);

// case 2: export, drop export, drop local ref
Expand All @@ -786,6 +830,12 @@ test('virtual object gc', t => {
t.deepEqual(dumpStore(), [
['kindIDID', '1'],
skit,
['vc.1.|entryCount', '0'],
['vc.1.|nextOrdinal', '1'],
['vc.2.|entryCount', '0'],
['vc.2.|nextOrdinal', '1'],
['vc.3.|entryCount', '0'],
['vc.3.|nextOrdinal', '1'],
[`vom.es.${tbase}/2`, 's'],
[`vom.${tbase}/2`, minThing('thing #2')],
[`vom.${tbase}/3`, minThing('thing #3')],
Expand All @@ -795,8 +845,12 @@ test('virtual object gc', t => {
[`vom.${tbase}/7`, minThing('thing #7')],
[`vom.${tbase}/8`, minThing('thing #8')],
[`vom.${tbase}/9`, minThing('thing #9')],
['vom.rc.o+d6/2', '1'],
['vom.rc.o+d6/3', '1'],
['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
['watchedPromiseTableID', 'o+d6/3'],
['watcherTableID', 'o+d6/2'],
]);

// drop local ref -- should delete
Expand All @@ -817,15 +871,25 @@ test('virtual object gc', t => {
t.deepEqual(dumpStore(), [
['kindIDID', '1'],
skit,
['vc.1.|entryCount', '0'],
['vc.1.|nextOrdinal', '1'],
['vc.2.|entryCount', '0'],
['vc.2.|nextOrdinal', '1'],
['vc.3.|entryCount', '0'],
['vc.3.|nextOrdinal', '1'],
[`vom.${tbase}/3`, minThing('thing #3')],
[`vom.${tbase}/4`, minThing('thing #4')],
[`vom.${tbase}/5`, minThing('thing #5')],
[`vom.${tbase}/6`, minThing('thing #6')],
[`vom.${tbase}/7`, minThing('thing #7')],
[`vom.${tbase}/8`, minThing('thing #8')],
[`vom.${tbase}/9`, minThing('thing #9')],
['vom.rc.o+d6/2', '1'],
['vom.rc.o+d6/3', '1'],
['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
['watchedPromiseTableID', 'o+d6/3'],
['watcherTableID', 'o+d6/2'],
]);

// case 3: drop local ref with no prior export
Expand All @@ -847,14 +911,24 @@ test('virtual object gc', t => {
t.deepEqual(dumpStore(), [
['kindIDID', '1'],
skit,
['vc.1.|entryCount', '0'],
['vc.1.|nextOrdinal', '1'],
['vc.2.|entryCount', '0'],
['vc.2.|nextOrdinal', '1'],
['vc.3.|entryCount', '0'],
['vc.3.|nextOrdinal', '1'],
[`vom.${tbase}/4`, minThing('thing #4')],
[`vom.${tbase}/5`, minThing('thing #5')],
[`vom.${tbase}/6`, minThing('thing #6')],
[`vom.${tbase}/7`, minThing('thing #7')],
[`vom.${tbase}/8`, minThing('thing #8')],
[`vom.${tbase}/9`, minThing('thing #9')],
['vom.rc.o+d6/2', '1'],
['vom.rc.o+d6/3', '1'],
['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
['watchedPromiseTableID', 'o+d6/3'],
['watcherTableID', 'o+d6/2'],
]);

// case 4: ref virtually, export, drop local ref, drop export
Expand All @@ -867,15 +941,25 @@ test('virtual object gc', t => {
t.deepEqual(dumpStore(), [
['kindIDID', '1'],
skit,
['vc.1.|entryCount', '0'],
['vc.1.|nextOrdinal', '1'],
['vc.2.|entryCount', '0'],
['vc.2.|nextOrdinal', '1'],
['vc.3.|entryCount', '0'],
['vc.3.|nextOrdinal', '1'],
[`vom.${tbase}/4`, minThing('thing #4')],
[`vom.${tbase}/5`, minThing('thing #5')],
[`vom.${tbase}/6`, minThing('thing #6')],
[`vom.${tbase}/7`, minThing('thing #7')],
[`vom.${tbase}/8`, minThing('thing #8')],
[`vom.${tbase}/9`, minThing('thing #9')],
['vom.rc.o+d6/2', '1'],
['vom.rc.o+d6/3', '1'],
[`vom.rc.${tbase}/4`, '1'],
['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
['watchedPromiseTableID', 'o+d6/3'],
['watcherTableID', 'o+d6/2'],
]);
// export
setExportStatus(`${tbase}/4`, 'reachable');
Expand Down Expand Up @@ -909,6 +993,12 @@ test('virtual object gc', t => {
t.deepEqual(dumpStore(), [
['kindIDID', '1'],
skit,
['vc.1.|entryCount', '0'],
['vc.1.|nextOrdinal', '1'],
['vc.2.|entryCount', '0'],
['vc.2.|nextOrdinal', '1'],
['vc.3.|entryCount', '0'],
['vc.3.|nextOrdinal', '1'],
[`vom.es.${tbase}/4`, 's'],
[`vom.es.${tbase}/5`, 'r'],
[`vom.${tbase}/4`, minThing('thing #4')],
Expand All @@ -917,10 +1007,14 @@ test('virtual object gc', t => {
[`vom.${tbase}/7`, minThing('thing #7')],
[`vom.${tbase}/8`, minThing('thing #8')],
[`vom.${tbase}/9`, minThing('thing #9')],
['vom.rc.o+d6/2', '1'],
['vom.rc.o+d6/3', '1'],
[`vom.rc.${tbase}/4`, '1'],
[`vom.rc.${tbase}/5`, '1'],
['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
['watchedPromiseTableID', 'o+d6/3'],
['watcherTableID', 'o+d6/2'],
]);
// drop local ref -- should not delete because ref'd virtually AND exported
pretendGC(`${tbase}/5`, false);
Expand All @@ -944,6 +1038,12 @@ test('virtual object gc', t => {
t.deepEqual(dumpStore(), [
['kindIDID', '1'],
skit,
['vc.1.|entryCount', '0'],
['vc.1.|nextOrdinal', '1'],
['vc.2.|entryCount', '0'],
['vc.2.|nextOrdinal', '1'],
['vc.3.|entryCount', '0'],
['vc.3.|nextOrdinal', '1'],
[`vom.es.${tbase}/4`, 's'],
[`vom.es.${tbase}/5`, 's'],
[`vom.${tbase}/4`, minThing('thing #4')],
Expand All @@ -952,11 +1052,15 @@ test('virtual object gc', t => {
[`vom.${tbase}/7`, minThing('thing #7')],
[`vom.${tbase}/8`, minThing('thing #8')],
[`vom.${tbase}/9`, minThing('thing #9')],
['vom.rc.o+d6/2', '1'],
['vom.rc.o+d6/3', '1'],
[`vom.rc.${tbase}/4`, '1'],
[`vom.rc.${tbase}/5`, '1'],
[`vom.rc.${tbase}/6`, '1'],
['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
['watchedPromiseTableID', 'o+d6/3'],
['watcherTableID', 'o+d6/2'],
]);
// drop local ref -- should not delete because ref'd virtually
pretendGC(`${tbase}/6`, false);
Expand All @@ -966,6 +1070,12 @@ test('virtual object gc', t => {
t.deepEqual(dumpStore(), [
['kindIDID', '1'],
skit,
['vc.1.|entryCount', '0'],
['vc.1.|nextOrdinal', '1'],
['vc.2.|entryCount', '0'],
['vc.2.|nextOrdinal', '1'],
['vc.3.|entryCount', '0'],
['vc.3.|nextOrdinal', '1'],
[`vom.es.${tbase}/4`, 's'],
[`vom.es.${tbase}/5`, 's'],
[`vom.${tbase}/4`, minThing('thing #4')],
Expand All @@ -974,11 +1084,15 @@ test('virtual object gc', t => {
[`vom.${tbase}/7`, minThing('thing #7')],
[`vom.${tbase}/8`, minThing('thing #8')],
[`vom.${tbase}/9`, minThing('thing #9')],
['vom.rc.o+d6/2', '1'],
['vom.rc.o+d6/3', '1'],
[`vom.rc.${tbase}/4`, '1'],
[`vom.rc.${tbase}/5`, '1'],
[`vom.rc.${tbase}/6`, '1'],
['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
['watchedPromiseTableID', 'o+d6/3'],
['watcherTableID', 'o+d6/2'],
]);
});

Expand Down
17 changes: 15 additions & 2 deletions packages/swingset-liveslots/tools/fakeVirtualSupport.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
/* eslint-disable max-classes-per-file */
import { makeMarshal } from '@endo/marshal';
import { assert } from '@agoric/assert';
import { parseVatSlot } from '../src/parseVatSlots.js';
import { isPromise } from '@endo/promise-kit';

import { parseVatSlot } from '../src/parseVatSlots.js';
import { makeVirtualReferenceManager } from '../src/virtualReferences.js';
import { makeWatchedPromiseManager } from '../src/watchedPromises.js';
import { makeFakeVirtualObjectManager } from './fakeVirtualObjectManager.js';
Expand Down Expand Up @@ -158,6 +159,14 @@ export function makeFakeLiveSlotsStuff(options = {}) {
return exportID;
}

// different starting point for more distinct IDs
let nextPromiseID = 7;
function allocatePromiseID() {
const promiseID = nextPromiseID;
nextPromiseID += 1;
return promiseID;
}

let nextCollectionID = 1;
function allocateCollectionID() {
const collectionID = nextCollectionID;
Expand Down Expand Up @@ -193,7 +202,9 @@ export function makeFakeLiveSlotsStuff(options = {}) {

function convertValToSlot(val) {
if (!valToSlot.has(val)) {
const slot = `o+${allocateExportID()}`;
const slot = isPromise(val)
? `p+${allocatePromiseID()}`
: `o+${allocateExportID()}`;
valToSlot.set(val, slot);
setValForSlot(slot, val);
}
Expand Down Expand Up @@ -311,6 +322,7 @@ export function makeFakeWatchedPromiseManager(
maybeExportPromise: fakeStuff.maybeExportPromise,
});
}

/**
* Configure virtual stuff with relaxed durability rules and fake liveslots
*
Expand All @@ -331,6 +343,7 @@ export function makeFakeVirtualStuff(options = {}) {
fakeStuff.setVrm(vrm);
const cm = makeFakeCollectionManager(vrm, fakeStuff, actualOptions);
const wpm = makeFakeWatchedPromiseManager(vrm, vom, cm, fakeStuff);
wpm.preparePromiseWatcherTables();
return { fakeStuff, vrm, vom, cm, wpm };
}

Expand Down
Loading