@agoric/swingset-vat 0.32.3-upgrade-18-dev-6ddbef0.0 → 0.32.3-upgrade-19-dev-2a71f04.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 +33 -34
- package/src/controller/controller.js +47 -44
- package/src/controller/initializeKernel.js +0 -3
- package/src/controller/initializeSwingset.js +86 -80
- package/src/controller/upgradeSwingset.js +50 -37
- package/src/devices/bridge/device-bridge.js +3 -2
- package/src/devices/lib/deviceTools.js +0 -1
- package/src/index.js +1 -0
- package/src/kernel/kernel.js +7 -10
- package/src/kernel/slogger.js +124 -121
- package/src/kernel/state/kernelKeeper.js +65 -59
- package/src/kernel/state/vatKeeper.js +64 -84
- package/src/kernel/vat-loader/manager-factory.js +26 -45
- package/src/kernel/vat-loader/manager-subprocess-xsnap.js +26 -2
- package/src/kernel/vat-loader/vat-loader.js +3 -3
- package/src/kernel/vat-warehouse.js +22 -16
- package/src/supervisors/subprocess-node/supervisor-subprocess-node.js +1 -0
- package/src/supervisors/supervisor-helper.js +9 -10
- package/src/typeGuards.js +22 -19
- package/src/types-external.js +39 -38
- package/src/types-internal.js +2 -3
- package/src/vats/comms/delivery.js +0 -2
- package/src/vats/comms/state.js +0 -4
- package/src/vats/timer/vat-timer.js +2 -2
- package/src/vats/vat-admin/vat-vat-admin.js +0 -4
- package/tools/baggage-check.js +0 -2
- package/tools/bootstrap-dvo-test.js +0 -1
- package/tools/bootstrap-relay.js +9 -0
- package/tools/bundleTool.js +5 -1
- package/tools/run-utils.js +63 -54
- package/tools/vat-puppet.js +111 -0
package/tools/run-utils.js
CHANGED
|
@@ -2,12 +2,18 @@ import { Fail, q } from '@endo/errors';
|
|
|
2
2
|
import { kunser } from '@agoric/kmarshal';
|
|
3
3
|
import { makeQueue } from '@endo/stream';
|
|
4
4
|
|
|
5
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* @import { ERef } from '@endo/far'
|
|
7
|
+
* @import { RunPolicy } from '../src/types-external.js'
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** @typedef {{ provideRunPolicy: () => RunPolicy | undefined }} RunHarness */
|
|
6
11
|
|
|
7
12
|
/**
|
|
8
13
|
* @param {import('../src/controller/controller.js').SwingsetController} controller
|
|
14
|
+
* @param {RunHarness} [harness]
|
|
9
15
|
*/
|
|
10
|
-
export const makeRunUtils = controller => {
|
|
16
|
+
export const makeRunUtils = (controller, harness) => {
|
|
11
17
|
const mutex = makeQueue();
|
|
12
18
|
const logRunFailure = reason =>
|
|
13
19
|
console.log('controller.run() failure', reason);
|
|
@@ -17,7 +23,7 @@ export const makeRunUtils = controller => {
|
|
|
17
23
|
* Wait for exclusive access to the controller, then before relinquishing that access,
|
|
18
24
|
* enqueue and process a delivery and return the result.
|
|
19
25
|
*
|
|
20
|
-
* @param {() => ERef<void | ReturnType<controller['queueToVatObject']>>} deliveryThunk
|
|
26
|
+
* @param {() => ERef<void | ReturnType<typeof controller['queueToVatObject']>>} deliveryThunk
|
|
21
27
|
* function for enqueueing a delivery and returning the result kpid (if any)
|
|
22
28
|
* @param {boolean} [voidResult] whether to ignore the result
|
|
23
29
|
* @returns {Promise<any>}
|
|
@@ -25,7 +31,8 @@ export const makeRunUtils = controller => {
|
|
|
25
31
|
const queueAndRun = async (deliveryThunk, voidResult = false) => {
|
|
26
32
|
await mutex.get();
|
|
27
33
|
const kpid = await deliveryThunk();
|
|
28
|
-
const
|
|
34
|
+
const runPolicy = harness && harness.provideRunPolicy();
|
|
35
|
+
const runResultP = controller.run(runPolicy);
|
|
29
36
|
mutex.put(runResultP.catch(logRunFailure));
|
|
30
37
|
await runResultP;
|
|
31
38
|
|
|
@@ -46,10 +53,25 @@ export const makeRunUtils = controller => {
|
|
|
46
53
|
};
|
|
47
54
|
|
|
48
55
|
/**
|
|
49
|
-
* @typedef
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
56
|
+
* @typedef EVProxyMethods
|
|
57
|
+
* @property {(presence: unknown) => Record<string, (...args: any) => Promise<void>>} sendOnly
|
|
58
|
+
* Returns a "methods proxy" for the presence that ignores the results of
|
|
59
|
+
* each method invocation.
|
|
60
|
+
* @property {(name: string) => Record<string, (...args: any) => Promise<any>>} vat
|
|
61
|
+
* Returns a "methods proxy" for the root object of the specified vat.
|
|
62
|
+
* So e.g. `EV.vat('foo').m(0)` becomes
|
|
63
|
+
* `controller.queueToVatRoot('foo', 'm', [0])`.
|
|
64
|
+
* @property {(presence: unknown) => Record<string, Promise<any>>} get
|
|
65
|
+
* Returns a "values proxy" for the presence for which each requested
|
|
66
|
+
* property manifests as a promise.
|
|
67
|
+
*/
|
|
68
|
+
/**
|
|
69
|
+
* @typedef {import('@endo/eventual-send').EProxy & EVProxyMethods} EVProxy
|
|
70
|
+
* Given a presence, return a "methods proxy" for which each requested
|
|
71
|
+
* property manifests as a method that forwards its invocation through the
|
|
72
|
+
* controller to the presence as an invocation of an identically-named method
|
|
73
|
+
* with identical arguments (modulo passable translation).
|
|
74
|
+
* So e.g. `EV(x).m(0)` becomes `controller.queueToVatObject(x, 'm', [0])`.
|
|
53
75
|
*/
|
|
54
76
|
|
|
55
77
|
// IMPORTANT WARNING TO USERS OF `EV`
|
|
@@ -96,52 +118,39 @@ export const makeRunUtils = controller => {
|
|
|
96
118
|
// promise that can remain pending indefinitely, possibly to be settled by a
|
|
97
119
|
// future message delivery.
|
|
98
120
|
|
|
99
|
-
/**
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
},
|
|
133
|
-
}),
|
|
134
|
-
get: presence =>
|
|
135
|
-
new Proxy(harden({}), {
|
|
136
|
-
get: (_t, pathElement, _rx) =>
|
|
137
|
-
queueAndRun(() =>
|
|
138
|
-
controller.queueToVatRoot('bootstrap', 'awaitVatObject', [
|
|
139
|
-
presence,
|
|
140
|
-
[pathElement],
|
|
141
|
-
]),
|
|
142
|
-
),
|
|
143
|
-
}),
|
|
144
|
-
},
|
|
121
|
+
/**
|
|
122
|
+
* @template {(typeof controller.queueToVatObject) | (typeof controller.queueToVatRoot)} T
|
|
123
|
+
* @param {T} invoker
|
|
124
|
+
* @param {Parameters<T>[0]} target
|
|
125
|
+
* @param {boolean} [voidResult]
|
|
126
|
+
*/
|
|
127
|
+
const makeMethodsProxy = (invoker, target, voidResult = false) =>
|
|
128
|
+
new Proxy(harden({}), {
|
|
129
|
+
get: (_t, method, _rx) => {
|
|
130
|
+
const resultPolicy = voidResult ? 'none' : undefined;
|
|
131
|
+
const boundMethod = (...args) =>
|
|
132
|
+
queueAndRun(
|
|
133
|
+
() => invoker(target, method, args, resultPolicy),
|
|
134
|
+
voidResult,
|
|
135
|
+
);
|
|
136
|
+
return harden(boundMethod);
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
const EV = /** @type {EVProxy} */ (
|
|
141
|
+
Object.assign(
|
|
142
|
+
presence => makeMethodsProxy(controller.queueToVatObject, presence),
|
|
143
|
+
{
|
|
144
|
+
vat: vatName => makeMethodsProxy(controller.queueToVatRoot, vatName),
|
|
145
|
+
sendOnly: presence =>
|
|
146
|
+
makeMethodsProxy(controller.queueToVatObject, presence, true),
|
|
147
|
+
get: presence =>
|
|
148
|
+
new Proxy(harden({}), {
|
|
149
|
+
get: (_t, key, _rx) =>
|
|
150
|
+
EV.vat('bootstrap').awaitVatObject(presence, [key]),
|
|
151
|
+
}),
|
|
152
|
+
},
|
|
153
|
+
)
|
|
145
154
|
);
|
|
146
155
|
return harden({ queueAndRun, EV });
|
|
147
156
|
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Source code for a vat that exposes reflective methods for use in
|
|
3
|
+
* testing.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Fail, q } from '@endo/errors';
|
|
7
|
+
import { Far, E } from '@endo/far';
|
|
8
|
+
import { makePromiseKit } from '@endo/promise-kit';
|
|
9
|
+
import { objectMap } from '@agoric/internal';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @callback Die
|
|
13
|
+
* @param {unknown} completion
|
|
14
|
+
* @param {[target: unknown, method: string, ...args: unknown[]]} [finalSend]
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @typedef {Array<[name: string, ...args: unknown[]]>} CallLog
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param {import('@agoric/swingset-vat').VatPowers} vatPowers
|
|
23
|
+
* @param {import('@agoric/vat-data').Baggage} baggage
|
|
24
|
+
*/
|
|
25
|
+
export const makeReflectionMethods = (vatPowers, baggage) => {
|
|
26
|
+
let baggageHoldCount = 0;
|
|
27
|
+
/** @type {Map<object, CallLog>} */
|
|
28
|
+
const callLogsByRemotable = new Map();
|
|
29
|
+
const heldInHeap = [];
|
|
30
|
+
const send = (target, method, ...args) => E(target)[method](...args);
|
|
31
|
+
const makeSpy = (value, name, callLog) => {
|
|
32
|
+
const spyName = `get ${name}`;
|
|
33
|
+
const spy = {
|
|
34
|
+
[spyName](...args) {
|
|
35
|
+
callLog.push([name, ...args]);
|
|
36
|
+
return value;
|
|
37
|
+
},
|
|
38
|
+
}[spyName];
|
|
39
|
+
return spy;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
/** @type {Die} */
|
|
44
|
+
dieHappy: (completion, finalSend) => {
|
|
45
|
+
vatPowers.exitVat(completion);
|
|
46
|
+
if (finalSend) send(...finalSend);
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
/** @type {Die} */
|
|
50
|
+
dieSad: (reason, finalSend) => {
|
|
51
|
+
vatPowers.exitVatWithFailure(/** @type {Error} */ (reason));
|
|
52
|
+
if (finalSend) send(...finalSend);
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
holdInBaggage: (...values) => {
|
|
56
|
+
for (const value of values) {
|
|
57
|
+
baggage.init(`held-${baggageHoldCount}`, value);
|
|
58
|
+
baggageHoldCount += 1;
|
|
59
|
+
}
|
|
60
|
+
return baggageHoldCount;
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
holdInHeap: (...values) => heldInHeap.push(...values),
|
|
64
|
+
|
|
65
|
+
makePromiseKit: () => {
|
|
66
|
+
const { promise, ...resolverMethods } = makePromiseKit();
|
|
67
|
+
void promise.catch(() => {});
|
|
68
|
+
const resolver = Far('resolver', resolverMethods);
|
|
69
|
+
return harden({ promise, resolver });
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
makeUnsettledPromise() {
|
|
73
|
+
const { promise } = makePromiseKit();
|
|
74
|
+
void promise.catch(() => {});
|
|
75
|
+
return promise;
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Returns a remotable with methods that return provided values. Invocations
|
|
80
|
+
* of those methods and their arguments are captured for later retrieval by
|
|
81
|
+
* `getCallLogForRemotable`.
|
|
82
|
+
*
|
|
83
|
+
* @param {string} [label]
|
|
84
|
+
* @param {Record<string, any>} [fields]
|
|
85
|
+
*/
|
|
86
|
+
makeRemotable: (label = 'Remotable', fields = {}) => {
|
|
87
|
+
/** @type {CallLog} */
|
|
88
|
+
const callLog = [];
|
|
89
|
+
const methods = objectMap(fields, (value, name) =>
|
|
90
|
+
makeSpy(value, name, callLog),
|
|
91
|
+
);
|
|
92
|
+
const remotable = Far(label, { ...methods });
|
|
93
|
+
callLogsByRemotable.set(remotable, callLog);
|
|
94
|
+
return remotable;
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* @param {object} remotable
|
|
99
|
+
* @returns {CallLog}
|
|
100
|
+
*/
|
|
101
|
+
getCallLogForRemotable: remotable =>
|
|
102
|
+
callLogsByRemotable.get(remotable) ||
|
|
103
|
+
Fail`unknown remotable ${q(remotable)}`,
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
harden(makeReflectionMethods);
|
|
107
|
+
|
|
108
|
+
export function buildRootObject(vatPowers, _vatParameters, baggage) {
|
|
109
|
+
const methods = makeReflectionMethods(vatPowers, baggage);
|
|
110
|
+
return Far('root', methods);
|
|
111
|
+
}
|