@agoric/swingset-vat 0.32.3-dev-657b621.0 → 0.32.3-dev-696f0a8.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 +13 -12
- package/tools/baggage-check.js +194 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/swingset-vat",
|
|
3
|
-
"version": "0.32.3-dev-
|
|
3
|
+
"version": "0.32.3-dev-696f0a8.0+696f0a8",
|
|
4
4
|
"description": "Vat/Container Launcher",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -28,16 +28,16 @@
|
|
|
28
28
|
"yargs-parser": "^21.1.1"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@agoric/assert": "0.6.1-dev-
|
|
32
|
-
"@agoric/internal": "0.3.3-dev-
|
|
33
|
-
"@agoric/store": "0.9.3-dev-
|
|
34
|
-
"@agoric/swing-store": "0.9.2-dev-
|
|
35
|
-
"@agoric/swingset-liveslots": "0.10.3-dev-
|
|
36
|
-
"@agoric/swingset-xsnap-supervisor": "0.10.3-dev-
|
|
37
|
-
"@agoric/time": "0.3.3-dev-
|
|
38
|
-
"@agoric/vat-data": "0.5.3-dev-
|
|
39
|
-
"@agoric/xsnap": "0.14.3-dev-
|
|
40
|
-
"@agoric/xsnap-lockdown": "0.14.1-dev-
|
|
31
|
+
"@agoric/assert": "0.6.1-dev-696f0a8.0+696f0a8",
|
|
32
|
+
"@agoric/internal": "0.3.3-dev-696f0a8.0+696f0a8",
|
|
33
|
+
"@agoric/store": "0.9.3-dev-696f0a8.0+696f0a8",
|
|
34
|
+
"@agoric/swing-store": "0.9.2-dev-696f0a8.0+696f0a8",
|
|
35
|
+
"@agoric/swingset-liveslots": "0.10.3-dev-696f0a8.0+696f0a8",
|
|
36
|
+
"@agoric/swingset-xsnap-supervisor": "0.10.3-dev-696f0a8.0+696f0a8",
|
|
37
|
+
"@agoric/time": "0.3.3-dev-696f0a8.0+696f0a8",
|
|
38
|
+
"@agoric/vat-data": "0.5.3-dev-696f0a8.0+696f0a8",
|
|
39
|
+
"@agoric/xsnap": "0.14.3-dev-696f0a8.0+696f0a8",
|
|
40
|
+
"@agoric/xsnap-lockdown": "0.14.1-dev-696f0a8.0+696f0a8",
|
|
41
41
|
"@endo/base64": "^0.2.31",
|
|
42
42
|
"@endo/bundle-source": "^2.5.1",
|
|
43
43
|
"@endo/captp": "^3.1.1",
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
"@endo/zip": "^0.2.31",
|
|
55
55
|
"ansi-styles": "^6.2.1",
|
|
56
56
|
"anylogger": "^0.21.0",
|
|
57
|
+
"better-sqlite3": "^8.2.0",
|
|
57
58
|
"import-meta-resolve": "^2.2.1",
|
|
58
59
|
"microtime": "^3.1.0",
|
|
59
60
|
"semver": "^6.3.0",
|
|
@@ -92,5 +93,5 @@
|
|
|
92
93
|
"publishConfig": {
|
|
93
94
|
"access": "public"
|
|
94
95
|
},
|
|
95
|
-
"gitHead": "
|
|
96
|
+
"gitHead": "696f0a8c4925c8a40f415c16536568fc4e8008c8"
|
|
96
97
|
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { makeMarshal } from '@endo/marshal';
|
|
2
|
+
import { Far } from '@endo/far';
|
|
3
|
+
|
|
4
|
+
/* eslint-disable no-use-before-define */
|
|
5
|
+
|
|
6
|
+
function fakeSTV(slot, iface = 'Remotable') {
|
|
7
|
+
return Far(iface, {
|
|
8
|
+
getSlot: () => slot,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const marshaller = makeMarshal(undefined, fakeSTV, {
|
|
13
|
+
serializeBodyFormat: 'smallcaps',
|
|
14
|
+
});
|
|
15
|
+
const { fromCapData } = marshaller;
|
|
16
|
+
|
|
17
|
+
function decodeValueString(s) {
|
|
18
|
+
const parsed = JSON.parse(s);
|
|
19
|
+
const value = fromCapData(parsed);
|
|
20
|
+
return [value, parsed.slots];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function extractDurableRefParts(ref) {
|
|
24
|
+
const patt = /^o\+d([0-9]+)\/([0-9]+)$/;
|
|
25
|
+
const matches = ref.match(patt);
|
|
26
|
+
if (matches) {
|
|
27
|
+
return [+matches[1], +matches[2]];
|
|
28
|
+
} else {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function checkBaggage(db, vatID, verbose = false) {
|
|
34
|
+
const sqlKVDump = db.prepare(`
|
|
35
|
+
SELECT key, value
|
|
36
|
+
FROM kvStore
|
|
37
|
+
WHERE key GLOB ?
|
|
38
|
+
`);
|
|
39
|
+
|
|
40
|
+
const sqlKVGet = db.prepare(`
|
|
41
|
+
SELECT value
|
|
42
|
+
FROM kvStore
|
|
43
|
+
WHERE key = ?
|
|
44
|
+
`);
|
|
45
|
+
sqlKVGet.pluck(true);
|
|
46
|
+
|
|
47
|
+
const vatStoreKeyRoot = `${vatID}.vs`;
|
|
48
|
+
const vomKeyRoot = `${vatStoreKeyRoot}.vom`;
|
|
49
|
+
const dkindKeyRoot = `${vomKeyRoot}.dkind`;
|
|
50
|
+
const vcKeyRoot = `${vatStoreKeyRoot}.vc`;
|
|
51
|
+
|
|
52
|
+
// Kinds which are known to have definitions. Initially these are just those
|
|
53
|
+
// whose definitions are built in.
|
|
54
|
+
const predefinedKinds = new Map(); // kindID -> tag
|
|
55
|
+
|
|
56
|
+
predefinedKinds.set(1, 'kindHandle');
|
|
57
|
+
const builtInKinds = JSON.parse(
|
|
58
|
+
sqlKVGet.get(`${vatStoreKeyRoot}.storeKindIDTable`),
|
|
59
|
+
);
|
|
60
|
+
for (const kindName of Object.keys(builtInKinds)) {
|
|
61
|
+
predefinedKinds.set(builtInKinds[kindName], kindName);
|
|
62
|
+
}
|
|
63
|
+
const KIND_HANDLE_BASEREF = 1;
|
|
64
|
+
const BIGMAP_BASEREF = 6;
|
|
65
|
+
const BIGSET_BASEREF = 8;
|
|
66
|
+
|
|
67
|
+
// Kinds for which we have seen a kindHandle entry in the vatStore. These are
|
|
68
|
+
// kinds which exist and have been used at some point, though their current
|
|
69
|
+
// ontological status is unknown.
|
|
70
|
+
const extantKinds = new Map(); // kindID -> tag
|
|
71
|
+
|
|
72
|
+
// Kinds for which we have seen a kindHandle value reference in the reference
|
|
73
|
+
// graph descended from baggage. These are kinds that are potentially
|
|
74
|
+
// definable, though we can't at this stage determine if they've actually been
|
|
75
|
+
// given definitions.
|
|
76
|
+
const knownKinds = new Set();
|
|
77
|
+
|
|
78
|
+
// Kinds that have been seen in use somewhere. These are kinds that had
|
|
79
|
+
// better have definitions or else something Bad will happen.
|
|
80
|
+
const usedKinds = new Set();
|
|
81
|
+
|
|
82
|
+
const kindKVs = sqlKVDump.iterate(`${dkindKeyRoot}.*`);
|
|
83
|
+
for (const kv of kindKVs) {
|
|
84
|
+
const descriptorSuffix = '.descriptor';
|
|
85
|
+
if (kv.key.endsWith(descriptorSuffix)) {
|
|
86
|
+
const dkindID = kv.key
|
|
87
|
+
.substring(0, kv.key.length - descriptorSuffix.length)
|
|
88
|
+
.substring(dkindKeyRoot.length + 1);
|
|
89
|
+
const descriptor = JSON.parse(kv.value);
|
|
90
|
+
extantKinds.set(+dkindID, descriptor.tag);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
let pendingCollections = new Set();
|
|
95
|
+
const knownCollections = new Set();
|
|
96
|
+
let pendingObjects = new Set();
|
|
97
|
+
const knownObjects = new Set();
|
|
98
|
+
|
|
99
|
+
pendingCollections.add(1);
|
|
100
|
+
do {
|
|
101
|
+
const workingCollections = pendingCollections;
|
|
102
|
+
pendingCollections = new Set();
|
|
103
|
+
for (const coll of workingCollections) {
|
|
104
|
+
knownCollections.add(coll);
|
|
105
|
+
}
|
|
106
|
+
for (const coll of workingCollections) {
|
|
107
|
+
scanCollection(coll);
|
|
108
|
+
}
|
|
109
|
+
const workingObjects = pendingObjects;
|
|
110
|
+
pendingObjects = new Set();
|
|
111
|
+
for (const obj of workingObjects) {
|
|
112
|
+
knownObjects.add(obj);
|
|
113
|
+
}
|
|
114
|
+
for (const obj of workingObjects) {
|
|
115
|
+
scanObject(obj);
|
|
116
|
+
}
|
|
117
|
+
} while (pendingCollections.size > 0 || pendingObjects.size > 0);
|
|
118
|
+
|
|
119
|
+
// Kinds which have been used but whose kindID handles have not been seen
|
|
120
|
+
const usedButNotKnownKinds = new Set();
|
|
121
|
+
usedKinds.forEach(v => usedButNotKnownKinds.add(v));
|
|
122
|
+
knownKinds.forEach(v => usedButNotKnownKinds.delete(v));
|
|
123
|
+
|
|
124
|
+
// Kinds which exist but whose kind handles have not been seen
|
|
125
|
+
const extantButNotSeen = new Map();
|
|
126
|
+
extantKinds.forEach((k, v) => extantButNotSeen.set(v, k));
|
|
127
|
+
knownKinds.forEach(k => extantButNotSeen.delete(k));
|
|
128
|
+
|
|
129
|
+
// Kinds which exist but are not used
|
|
130
|
+
const extantButNotUsed = new Map();
|
|
131
|
+
extantKinds.forEach((k, v) => extantButNotUsed.set(v, k));
|
|
132
|
+
usedKinds.forEach(k => extantButNotUsed.delete(k));
|
|
133
|
+
|
|
134
|
+
if (verbose || usedButNotKnownKinds.size > 0) {
|
|
135
|
+
console.log('predefinedKinds', predefinedKinds);
|
|
136
|
+
console.log('extantKinds', extantKinds);
|
|
137
|
+
console.log('knownKinds', knownKinds);
|
|
138
|
+
console.log('usedKinds', usedKinds);
|
|
139
|
+
console.log('extantButNotSeen', extantButNotSeen);
|
|
140
|
+
console.log('extantButNotUsed', extantButNotUsed);
|
|
141
|
+
console.log('usedButNotKnownKinds', usedButNotKnownKinds);
|
|
142
|
+
}
|
|
143
|
+
if (usedButNotKnownKinds.size > 0) {
|
|
144
|
+
throw Error(
|
|
145
|
+
`kind IDs used without reachable kind ID handles: ${usedButNotKnownKinds.size}`,
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function scanSlots(slots) {
|
|
150
|
+
for (const slot of slots) {
|
|
151
|
+
const refParts = extractDurableRefParts(slot);
|
|
152
|
+
if (refParts) {
|
|
153
|
+
const [baseRef, subRef] = refParts;
|
|
154
|
+
if (baseRef === BIGMAP_BASEREF || baseRef === BIGSET_BASEREF) {
|
|
155
|
+
if (!knownCollections.has(subRef)) {
|
|
156
|
+
pendingCollections.add(subRef);
|
|
157
|
+
}
|
|
158
|
+
} else if (baseRef === KIND_HANDLE_BASEREF) {
|
|
159
|
+
knownKinds.add(subRef);
|
|
160
|
+
} else {
|
|
161
|
+
if (!usedKinds.has(baseRef)) {
|
|
162
|
+
usedKinds.add(baseRef);
|
|
163
|
+
}
|
|
164
|
+
if (!knownObjects.has(slot)) {
|
|
165
|
+
pendingObjects.add(slot);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function scanCollection(collectionID) {
|
|
173
|
+
const collectionKeyRoot = `${vcKeyRoot}.${collectionID}.`;
|
|
174
|
+
const keyMatch = `${collectionKeyRoot}[a-z]*`;
|
|
175
|
+
const kvPairs = sqlKVDump.iterate(keyMatch);
|
|
176
|
+
for (const kv of kvPairs) {
|
|
177
|
+
const key = kv.key.substring(collectionKeyRoot.length);
|
|
178
|
+
const [_, slots] = decodeValueString(kv.value);
|
|
179
|
+
if (key[0] === 'r') {
|
|
180
|
+
const rkey = key.split(':')[1];
|
|
181
|
+
scanSlots([rkey]);
|
|
182
|
+
}
|
|
183
|
+
scanSlots(slots);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function scanObject(objectID) {
|
|
188
|
+
const rawObj = sqlKVGet.get(`${vomKeyRoot}.${objectID}`);
|
|
189
|
+
const props = JSON.parse(rawObj);
|
|
190
|
+
for (const prop of Object.keys(props)) {
|
|
191
|
+
scanSlots(props[prop].slots);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|