@agoric/async-flow 0.1.1-dev-7d1dfc0.0 → 0.1.1-dev-b232bfe.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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/async-flow",
|
|
3
|
-
"version": "0.1.1-dev-
|
|
3
|
+
"version": "0.1.1-dev-b232bfe.0+b232bfe",
|
|
4
4
|
"description": "Upgrade async functions at await points by replay",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": "https://github.com/Agoric/agoric-sdk",
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
"author": "Agoric",
|
|
25
25
|
"license": "Apache-2.0",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@agoric/base-zone": "0.1.1-dev-
|
|
28
|
-
"@agoric/internal": "0.3.3-dev-
|
|
29
|
-
"@agoric/store": "0.9.3-dev-
|
|
30
|
-
"@agoric/vow": "0.1.1-dev-
|
|
27
|
+
"@agoric/base-zone": "0.1.1-dev-b232bfe.0+b232bfe",
|
|
28
|
+
"@agoric/internal": "0.3.3-dev-b232bfe.0+b232bfe",
|
|
29
|
+
"@agoric/store": "0.9.3-dev-b232bfe.0+b232bfe",
|
|
30
|
+
"@agoric/vow": "0.1.1-dev-b232bfe.0+b232bfe",
|
|
31
31
|
"@endo/common": "^1.2.5",
|
|
32
32
|
"@endo/errors": "^1.2.5",
|
|
33
33
|
"@endo/eventual-send": "^1.2.5",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"@endo/promise-kit": "^1.1.5"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@agoric/swingset-vat": "0.32.3-dev-
|
|
41
|
-
"@agoric/zone": "0.2.3-dev-
|
|
40
|
+
"@agoric/swingset-vat": "0.32.3-dev-b232bfe.0+b232bfe",
|
|
41
|
+
"@agoric/zone": "0.2.3-dev-b232bfe.0+b232bfe",
|
|
42
42
|
"@endo/env-options": "^1.1.6",
|
|
43
43
|
"ava": "^5.3.0",
|
|
44
44
|
"tsd": "^0.31.1"
|
|
@@ -62,5 +62,5 @@
|
|
|
62
62
|
"typeCoverage": {
|
|
63
63
|
"atLeast": 76.93
|
|
64
64
|
},
|
|
65
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "b232bfe00c337a0f2016c8af308261e14c19cb9a"
|
|
66
66
|
}
|
package/src/replay-membrane.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export function makeReplayMembrane(
|
|
1
|
+
export function makeReplayMembrane(arg: {
|
|
2
2
|
log: LogStore;
|
|
3
3
|
bijection: Bijection;
|
|
4
4
|
vowTools: VowTools;
|
|
@@ -9,13 +9,31 @@ export function makeReplayMembrane({ log, bijection, vowTools, watchWake, panic,
|
|
|
9
9
|
guestToHost: (specimen: Passable, label?: string | undefined) => any;
|
|
10
10
|
wake: () => void;
|
|
11
11
|
stop: () => void;
|
|
12
|
-
} & import("@endo/pass-style").RemotableObject<`Alleged: ${string}`> &
|
|
12
|
+
} & import("@endo/pass-style").RemotableObject<`Alleged: ${string}`> & RemotableBrand<{}, {
|
|
13
13
|
hostToGuest: (specimen: Passable, label?: string | undefined) => any;
|
|
14
14
|
guestToHost: (specimen: Passable, label?: string | undefined) => any;
|
|
15
15
|
wake: () => void;
|
|
16
16
|
stop: () => void;
|
|
17
17
|
}>;
|
|
18
|
-
export
|
|
18
|
+
export function makeReplayMembraneForTesting({ log, bijection, vowTools, watchWake, panic, __eventualSendForTesting, }: {
|
|
19
|
+
log: LogStore;
|
|
20
|
+
bijection: Bijection;
|
|
21
|
+
vowTools: VowTools;
|
|
22
|
+
watchWake: (vowish: Promise<any> | Vow) => void;
|
|
23
|
+
panic: (problem: Error) => never;
|
|
24
|
+
__eventualSendForTesting?: boolean | undefined;
|
|
25
|
+
}): {
|
|
26
|
+
hostToGuest: (specimen: Passable, label?: string | undefined) => any;
|
|
27
|
+
guestToHost: (specimen: Passable, label?: string | undefined) => any;
|
|
28
|
+
wake: () => void;
|
|
29
|
+
stop: () => void;
|
|
30
|
+
} & import("@endo/pass-style").RemotableObject<`Alleged: ${string}`> & RemotableBrand<{}, {
|
|
31
|
+
hostToGuest: (specimen: Passable, label?: string | undefined) => any;
|
|
32
|
+
guestToHost: (specimen: Passable, label?: string | undefined) => any;
|
|
33
|
+
wake: () => void;
|
|
34
|
+
stop: () => void;
|
|
35
|
+
}>;
|
|
36
|
+
export type ReplayMembrane = ReturnType<(arg: {
|
|
19
37
|
log: LogStore;
|
|
20
38
|
bijection: Bijection;
|
|
21
39
|
vowTools: VowTools;
|
|
@@ -26,7 +44,7 @@ export type ReplayMembrane = ReturnType<({ log, bijection, vowTools, watchWake,
|
|
|
26
44
|
guestToHost: (specimen: Passable, label?: string | undefined) => any;
|
|
27
45
|
wake: () => void;
|
|
28
46
|
stop: () => void;
|
|
29
|
-
} & import("@endo/pass-style").RemotableObject<`Alleged: ${string}`> &
|
|
47
|
+
} & import("@endo/pass-style").RemotableObject<`Alleged: ${string}`> & RemotableBrand<{}, {
|
|
30
48
|
hostToGuest: (specimen: Passable, label?: string | undefined) => any;
|
|
31
49
|
guestToHost: (specimen: Passable, label?: string | undefined) => any;
|
|
32
50
|
wake: () => void;
|
|
@@ -37,4 +55,5 @@ import type { Bijection } from '../src/bijection.js';
|
|
|
37
55
|
import type { VowTools } from '@agoric/vow';
|
|
38
56
|
import type { Vow } from '@agoric/vow';
|
|
39
57
|
import type { Passable } from '@endo/pass-style';
|
|
58
|
+
import type { RemotableBrand } from '@endo/eventual-send';
|
|
40
59
|
//# sourceMappingURL=replay-membrane.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replay-membrane.d.ts","sourceRoot":"","sources":["replay-membrane.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"replay-membrane.d.ts","sourceRoot":"","sources":["replay-membrane.js"],"names":[],"mappings":"AA+BO,wCANJ;IAAsB,GAAG,EAAjB,QAAQ;IACO,SAAS,EAAxB,SAAS;IACK,QAAQ,EAAtB,QAAQ;IAC6B,SAAS,EAA9C,CAAC,MAAM,EAAE,eAAU,GAAG,KAAK,IAAI;IACA,KAAK,EAApC,CAAC,OAAO,EAAE,KAAK,KAAK,KAAK;CACnC;;;;;;;;;;GAMA;AAWM,wHAPJ;IAAsB,GAAG,EAAjB,QAAQ;IACO,SAAS,EAAxB,SAAS;IACK,QAAQ,EAAtB,QAAQ;IAC6B,SAAS,EAA9C,CAAC,MAAM,EAAE,eAAU,GAAG,KAAK,IAAI;IACA,KAAK,EAApC,CAAC,OAAO,EAAE,KAAK,KAAK,KAAK;IACX,wBAAwB;CAChD;;;;;;;;;;GAmpBA;6BAGa,UAAU,OA3qBrB;IAAsB,GAAG,EAAjB,QAAQ;IACO,SAAS,EAAxB,SAAS;IACK,QAAQ,EAAtB,QAAQ;IAC6B,SAAS,EAA9C,CAAC,MAAM,EAAE,eAAU,GAAG,KAAK,IAAI;IACA,KAAK,EAApC,CAAC,OAAO,EAAE,KAAK,KAAK,KAAK;CACnC;;;;;;;;;;GAsqB2C;8BAprBjB,qBAAqB;+BACpB,qBAAqB;8BAFT,aAAa;yBAAb,aAAa;8BADH,kBAAkB;oCADnC,qBAAqB"}
|
package/src/replay-membrane.js
CHANGED
|
@@ -10,9 +10,10 @@ import { makeConvertKit } from './convert.js';
|
|
|
10
10
|
import { makeEquate } from './equate.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
* @import {PromiseKit} from '@endo/promise-kit'
|
|
14
|
-
* @import {
|
|
15
|
-
* @import {
|
|
13
|
+
* @import {PromiseKit} from '@endo/promise-kit';
|
|
14
|
+
* @import {RemotableBrand} from '@endo/eventual-send';
|
|
15
|
+
* @import {Callable, Passable, PassableCap} from '@endo/pass-style';
|
|
16
|
+
* @import {Vow, VowTools, VowKit} from '@agoric/vow';
|
|
16
17
|
* @import {LogStore} from '../src/log-store.js';
|
|
17
18
|
* @import {Bijection} from '../src/bijection.js';
|
|
18
19
|
* @import {Host, HostVow, LogEntry, Outcome} from '../src/types.js';
|
|
@@ -28,12 +29,29 @@ const { fromEntries, defineProperties, assign } = Object;
|
|
|
28
29
|
* @param {(vowish: Promise | Vow) => void} arg.watchWake
|
|
29
30
|
* @param {(problem: Error) => never} arg.panic
|
|
30
31
|
*/
|
|
31
|
-
export const makeReplayMembrane =
|
|
32
|
+
export const makeReplayMembrane = arg => {
|
|
33
|
+
const noDunderArg = /** @type {typeof arg} */ (
|
|
34
|
+
Object.fromEntries(Object.entries(arg).filter(([k]) => !k.startsWith('__')))
|
|
35
|
+
);
|
|
36
|
+
return makeReplayMembraneForTesting(noDunderArg);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {object} arg
|
|
41
|
+
* @param {LogStore} arg.log
|
|
42
|
+
* @param {Bijection} arg.bijection
|
|
43
|
+
* @param {VowTools} arg.vowTools
|
|
44
|
+
* @param {(vowish: Promise | Vow) => void} arg.watchWake
|
|
45
|
+
* @param {(problem: Error) => never} arg.panic
|
|
46
|
+
* @param {boolean} [arg.__eventualSendForTesting] CAVEAT: Only for async-flow tests
|
|
47
|
+
*/
|
|
48
|
+
export const makeReplayMembraneForTesting = ({
|
|
32
49
|
log,
|
|
33
50
|
bijection,
|
|
34
51
|
vowTools,
|
|
35
52
|
watchWake,
|
|
36
53
|
panic,
|
|
54
|
+
__eventualSendForTesting,
|
|
37
55
|
}) => {
|
|
38
56
|
const { when, makeVowKit } = vowTools;
|
|
39
57
|
|
|
@@ -218,30 +236,22 @@ export const makeReplayMembrane = ({
|
|
|
218
236
|
// //////////////// Eventual Send ////////////////////////////////////////////
|
|
219
237
|
|
|
220
238
|
/**
|
|
221
|
-
* @param {PassableCap} hostTarget
|
|
239
|
+
* @param {RemotableBrand<PassableCap, Callable>} hostTarget
|
|
222
240
|
* @param {string | undefined} optVerb
|
|
223
241
|
* @param {Passable[]} hostArgs
|
|
224
242
|
*/
|
|
225
243
|
const performSendOnly = (hostTarget, optVerb, hostArgs) => {
|
|
226
244
|
try {
|
|
227
|
-
optVerb
|
|
228
|
-
? heapVowE.sendOnly(hostTarget)
|
|
229
|
-
:
|
|
230
|
-
// @ts-ignore once we changed this from E to heapVowE,
|
|
231
|
-
// typescript started complaining that heapVowE(hostTarget)
|
|
232
|
-
// is not callable. I'm not sure if this is a just a typing bug
|
|
233
|
-
// in heapVowE or also reflects a runtime deficiency. But this
|
|
234
|
-
// case it not used yet anyway. We disable it
|
|
235
|
-
// with at-ts-ignore rather than at-ts-expect-error because
|
|
236
|
-
// the dependency-graph tests complains that the latter is unused.
|
|
237
|
-
heapVowE.sendOnly(hostTarget)(...hostArgs);
|
|
245
|
+
optVerb === undefined
|
|
246
|
+
? heapVowE.sendOnly(hostTarget)(...hostArgs)
|
|
247
|
+
: heapVowE.sendOnly(hostTarget)[optVerb](...hostArgs);
|
|
238
248
|
} catch (hostProblem) {
|
|
239
|
-
throw Panic`internal: eventual sendOnly
|
|
249
|
+
throw Panic`internal: eventual sendOnly synchronously failed ${hostProblem}`;
|
|
240
250
|
}
|
|
241
251
|
};
|
|
242
252
|
|
|
243
253
|
/**
|
|
244
|
-
* @param {PassableCap} hostTarget
|
|
254
|
+
* @param {RemotableBrand<PassableCap, Callable>} hostTarget
|
|
245
255
|
* @param {string | undefined} optVerb
|
|
246
256
|
* @param {Passable[]} hostArgs
|
|
247
257
|
* @param {number} callIndex
|
|
@@ -259,20 +269,13 @@ export const makeReplayMembrane = ({
|
|
|
259
269
|
) => {
|
|
260
270
|
const { vow, resolver } = hostResultKit;
|
|
261
271
|
try {
|
|
262
|
-
const hostPromise =
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
// typescript started complaining that heapVowE(hostTarget)
|
|
267
|
-
// is not callable. I'm not sure if this is a just a typing bug
|
|
268
|
-
// in heapVowE or also reflects a runtime deficiency. But this
|
|
269
|
-
// case it not used yet anyway. We disable it
|
|
270
|
-
// with at-ts-ignore rather than at-ts-expect-error because
|
|
271
|
-
// the dependency-graph tests complains that the latter is unused.
|
|
272
|
-
heapVowE(hostTarget)(...hostArgs);
|
|
272
|
+
const hostPromise =
|
|
273
|
+
optVerb === undefined
|
|
274
|
+
? heapVowE(hostTarget)(...hostArgs)
|
|
275
|
+
: heapVowE(hostTarget)[optVerb](...hostArgs);
|
|
273
276
|
resolver.resolve(hostPromise); // TODO does this always work?
|
|
274
277
|
} catch (hostProblem) {
|
|
275
|
-
throw Panic`internal: eventual send
|
|
278
|
+
throw Panic`internal: eventual send synchronously failed ${hostProblem}`;
|
|
276
279
|
}
|
|
277
280
|
try {
|
|
278
281
|
const entry = harden(['doReturn', callIndex, vow]);
|
|
@@ -293,6 +296,10 @@ export const makeReplayMembrane = ({
|
|
|
293
296
|
|
|
294
297
|
const guestHandler = harden({
|
|
295
298
|
applyMethodSendOnly(guestTarget, optVerb, guestArgs) {
|
|
299
|
+
__eventualSendForTesting ||
|
|
300
|
+
Panic`guest eventual applyMethodSendOnly not yet supported: ${guestTarget}.${b(optVerb)}`;
|
|
301
|
+
// The following code is only intended to be used by tests.
|
|
302
|
+
// TODO: properly support applyMethodSendOnly
|
|
296
303
|
const callIndex = log.getIndex();
|
|
297
304
|
if (stopped || !bijection.hasGuest(guestTarget)) {
|
|
298
305
|
Fail`Sent from a previous run: ${guestTarget}`;
|
|
@@ -331,6 +338,10 @@ export const makeReplayMembrane = ({
|
|
|
331
338
|
}
|
|
332
339
|
},
|
|
333
340
|
applyMethod(guestTarget, optVerb, guestArgs, guestReturnedP) {
|
|
341
|
+
__eventualSendForTesting ||
|
|
342
|
+
Panic`guest eventual applyMethod not yet supported: ${guestTarget}.${b(optVerb)} -> ${b(guestReturnedP)}`;
|
|
343
|
+
// The following code is only intended to be used by tests.
|
|
344
|
+
// TODO: properly support applyMethod
|
|
334
345
|
const callIndex = log.getIndex();
|
|
335
346
|
if (stopped || !bijection.hasGuest(guestTarget)) {
|
|
336
347
|
Fail`Sent from a previous run: ${guestTarget}`;
|
|
@@ -398,6 +409,8 @@ export const makeReplayMembrane = ({
|
|
|
398
409
|
}
|
|
399
410
|
},
|
|
400
411
|
applyFunctionSendOnly(guestTarget, guestArgs) {
|
|
412
|
+
__eventualSendForTesting ||
|
|
413
|
+
Panic`guest eventual applyFunctionSendOnly not yet supported: ${guestTarget}`;
|
|
401
414
|
return guestHandler.applyMethodSendOnly(
|
|
402
415
|
guestTarget,
|
|
403
416
|
undefined,
|
|
@@ -405,6 +418,8 @@ export const makeReplayMembrane = ({
|
|
|
405
418
|
);
|
|
406
419
|
},
|
|
407
420
|
applyFunction(guestTarget, guestArgs, guestReturnedP) {
|
|
421
|
+
__eventualSendForTesting ||
|
|
422
|
+
Panic`guest eventual applyFunction not yet supported: ${guestTarget} -> ${b(guestReturnedP)}`;
|
|
408
423
|
return guestHandler.applyMethod(
|
|
409
424
|
guestTarget,
|
|
410
425
|
undefined,
|
|
@@ -413,9 +428,11 @@ export const makeReplayMembrane = ({
|
|
|
413
428
|
);
|
|
414
429
|
},
|
|
415
430
|
getSendOnly(guestTarget, prop) {
|
|
431
|
+
// TODO: support getSendOnly
|
|
416
432
|
throw Panic`guest eventual getSendOnly not yet supported: ${guestTarget}.${b(prop)}`;
|
|
417
433
|
},
|
|
418
434
|
get(guestTarget, prop, guestReturnedP) {
|
|
435
|
+
// TODO: support get
|
|
419
436
|
throw Panic`guest eventual get not yet supported: ${guestTarget}.${b(prop)} -> ${b(guestReturnedP)}`;
|
|
420
437
|
},
|
|
421
438
|
});
|
|
@@ -17,10 +17,9 @@ import { makeDurableZone } from '@agoric/zone/durable.js';
|
|
|
17
17
|
|
|
18
18
|
import { prepareLogStore } from '../src/log-store.js';
|
|
19
19
|
import { prepareBijection } from '../src/bijection.js';
|
|
20
|
-
import {
|
|
20
|
+
import { makeReplayMembraneForTesting } from '../src/replay-membrane.js';
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
* @import {PromiseKit} from '@endo/promise-kit'
|
|
24
23
|
* @import {Zone} from '@agoric/base-zone'
|
|
25
24
|
* @import {LogStore} from '../src/log-store.js';
|
|
26
25
|
* @import {Bijection} from '../src/bijection.js';
|
|
@@ -41,11 +40,19 @@ const preparePingee = zone =>
|
|
|
41
40
|
* @typedef {ReturnType<ReturnType<preparePingee>>} Pingee
|
|
42
41
|
*/
|
|
43
42
|
|
|
43
|
+
const testMode = /** @type {const} */ ({
|
|
44
|
+
normal: 'normal',
|
|
45
|
+
noEventualSend: 'noEventualSend',
|
|
46
|
+
retry: 'retry',
|
|
47
|
+
});
|
|
48
|
+
|
|
44
49
|
/**
|
|
45
50
|
* @param {any} t
|
|
46
51
|
* @param {Zone} zone
|
|
52
|
+
* @param {testMode[keyof testMode]} [mode]
|
|
47
53
|
*/
|
|
48
|
-
const testFirstPlay = async (t, zone) => {
|
|
54
|
+
const testFirstPlay = async (t, zone, mode = testMode.normal) => {
|
|
55
|
+
t.log('testFirstPlay', mode);
|
|
49
56
|
const vowTools = prepareVowTools(zone);
|
|
50
57
|
const { makeVowKit } = vowTools;
|
|
51
58
|
const makeLogStore = prepareLogStore(zone);
|
|
@@ -57,22 +64,33 @@ const testFirstPlay = async (t, zone) => {
|
|
|
57
64
|
const log = zone.makeOnce('log', () => makeLogStore());
|
|
58
65
|
const bijection = zone.makeOnce('bij', makeBijection);
|
|
59
66
|
|
|
60
|
-
const mem =
|
|
67
|
+
const mem = makeReplayMembraneForTesting({
|
|
61
68
|
log,
|
|
62
69
|
bijection,
|
|
63
70
|
vowTools,
|
|
64
71
|
watchWake,
|
|
65
72
|
panic,
|
|
73
|
+
__eventualSendForTesting: mode !== testMode.noEventualSend,
|
|
66
74
|
});
|
|
67
75
|
|
|
68
|
-
const p1 = mem.hostToGuest(v1);
|
|
69
|
-
t.deepEqual(log.dump(), []);
|
|
70
|
-
|
|
71
76
|
/** @type {Pingee} */
|
|
72
77
|
const pingee = zone.makeOnce('pingee', () => makePingee());
|
|
78
|
+
const beforeSend = [
|
|
79
|
+
['checkCall', pingee, 'ping', ['call'], 0],
|
|
80
|
+
['doReturn', 0, undefined],
|
|
81
|
+
];
|
|
82
|
+
|
|
83
|
+
const initialDump = [];
|
|
84
|
+
if (mode === testMode.retry) {
|
|
85
|
+
initialDump.push(...beforeSend);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const p1 = mem.hostToGuest(v1);
|
|
89
|
+
t.deepEqual(log.dump(), initialDump);
|
|
90
|
+
|
|
73
91
|
/** @type {Pingee} */
|
|
74
92
|
const guestPingee = mem.hostToGuest(pingee);
|
|
75
|
-
t.deepEqual(log.dump(),
|
|
93
|
+
t.deepEqual(log.dump(), initialDump);
|
|
76
94
|
|
|
77
95
|
const p = E(guestPingee).ping('send');
|
|
78
96
|
const pOnly = E.sendOnly(guestPingee).ping('sendOnly');
|
|
@@ -80,17 +98,29 @@ const testFirstPlay = async (t, zone) => {
|
|
|
80
98
|
|
|
81
99
|
guestPingee.ping('call');
|
|
82
100
|
|
|
101
|
+
/** @type {any[][]} */
|
|
102
|
+
const afterPingDump = [...beforeSend];
|
|
103
|
+
if (mode === testMode.noEventualSend) {
|
|
104
|
+
await t.throwsAsync(p, {
|
|
105
|
+
message:
|
|
106
|
+
/panic over "\[Error: guest eventual applyMethod not yet supported:/,
|
|
107
|
+
});
|
|
108
|
+
const dump = log.dump();
|
|
109
|
+
t.deepEqual(dump, afterPingDump);
|
|
110
|
+
return p;
|
|
111
|
+
}
|
|
112
|
+
|
|
83
113
|
t.is(await p, undefined);
|
|
84
114
|
const dump = log.dump();
|
|
85
115
|
const v3 = dump[3][2];
|
|
86
|
-
|
|
87
|
-
['checkCall', pingee, 'ping', ['call'], 0],
|
|
88
|
-
['doReturn', 0, undefined],
|
|
116
|
+
const afterSend = [
|
|
89
117
|
['checkSend', pingee, 'ping', ['send'], 2],
|
|
90
118
|
['doReturn', 2, v3],
|
|
91
119
|
['checkSendOnly', pingee, 'ping', ['sendOnly'], 4],
|
|
92
120
|
['doFulfill', v3, undefined],
|
|
93
|
-
]
|
|
121
|
+
];
|
|
122
|
+
afterPingDump.push(...afterSend);
|
|
123
|
+
t.deepEqual(dump, afterPingDump);
|
|
94
124
|
|
|
95
125
|
r1.resolve('x');
|
|
96
126
|
t.is(await p1, 'x');
|
|
@@ -109,8 +139,10 @@ const testFirstPlay = async (t, zone) => {
|
|
|
109
139
|
/**
|
|
110
140
|
* @param {any} t
|
|
111
141
|
* @param {Zone} zone
|
|
142
|
+
* @param {testMode[keyof testMode]} [mode]
|
|
112
143
|
*/
|
|
113
|
-
const testReplay = async (t, zone) => {
|
|
144
|
+
const testReplay = async (t, zone, mode = testMode.normal) => {
|
|
145
|
+
t.log('testReplay', mode);
|
|
114
146
|
const vowTools = prepareVowTools(zone);
|
|
115
147
|
prepareLogStore(zone);
|
|
116
148
|
prepareBijection(zone);
|
|
@@ -129,7 +161,7 @@ const testReplay = async (t, zone) => {
|
|
|
129
161
|
|
|
130
162
|
const dump = log.dump();
|
|
131
163
|
const v3 = dump[3][2];
|
|
132
|
-
|
|
164
|
+
const beforeY = [
|
|
133
165
|
['checkCall', pingee, 'ping', ['call'], 0],
|
|
134
166
|
['doReturn', 0, undefined],
|
|
135
167
|
['checkSend', pingee, 'ping', ['send'], 2],
|
|
@@ -137,14 +169,18 @@ const testReplay = async (t, zone) => {
|
|
|
137
169
|
['checkSendOnly', pingee, 'ping', ['sendOnly'], 4],
|
|
138
170
|
['doFulfill', v3, undefined],
|
|
139
171
|
['doFulfill', v1, 'x'],
|
|
140
|
-
]
|
|
172
|
+
];
|
|
173
|
+
const afterY = [['doFulfill', v2, 'y']];
|
|
174
|
+
const initialDump = beforeY;
|
|
175
|
+
t.deepEqual(dump, initialDump);
|
|
141
176
|
|
|
142
|
-
const mem =
|
|
177
|
+
const mem = makeReplayMembraneForTesting({
|
|
143
178
|
log,
|
|
144
179
|
bijection,
|
|
145
180
|
vowTools,
|
|
146
181
|
watchWake,
|
|
147
182
|
panic,
|
|
183
|
+
__eventualSendForTesting: mode !== testMode.noEventualSend,
|
|
148
184
|
});
|
|
149
185
|
t.true(log.isReplaying());
|
|
150
186
|
t.is(log.getIndex(), 0);
|
|
@@ -153,23 +189,15 @@ const testReplay = async (t, zone) => {
|
|
|
153
189
|
const p2 = mem.hostToGuest(v2);
|
|
154
190
|
// @ts-expect-error TS doesn't know that r2 is a resolver
|
|
155
191
|
r2.resolve('y');
|
|
156
|
-
await eventLoopIteration();
|
|
157
192
|
|
|
158
193
|
const p1 = mem.hostToGuest(v1);
|
|
159
194
|
mem.wake();
|
|
160
195
|
t.true(log.isReplaying());
|
|
161
196
|
t.is(log.getIndex(), 0);
|
|
162
|
-
t.deepEqual(log.dump(),
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
['checkSend', pingee, 'ping', ['send'], 2],
|
|
166
|
-
['doReturn', 2, v3],
|
|
167
|
-
['checkSendOnly', pingee, 'ping', ['sendOnly'], 4],
|
|
168
|
-
['doFulfill', v3, undefined],
|
|
169
|
-
['doFulfill', v1, 'x'],
|
|
170
|
-
]);
|
|
197
|
+
t.deepEqual(log.dump(), initialDump);
|
|
198
|
+
|
|
199
|
+
const pingSend = E(guestPingee).ping('send');
|
|
171
200
|
|
|
172
|
-
E(guestPingee).ping('send');
|
|
173
201
|
// TODO Once https://github.com/endojs/endo/issues/2336 is fixed,
|
|
174
202
|
// the following `void` should not be needed. But strangely, TS isn't
|
|
175
203
|
// telling me a `void` is needed above, which is also incorrect.
|
|
@@ -177,20 +205,19 @@ const testReplay = async (t, zone) => {
|
|
|
177
205
|
|
|
178
206
|
guestPingee.ping('call');
|
|
179
207
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
[
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
]);
|
|
208
|
+
let finalDump;
|
|
209
|
+
if (mode === testMode.noEventualSend) {
|
|
210
|
+
t.true(log.isReplaying());
|
|
211
|
+
finalDump = beforeY;
|
|
212
|
+
} else {
|
|
213
|
+
t.is(await p1, 'x');
|
|
214
|
+
t.is(await p2, 'y');
|
|
215
|
+
t.false(log.isReplaying());
|
|
216
|
+
finalDump = [...beforeY, ...afterY];
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
t.deepEqual(log.dump(), finalDump);
|
|
220
|
+
return pingSend;
|
|
194
221
|
};
|
|
195
222
|
|
|
196
223
|
test.serial('test heap replay-membrane settlement', async t => {
|
|
@@ -215,3 +242,32 @@ test.serial('test durable replay-membrane settlement', async t => {
|
|
|
215
242
|
const zone3 = makeDurableZone(getBaggage(), 'durableRoot');
|
|
216
243
|
return testReplay(t, zone3);
|
|
217
244
|
});
|
|
245
|
+
|
|
246
|
+
test.serial('test durable toggle eventual send', async t => {
|
|
247
|
+
annihilate();
|
|
248
|
+
|
|
249
|
+
nextLife();
|
|
250
|
+
const zone1 = makeDurableZone(getBaggage(), 'durableRoot');
|
|
251
|
+
await t.throwsAsync(() => testFirstPlay(t, zone1, testMode.noEventualSend), {
|
|
252
|
+
message:
|
|
253
|
+
/^panic over "\[Error: guest eventual applyMethod not yet supported:/,
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
await eventLoopIteration();
|
|
257
|
+
nextLife();
|
|
258
|
+
const zone1a = makeDurableZone(getBaggage(), 'durableRoot');
|
|
259
|
+
await testFirstPlay(t, zone1a, testMode.retry);
|
|
260
|
+
|
|
261
|
+
await eventLoopIteration();
|
|
262
|
+
nextLife();
|
|
263
|
+
const zone2 = makeDurableZone(getBaggage(), 'durableRoot');
|
|
264
|
+
await t.throwsAsync(() => testReplay(t, zone2, testMode.noEventualSend), {
|
|
265
|
+
message:
|
|
266
|
+
/^panic over "\[Error: guest eventual applyMethod not yet supported:/,
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
await eventLoopIteration();
|
|
270
|
+
nextLife();
|
|
271
|
+
const zone2a = makeDurableZone(getBaggage(), 'durableRoot');
|
|
272
|
+
await testReplay(t, zone2a, testMode.retry);
|
|
273
|
+
});
|