diff --git a/packages/SwingSet/src/liveslots/liveslots.js b/packages/SwingSet/src/liveslots/liveslots.js index 6403e6e4a18..691e621555b 100644 --- a/packages/SwingSet/src/liveslots/liveslots.js +++ b/packages/SwingSet/src/liveslots/liveslots.js @@ -437,21 +437,29 @@ function build( return Remotable(iface); } + // We start exportIDs with 1 because 'o+0' is always automatically + // pre-assigned to the root object. The starting point for + // numbering promiseIDs is pretty arbitrary. We start from 5 as a + // very minor aid to debugging: It helps, when puzzling over trace + // logs and the like, for the numbers in the various species of IDs + // to be a little out of sync and thus a little less similar to each + // other when jumbled together. + + const initialIDCounters = { exportID: 1, collectionID: 1, promiseID: 5 }; let idCounters; let idCountersAreDirty = false; function initializeIDCounters() { if (!idCounters) { - const raw = syscall.vatstoreGet('idCounters'); - if (raw) { - idCounters = JSON.parse(raw); - } else { - idCounters = {}; - } + // the saved value might be missing, or from an older liveslots + // (with fewer counters), so merge it with our initial values + const saved = JSON.parse(syscall.vatstoreGet('idCounters') || '{}'); + idCounters = { ...initialIDCounters, ...saved }; + idCountersAreDirty = true; } } - function allocateNextID(name, initialValue = 1) { + function allocateNextID(name) { if (!idCounters) { // Normally `initializeIDCounters` would be called from startVat, but some // tests bypass that so this is a backstop. Note that the invocation from @@ -461,10 +469,8 @@ function build( // issue. initializeIDCounters(); } - if (!idCounters[name]) { - idCounters[name] = initialValue; - } const result = idCounters[name]; + assert(result !== undefined, `unknown idCounters[${name}]`); idCounters[name] += 1; idCountersAreDirty = true; return result; @@ -485,22 +491,15 @@ function build( // use a slot from the corresponding allocateX function allocateExportID() { - // We start exportIDs with 1 because 'o+0' is always automatically - // pre-assigned to the root object. - return allocateNextID('exportID', 1); + return allocateNextID('exportID'); } function allocateCollectionID() { - return allocateNextID('collectionID', 1); + return allocateNextID('collectionID'); } function allocatePromiseID() { - // The starting point for numbering promiseIDs is pretty arbitrary. We start - // from 5 as a very minor aid to debugging: It helps, when puzzling over - // trace logs and the like, for the numbers in the various species of IDs to - // be a little out of sync and thus a little less similar to each other when - // jumbled together. - const promiseID = allocateNextID('promiseID', 5); + const promiseID = allocateNextID('promiseID'); return makeVatSlot('promise', true, promiseID); } diff --git a/packages/SwingSet/test/test-liveslots.js b/packages/SwingSet/test/test-liveslots.js index eb0ef81414d..1a058684c16 100644 --- a/packages/SwingSet/test/test-liveslots.js +++ b/packages/SwingSet/test/test-liveslots.js @@ -752,7 +752,7 @@ test('GC syscall.dropImports', async t => { t.deepEqual(log.shift(), { type: 'vatstoreSet', key: 'idCounters', - value: '{"collectionID":2,"exportID":9}', + value: '{"exportID":9,"collectionID":2,"promiseID":5}', }); const l2 = log.shift(); t.deepEqual(l2, { @@ -1153,7 +1153,7 @@ test('GC dispatch.dropExports', async t => { t.deepEqual(log.shift(), { type: 'vatstoreSet', key: 'idCounters', - value: '{"collectionID":2,"exportID":10}', + value: '{"exportID":10,"collectionID":2,"promiseID":5}', }); t.deepEqual(log, []); @@ -1220,7 +1220,7 @@ test('GC dispatch.retireExports inhibits syscall.retireExports', async t => { t.deepEqual(log.shift(), { type: 'vatstoreSet', key: 'idCounters', - value: '{"collectionID":2,"exportID":10}', + value: '{"exportID":10,"collectionID":2,"promiseID":5}', }); t.deepEqual(log, []); diff --git a/packages/SwingSet/test/virtualObjects/test-representatives.js b/packages/SwingSet/test/virtualObjects/test-representatives.js index 8e3eb59b5dd..c5c2c7d7cb7 100644 --- a/packages/SwingSet/test/virtualObjects/test-representatives.js +++ b/packages/SwingSet/test/virtualObjects/test-representatives.js @@ -382,7 +382,7 @@ test('virtual object gc', async t => { } t.deepEqual(remainingVOs, { 'v1.vs.baggageID': 'o+5/1', - 'v1.vs.idCounters': '{"collectionID":2,"exportID":10,"promiseID":8}', + 'v1.vs.idCounters': '{"exportID":10,"collectionID":2,"promiseID":8}', 'v1.vs.storeKindIDTable': '{"scalarMapStore":1,"scalarWeakMapStore":2,"scalarSetStore":3,"scalarWeakSetStore":4,"scalarDurableMapStore":5,"scalarDurableWeakMapStore":6,"scalarDurableSetStore":7,"scalarDurableWeakSetStore":8}', 'v1.vs.vc.1.|entryCount': '0',