@agoric/swingset-liveslots 0.10.3-mainnet1B-dev-26244e8.0 → 0.10.3-orchestration-dev-096c4e8.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.
Files changed (58) hide show
  1. package/README.md +2 -0
  2. package/package.json +25 -17
  3. package/src/cache.js +5 -3
  4. package/src/collectionManager.js +147 -69
  5. package/src/index.js +2 -1
  6. package/src/liveslots.js +52 -79
  7. package/src/message.js +4 -4
  8. package/src/types.js +8 -2
  9. package/src/vatDataTypes.d.ts +234 -0
  10. package/src/vatDataTypes.js +2 -0
  11. package/src/vatstore-iterators.js +2 -0
  12. package/src/virtualObjectManager.js +107 -63
  13. package/src/virtualReferences.js +51 -0
  14. package/src/watchedPromises.js +50 -15
  15. package/test/gc-and-finalize.js +30 -1
  16. package/test/gc-helpers.js +2 -1
  17. package/test/liveslots-helpers.js +6 -6
  18. package/test/mock-gc.js +1 -0
  19. package/test/storeGC/test-lifecycle.js +2 -2
  20. package/test/storeGC/test-refcount-management.js +1 -2
  21. package/test/storeGC/test-scalar-store-kind.js +0 -1
  22. package/test/storeGC/test-weak-key.js +1 -2
  23. package/test/test-baggage.js +1 -2
  24. package/test/test-cache.js +0 -1
  25. package/test/test-collection-schema-refcount.js +1 -2
  26. package/test/test-collection-upgrade.js +1 -3
  27. package/test/test-collections.js +117 -14
  28. package/test/test-dropped-collection-weakrefs.js +1 -2
  29. package/test/test-durabilityChecks.js +3 -3
  30. package/test/test-facetiousness.js +1 -2
  31. package/test/test-gc-sensitivity.js +2 -2
  32. package/test/test-handled-promises.js +5 -7
  33. package/test/test-initial-vrefs.js +2 -3
  34. package/test/test-liveslots-mock-gc.js +2 -2
  35. package/test/test-liveslots-real-gc.js +44 -35
  36. package/test/test-liveslots.js +13 -14
  37. package/test/test-vo-test-harness.js +0 -1
  38. package/test/test-vpid-liveslots.js +4 -5
  39. package/test/util.js +2 -2
  40. package/test/vat-util.js +1 -1
  41. package/test/virtual-objects/test-cease-recognition.js +2 -2
  42. package/test/virtual-objects/test-cross-facet.js +1 -2
  43. package/test/virtual-objects/test-empty-data.js +1 -2
  44. package/test/virtual-objects/test-facets.js +1 -2
  45. package/test/virtual-objects/test-kind-changes.js +2 -2
  46. package/test/virtual-objects/test-reachable-vrefs.js +2 -2
  47. package/test/virtual-objects/test-rep-tostring.js +2 -3
  48. package/test/virtual-objects/test-retain-remotable.js +25 -24
  49. package/test/virtual-objects/test-state-shape.js +2 -2
  50. package/test/virtual-objects/test-virtualObjectGC.js +2 -2
  51. package/test/virtual-objects/test-virtualObjectManager.js +126 -8
  52. package/test/virtual-objects/test-vo-real-gc.js +8 -8
  53. package/test/virtual-objects/test-weakcollections-vref-handling.js +1 -2
  54. package/tools/fakeVirtualSupport.js +48 -21
  55. package/tools/prepare-test-env.js +13 -0
  56. package/tools/setup-vat-data.js +62 -0
  57. package/CHANGELOG.md +0 -77
  58. package/test/kmarshal.js +0 -79
@@ -1,13 +1,13 @@
1
+ // @ts-nocheck
1
2
  import test from 'ava';
2
- import '@endo/init/debug.js';
3
3
 
4
4
  import { E } from '@endo/eventual-send';
5
5
  import { Far } from '@endo/marshal';
6
6
  import { makePromiseKit } from '@endo/promise-kit';
7
7
  import { Fail } from '@agoric/assert';
8
+ import { kslot, kser, kunser } from '@agoric/kmarshal';
8
9
  import { M } from '@agoric/store';
9
10
  import { makeLiveSlots, makeMarshaller } from '../src/liveslots.js';
10
- import { kslot, kser, kunser } from './kmarshal.js';
11
11
  import { buildSyscall, makeDispatch } from './liveslots-helpers.js';
12
12
  import { makeMessage, makeStartVat, makeResolve, makeReject } from './util.js';
13
13
  import { makeMockGC } from './mock-gc.js';
@@ -45,14 +45,14 @@ test('calls', async t => {
45
45
 
46
46
  // root!one() // sendOnly
47
47
  await dispatch(makeMessage(rootA, 'one', ['args']));
48
- t.deepEqual(log.shift(), 'one');
48
+ t.is(log.shift(), 'one');
49
49
 
50
50
  // pr = makePromise()
51
51
  // root!two(pr.promise)
52
52
  // pr.resolve('result')
53
53
  await dispatch(makeMessage(rootA, 'two', [kslot('p-1')]));
54
54
  t.deepEqual(log.shift(), { type: 'subscribe', target: 'p-1' });
55
- t.deepEqual(log.shift(), 'two true');
55
+ t.is(log.shift(), 'two true');
56
56
 
57
57
  await dispatch(makeResolve('p-1', kser('result')));
58
58
  t.deepEqual(log.shift(), ['res', 'result']);
@@ -63,7 +63,7 @@ test('calls', async t => {
63
63
 
64
64
  await dispatch(makeMessage(rootA, 'two', [kslot('p-2')]));
65
65
  t.deepEqual(log.shift(), { type: 'subscribe', target: 'p-2' });
66
- t.deepEqual(log.shift(), 'two true');
66
+ t.is(log.shift(), 'two true');
67
67
 
68
68
  await dispatch(makeReject('p-2', kser('rejection')));
69
69
  t.deepEqual(log.shift(), ['rej', 'rejection']);
@@ -99,7 +99,7 @@ test('liveslots pipelines to syscall.send', async t => {
99
99
  // for x!pipe1(), a second pipelined to the result promise of it, and a
100
100
  // third pipelined to the result of the second.
101
101
 
102
- t.deepEqual(log.shift(), 'sent p1p2p3');
102
+ t.is(log.shift(), 'sent p1p2p3');
103
103
  t.deepEqual(log.shift(), {
104
104
  type: 'send',
105
105
  targetSlot: x,
@@ -656,8 +656,7 @@ test('capdata size limit on syscalls', async t => {
656
656
  };
657
657
 
658
658
  const send = op => dispatch(makeMessage(rootA, op, [kslot(target)], rp));
659
- const expectFail = () =>
660
- t.deepEqual(log.shift(), 'fail: syscall capdata too large');
659
+ const expectFail = () => t.is(log.shift(), 'fail: syscall capdata too large');
661
660
  const expectVoidReturn = () =>
662
661
  t.deepEqual(log.shift(), {
663
662
  type: 'resolve',
@@ -906,7 +905,7 @@ test('disable disavow', async t => {
906
905
 
907
906
  // root~.one() // sendOnly
908
907
  await dispatch(makeMessage(rootA, 'one', []));
909
- t.deepEqual(log.shift(), false);
908
+ t.is(log.shift(), false);
910
909
  t.deepEqual(log, []);
911
910
  });
912
911
 
@@ -967,7 +966,7 @@ test('disavow', async t => {
967
966
  // root~.one(import1) // sendOnly
968
967
  await dispatch(makeMessage(rootA, 'one', [kslot(import1)]));
969
968
  t.deepEqual(log.shift(), { type: 'dropImports', slots: [import1] });
970
- t.deepEqual(log.shift(), 'disavowed pres1');
969
+ t.is(log.shift(), 'disavowed pres1');
971
970
 
972
971
  function loggedError(re) {
973
972
  const l = log.shift();
@@ -975,11 +974,11 @@ test('disavow', async t => {
975
974
  t.truthy(re.test(l.message));
976
975
  }
977
976
  loggedError(/attempt to disavow unknown/);
978
- t.deepEqual(log.shift(), 'tried duplicate disavow');
977
+ t.is(log.shift(), 'tried duplicate disavow');
979
978
  loggedError(/attempt to disavow unknown/);
980
- t.deepEqual(log.shift(), 'tried to disavow Promise');
979
+ t.is(log.shift(), 'tried to disavow Promise');
981
980
  loggedError(/attempt to disavow an export/);
982
- t.deepEqual(log.shift(), 'tried to disavow export');
981
+ t.is(log.shift(), 'tried to disavow export');
983
982
  const msg = log.shift();
984
983
  t.like(msg, {
985
984
  type: 'exit',
@@ -987,7 +986,7 @@ test('disavow', async t => {
987
986
  });
988
987
  expectError(t, msg.info, /this Presence has been disavowed/);
989
988
  t.deepEqual(log.shift(), Error('this Presence has been disavowed'));
990
- t.deepEqual(log.shift(), 'tried to send to disavowed');
989
+ t.is(log.shift(), 'tried to send to disavowed');
991
990
  t.deepEqual(log, []);
992
991
  });
993
992
 
@@ -1,5 +1,4 @@
1
1
  import test from 'ava';
2
- import '@endo/init/debug.js';
3
2
  import { runVOTest } from '../tools/vo-test-harness.js';
4
3
 
5
4
  async function voTestTest(t, mode) {
@@ -1,13 +1,13 @@
1
+ // @ts-nocheck
1
2
  import test from 'ava';
2
- import '@endo/init/debug.js';
3
3
 
4
4
  import { E } from '@endo/eventual-send';
5
5
  import { makePromiseKit } from '@endo/promise-kit';
6
- import { Fail } from '@agoric/assert';
7
6
  import { Far } from '@endo/marshal';
7
+ import { Fail } from '@agoric/assert';
8
+ import { kser, kslot } from '@agoric/kmarshal';
8
9
  import { buildSyscall, makeDispatch } from './liveslots-helpers.js';
9
10
  import { makeMessage, makeResolve, makeReject } from './util.js';
10
- import { kser, kslot } from './kmarshal.js';
11
11
 
12
12
  function hush(p) {
13
13
  p.then(
@@ -293,7 +293,6 @@ async function doVatResolveCase23(t, which, mode, stalls) {
293
293
  // another few turns. We wait some number of turns before using p1
294
294
  // again, to exercise as many race conditions as possible.
295
295
  for (let i = 0; i < stalls; i += 1) {
296
- // eslint-disable-next-line no-await-in-loop
297
296
  await Promise.resolve();
298
297
  }
299
298
 
@@ -858,7 +857,7 @@ test('inter-vat circular promise references', async t => {
858
857
  let r;
859
858
  return Far('root', {
860
859
  genPromise() {
861
- [p, r] = makePR();
860
+ void ([p, r] = makePR());
862
861
  return p;
863
862
  },
864
863
  usePromise(pa) {
package/test/util.js CHANGED
@@ -1,5 +1,5 @@
1
+ import { kser } from '@agoric/kmarshal';
1
2
  import { vstr } from './vat-util.js';
2
- import { kser } from './kmarshal.js';
3
3
 
4
4
  export { vstr };
5
5
 
@@ -48,7 +48,7 @@ export function buildDispatch(onDispatchCallback) {
48
48
 
49
49
  /**
50
50
  * @param {unknown} target
51
- * @param {string} method
51
+ * @param {string | symbol} method
52
52
  * @param {any[]} args
53
53
  * @param {unknown} result
54
54
  */
package/test/vat-util.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // modules
3
3
 
4
4
  import { Fail } from '@agoric/assert';
5
- import { kser, kunser } from './kmarshal.js';
5
+ import { kser, kunser } from '@agoric/kmarshal';
6
6
 
7
7
  export function extractMessage(vatDeliverObject) {
8
8
  const [type, ...vdoargs] = vatDeliverObject;
@@ -1,6 +1,6 @@
1
+ // @ts-nocheck
1
2
  /* global FinalizationRegistry WeakRef */
2
3
  import test from 'ava';
3
- import '@endo/init/debug.js';
4
4
 
5
5
  import { buildSyscall } from '../liveslots-helpers.js';
6
6
  import { makeVirtualReferenceManager } from '../../src/virtualReferences.js';
@@ -38,7 +38,7 @@ function weakKeyCheck(t, log, vref) {
38
38
  t.true(result === undefined || !result.startsWith(prefix), `ew:${result}`);
39
39
  }
40
40
 
41
- test('only enumerate virtual objects', async t => {
41
+ test('only enumerate virtual objects', t => {
42
42
  const { log, vrm } = makeVRM();
43
43
 
44
44
  // retiring a plain Remotable does a is-it-a-weak-key chck
@@ -1,5 +1,4 @@
1
1
  import test from 'ava';
2
- import '@endo/init/debug.js';
3
2
 
4
3
  import { makeFakeVirtualObjectManager } from '../../tools/fakeVirtualSupport.js';
5
4
 
@@ -15,7 +14,7 @@ function attack2(mut1, immut2) {
15
14
  Reflect.apply(mutableProto.set, immut2, [6]);
16
15
  }
17
16
 
18
- test('forbid cross-facet prototype attack', async t => {
17
+ test('forbid cross-facet prototype attack', t => {
19
18
  const vom = makeFakeVirtualObjectManager();
20
19
  const init = () => ({ value: 0 });
21
20
  const behavior = {
@@ -1,9 +1,8 @@
1
1
  import test from 'ava';
2
- import '@endo/init/debug.js';
3
2
 
4
3
  import { makeFakeVirtualObjectManager } from '../../tools/fakeVirtualSupport.js';
5
4
 
6
- test('non-object initial data message', async t => {
5
+ test('non-object initial data message', t => {
7
6
  const vom = makeFakeVirtualObjectManager();
8
7
  const goodInit = () => ({ value: 0 });
9
8
  // 'badInit' is () => { value: 0 }
@@ -1,9 +1,8 @@
1
1
  import test from 'ava';
2
- import '@endo/init/debug.js';
3
2
 
4
3
  import { makeFakeVirtualObjectManager } from '../../tools/fakeVirtualSupport.js';
5
4
 
6
- test('facets', async t => {
5
+ test('facets', t => {
7
6
  const vom = makeFakeVirtualObjectManager();
8
7
  const init = () => ({ value: 0 });
9
8
  const behavior = {
@@ -1,10 +1,10 @@
1
+ // @ts-nocheck
1
2
  import test from 'ava';
2
- import '@endo/init/debug.js';
3
3
  import { Far } from '@endo/marshal';
4
+ import { kser } from '@agoric/kmarshal';
4
5
  import { makeFakeVirtualStuff } from '../../tools/fakeVirtualSupport.js';
5
6
  import { makeLiveSlots } from '../../src/liveslots.js';
6
7
  import { parseVatSlot } from '../../src/parseVatSlots.js';
7
- import { kser } from '../kmarshal.js';
8
8
  import { buildSyscall } from '../liveslots-helpers.js';
9
9
  import { makeStartVat, makeMessage } from '../util.js';
10
10
  import { makeMockGC } from '../mock-gc.js';
@@ -1,5 +1,5 @@
1
+ // @ts-nocheck
1
2
  import test from 'ava';
2
- import '@endo/init/debug.js';
3
3
 
4
4
  import { Remotable } from '@endo/marshal';
5
5
  import { initEmpty } from '@agoric/store';
@@ -7,7 +7,7 @@ import { initEmpty } from '@agoric/store';
7
7
  import { makeVatSlot } from '../../src/parseVatSlots.js';
8
8
  import { makeFakeVirtualStuff } from '../../tools/fakeVirtualSupport.js';
9
9
 
10
- test('VOM tracks reachable vrefs', async t => {
10
+ test('VOM tracks reachable vrefs', t => {
11
11
  const { vom, vrm, cm } = makeFakeVirtualStuff();
12
12
  const { defineKind } = vom;
13
13
  const { makeScalarBigWeakMapStore } = cm;
@@ -1,5 +1,4 @@
1
1
  import test from 'ava';
2
- import '@endo/init/debug.js';
3
2
  // this sets process.env.DEBUG = 'label-instances'
4
3
  import './set-debug-label-instances.js';
5
4
 
@@ -16,7 +15,7 @@ const init = () => ({});
16
15
  const behavior = {};
17
16
  const facets = { foo: {}, bar: {} };
18
17
 
19
- test('representatives with label-instances', async t => {
18
+ test('representatives with label-instances', t => {
20
19
  const { fakeStuff, vom } = makeFakeVirtualStuff();
21
20
  const { getSlotForVal } = fakeStuff;
22
21
  const makeThing = vom.defineKind('thing', init, behavior);
@@ -33,7 +32,7 @@ test('representatives with label-instances', async t => {
33
32
  t.is(`${q(thing2)}`, `"[Alleged: thing#${thing2vref}]"`);
34
33
  });
35
34
 
36
- test('facets with label-instances', async t => {
35
+ test('facets with label-instances', t => {
37
36
  const { fakeStuff, vom } = makeFakeVirtualStuff();
38
37
  const { getSlotForVal } = fakeStuff;
39
38
  const makeThings = vom.defineKindMulti('thing', init, facets);
@@ -1,56 +1,57 @@
1
- /* global WeakRef */
1
+ // @ts-nocheck
2
2
  import test from 'ava';
3
- import '@endo/init/debug.js';
4
3
 
5
4
  import { Far } from '@endo/marshal';
6
5
  import { initEmpty } from '@agoric/store';
7
6
 
8
7
  import engineGC from '../engine-gc.js';
9
- import { makeGcAndFinalize } from '../gc-and-finalize.js';
8
+ import { makeGcAndFinalize, watchCollected } from '../gc-and-finalize.js';
10
9
  import { makeFakeVirtualStuff } from '../../tools/fakeVirtualSupport.js';
11
10
 
12
- function makeHeld() {
13
- const held = Far('held');
14
- const wr = new WeakRef(held);
11
+ function makeStashKit(name = 'held') {
12
+ const held = Far(name);
13
+ const collected = watchCollected(held);
15
14
  const ws = new WeakSet(); // note: real WeakSet, not vref-aware
16
15
  ws.add(held);
17
16
  function isHeld(obj) {
18
17
  return ws.has(obj);
19
18
  }
20
- return { held, wr, isHeld };
19
+ function isCollected() {
20
+ return collected.result;
21
+ }
22
+ return { held, isCollected, isHeld };
21
23
  }
22
24
 
23
25
  function prepareEphemeral(vom) {
24
- const ephemeral = Far('ephemeral');
25
- vom.registerEntry('o+12345', ephemeral);
26
- const wr = new WeakRef(ephemeral);
27
- return { wr };
26
+ const { held, isCollected } = makeStashKit('ephemeral');
27
+ vom.registerEntry('o+12345', held);
28
+ return { isCollected };
28
29
  }
29
30
 
30
31
  function stashRemotableOne(weakStore, key1) {
31
- const { held, wr, isHeld } = makeHeld();
32
+ const { held, isCollected, isHeld } = makeStashKit();
32
33
  weakStore.init(key1, held);
33
- return { wr, isHeld };
34
+ return { isCollected, isHeld };
34
35
  }
35
36
 
36
37
  function stashRemotableTwo(weakStore, key1) {
37
- const { held, wr, isHeld } = makeHeld();
38
+ const { held, isCollected, isHeld } = makeStashKit();
38
39
  weakStore.init(key1, 'initial');
39
40
  weakStore.set(key1, held);
40
- return { wr, isHeld };
41
+ return { isCollected, isHeld };
41
42
  }
42
43
 
43
44
  function stashRemotableThree(holderMaker) {
44
- const { held, wr, isHeld } = makeHeld();
45
+ const { held, isCollected, isHeld } = makeStashKit();
45
46
  const holder = holderMaker(held);
46
- return { wr, isHeld, holder };
47
+ return { isCollected, isHeld, holder };
47
48
  }
48
49
 
49
50
  function stashRemotableFour(holderMaker) {
50
- const { held, wr, isHeld } = makeHeld();
51
+ const { held, isCollected, isHeld } = makeStashKit();
51
52
  const holder = holderMaker('initial');
52
53
  holder.setHeld(held);
53
- return { wr, isHeld, holder };
54
+ return { isCollected, isHeld, holder };
54
55
  }
55
56
 
56
57
  test('remotables retained by virtualized data', async t => {
@@ -74,7 +75,7 @@ test('remotables retained by virtualized data', async t => {
74
75
  // false positive in the subsequent test
75
76
  const stash0 = prepareEphemeral(vom);
76
77
  await gcAndFinalize();
77
- t.falsy(stash0.wr.deref(), `caution: fake VOM didn't release Remotable`);
78
+ t.true(stash0.isCollected(), `caution: fake VOM didn't release Remotable`);
78
79
 
79
80
  // stash a Remotable in the value of a weakStore
80
81
  const key1 = makeKey();
@@ -84,14 +85,14 @@ test('remotables retained by virtualized data', async t => {
84
85
  // Representatives or Presences, so the value is not holding a strong
85
86
  // reference to the Remotable. The VOM is supposed to keep it alive, via
86
87
  // reachableRemotables.
87
- t.truthy(stash1.wr.deref());
88
+ t.false(stash1.isCollected());
88
89
  t.truthy(stash1.isHeld(weakStore.get(key1)));
89
90
 
90
91
  // do the same, but exercise weakStore.set instead of .init
91
92
  const key2 = makeKey();
92
93
  const stash2 = stashRemotableTwo(weakStore, key2);
93
94
  await gcAndFinalize();
94
- t.truthy(stash2.wr.deref());
95
+ t.false(stash2.isCollected());
95
96
  t.truthy(stash2.isHeld(weakStore.get(key2)));
96
97
 
97
98
  // now stash a Remotable in the state of a virtual object during init()
@@ -100,12 +101,12 @@ test('remotables retained by virtualized data', async t => {
100
101
  // Each state property is virtualized upon write (via the generated
101
102
  // setters). So again we rely on the VOM to keep the Remotable alive in
102
103
  // case someone retrieves it again.
103
- t.truthy(stash3.wr.deref());
104
+ t.false(stash3.isCollected());
104
105
  t.truthy(stash3.isHeld(stash3.holder.getHeld()));
105
106
 
106
107
  // same, but stash after init()
107
108
  const stash4 = stashRemotableFour(makeHolder);
108
109
  await gcAndFinalize();
109
- t.truthy(stash4.wr.deref());
110
+ t.false(stash4.isCollected());
110
111
  t.truthy(stash4.isHeld(stash4.holder.getHeld()));
111
112
  });
@@ -1,10 +1,10 @@
1
+ // @ts-nocheck
1
2
  import test from 'ava';
2
- import '@endo/init/debug.js';
3
3
 
4
4
  import { Far } from '@endo/marshal';
5
+ import { kser, kslot } from '@agoric/kmarshal';
5
6
  import { M } from '@agoric/store';
6
7
  import { makeLiveSlots } from '../../src/liveslots.js';
7
- import { kser, kslot } from '../kmarshal.js';
8
8
  import { buildSyscall } from '../liveslots-helpers.js';
9
9
  import { makeStartVat, makeMessage } from '../util.js';
10
10
  import { makeMockGC } from '../mock-gc.js';
@@ -1,12 +1,12 @@
1
+ // @ts-nocheck
1
2
  import test from 'ava';
2
- import '@endo/init/debug.js';
3
3
 
4
4
  import { Far } from '@endo/marshal';
5
+ import { krefOf, kser, kslot } from '@agoric/kmarshal';
5
6
  import {
6
7
  setupTestLiveslots,
7
8
  findSyscallsByType,
8
9
  } from '../liveslots-helpers.js';
9
- import { krefOf, kser, kslot } from '../kmarshal.js';
10
10
  import { parseVatSlot } from '../../src/parseVatSlots.js';
11
11
 
12
12
  // Legs: