@agoric/swingset-liveslots 0.10.3-upgrade-19-dev-0754752.0 → 0.10.3-upgrade-18a-dev-4ee0508.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.
- package/package.json +22 -22
- package/src/liveslots.js +2 -4
- package/test/liveslots-real-gc.test.js +7 -9
- package/src/boyd-gc.d.ts +0 -12
- package/src/boyd-gc.d.ts.map +0 -1
- package/src/cache.d.ts +0 -71
- package/src/cache.d.ts.map +0 -1
- package/src/capdata.d.ts +0 -12
- package/src/capdata.d.ts.map +0 -1
- package/src/collectionManager.d.ts +0 -46
- package/src/collectionManager.d.ts.map +0 -1
- package/src/facetiousness.d.ts +0 -25
- package/src/facetiousness.d.ts.map +0 -1
- package/src/index.d.ts +0 -4
- package/src/index.d.ts.map +0 -1
- package/src/kdebug.d.ts +0 -7
- package/src/kdebug.d.ts.map +0 -1
- package/src/liveslots.d.ts +0 -42
- package/src/liveslots.d.ts.map +0 -1
- package/src/message.d.ts +0 -45
- package/src/message.d.ts.map +0 -1
- package/src/parseVatSlots.d.ts +0 -125
- package/src/parseVatSlots.d.ts.map +0 -1
- package/src/types.d.ts +0 -76
- package/src/types.d.ts.map +0 -1
- package/src/vatDataTypes.d.ts +0 -170
- package/src/vatDataTypes.d.ts.map +0 -1
- package/src/vatDataTypes.ts +0 -272
- package/src/vatstore-iterators.d.ts +0 -4
- package/src/vatstore-iterators.d.ts.map +0 -1
- package/src/vatstore-usage.md +0 -197
- package/src/virtualObjectManager.d.ts +0 -44
- package/src/virtualObjectManager.d.ts.map +0 -1
- package/src/virtualReferences.d.ts +0 -61
- package/src/virtualReferences.d.ts.map +0 -1
- package/src/vpid-tracking.md +0 -92
- package/src/watchedPromises.d.ts +0 -31
- package/src/watchedPromises.d.ts.map +0 -1
- package/test/dummyMeterControl.d.ts +0 -2
- package/test/dummyMeterControl.d.ts.map +0 -1
- package/test/engine-gc.d.ts +0 -3
- package/test/engine-gc.d.ts.map +0 -1
- package/test/gc-and-finalize.d.ts +0 -5
- package/test/gc-and-finalize.d.ts.map +0 -1
- package/test/liveslots-helpers.d.ts +0 -63
- package/test/liveslots-helpers.d.ts.map +0 -1
- package/test/util.d.ts +0 -25
- package/test/util.d.ts.map +0 -1
- package/test/vat-util.d.ts +0 -9
- package/test/vat-util.d.ts.map +0 -1
- package/test/waitUntilQuiescent.d.ts +0 -3
- package/test/waitUntilQuiescent.d.ts.map +0 -1
- package/tools/fakeCollectionManager.d.ts +0 -14
- package/tools/fakeCollectionManager.d.ts.map +0 -1
- package/tools/fakeVirtualObjectManager.d.ts +0 -32
- package/tools/fakeVirtualObjectManager.d.ts.map +0 -1
- package/tools/fakeVirtualSupport.d.ts +0 -278
- package/tools/fakeVirtualSupport.d.ts.map +0 -1
- package/tools/prepare-strict-test-env.d.ts +0 -37
- package/tools/prepare-strict-test-env.d.ts.map +0 -1
- package/tools/prepare-test-env.d.ts +0 -2
- package/tools/prepare-test-env.d.ts.map +0 -1
- package/tools/setup-vat-data.d.ts +0 -9
- package/tools/setup-vat-data.d.ts.map +0 -1
- package/tools/vo-test-harness.d.ts +0 -2
- package/tools/vo-test-harness.d.ts.map +0 -1
package/src/vatstore-usage.md
DELETED
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
# How Liveslots Uses the Vatstore
|
|
2
|
-
|
|
3
|
-
Each vat gets exclusive access to a portion of the kernel's `kvStore`, implemented with a simple prefix: when vat `v6` uses `syscall.vatstoreSet('key', 'value')`, the kvStore records the value in key `v6.vs.key`.
|
|
4
|
-
|
|
5
|
-
Userspace gets an attenuated object named `vatPowers.vatstore`. When userspace calls `vatPowers.vatstore.set('key', 'value')`, liveslots performs `syscall.vatstoreSet('vvs.key', value)`, which results in a kernel kvStore entry under key `v6.vs.vvs.key`.
|
|
6
|
-
|
|
7
|
-
The rest of the vat's keyspace is used by liveslots:
|
|
8
|
-
|
|
9
|
-
* virtual object Kind metainformation
|
|
10
|
-
* data for each virtual object
|
|
11
|
-
* virtual collection metainformation and entries
|
|
12
|
-
* reference counts for virtual objects (tracking references from other virtual objects)
|
|
13
|
-
* export status for virtual objects
|
|
14
|
-
* the id of the "baggage" object, delivered across vat upgrades
|
|
15
|
-
|
|
16
|
-
This file describes the layout of the vatstore keyspace.
|
|
17
|
-
|
|
18
|
-
# vref virtual/durable annotations
|
|
19
|
-
|
|
20
|
-
When vats export object references into the kernel, they create "vrefs" as reference identifiers. For non-virtual objects (ephemeral "Remotables", held in RAM rather than the DB), these take the form of `o+NN` (e.g. `o+0`, `o+12`, `o+937`). Virtual and durable exported objects get an additional `v` or `d` annotation, so their vrefs start with e.g. `o+v99` or `o+v132` for virtual objects, and `o+d3` or `o+d77` for durable objects. The kernel can use these annotations to assist in the cleanup process when a vat is upgraded, and non-durable objects are abandoned.
|
|
21
|
-
|
|
22
|
-
Kind handles are necessarily durable, as is the "baggage" object. Promises are necessarily ephemeral, so vat-allocated promise vrefs (aka "vpids") always use the `p+NN` form, and never have a `v` or `d` annotation.
|
|
23
|
-
|
|
24
|
-
# Counters
|
|
25
|
-
|
|
26
|
-
Liveslots maintains three durable counters to create the distinct vrefs that it transmits to the kernel. These counters are initialized when `startVat` is called to create the first incarnation of a vat (see `initialIDCounters` and `initializeIDCounters` in [liveslots.js](./liveslots.js)), and written to the vatstore at the end of each delivery as a JSON-serialized record at key `idCounters` (see `flushIDCounters`).
|
|
27
|
-
|
|
28
|
-
* `exportID`: an integer indicating the ID of the next exported Remotable or defined Kind and incremented upon each allocation of such a value. Technically starts at 1, but that is mostly irrelevant because the root object itself is associated with 0 and many initial values are claimed before any userspace vat code has a chance to run (described below).
|
|
29
|
-
* `collectionID`: an integer indicating the ID of the next collection and incremented upon each allocation of a new collection. Starts at 1, which is claimed by "[baggage](#baggage)".
|
|
30
|
-
* `promiseID`: an integer indicating the ID for the next exported promise (including a promise implicitly created for outbound-message results) and incremented upon each allocation. Starts at 5.
|
|
31
|
-
|
|
32
|
-
The current version of liveslots consumes the first ten exportIDs (covering `o+0` through `o+9`) during vat startup, leaving `10` as the first exportID available for userspace.
|
|
33
|
-
|
|
34
|
-
* `o+0`: root object
|
|
35
|
-
* `o+d1`: identifies the KindHandle Kind ID, each `o+d1/${kindHandleID}` instance of which is a KindHandle
|
|
36
|
-
* `o+v2` through `o+v5`: KindHandles for the built-in [virtual collections](#virtualdurable-collections-aka-stores)
|
|
37
|
-
* `o+d6` through `o+d9`: KindHandles for the built-in [durable collections](#virtualdurable-collections-aka-stores)
|
|
38
|
-
* `o+10` / `o+v10` / `o+d10`: first available for userspace Remotables or Kinds
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
# Virtual Object Kinds
|
|
42
|
-
|
|
43
|
-
Vats can use `VatData.defineKind()` to define categories (classes) of virtual data (see [Virtual and Durable Objects](../../SwingSet/docs/virtual-objects.md)). The effective schema for each "Kind" contains an interface name, a set of `state` property names, and a list of facet names (which may be empty, indicating a single-facet Kind).
|
|
44
|
-
|
|
45
|
-
The standard Kind is "single-facet", meaning that each instance of the virtual object yields exactly one "Representative". However many security patterns require a collection of "Facet" Representatives which share access to common state. These Facets are all created at the same time and returned in a single record called a "cohort".
|
|
46
|
-
|
|
47
|
-
`defineKind` also specifies the runtime behavior: an `init` function called to create the initial state of each instance, a `behavior` record to provide methods for each instance, and an optional `finish` function to perform post-initialization tasks like registering the new object in a collection. `defineKind` returns a "kind constructor", typically named e.g. `makeFoo()` to make instances of the "foo" kind.
|
|
48
|
-
|
|
49
|
-
Each time the kind constructor is called, a new "baseref" is allocated for the cohort, and the (one or multiple) facet Representatives are created. Each Representative/Facet gets a separate vref, all of which are extensions of the baseref.
|
|
50
|
-
Those vrefs are used when interacting with the kernel (in `syscall.send` etc.), and in virtualized data (inside the capdata `slots` that point to other objects), but the vatstore keys that track GC refcounts and export status use the "baseref" instead.
|
|
51
|
-
|
|
52
|
-
The baseref is built out of two pieces separated by a literal `/`:
|
|
53
|
-
|
|
54
|
-
1. Prefixed Kind ID, e.g. `o+v11` or `o+d11`. These are allocated using the same exportID [counter](#counters) as exported Remotables (JavaScript objects marked with `Far`), meaning exported objects and Kind IDs share a numberspace.
|
|
55
|
-
2. Instance ID, an integer. `1` for the first instance of each Kind and incremented for each subsequent instance.
|
|
56
|
-
|
|
57
|
-
The vref for a Representative of a single-facet virtual Kind is just the `o+v${kindID}/${instanceID}` baseref. The vref for a Representative of a facet of a multi-facet virtual Kind extends that to `o+v${kindID}/${instanceID}:${facetID}`, where the additional component is:
|
|
58
|
-
|
|
59
|
-
3. Facet ID, an integer. `0` for the first facet and incremented for each subsequent facet.
|
|
60
|
-
|
|
61
|
-
In a c-list or virtualized data, you may see vrefs like these:
|
|
62
|
-
|
|
63
|
-
* `o-3`: an imported Presence, pointing to some object in a different vat
|
|
64
|
-
* `o+0`: the root object, a plain Remotable
|
|
65
|
-
* `o+10`: another plain Remotable, exported from this vat or stored in virtualized data
|
|
66
|
-
* `o+d11/1`: a Representative for the first instance of single-facet virtual Kind `o+v11`
|
|
67
|
-
* `o+d11/2`: a Representative for the second instance of single-facet virtual Kind `o+v11`
|
|
68
|
-
* `o+d12/1:0`: the first facet of the first instance of a multi-facet durable Kind `o+d12`
|
|
69
|
-
* `o+d12/1:1`: the second facet of that same instance
|
|
70
|
-
* `o+d12/2:0`: the first facet of a different instance
|
|
71
|
-
* `o+d12/3:0`: the first facet of yet another different instance
|
|
72
|
-
|
|
73
|
-
Each instance of a virtual object stores state in a vatstore key indexed by the baseref. If `o+d12/1:0` and `o+d12/1:1` are the facet vrefs for a cohort whose baseref is `o+d12/1`, the cohort's shared state will be stored by the virtual object manager in `vom.o+d12/1` as a JSON-serialized record. The keys of this record are property names: if the Kind uses `state.prop1`, the record will have a key named `prop1`. For each property, the value is a `{ body: string, slots: any[] }` capdata record with string-valued slot items (and unlike the treatment of capdata in many other parts of the system, it is not serialized independently of the enclosing structure).
|
|
74
|
-
|
|
75
|
-
* `v6.vs.vom.o+d12/1` : `{"booleanProp":{"body":"true","slots":[]},"arrayProp":{"body":"[]","slots":[]}}`
|
|
76
|
-
|
|
77
|
-
In the refcounting portion of the vatstore (`vom.rc.${baseref}`), you will see baserefs:
|
|
78
|
-
|
|
79
|
-
* `v6.vs.vom.rc.o+10`: the count of virtualized references to plain Remotable `o+10` (held in RAM)
|
|
80
|
-
* `v6.vs.vom.rc.o+d12/1`: the count of references to any member of the cohort for the first instance of durable Kind `o+d12`
|
|
81
|
-
* This Kind might be single-facet or multi-facet.
|
|
82
|
-
* References to distinct facets of the same cohort are counted independently. For example, if one object references both the first and second facets (`o+d12/1:0` and `o+d12/1:1`), it accounts for two increments to this value.
|
|
83
|
-
|
|
84
|
-
In the export-status portion of the vatstore (`vom.es.${baseref}`), you will see baserefs, and any facets are tracked in the value, not the key:
|
|
85
|
-
|
|
86
|
-
* `v6.vs.vom.es.o+10` records the export status for plain Remotable `o+10`
|
|
87
|
-
* value `r`: the plain Remotable has been exported and is "reachable" by the kernel
|
|
88
|
-
* value `s`: the Remotable was exported, the kernel dropped it, and is still "recognizable" by the kernel ("s" for "see", refer to [Garbage Collection in SwingSet](../../SwingSet/docs/garbage-collection.md) for details)
|
|
89
|
-
* If the kernel can neither reach nor recognize the export, the vatstore key will be missing entirely.
|
|
90
|
-
* `v6.vs.vom.es.o+d12/1` records the export status for all facets of the durable object whose vref is `o+d12/1` (i.e., the first instance of durable Kind `o+d12`)
|
|
91
|
-
* If the Kind is single-facet, the value will be the same as for a plain Remotable: a single `r` or `s` character
|
|
92
|
-
* If the Kind is multi-facet, the value will be a string with one letter for each facet, in the same order as their Facet ID. `n` is used to indicate neither reachable nor recognizable. For example, a value of `rsnr` means there are four facets, the first (`o+d12/1:0`) and last (`o+d12/1:3`) are reachable, the second (`o+d12/1:1`) is recognizable, and the third (`o+d12/1:2`) is neither.
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
# Durable Kinds
|
|
96
|
-
|
|
97
|
-
Virtual objects are held on disk, which makes them suitable for high-cardinality data that is likely too large for our vat workers' limited RAM budget: many objects, most of which are "idle" at any given time. However virtual objects do not survive a vat upgrade. For this, vats should define one or more "Durable Kinds" instead.
|
|
98
|
-
|
|
99
|
-
Durable Kinds are defined just like virtual Kinds, but they use a different constructor (`defineDurableKind` instead of `defineKind`), which requires a "handle" created by `makeKindHandle`. Durable virtual objects can only hold durable data in their `state`.
|
|
100
|
-
|
|
101
|
-
The KindHandle is a durable virtual object of a special internal Kind. This is the first Kind allocated, so usually it gets exportID 1 to use as a Kind ID, and the kind handles for virtual and durable Kinds get vrefs like `o+d1/${kindHandleID}`.
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
# Kind Metadata
|
|
105
|
-
|
|
106
|
-
For each virtual object kind that is defined, we store a metadata record for purposes of scanning directly through the defined kinds when a vat is stopped or upgraded. For durable kinds this record is stored in `vom.dkind.${kindID}`; for non-durable kinds it is stored in `vom.vkind.${kindID}`. Currently this metadata takes the form of a JSON-serialized record with the following properties:
|
|
107
|
-
* `kindID`, the kind ID as a numeric string (redundantly with the storage key)
|
|
108
|
-
* `tag`, the tag string as provided in the `defineKind` or `makeKindHandle` call
|
|
109
|
-
* `nextInstanceID`, an integer that is present only for durable kinds. It ensures that all versions share a single sequence of unique instance IDs. `nextInstanceID` is added to the metadata record upon allocation of the first instance of the kind and updated after each subsequent allocation.
|
|
110
|
-
* `unfaceted`, a property with boolean value `true` that is present only for single-facet durable kinds.
|
|
111
|
-
* `facets`, an array that is present only for multi-facet durable kinds. Its elements are the names of the kind's facets, in the same order as the assignment of facet indices within the cohort record.
|
|
112
|
-
|
|
113
|
-
`unfaceted` and `facets` are required so that kind definitions in upgraded versions of the containing vat are maintained in a backwards compatible manner over time.
|
|
114
|
-
|
|
115
|
-
# Virtual/Durable Collections (aka Stores)
|
|
116
|
-
|
|
117
|
-
Liveslots provides vats with a handful of "virtual collection" types for storing high-cardinality data on disk rather than in RAM. Each instance of one of these types is described as a "[Store](../../store/docs/store-taxonomy.md)". They provide limited range queries and offer a single fixed sort index: numbers sort as usual, BigInts sort as usual but separate from numbers, strings sort lexicographically by UTF-8 encoding, and object references sort by insertion order.
|
|
118
|
-
|
|
119
|
-
Collections are created by functions on the `VatStore` global:
|
|
120
|
-
|
|
121
|
-
* `makeScalarBigMapStore`
|
|
122
|
-
* `makeScalarBigWeakMapStore`
|
|
123
|
-
* `makeScalarBigSetStore`
|
|
124
|
-
* `makeScalarBigWeakSetStore`
|
|
125
|
-
|
|
126
|
-
Each function accepts a boolean `durable` option, so there are currently 8 collection types.
|
|
127
|
-
|
|
128
|
-
Each collection type is assigned a Kind index, just like the user-defined Kinds. The 8 collection types are allocated before userspace gets a chance to call `defineKind` or `defineDurableKind`, so they claim earlier exportID numbers as described [above](#counters).
|
|
129
|
-
|
|
130
|
-
These index values are stored in `storeKindIDTable`, as a mapping from the collection type name ("scalarMapStore", "scalarDurableMapStore", "scalarWeakSetStore", etc.) to the integer of their ID. The current table assignments are:
|
|
131
|
-
|
|
132
|
-
* `v6.vs.storeKindIDTable` : `{"scalarMapStore":2,"scalarWeakMapStore":3,"scalarSetStore":4,"scalarWeakSetStore":5,"scalarDurableMapStore":6,"scalarDurableWeakMapStore":7,"scalarDurableSetStore":8,"scalarDurableWeakSetStore":9}`
|
|
133
|
-
|
|
134
|
-
which means `2` is the Kind ID for non-durable merely-virtual "scalarMapStore", instances of which will have vrefs like `o+v2/${collectionID}`.
|
|
135
|
-
|
|
136
|
-
Each new store, regardless of type, is allocated the next available collectionID [counter](#counters). This is an incrementing integer that starts at 1, and forms a numberspace independent of the exportID counter used by exported Remotables and Kind IDs. The same collectionID numberspace is shared by all collection types. So unlike virtual objects (where the instanceID in `o+v${kindID}/${instanceID}` is scoped to `o+v${kindID}`), for collections the collectionID in `o+v${collectionType}/${collectionID}` is global to the entire vat. No two stores will have the same collectionID, even if they are of different types.
|
|
137
|
-
|
|
138
|
-
The interpretation of a vref therefore varies based on whether the initial "type" portion before a slash (`o+v${exportID}` or `o+d${exportID}`) identifies a collection type or a virtual object kind:
|
|
139
|
-
|
|
140
|
-
* `o+d6/1`: `6` is a collection type in the storeKindIDTable ("scalarDurableMapStore"), so `o+d6/1` refers to the first collection (of any type) in the vat
|
|
141
|
-
* `o+d7/1`: `7` is also a collection type in the storeKindIDTable ("scalarDurableWeakMapStore"), so `o+d7/1` is guaranteed not to coexist with `o+d6/1`
|
|
142
|
-
* `o+d7/2`: refers to the second collection (of any type) in the vat, which has type `7` ("scalarDurableWeakMapStore")
|
|
143
|
-
* `o+v5/3`: refers to the third collection (of any type) in the vat, which has type `5` ("scalarWeakSetStore")
|
|
144
|
-
* `o+v5/4`: refers to the fourth collection (of any type) in the vat, also a scalarWeakSetStore
|
|
145
|
-
* `o+v11/1`: `11` is not a collection type in the storeKindIDTable, so is instead a kind and `o+v11/1` refers to the first instance of that kind
|
|
146
|
-
* `o+v11/2`: refers to the second instance of that kind
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
# Baggage
|
|
150
|
-
|
|
151
|
-
Most collections are created by userspace code, but to support vat upgrade, liveslots creates one special collection named "baggage". This is a `scalarDurableMapStore` that is passed into the third argument of `buildRootObject`.
|
|
152
|
-
|
|
153
|
-
This object needs to be pre-generated because the second (and subsequent) versions of the vat will use it to reach all other durable objects from their predecessors, so v2 can remember things that were stored by v1. The most significant values of "baggage" are the KindHandles for durable Kinds made by v1. V2 will need these to call `defineDurableKind` and re-attach behavior for each one. Each version must re-attach behavior for *all* durable Kinds created by its predecessors.
|
|
154
|
-
|
|
155
|
-
The above rules about kindID and collectionID allocation result in the baggage being associated with vref `o+d6/1`, indicating that it is a scalarDurableMapStore (`o+d6` is used for that collection type) and also that it is the first collection of any type allocated in the vat. This value is also stored under key `baggageID` (see `provideBaggage` in [collectionManager.js](./collectionManager.js)).
|
|
156
|
-
* `v6.vs.baggageID` : `o+d6/1`
|
|
157
|
-
|
|
158
|
-
If userspace version 1 starts `buildRootObject` by calling `makeScalarBigWeakSetStore()` and then three `makeScalarSetStore()`s, the collections are likely to be assigned `o+v5/2`, `o+v4/3`, `o+v4/4`, and `o+v4/5` respectively. Such collectionIDs start with `2` because `1` is claimed by baggage.
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
# Collection Data Records
|
|
162
|
-
|
|
163
|
-
We examine a vat which performs the following at startup:
|
|
164
|
-
|
|
165
|
-
```js
|
|
166
|
-
const initFoo = arg => ({ prop1: arg });
|
|
167
|
-
const fooBehavior = {
|
|
168
|
-
getProp1: ({ state }) => state.prop1,
|
|
169
|
-
};
|
|
170
|
-
const makeFoo = VatData.defineKind('foo', initFoo, fooBehavior);
|
|
171
|
-
const foo = makeFoo(1);
|
|
172
|
-
const foo2 = makeFoo(2);
|
|
173
|
-
const c1 = VatData.makeScalarBigMapStore('mylabel');
|
|
174
|
-
c1.init('key1', foo);
|
|
175
|
-
c1.init('key2', foo);
|
|
176
|
-
c1.init('key3', foo);
|
|
177
|
-
c1.init('key4', foo2);
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
Each collection stores a number of metadata keys in the vatstore, all with a prefix of `vc.${collectionID}.|` (note that the collection *type* is not a part of the key, only the collection *index*). The currently defined metadata keys (copied from the record for the "mylabel" Kind stored in `c1`) are:
|
|
181
|
-
|
|
182
|
-
* `v6.vs.vc.2.|entryCount`: `4` (the size of the collection as a numeric string, incremented with each call to `c1.init` and decremented with each call to `c1.delete`)
|
|
183
|
-
* `v6.vs.vc.2.|nextOrdinal`: `1` (a numeric string counter used to allocate index values for Objects used as keys, see `generateOrdinal` in [collectionManager.js](./collectionManager.js))
|
|
184
|
-
* `v6.vs.vc.2.|schemata`: `{"label":"mylabel","body":"#[{\\"#tag\\":\\"match:scalar\\",\\"payload\\":\\"#undefined\\"}]","slots":[]}`
|
|
185
|
-
|
|
186
|
-
The `schemata` is a capdata serialization of the debugging label provided in the `make*Store` call that created the collection, plus the Matcher constraints recorded for the collection. These constraints can limit keys to be just strings, or numbers, etc. (see [Patterns](https://github.com/endojs/endo/tree/master/packages/patterns)). The schemata consists of an array in which the first element is a schema for the keys and the second is a separate schema for the values.
|
|
187
|
-
|
|
188
|
-
Each entry in the collection gets put into a single vatstore entry with a capdata-serialized value:
|
|
189
|
-
|
|
190
|
-
* `v6.vs.vc.2.skey1`: `{"body":"#\"$0.Alleged: foo\"","slots":["o+d9/1"]}`
|
|
191
|
-
* `v6.vs.vc.2.skey2`: `{"body":"#\"$0.Alleged: foo\"","slots":["o+d9/1"]}`
|
|
192
|
-
* `v6.vs.vc.2.skey3`: `{"body":"#\"$0.Alleged: foo\"","slots":["o+d9/1"]}`
|
|
193
|
-
* `v6.vs.vc.2.skey4`: `{"body":"#\"$0.Alleged: foo\"","slots":["o+d9/2"]}`
|
|
194
|
-
|
|
195
|
-
The key string for each entry (e.g. `skey1`) is formed by serializing the key object. Strings get a simple `s` prefix. Other objects use more complex encodings, designed to allow numbers (floats and BigInts, separately) to sort numerically despite the kvStore keys sorting lexicographically. See Endo [encodePassable.js](https://github.com/endojs/endo/blob/master/packages/marshal/src/encodePassable.js) for details. Object references involve an additional kvStore entry, to manage the mapping from Object to ordinal and back.
|
|
196
|
-
|
|
197
|
-
For weak stores, the collection manager also maintains inbound-reference database keys of the form `vom.ir.${vref}|${collectionID}`, where in this case `${vref}` is the vref of a virtual object, store, import, or remotable, and `${collectionID}` is the collectionID of a weak store in which the given vref is used as a key. This enables the collection manager to locate and remove collection entries whose keys are being garbage collected. Note that mere presence or absence of such a key in the database is significant but the value associated with it is not.
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
export function makeVirtualObjectManager(syscall: any, vrm: import("./virtualReferences.js").VirtualReferenceManager, allocateExportID: () => number, getSlotForVal: (val: object) => string | undefined, requiredValForSlot: (slot: string) => object, registerValue: any, serialize: ToCapData<string>, unserialize: FromCapData<string>, assertAcceptableSyscallCapdataSize: any, liveSlotsOptions?: import("./types.js").LiveSlotsOptions, { WeakMap, WeakSet }?: {
|
|
2
|
-
WeakMap: typeof globalThis.WeakMap;
|
|
3
|
-
WeakSet: typeof globalThis.WeakSet;
|
|
4
|
-
}): {
|
|
5
|
-
initializeKindHandleKind: () => void;
|
|
6
|
-
defineKind: <P extends Array<any>, S, F>(tag: string, init: (...args: P) => S, facet: F, options?: DefineKindOptions<import("@agoric/swingset-liveslots").KindContext<S, F>>) => (...args: P) => import("@agoric/swingset-liveslots").KindFacet<F>;
|
|
7
|
-
defineKindMulti: <P extends Array<any>, S, B>(tag: string, init: (...args: P) => S, behavior: B, options?: DefineKindOptions<import("@agoric/swingset-liveslots").MultiKindContext<S, B>>) => (...args: P) => import("@agoric/swingset-liveslots").KindFacets<B>;
|
|
8
|
-
defineDurableKind: <P extends Array<any>, S, F>(kindHandle: DurableKindHandle, init: (...args: P) => S, facet: F, options?: DefineKindOptions<import("@agoric/swingset-liveslots").KindContext<S, F>>) => (...args: P) => import("@agoric/swingset-liveslots").KindFacet<F>;
|
|
9
|
-
defineDurableKindMulti: <P extends Array<any>, S, B>(kindHandle: DurableKindHandle, init: (...args: P) => S, behavior: B, options?: DefineKindOptions<import("@agoric/swingset-liveslots").MultiKindContext<S, B>>) => (...args: P) => import("@agoric/swingset-liveslots").KindFacets<B>;
|
|
10
|
-
makeKindHandle: (tag: string) => DurableKindHandle;
|
|
11
|
-
insistAllDurableKindsReconnected: () => void;
|
|
12
|
-
VirtualObjectAwareWeakMap: {
|
|
13
|
-
new (): {
|
|
14
|
-
has(key: any): any;
|
|
15
|
-
get(key: any): any;
|
|
16
|
-
set(key: any, value: any): /*elided*/ any;
|
|
17
|
-
delete(key: any): any;
|
|
18
|
-
};
|
|
19
|
-
};
|
|
20
|
-
VirtualObjectAwareWeakSet: {
|
|
21
|
-
new (): {
|
|
22
|
-
has(value: any): any;
|
|
23
|
-
add(value: any): /*elided*/ any;
|
|
24
|
-
delete(value: any): any;
|
|
25
|
-
};
|
|
26
|
-
};
|
|
27
|
-
flushStateCache: () => void;
|
|
28
|
-
getRetentionStats: () => {
|
|
29
|
-
definedDurableKinds: number;
|
|
30
|
-
nextInstanceIDs: number;
|
|
31
|
-
};
|
|
32
|
-
testHooks: {
|
|
33
|
-
countWeakKeysForCollection: (collection: any) => any;
|
|
34
|
-
definedDurableKinds: Set<any>;
|
|
35
|
-
nextInstanceIDs: Map<any, any>;
|
|
36
|
-
};
|
|
37
|
-
canBeDurable: (specimen: any) => boolean;
|
|
38
|
-
};
|
|
39
|
-
export type VirtualObjectManager = ReturnType<typeof makeVirtualObjectManager>;
|
|
40
|
-
import type { ToCapData } from '@endo/marshal';
|
|
41
|
-
import type { FromCapData } from '@endo/marshal';
|
|
42
|
-
import type { DefineKindOptions } from '@agoric/swingset-liveslots';
|
|
43
|
-
import type { DurableKindHandle } from '@agoric/swingset-liveslots';
|
|
44
|
-
//# sourceMappingURL=virtualObjectManager.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"virtualObjectManager.d.ts","sourceRoot":"","sources":["virtualObjectManager.js"],"names":[],"mappings":"AA2TO,kDApDI,GAAC,OACD,OAAO,wBAAwB,EAAE,uBAAuB,oBAExD,MAAM,MAAM,iBAEZ,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,sBAGnC,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,iBACxB,GAAC,aAED,UAAU,MAAM,CAAC,eACjB,YAAY,MAAM,CAAC,sCACnB,GAAC,qBAED,OAAO,YAAY,EAAE,gBAAgB,yBACrC;IAAE,OAAO,EAAE,yBAAc,CAAC;IAAC,OAAO,EAAE,yBAAc,CAAA;CAAE;;iEAnItC,GAAG,kHAC0B,GAAG;sEAGjB,GAAG,0HAE1B,GAAG;0FAKc,GAAG,kHAEpB,GAAG;+FAIX,GAAG,0HACiB,GAAG;0BAsiCnB,MAAM,KACJ,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqI/B;mCAEa,UAAU,CAAC,OAAO,wBAAwB,CAAC;+BA/zChB,eAAe;iCAAf,eAAe;uCAFpB,4BAA4B;uCAD5B,4BAA4B"}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @param {*} syscall Vat's syscall object, used to access the vatstore operations.
|
|
3
|
-
* @param {(val: object) => string | undefined} getSlotForVal A function that returns the
|
|
4
|
-
* object ID (vref) for a given object, if any. their corresponding export
|
|
5
|
-
* IDs
|
|
6
|
-
* @param {(slot: string) => object} requiredValForSlot A function that
|
|
7
|
-
* converts an object ID (vref) to an object.
|
|
8
|
-
* @param {*} FinalizationRegistry Powerful JavaScript intrinsic normally denied
|
|
9
|
-
* by SES
|
|
10
|
-
* @param {*} WeakRef Powerful JavaScript intrinsic normally denied
|
|
11
|
-
* by SES
|
|
12
|
-
* @param {*} addToPossiblyDeadSet Function to record objects whose deaths
|
|
13
|
-
* should be reinvestigated
|
|
14
|
-
* @param {*} addToPossiblyRetiredSet Function to record dead objects whose
|
|
15
|
-
* retirement should be reinvestigated
|
|
16
|
-
* @param {boolean} relaxDurabilityRules True IFF the associated swingset is
|
|
17
|
-
* running with relaxed durability rules
|
|
18
|
-
*/
|
|
19
|
-
export function makeVirtualReferenceManager(syscall: any, getSlotForVal: (val: object) => string | undefined, requiredValForSlot: (slot: string) => object, FinalizationRegistry: any, WeakRef: any, addToPossiblyDeadSet: any, addToPossiblyRetiredSet: any, relaxDurabilityRules: boolean): {
|
|
20
|
-
registerDroppedCollection: (target: any, descriptor: any) => void;
|
|
21
|
-
isDurable: (vref: string) => boolean;
|
|
22
|
-
isDurableKind: (kindID: string) => boolean;
|
|
23
|
-
registerKind: (kindID: string, reanimator?: (string: any, boolean: any) => object, deleter?: (string: any) => boolean, durable?: boolean) => void;
|
|
24
|
-
rememberFacetNames: (kindID: string, facetNames: string[] | null) => void;
|
|
25
|
-
getFacet: (kindID: any, facets: any, facetIndex: any) => any;
|
|
26
|
-
getFacetNames: (kindID: any) => any;
|
|
27
|
-
reanimate: (baseRef: string) => any;
|
|
28
|
-
addReachableVref: (vref: any) => void;
|
|
29
|
-
removeReachableVref: (vref: any) => boolean;
|
|
30
|
-
updateReferenceCounts: (beforeSlots: any, afterSlots: any) => void;
|
|
31
|
-
getReachablePromiseRefCount: (p: any) => number;
|
|
32
|
-
addRecognizableValue: (value: any, recognizer: string | (Map<string, any> | Set<string>), recognizerIsVirtual?: boolean) => void;
|
|
33
|
-
removeRecognizableVref: (vref: string, recognizer: string | (Map<string, any> | Set<string>), recognizerIsVirtual?: boolean) => void;
|
|
34
|
-
removeRecognizableValue: (value: any, recognizer: string | (Map<string, any> | Set<string>), recognizerIsVirtual?: boolean) => void;
|
|
35
|
-
vrefKey: (value: any) => string | undefined;
|
|
36
|
-
isPresenceReachable: (vref: string) => boolean;
|
|
37
|
-
isVrefRecognizable: (vref: any) => boolean;
|
|
38
|
-
setExportStatus: (vref: any, exportStatus: any) => void;
|
|
39
|
-
isVirtualObjectReachable: (baseRef: string) => boolean;
|
|
40
|
-
deleteVirtualObject: (baseRef: string) => [boolean, string[]];
|
|
41
|
-
ceaseRecognition: (vref: string) => boolean;
|
|
42
|
-
setDeleteCollectionEntry: (fn: any) => void;
|
|
43
|
-
getRetentionStats: () => {
|
|
44
|
-
remotableRefCounts: number;
|
|
45
|
-
vrefRecognizers: number;
|
|
46
|
-
kindInfoTable: number;
|
|
47
|
-
};
|
|
48
|
-
initializeIDCounters: () => void;
|
|
49
|
-
allocateNextID: (name: any) => number;
|
|
50
|
-
flushIDCounters: () => void;
|
|
51
|
-
testHooks: {
|
|
52
|
-
getReachableRefCount: (vref: any) => number | undefined;
|
|
53
|
-
countCollectionsForWeakKey: (vref: any) => number;
|
|
54
|
-
getDroppedCollectionRegistry: () => any;
|
|
55
|
-
remotableRefCounts: Map<any, number>;
|
|
56
|
-
vrefRecognizers: Map<string, Set<Map<string, any> | Set<string>>>;
|
|
57
|
-
kindInfoTable: Map<any, any>;
|
|
58
|
-
};
|
|
59
|
-
};
|
|
60
|
-
export type VirtualReferenceManager = ReturnType<typeof makeVirtualReferenceManager>;
|
|
61
|
-
//# sourceMappingURL=virtualReferences.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"virtualReferences.d.ts","sourceRoot":"","sources":["virtualReferences.js"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;GAiBG;AACH,qDAjBW,GAAC,iBACD,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,sBAGnC,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,wBAExB,GAAC,WAED,GAAC,wBAED,GAAC,2BAED,GAAC,wBAED,OAAO;;sBAqQL,MAAM,KAEJ,OAAO;4BAfT,MAAM,KAEJ,OAAO;2BA9CT,MAAM,eACN,CAAC,MAAM,KAAA,EAAE,OAAO,KAAA,KAAK,MAAM,YAC3B,CAAC,MAAM,KAAA,KAAK,OAAO,YACnB,OAAO;iCASP,MAAM,cACN,MAAM,EAAE,GAAC,IAAI;;;yBA8Eb,MAAM;;;;;kCAmPN,GAAC,cACD,MAAM,mCAAW,wBACjB,OAAO;mCA2BP,MAAM,cACN,MAAM,mCAAW,wBACjB,OAAO;qCAgCP,GAAC,cACD,MAAM,mCAAW,wBACjB,OAAO;;gCAvIP,MAAM,KAEJ,OAAO;;;wCAzaT,MAAM,KAEJ,OAAO;mCAoBT,MAAM,KAEJ,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;6BAwiBrB,MAAM,KAEJ,OAAO;;;;;;;;;;;;;;;;;;EA+LrB;sCACa,UAAU,CAAC,OAAO,2BAA2B,CAAC"}
|
package/src/vpid-tracking.md
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
# Promise/VPID Management in Liveslots
|
|
2
|
-
|
|
3
|
-
Kernels and vats communicate about promises by referring to their VPIDs: vat(-centric) promise IDs. These are strings like `p+12` and `p-23`. Like VOIDs (object IDs), the plus/minus sign indicates which side of the boundary allocated the number (`p+12` and `o+12` are allocated by the vat, `p-13` and `o-13` are allocated by the kernel). But where the object ID sign also indicates which side "owns" the object (i.e. where the behavior lives), the promise ID sign is generally irrelevant.
|
|
4
|
-
|
|
5
|
-
Instead, we care about which side holds the resolution authority for a promise (referred to as being its **decider**). This is not indicated by the VPID sign, and in fact is not necessarily static. Liveslots does not currently have any mechanism to allow one promise to be forwarded to another, but if it acquires this some day, then the decider of a promise could shift from kernel to vat to kernel again before it finally gets resolved. And there *are* sequences that allow a vat to receive a reference to a promise in method arguments before receiving a message whose result promise uses that same VPID (e.g., `p1 = p2~.foo(); x~.bar(p1)`, then someone resolves `p2` to `x`. Consider also tildot-free code like `{ promise: p1, resolve: resolveP1 } = makePromiseKit(); p2 = E(p1).push('queued'); await E(observer).push(p2); resolveP1(observer);` with an observer whose `push` returns a prompt response). In such cases, the decider is initially the kernel but that authority is transferred to a vat later.
|
|
6
|
-
|
|
7
|
-
Each Promise starts out in the "unresolved" state, then later transitions irrevocably to the "resolved" state. Liveslots frequently (but not always) pays attention to this transition by calling `then` to attach fulfillment/rejection settlement callbacks. To handle resolution cycles, liveslots remembers the resolution of old promises in a `WeakMap` for as long as the Promise exists. Consequently, for liveslots' purposes, every Promise is either resolved (a callback has fired and liveslots remembers the settlement), or unresolved (liveslots has not yet seen a resolution that settles it).
|
|
8
|
-
|
|
9
|
-
There are roughly four ways that liveslots might become aware of a promise:
|
|
10
|
-
|
|
11
|
-
* serialization: a Promise instance is serialized, either for the arguments of an outbound `syscall.send` or `syscall.resolve`, the argument of `watchPromise()`, or to be stored into virtualized data (e.g. `bigMapStore.set(key, promise)`, or assignment to a property of a virtual object)
|
|
12
|
-
* creation for outbound result: liveslots allocates a VPID for the `result` of an outbound `syscall.send`, and creates a new Promise instance to give back to userspace
|
|
13
|
-
* deserialization: the arguments of an inbound `dispatch.deliver` or `dispatch.notify` are deserialized, and a new Promise instance is created
|
|
14
|
-
* inbound result: the kernel-allocated `result` VPID of an inbound `dispatch.deliver` is associated with the Promise we get back from `HandledPromise.applyMethod`
|
|
15
|
-
|
|
16
|
-
A Promise may be associated with a VPID even though the kernel does not know about it (i.e. the VPID is not in the kernel's c-list for that vat). This can occur when a Promise is stored into virtual data without also being sent to (or received from) the kernel, although note that every Promise associated with a durable promise watcher _is_ sent to the kernel so it can be rejected during vat upgrade. A Promise can also be resolved but still referenced in vdata and forgotten by the kernel (the kernel's knowledge is temporary; it retires VPIDs from c-lists upon `syscall.resolve` or `dispatch.notify` as appropriate). So a VPID might start out stored only in vdata, then get sent to the kernel, then get resolved, leaving it solely in vdata once more.
|
|
17
|
-
|
|
18
|
-
Each unresolved VPID has a decider: either the kernel or a vat. It can remain unresolved for arbitrarily long, but becomes resolved by the first of the following events:
|
|
19
|
-
|
|
20
|
-
* if liveslots learns about local resolution of the corresponding Promise by userspace, then liveslots will perform a `syscall.resolve()` (prompting 'notify' deliveries to other subscribed vats)
|
|
21
|
-
* if liveslots learns about resolution by inbound notify, then liveslots will unregister it as necessary and inform userspace of the resolution
|
|
22
|
-
* if the vat is terminated, the kernel internally rejects all remaining vat-decided KPIDs without involving the vat
|
|
23
|
-
* if the vat is upgraded, each of those terminate-associated rejections is followed by a 'notify' delivery to the new incarnation
|
|
24
|
-
|
|
25
|
-
Liveslots tracks promises in the following data structures:
|
|
26
|
-
|
|
27
|
-
* `slotToVal` / `valToSlot` : these manage *registration*, the mapping from VPID to Promise and vice versa. These also register objects (Presences, Remotables, and Representatives) to/from VOIDs, and device nodes.
|
|
28
|
-
* to support GC of objects, `slotToVal.get(vref)` is a WeakRef, and `valToSlot` is a WeakMap
|
|
29
|
-
* liveslots uses independent strong references to maintain object/promise lifetimes
|
|
30
|
-
* `exportedVPIDs`: a `Map<VPID, Promise>`: all Promises currently known to the kernel and decided by the vat
|
|
31
|
-
* `importedVPIDs`: a `Map<VPID, PromiseKit>`: all Promises currently known to the kernel and decided by the kernel
|
|
32
|
-
* `remotableRefCounts`: a `Map<Object|Promise, Number>`: all Promises (and Remotables) referenced by virtual data
|
|
33
|
-
|
|
34
|
-
The kernel's c-list for a vat contains all VPIDs in `exportedVPIDs` and `importedVPIDs`. The vat is the decider for `exportedVPIDs`, while the kernel is the decider for `importedVPIDs`. For every VPID in `exportedVPIDs`, we've used `then` on the Promise instance to arrange for a `syscall.resolve` when it settles (becomes fulfilled or rejected). For every VPID key of the `importedVPIDs` Map, the corresponding value is a `[resolve, reject]` "**pRec**", so one of the functions can be called during `dispatch.notify`. Every VPID in `slotToVal` is either in `exportedVPIDs` but not `importedVPIDs`, `importedVPIDs` but not `exportedVPIDs`, or neither.
|
|
35
|
-
|
|
36
|
-
If a VPID in `importedVPIDs` is resolved (by the kernel, via `dispatch.notify`), the VPID is removed from `importedVPIDs`. If a VPID in `exportedVPIDs` is resolved (by the vat, i.e. liveslots observes invocation of a previously-added settlement callback), liveslots invokes `syscall.resolve` and removes the VPID from `exportedVPIDs`. The c-list for a vat will not contain a VPID for any resolved promise.
|
|
37
|
-
|
|
38
|
-
The `slotToVal`/`valToSlot` registration must remain until all of the following are true:
|
|
39
|
-
|
|
40
|
-
* the kernel is no longer aware of the VPID
|
|
41
|
-
* the Promise is not present in any virtual data
|
|
42
|
-
* the promise is not being watched by a `promiseWatcher`.
|
|
43
|
-
|
|
44
|
-
If the registration were to be lost while any of the above conditions were still true, a replacement Promise might be created while the original was still around, causing confusion.
|
|
45
|
-
|
|
46
|
-
## Maintaining Strong References
|
|
47
|
-
|
|
48
|
-
Remember that the `slotToVal` registration uses a WeakRef, so being registered there does not keep the Promise object alive.
|
|
49
|
-
|
|
50
|
-
`exportedVPIDs` and `importedVPIDs` keep their Promise alive in their value. vdata keeps it alive through the key of `remotableRefCounts`. `promiseWatcher` uses an internal `ScalarBigMapStore` to keep the Promise alive.
|
|
51
|
-
|
|
52
|
-
## Promise/VPID Management Algorithm
|
|
53
|
-
|
|
54
|
-
* When a Promise is first serialized (it appears in `convertValToSlot`), a VPID is assigned and the VPID/Promise mapping is registered in `valToSlot`/`slotToVal`
|
|
55
|
-
* at this point, there is not yet a strong reference to the Promise
|
|
56
|
-
* When a VPID appears in the serialized arguments of `syscall.send` or `syscall.resolve`:
|
|
57
|
-
* if the VPID already exists in `exportedVPIDs` or `importedVPIDs`: do nothing
|
|
58
|
-
* else: use `followForKernel` to add the VPID to `exportedVPIDs` and attach `.then(onFulfill, onReject)` callbacks that will map fulfillment/rejection to `syscall.resolve()`
|
|
59
|
-
* When a `followForKernel` settlement callback is executed:
|
|
60
|
-
* do `syscall.resolve()`
|
|
61
|
-
* remove from `exportedVPIDs`
|
|
62
|
-
* if `remotableRefCounts` reports 0 references: unregister from `valToSlot`/`slotToVal`
|
|
63
|
-
* When the kernel delivers a `dispatch.notify`:
|
|
64
|
-
* retrieve the `[resolve, reject]` pRec from `importedVPIDs`
|
|
65
|
-
* invoke the appropriate function with the deserialized argument
|
|
66
|
-
* if `remotableRefCounts` reports 0 references: unregister from `valToSlot`/`slotToVal`
|
|
67
|
-
* When the vdata refcount for a VPID drops to zero:
|
|
68
|
-
* if the VPID still exists in `exportedVPIDs` or `importedVPIDs`: do nothing
|
|
69
|
-
* else: unregister from `valToSlot`/`slotToVal`
|
|
70
|
-
* When a new VPID is deserialized (it appears in `convertSlotToVal`), this must be the arguments of a delivery (not vdata)
|
|
71
|
-
* use `makePipelinablePromise` to create a HandledPromise for the VPID
|
|
72
|
-
* add the Promise and its `resolve`/`reject` pair to `importedVPIDs`
|
|
73
|
-
* register the Promise in `valToSlot`/`slotToVal`
|
|
74
|
-
* use `syscall.subscribe` to request a `dispatch.notify` delivery when the kernel resolves this promise
|
|
75
|
-
* When a VPID appears as the `result` of an outbound `syscall.send`: (_note overlap with the preceding_)
|
|
76
|
-
* use `allocateVPID` to allocate a new VPID
|
|
77
|
-
* use `makePipelinablePromise` to create a HandledPromise for the VPID
|
|
78
|
-
* add the Promise and its `resolve`/`reject` pair to `importedVPIDs`
|
|
79
|
-
* register the Promise in `valToSlot`/`slotToVal`
|
|
80
|
-
* use `syscall.subscribe` to request a `dispatch.notify` delivery when the kernel resolves this promise
|
|
81
|
-
* When a VPID appears as the `result` of an inbound `dispatch.deliver`, the vat is responsible for deciding it:
|
|
82
|
-
* construct a promise `res` to capture the userspace-provided result
|
|
83
|
-
* if the VPID is present in `importedVPIDs`: retrieve the `[resolve, reject]` pRec and use `resolve(res)` to forward eventual settlement of `res` to settlement of the previously-imported promise, then remove the VPID from `importedVPIDs`
|
|
84
|
-
* else: register marshaller association between the VPID and `res`
|
|
85
|
-
* in either case, use `followForKernel` to add the VPID to `exportedVPIDs` and attach `.then(onFulfill, onReject)` callbacks that will map fulfillment/rejection to `syscall.resolve()`
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
If the serialization is for storage in virtual data, the act of storing the VPID will add the Promise to `remotableRefCounts`, which maintains a strong reference for as long as the VPID is held. When it is removed from virtual data (or the object/collection is deleted), the refcount will be decremented. When the refcount drops to zero, we perform the `exportedVPIDs`/`importedVPIDs` check and then maybe unregister the promise.
|
|
89
|
-
|
|
90
|
-
If the serialization is for the arguments of an outbound `syscall.send` or `syscall.resolve` (or `syscall.callNow`, or `syscall.exit`), the VPID will be added to `exportedVPIDs`.
|
|
91
|
-
|
|
92
|
-
If the *un*serialization occurred when processing the arguments of an *in*bound `dispatch.deliver` or `dispatch.notify`, the VPID (and the "promise kit" trio of Promise, `resolve`, and `reject`) will be stored in `importedVPIDs`.
|
package/src/watchedPromises.d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @template V
|
|
3
|
-
* @template {any[]} [A=unknown[]]
|
|
4
|
-
* @typedef {[watcher: import('./types.js').PromiseWatcher<V, A>, ...args: A]} PromiseWatcherTuple
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* @param {object} options
|
|
8
|
-
* @param {*} options.syscall
|
|
9
|
-
* @param {import('./virtualReferences.js').VirtualReferenceManager} options.vrm
|
|
10
|
-
* @param {import('./virtualObjectManager.js').VirtualObjectManager} options.vom
|
|
11
|
-
* @param {*} options.collectionManager
|
|
12
|
-
* @param {import('@endo/marshal').ConvertValToSlot<any>} options.convertValToSlot
|
|
13
|
-
* @param {import('@endo/marshal').ConvertSlotToVal<any>} options.convertSlotToVal
|
|
14
|
-
* @param {(vref: any) => boolean} options.maybeExportPromise
|
|
15
|
-
*/
|
|
16
|
-
export function makeWatchedPromiseManager({ syscall, vrm, vom, collectionManager, convertValToSlot, convertSlotToVal, maybeExportPromise, }: {
|
|
17
|
-
syscall: any;
|
|
18
|
-
vrm: import("./virtualReferences.js").VirtualReferenceManager;
|
|
19
|
-
vom: import("./virtualObjectManager.js").VirtualObjectManager;
|
|
20
|
-
collectionManager: any;
|
|
21
|
-
convertValToSlot: import("@endo/marshal").ConvertValToSlot<any>;
|
|
22
|
-
convertSlotToVal: import("@endo/marshal").ConvertSlotToVal<any>;
|
|
23
|
-
maybeExportPromise: (vref: any) => boolean;
|
|
24
|
-
}): {
|
|
25
|
-
preparePromiseWatcherTables: () => void;
|
|
26
|
-
loadWatchedPromiseTable: (revivePromise: (vref: any) => Promise<any>) => void;
|
|
27
|
-
providePromiseWatcher: <V, A extends any[]>(kindHandle: import("./vatDataTypes.js").DurableKindHandle, fulfillHandler?: (value: V, ...args: A) => void, rejectHandler?: (reason: any, ...args: A) => void) => import("./types.js").PromiseWatcher<V, A>;
|
|
28
|
-
watchPromise: <P extends Promise<any>, A extends any[]>(p: P, watcher: import("./types.js").PromiseWatcher<Awaited<P>, A>, ...args: A) => void;
|
|
29
|
-
};
|
|
30
|
-
export type PromiseWatcherTuple<V, A extends any[] = unknown[]> = [watcher: import("./types.js").PromiseWatcher<V, A>, ...args: A];
|
|
31
|
-
//# sourceMappingURL=watchedPromises.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"watchedPromises.d.ts","sourceRoot":"","sources":["watchedPromises.js"],"names":[],"mappings":"AASA;;;;GAIG;AAEH;;;;;;;;;GASG;AACH,6IARG;IAAmB,OAAO,EAAlB,GAAC;IACiE,GAAG,EAArE,OAAO,wBAAwB,EAAE,uBAAuB;IACU,GAAG,EAArE,OAAO,2BAA2B,EAAE,oBAAoB;IAC7C,iBAAiB,EAA5B,GAAC;IACsD,gBAAgB,EAAvE,OAAO,eAAe,EAAE,gBAAgB,CAAC,GAAG,CAAC;IACU,gBAAgB,EAAvE,OAAO,eAAe,EAAE,gBAAgB,CAAC,GAAG,CAAC;IACb,kBAAkB,EAAlD,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO;CAChC;;6CAgHY,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,KACzB,IAAI;4BAiBJ,CAAC,EACO,CAAC,SAAR,GAAG,EAAG,cACT,OAAO,mBAAmB,EAAE,iBAAiB,mBAC7C,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,kBAC9B,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,KAC/B,OAAO,YAAY,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC;mBAmC3C,CAAC,SAAS,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,GAAG,EAAE,KAAK,CAAC,WAAW,OAAO,YAAY,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,KAAK,IAAI;EAsE3I;gCA9PY,CAAC,EACQ,CAAC,SAAT,GAAG,EAAG,gBACP,CAAC,OAAO,EAAE,OAAO,YAAY,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dummyMeterControl.d.ts","sourceRoot":"","sources":["dummyMeterControl.js"],"names":[],"mappings":"AAEA,gFAmDC"}
|
package/test/engine-gc.d.ts
DELETED
package/test/engine-gc.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"engine-gc.d.ts","sourceRoot":"","sources":["engine-gc.js"],"names":[],"mappings":";AAoBA,mCAAwB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gc-and-finalize.d.ts","sourceRoot":"","sources":["gc-and-finalize.js"],"names":[],"mappings":"AAkEA,qEAwBC;AAwBD;YAbsD,OAAO;EAkB5D"}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @param {object} [options]
|
|
3
|
-
* @param {boolean} [options.skipLogging]
|
|
4
|
-
* @param {Map<string, string>} [options.kvStore]
|
|
5
|
-
*/
|
|
6
|
-
export function buildSyscall(options?: {
|
|
7
|
-
skipLogging?: boolean | undefined;
|
|
8
|
-
kvStore?: Map<string, string> | undefined;
|
|
9
|
-
}): {
|
|
10
|
-
syscall: {
|
|
11
|
-
send(targetSlot: any, methargs: any, resultSlot: any): void;
|
|
12
|
-
subscribe(target: any): void;
|
|
13
|
-
resolve(resolutions: any): void;
|
|
14
|
-
dropImports(slots: any): void;
|
|
15
|
-
retireImports(slots: any): void;
|
|
16
|
-
retireExports(slots: any): void;
|
|
17
|
-
exit(isFailure: any, info: any): void;
|
|
18
|
-
vatstoreGet(key: any): any;
|
|
19
|
-
vatstoreGetNextKey(priorKey: any): any;
|
|
20
|
-
vatstoreSet(key: any, value: any): void;
|
|
21
|
-
vatstoreDelete(key: any): void;
|
|
22
|
-
};
|
|
23
|
-
fakestore: Map<any, any>;
|
|
24
|
-
log: any[];
|
|
25
|
-
};
|
|
26
|
-
export function makeDispatch(syscall: any, build: any, vatID?: string, liveSlotsOptions?: {}, vatParameters?: undefined): Promise<{
|
|
27
|
-
dispatch: any;
|
|
28
|
-
testHooks: any;
|
|
29
|
-
}>;
|
|
30
|
-
/**
|
|
31
|
-
* @param {import('ava').ExecutionContext} t
|
|
32
|
-
* @param {Function} buildRootObject
|
|
33
|
-
* @param {string} vatName
|
|
34
|
-
* @param {object} [options]
|
|
35
|
-
* @param {boolean} [options.forceGC]
|
|
36
|
-
* @param {Map<string, string>} [options.kvStore]
|
|
37
|
-
* @param {number} [options.nextPromiseImportNumber]
|
|
38
|
-
* @param {boolean} [options.skipLogging]
|
|
39
|
-
* @param {any} [options.vatParameters]
|
|
40
|
-
*/
|
|
41
|
-
export function setupTestLiveslots(t: import("ava").ExecutionContext, buildRootObject: Function, vatName: string, options?: {
|
|
42
|
-
forceGC?: boolean | undefined;
|
|
43
|
-
kvStore?: Map<string, string> | undefined;
|
|
44
|
-
nextPromiseImportNumber?: number | undefined;
|
|
45
|
-
skipLogging?: boolean | undefined;
|
|
46
|
-
vatParameters?: any;
|
|
47
|
-
}): Promise<{
|
|
48
|
-
v: {
|
|
49
|
-
t: import("ava").ExecutionContext<unknown>;
|
|
50
|
-
log: any[];
|
|
51
|
-
fakestore: Map<any, any>;
|
|
52
|
-
dumpFakestore: () => void;
|
|
53
|
-
};
|
|
54
|
-
dispatch: any;
|
|
55
|
-
dispatchMessage: (message: any, ...args: any[]) => Promise<string>;
|
|
56
|
-
dispatchMessageSuccessfully: (message: any, ...args: any[]) => Promise<any>;
|
|
57
|
-
dispatchDropExports: (...vrefs: any[]) => Promise<void>;
|
|
58
|
-
dispatchRetireExports: (...vrefs: any[]) => Promise<void>;
|
|
59
|
-
dispatchRetireImports: (...vrefs: any[]) => Promise<void>;
|
|
60
|
-
testHooks: any;
|
|
61
|
-
}>;
|
|
62
|
-
export function findSyscallsByType(log: any, type: any): any;
|
|
63
|
-
//# sourceMappingURL=liveslots-helpers.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"liveslots-helpers.d.ts","sourceRoot":"","sources":["liveslots-helpers.js"],"names":[],"mappings":"AAgBA;;;;GAIG;AACH,uCAHG;IAA0B,WAAW;IACC,OAAO;CAAC;;;;;;;;;;;;;;;;EA2GhD;AAED;;;GA2BC;AAUD;;;;;;;;;;GAUG;AACH,sCAVW,OAAO,KAAK,EAAE,gBAAgB,sCAE9B,MAAM,YAEd;IAA0B,OAAO;IACK,OAAO;IACpB,uBAAuB;IACtB,WAAW;IACf,aAAa,GAA3B,GAAG;CAAyB;;;;;;;;;;;;;;GA4GtC;AAED,6DAEC"}
|
package/test/util.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @param {(d: unknown) => void} [onDispatchCallback ]
|
|
3
|
-
*/
|
|
4
|
-
export function buildDispatch(onDispatchCallback?: (d: unknown) => void): {
|
|
5
|
-
log: any[];
|
|
6
|
-
dispatch: (vatDeliverObject: any) => void;
|
|
7
|
-
};
|
|
8
|
-
/**
|
|
9
|
-
* @param {unknown} target
|
|
10
|
-
* @param {string | symbol} method
|
|
11
|
-
* @param {any[]} args
|
|
12
|
-
* @param {unknown} result
|
|
13
|
-
*/
|
|
14
|
-
export function makeMessage(target: unknown, method: string | symbol, args?: any[], result?: unknown): unknown[];
|
|
15
|
-
export function makeStartVat(vatParameters: any): any[];
|
|
16
|
-
export function makeBringOutYourDead(): string[];
|
|
17
|
-
export function makeResolutions(resolutions: any): any[];
|
|
18
|
-
export function makeResolve(target: any, result: any): any[];
|
|
19
|
-
export function makeReject(target: any, result: any): (string | any[][])[];
|
|
20
|
-
export function makeDropExports(...vrefs: any[]): (string | any[])[];
|
|
21
|
-
export function makeRetireExports(...vrefs: any[]): (string | any[])[];
|
|
22
|
-
export function makeRetireImports(...vrefs: any[]): (string | any[])[];
|
|
23
|
-
export { vstr };
|
|
24
|
-
import { vstr } from './vat-util.js';
|
|
25
|
-
//# sourceMappingURL=util.d.ts.map
|
package/test/util.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["util.js"],"names":[],"mappings":"AAKA;;GAEG;AACH,mDAFW,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI;;;EAwC9B;AAED;;;;;GAKG;AACH,oCALW,OAAO,UACP,MAAM,GAAG,MAAM,SACf,GAAG,EAAE,WACL,OAAO,aAOjB;AAED,wDAEC;AAED,iDAEC;AAED,yDAGC;AAED,6DAGC;AAED,2EAIC;AAED,qEAGC;AAED,uEAGC;AAED,uEAGC;;qBAjGoB,eAAe"}
|
package/test/vat-util.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export function extractMessage(vatDeliverObject: any): {
|
|
2
|
-
facetID: any;
|
|
3
|
-
method: any;
|
|
4
|
-
args: import("@endo/marshal").CapData<string>;
|
|
5
|
-
result: any;
|
|
6
|
-
};
|
|
7
|
-
export function ignore(p: any): void;
|
|
8
|
-
export function vstr(v: any): string;
|
|
9
|
-
//# sourceMappingURL=vat-util.d.ts.map
|
package/test/vat-util.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vat-util.d.ts","sourceRoot":"","sources":["vat-util.js"],"names":[],"mappings":"AAMA;;;;;EAQC;AAED,qCAKC;AAEM,qCAAyC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"waitUntilQuiescent.d.ts","sourceRoot":"","sources":["waitUntilQuiescent.js"],"names":[],"mappings":"AAGA,oDAAoD;AAKpD,oDAWC"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export function makeFakeCollectionManager(vrm: any, fakeStuff: any, _options?: {}): {
|
|
2
|
-
getValForSlot: any;
|
|
3
|
-
setValForSlot: any;
|
|
4
|
-
registerEntry: any;
|
|
5
|
-
deleteEntry: any;
|
|
6
|
-
dumpStore: any;
|
|
7
|
-
makeScalarBigMapStore: <K, V>(label?: string, options?: StoreOptions) => MapStore<K, V>;
|
|
8
|
-
makeScalarBigWeakMapStore: <K, V>(label?: string, options?: StoreOptions) => WeakMapStore<K, V>;
|
|
9
|
-
makeScalarBigSetStore: <K>(label?: string, options?: StoreOptions) => SetStore<K>;
|
|
10
|
-
makeScalarBigWeakSetStore: <K>(label?: string, options?: StoreOptions) => WeakSetStore<K>;
|
|
11
|
-
provideBaggage: () => any;
|
|
12
|
-
flushSchemaCache: () => void;
|
|
13
|
-
};
|
|
14
|
-
//# sourceMappingURL=fakeCollectionManager.d.ts.map
|