@agoric/swingset-liveslots 0.10.3-u16.0 → 0.10.3-u17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,65 @@
1
+ // @ts-nocheck
2
+ import '@endo/init/debug.js';
3
+ import test from 'ava';
4
+ import { Far } from '@endo/marshal';
5
+ import { kser } from '@agoric/kmarshal';
6
+ import { passStyleOf } from '@endo/pass-style';
7
+ import { PassStyleOfEndowmentSymbol } from '@endo/pass-style/endow.js';
8
+ import { makeLiveSlots } from '../src/index.js';
9
+ import { makeStartVat } from './util.js';
10
+ import { buildSyscall } from './liveslots-helpers.js';
11
+ import { makeMockGC } from './mock-gc.js';
12
+
13
+ test('vat globals', async t => {
14
+ const { syscall } = buildSyscall();
15
+ const gcTools = makeMockGC();
16
+ const buildRootObject = () => Far('root', {});
17
+ let called = 0;
18
+ let vatGlobals;
19
+ let inescapableGlobalProperties;
20
+ const vatNS = harden({ buildRootObject });
21
+ // buildVatNamespace
22
+ const bVN = async (vG, iGP) => {
23
+ called += 1;
24
+ vatGlobals = vG;
25
+ inescapableGlobalProperties = iGP;
26
+ return vatNS;
27
+ };
28
+
29
+ const ls = makeLiveSlots(syscall, 'vatA', {}, {}, gcTools, undefined, bVN);
30
+ t.is(called, 0); // not called yet
31
+ await ls.dispatch(makeStartVat(kser()));
32
+ t.is(called, 1);
33
+ t.truthy(vatGlobals);
34
+
35
+ // 'harden' is provided by SES (installed by the lockdown bundle),
36
+ // not liveslots
37
+ t.is(typeof vatGlobals.harden, 'undefined');
38
+
39
+ // but liveslots provides VatData
40
+ t.is(typeof vatGlobals.VatData, 'object');
41
+ t.is(typeof vatGlobals.VatData, 'object');
42
+ t.is(typeof vatGlobals.VatData.defineKind, 'function');
43
+ t.is(typeof vatGlobals.VatData.defineKindMulti, 'function');
44
+ t.is(typeof vatGlobals.VatData.defineDurableKind, 'function');
45
+ t.is(typeof vatGlobals.VatData.defineDurableKindMulti, 'function');
46
+ t.is(typeof vatGlobals.VatData.makeKindHandle, 'function');
47
+ t.is(typeof vatGlobals.VatData.canBeDurable, 'function');
48
+ t.is(typeof vatGlobals.VatData.providePromiseWatcher, 'function');
49
+ t.is(typeof vatGlobals.VatData.watchPromise, 'function');
50
+ t.is(typeof vatGlobals.VatData.makeScalarBigMapStore, 'function');
51
+ t.is(typeof vatGlobals.VatData.makeScalarBigWeakMapStore, 'function');
52
+ t.is(typeof vatGlobals.VatData.makeScalarBigSetStore, 'function');
53
+ t.is(typeof vatGlobals.VatData.makeScalarBigWeakSetStore, 'function');
54
+
55
+ t.is(typeof inescapableGlobalProperties.WeakMap, 'function');
56
+ t.not(inescapableGlobalProperties.WeakMap, WeakMap);
57
+ t.is(typeof inescapableGlobalProperties.WeakSet, 'function');
58
+ t.not(inescapableGlobalProperties.WeakSet, WeakSet);
59
+ t.is(
60
+ typeof inescapableGlobalProperties[PassStyleOfEndowmentSymbol],
61
+ 'function',
62
+ );
63
+ // this is the passStyleOf created by liveslots, with a real WeakMap
64
+ t.is(inescapableGlobalProperties[PassStyleOfEndowmentSymbol], passStyleOf);
65
+ });
package/test/vat-util.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // this file is imported by some test vats, so don't import any non-pure
2
2
  // modules
3
3
 
4
- import { Fail } from '@agoric/assert';
4
+ import { Fail } from '@endo/errors';
5
5
  import { kser, kunser } from '@agoric/kmarshal';
6
6
 
7
7
  export function extractMessage(vatDeliverObject) {
@@ -5,12 +5,11 @@ import './set-debug-label-instances.js';
5
5
  import { passStyleOf } from '@endo/far';
6
6
 
7
7
  // this samples it
8
+ import { q } from '@endo/errors';
8
9
  import { makeFakeVirtualStuff } from '../../tools/fakeVirtualSupport.js';
9
10
  // all tests in this file will be run with DEBUG='label-instances'
10
11
  import { parseVatSlot } from '../../src/parseVatSlots.js';
11
12
 
12
- const { quote: q } = assert;
13
-
14
13
  const init = () => ({});
15
14
  const behavior = {};
16
15
  const facets = { foo: {}, bar: {} };
@@ -1,10 +1,10 @@
1
1
  // @ts-nocheck
2
2
  import test from 'ava';
3
3
 
4
+ import { Fail } from '@endo/errors';
4
5
  import { E } from '@endo/eventual-send';
5
6
  import { makePromiseKit } from '@endo/promise-kit';
6
7
  import { Far } from '@endo/marshal';
7
- import { Fail } from '@agoric/assert';
8
8
  import { kser, kslot } from '@agoric/kmarshal';
9
9
  import { buildSyscall, makeDispatch } from './liveslots-helpers.js';
10
10
  import { makeMessage, makeResolve, makeReject } from './util.js';
@@ -898,3 +898,104 @@ test('inter-vat circular promise references', async t => {
898
898
  // });
899
899
  // t.deepEqual(log, []);
900
900
  });
901
+
902
+ test('accept previously allocated promise', async t => {
903
+ function build(vatPowers, vatParameters) {
904
+ const { target } = vatParameters;
905
+ return Far('root', {
906
+ call() {
907
+ const promise = E(target).foo();
908
+ // wrap to avoid adoption
909
+ return { promise };
910
+ },
911
+ async waitFor(promise2) {
912
+ // if we're in the same incarnation as the `E(target).foo()`, this
913
+ // `promise2` will be the same JS Promise as the `promise` above
914
+ const v = await promise2;
915
+ return v;
916
+ },
917
+ });
918
+ }
919
+
920
+ let log;
921
+ let syscall;
922
+ let dispatch;
923
+
924
+ const kvStore = new Map();
925
+ ({ log, syscall } = buildSyscall({ kvStore }));
926
+
927
+ const target = 'o-1';
928
+ ({ dispatch } = await makeDispatch(
929
+ syscall,
930
+ build,
931
+ 'reimport-promise',
932
+ {},
933
+ { target: kslot(target) },
934
+ ));
935
+ log.length = 0; // assume pre-build vatstore operations are correct
936
+
937
+ const root = 'o+0';
938
+ const callResultP = 'p-1';
939
+ const waitForResultP = 'p-2';
940
+ const expectedP1 = 'p+5';
941
+
942
+ await dispatch(makeMessage(root, 'call', [], callResultP));
943
+
944
+ // The vat should send 'foo', subscribe to the result promise, and resolve with that promise
945
+ t.deepEqual(log.splice(0, 3), [
946
+ {
947
+ type: 'send',
948
+ targetSlot: target,
949
+ methargs: kser(['foo', []]),
950
+ resultSlot: expectedP1,
951
+ },
952
+ { type: 'subscribe', target: expectedP1 },
953
+ {
954
+ type: 'resolve',
955
+ resolutions: [[callResultP, false, kser({ promise: kslot(expectedP1) })]],
956
+ },
957
+ ]);
958
+ matchIDCounterSet(t, log);
959
+ t.deepEqual(log, []);
960
+
961
+ // snapshot the store at this point
962
+ const clonedStore = new Map(kvStore);
963
+
964
+ const verifyPromiseReImport = async shouldSubscribe => {
965
+ await dispatch(
966
+ makeMessage(root, 'waitFor', [kslot(expectedP1)], waitForResultP),
967
+ );
968
+
969
+ // The vat will only subscribe if it was upgraded; if the vat still
970
+ // remembers it, receiving the vref will merely look it up in slotToVal and
971
+ // not create a new Promise (and trigger a subscribe)
972
+ if (shouldSubscribe) {
973
+ t.deepEqual(log.shift(), { type: 'subscribe', target: expectedP1 });
974
+ }
975
+
976
+ // waitFor will suspend until promise is resolved
977
+ t.deepEqual(log, []);
978
+
979
+ // Resolution propagates the value to the waitFor result
980
+ await dispatch(makeResolve(expectedP1, kser('success')));
981
+ t.deepEqual(log.shift(), {
982
+ type: 'resolve',
983
+ resolutions: [[waitForResultP, false, kser('success')]],
984
+ });
985
+ t.deepEqual(log, []);
986
+ };
987
+
988
+ await verifyPromiseReImport(false);
989
+ ({ log, syscall } = buildSyscall({ kvStore: clonedStore }));
990
+ ({ dispatch } = await makeDispatch(
991
+ syscall,
992
+ build,
993
+ 'reimport-promise-v2',
994
+ {},
995
+ {},
996
+ ));
997
+ log.length = 0;
998
+
999
+ // verify this works the same in the restarted vat
1000
+ await verifyPromiseReImport(true);
1001
+ });
@@ -0,0 +1,50 @@
1
+ import test from 'ava';
2
+ import { Far } from '@endo/marshal';
3
+ import { kser, kslot } from '@agoric/kmarshal';
4
+ import { makeLiveSlots } from '../src/liveslots.js';
5
+ import { buildSyscall } from './liveslots-helpers.js';
6
+ import { makeStartVat, makeMessage, makeBringOutYourDead } from './util.js';
7
+ import { makeMockGC } from './mock-gc.js';
8
+
9
+ // Test for https://github.com/Agoric/agoric-sdk/issues/9956
10
+
11
+ test('delete remotable key from weakset', async t => {
12
+ const { syscall, log } = buildSyscall();
13
+ const gcTools = makeMockGC();
14
+ const rem = Far('remotable', {});
15
+
16
+ function buildRootObject(vatPowers) {
17
+ const { VatData } = vatPowers;
18
+ const { makeScalarBigWeakMapStore } = VatData;
19
+ const wms = makeScalarBigWeakMapStore();
20
+ return Far('root', {
21
+ store: p => {
22
+ wms.init(rem, p);
23
+ gcTools.kill(p);
24
+ },
25
+ });
26
+ }
27
+
28
+ const makeNS = () => ({ buildRootObject });
29
+ const ls = makeLiveSlots(syscall, 'vatA', {}, {}, gcTools, undefined, makeNS);
30
+ const { dispatch } = ls;
31
+ await dispatch(makeStartVat(kser()));
32
+
33
+ await dispatch(makeMessage('o+0', 'store', [kslot('o-1')]));
34
+
35
+ // pretend the Remotable was dropped from RAM
36
+ log.length = 0;
37
+ gcTools.kill(rem);
38
+ gcTools.flushAllFRs();
39
+ await dispatch(makeBringOutYourDead());
40
+
41
+ // that ought to emit a drop and retire for the presence
42
+ const gcCalls = log.filter(
43
+ l => l.type === 'dropImports' || l.type === 'retireImports',
44
+ );
45
+ t.deepEqual(gcCalls, [
46
+ { type: 'dropImports', slots: ['o-1'] },
47
+ { type: 'retireImports', slots: ['o-1'] },
48
+ ]);
49
+ log.length = 0;
50
+ });
@@ -1,7 +1,7 @@
1
1
  /* global globalThis */
2
2
  /* eslint-disable max-classes-per-file */
3
+ import { assert, Fail } from '@endo/errors';
3
4
  import { makeMarshal } from '@endo/marshal';
4
- import { assert } from '@agoric/assert';
5
5
  import { isPromise } from '@endo/promise-kit';
6
6
 
7
7
  import { parseVatSlot } from '../src/parseVatSlots.js';
@@ -10,8 +10,6 @@ import { makeWatchedPromiseManager } from '../src/watchedPromises.js';
10
10
  import { makeFakeVirtualObjectManager } from './fakeVirtualObjectManager.js';
11
11
  import { makeFakeCollectionManager } from './fakeCollectionManager.js';
12
12
 
13
- const { Fail } = assert;
14
-
15
13
  const {
16
14
  WeakRef: RealWeakRef,
17
15
  WeakMap: RealWeakMap,
@@ -1,8 +1,13 @@
1
1
  // @ts-check
2
2
  /* global globalThis */
3
- // This file produces the globalThis.VatData property outside of a running
4
- // SwingSet so that it can be used by '@agoric/vat-data' (which only *consumes*
5
- // `globalThis.VatData`) in code under test.
3
+
4
+ // This file produces the globalThis.VatData property outside of a
5
+ // running SwingSet so that it can be used by '@agoric/vat-data'
6
+ // (which only *consumes* `globalThis.VatData`) in code under test. It
7
+ // also populates the passStyleOf symbol-named property.
8
+
9
+ import { passStyleOf } from '@endo/pass-style';
10
+ import { PassStyleOfEndowmentSymbol } from '@endo/pass-style/endow.js';
6
11
  import { makeFakeVirtualStuff } from './fakeVirtualSupport.js';
7
12
 
8
13
  const { WeakMap, WeakSet } = globalThis;
@@ -37,6 +42,8 @@ globalThis.VatData = harden({
37
42
  fakeVomKit.cm.makeScalarBigWeakSetStore(...args),
38
43
  });
39
44
 
45
+ globalThis[PassStyleOfEndowmentSymbol] = passStyleOf;
46
+
40
47
  export const reincarnate = (options = {}) => {
41
48
  const { fakeStore = new Map(), fakeVomKit: fvk } = options;
42
49