From fd44ce73d6709879667376418aaab2e82d1ff7a2 Mon Sep 17 00:00:00 2001 From: Michael FIG Date: Sat, 18 Sep 2021 20:49:21 -0600 Subject: [PATCH 1/6] docs(timer): remove obsolete or misleading documentation --- packages/SwingSet/docs/timer.md | 20 ++--- packages/cosmic-swingset/TimerService.md | 98 ------------------------ 2 files changed, 11 insertions(+), 107 deletions(-) delete mode 100644 packages/cosmic-swingset/TimerService.md diff --git a/packages/SwingSet/docs/timer.md b/packages/SwingSet/docs/timer.md index 53dcab49f5b..267bda6f449 100644 --- a/packages/SwingSet/docs/timer.md +++ b/packages/SwingSet/docs/timer.md @@ -33,29 +33,31 @@ and creating the service. The vat is responsible for creating repeater objects to wrap the device node as a capability that can be accessed by regular vat code. -In `bootstrap()` for a particular SwingSet, we create a timerService, and -make it accessible to the user in `home` +In `bootstrap()` for a particular SwingSet, we create a timerService, and make +it accessible to the user in `home.localTimerService` (whose timestamps are +measured in milliseconds). ``` const timerService = E(vats.timerWrapper).createTimerService(devices.timer); ``` -Then users in the REPL can use the timerService to schedule wakeups. +Then users in the REPL can use the `localTimerService` or `chainTimerService` +(both in seconds) to schedule wakeups. ``` -const timestampP = E(timerService).getCurrentTimestamp(); +timestamp = E(home.localTimerService).getCurrentTimestamp(); -const handler = harden({wake(now) { console.log(`woke up ${now}`); }}); -const willWakeAt = E(timerService).setWakeup(60, handler); +handler = Far('waker', { wake(now) { console.log(`woke up ${now}`); } }); +willWakeAt = E(home.localTimerService).setWakeup(timestamp + 60n, handler); ``` The handler will fire somewhat after 60 seconds from now. ``` -const repeater = E(timerService).makeRepeater(20, 60); +const repeater = E(home.localTimerService).makeRepeater(20n, 60n); E(repeater).schedule(handler); ``` The handler will fire in somewhat after 80 seconds from now, and every 60 -seconds thereafter. Calling `E(repeater).disable()` will cancel prevent the repeater -from scheduling future activations +seconds thereafter. Calling `E(repeater).disable()` will cancel the repeater and +prevent it from scheduling future activations diff --git a/packages/cosmic-swingset/TimerService.md b/packages/cosmic-swingset/TimerService.md deleted file mode 100644 index f169f2ac065..00000000000 --- a/packages/cosmic-swingset/TimerService.md +++ /dev/null @@ -1,98 +0,0 @@ -There will be one or two timerServices in home. One is from the chain (if -present), the other from the local vat. It would probably be sensible to use a -chain-based timer for contracts, but more efficient to use the local timer -for operations that don't need consensus or consistency. Each timerService -gives the ability to get the current time, schedule a single wake() call, -create a repeater that will allow scheduling of events at regular intervals, -or remove scheduled calls. - -The timerService's API is - -``` -interface TimerService { - // Retrieve the time of the start of the current block. - getCurrentTimestamp() -> (integer); - - // Return value is the time at which the call is scheduled to take place. - setWakeup(baseTime :integer, handler :Handler) -> (integer); - - // Remove the handler from all its scheduled wakeups, whether - // produced by timer.setWakeup(h) or repeater.schedule(h). - removeWakeup(handler :Handler) -> (List(integer)); - - // Create and return a repeater that will schedule wake() calls repeatedly at - // times that are a multiple of interval following baseTime. Interval is the - // delay between successive times at which wake will be called. When - // schedule(h) is called, h.wake() will be scheduled to be called after the - // next multiple of interval from the base. Since block times are coarse- - // grained, the actual call may occur later, but this won't change when the - // next event will be called. - makeRepeater(delaySecs :integer, interval :integer) -> (Repeater); -} - -interface Repeater { - // Return value is the time scheduled for the first call on handler. - // The handler will continue to be scheduled for a wake() call every - // interval until the repeater is disabled. - schedule(handler :Handler) -> (integer); - - // Disable this repeater, so schedule() can't be called, and handlers - // already scheduled with this repeater won't be rescheduled again after - // wake() is next called on them. - disable(); -} - -interface Handler { - // The time passed to wake() is the time that the call was scheduled to - // occur. - wake(time); -} -``` - -Here's a transcript of a session showing the use of the repeater. - -``` -command[0] home -history[0] {"LOADING":[Promise],"gallery":[Presence o-50],"sharingService":[Presence o-51], -"purse":[Presence o-52],"canvasStatePublisher":[Presence o-53],"contractHost":[Presence o-54], -"chainTimerService":[Presence o-55],"sharing":[Presence o-56],"registry":[Presence o-57],"zoe": -[Presence o-58],"localTimerService":[Presence o-59],"uploads":[Presence o-60]} -command[1] home.localTimerService~.getCurrentTimestamp() -history[1] 1571782780000 -command[2] home.chainTimerService~.getCurrentTimestamp() -history[2] 1571782793 -command[3] makeHandler = () => { let calls = 0; const args = []; return { getCalls() { -return calls; }, getArgs() { return args; }, wake(arg) { args.push(arg); calls += 1; }, }; } -history[3] [Function makeHandler] -command[4] h1 = makeHandler() -history[4] {"getCalls":[Function getCalls],"getArgs":[Function getArgs],"wake":[Function wake]} -command[5] h2 = makeHandler() -history[5] {"getCalls":[Function getCalls],"getArgs":[Function getArgs],"wake":[Function wake]} -command[6] tl = home.localTimerService -history[6] [Presence o-59] -command[7] tc = home.chainTimerService -history[7] [Presence o-55] -command[8] rl = tl~.makeRepeater(7, 1500) -history[8] [Presence o-64] -command[9] rc = tc~.makeRepeater(7, 1) -history[9] [Presence o-65] -command[10] rl~.schedule(h1) -history[10] 1571783040007 -command[11] rc~.schedule(h2) -history[11] 1571783051 -command[12] h1.getCalls() -history[12] 3 -command[13] h2.getCalls() -history[13] 1 -... -command[22] h1.getCalls() -history[22] 50 -command[23] h1.getCalls() -history[23] 53 -command[24] h1.getCalls() -history[24] 54 -command[25] tl~.getCurrentTimestamp() -history[25] 1571783375000 -command[26] tc~.getCurrentTimestamp() -history[26] 1571783384 -``` From 7a2c830b6cdea1e81cc0eb8fef517704dc30a922 Mon Sep 17 00:00:00 2001 From: Michael FIG Date: Sun, 19 Sep 2021 19:59:36 -0600 Subject: [PATCH 2/6] feat(TimerService): add new `delay` method and protect device args --- packages/SwingSet/src/devices/timer-src.js | 14 ++--- packages/SwingSet/src/vats/types.js | 6 ++- .../SwingSet/src/vats/vat-timerWrapper.js | 53 ++++++++++++++----- packages/zoe/tools/manualTimer.js | 40 +++++++++----- 4 files changed, 80 insertions(+), 33 deletions(-) diff --git a/packages/SwingSet/src/devices/timer-src.js b/packages/SwingSet/src/devices/timer-src.js index 1479e62b9f7..c394f839eb7 100644 --- a/packages/SwingSet/src/devices/timer-src.js +++ b/packages/SwingSet/src/devices/timer-src.js @@ -1,10 +1,10 @@ /** * A Timer device that provides a capability that can be used to schedule wake() * calls at particular times. The simpler form is a handler object with a wake() - * function can be passed to D(timer).setWakeup(delaySecs, handler) to be woken - * after delaySecs. + * function can be passed to D(timer).setWakeup(baseTime, handler) to be woken + * after baseTime. * - * The other form r = D(timer).makeRepeater(startTime, interval) allows one to + * The other form r = D(timer).makeRepeater(baseTime, interval) allows one to * create a repeater object which can be used to scheduled regular wakeups. Each * time D(timer).schedule(r, w) is called, w.wake(r) will be scheduled to be * called after the next multiple of interval since startTime. This doesn't @@ -265,11 +265,11 @@ export function buildRootDeviceNode(tools) { // but the repeated calls won't accumulate timing drift, so the trigger // point will be reached at consistent intervals. return Far('root', { - setWakeup(delaySecs, handler) { - assert.typeof(delaySecs, 'bigint'); - deadlines.add(lastPolled + Nat(delaySecs), handler); + setWakeup(baseTime, handler) { + baseTime = Nat(baseTime); + deadlines.add(baseTime, handler); saveState(); - return lastPolled + Nat(delaySecs); + return baseTime; }, removeWakeup(handler) { const times = deadlines.remove(handler); diff --git a/packages/SwingSet/src/vats/types.js b/packages/SwingSet/src/vats/types.js index 99f77a3ba9f..f47ed7f7ed7 100644 --- a/packages/SwingSet/src/vats/types.js +++ b/packages/SwingSet/src/vats/types.js @@ -10,7 +10,7 @@ * `repeater.schedule(h)`. * @property {(delay: RelativeTime, interval: RelativeTime) => TimerRepeater} createRepeater * DEPRECATED: use makeRepeater instead. - * @property {(delaySecs: RelativeTime, interval: RelativeTime) => TimerRepeater} makeRepeater + * @property {(delay: RelativeTime, interval: RelativeTime) => TimerRepeater} makeRepeater * Create and return a repeater that will schedule `wake()` calls * repeatedly at times that are a multiple of interval following delay. * Interval is the difference between successive times at which wake will be @@ -18,9 +18,11 @@ * called after the next multiple of interval from the base. Since times can be * coarse-grained, the actual call may occur later, but this won't change when * the next event will be called. - * @property {(delaySecs: RelativeTime, interval: RelativeTime) => Notifier} makeNotifier + * @property {(delay: RelativeTime, interval: RelativeTime) => Notifier} makeNotifier * Create and return a Notifier that will deliver updates repeatedly at times * that are a multiple of interval following delay. + * @property {(delay: RelativeTime) => Promise} delay + * Create and return a promise that will resolve after the relative time has passed. */ /** diff --git a/packages/SwingSet/src/vats/vat-timerWrapper.js b/packages/SwingSet/src/vats/vat-timerWrapper.js index 00faa15a923..01db70b8e1d 100644 --- a/packages/SwingSet/src/vats/vat-timerWrapper.js +++ b/packages/SwingSet/src/vats/vat-timerWrapper.js @@ -1,7 +1,10 @@ +// @ts-check + import { Nat } from '@agoric/nat'; import { assert, details as X } from '@agoric/assert'; import { Far } from '@agoric/marshal'; import { makeNotifierKit } from '@agoric/notifier'; +import { makePromiseKit } from '@agoric/promise-kit'; export function buildRootObject(vatPowers) { const { D } = vatPowers; @@ -13,8 +16,9 @@ export function buildRootObject(vatPowers) { getCurrentTimestamp() { return Nat(D(timerNode).getLastPolled()); }, - setWakeup(delaySecs, handler) { - return D(timerNode).setWakeup(delaySecs, handler); + setWakeup(baseTime, handler) { + baseTime = Nat(baseTime); + return D(timerNode).setWakeup(baseTime, handler); }, // can be used after setWakeup(h) or schedule(h) removeWakeup(handler) { @@ -22,17 +26,20 @@ export function buildRootObject(vatPowers) { }, // deprecated in favor of makeRepeater(). // TODO(#2164): remove before Beta - createRepeater(delaySecs, interval) { - return timerService.makeRepeater(delaySecs, interval); + createRepeater(delay, interval) { + delay = Nat(delay); + interval = Nat(interval); + return timerService.makeRepeater(delay, interval); }, - makeRepeater(delaySecs, interval) { - Nat(delaySecs); + makeRepeater(delay, interval) { + delay = Nat(delay); + interval = Nat(interval); assert( - Nat(interval) > 0, + interval > 0, X`makeRepeater's second parameter must be a positive integer: ${interval}`, ); - const index = D(timerNode).makeRepeater(delaySecs, interval); + const index = D(timerNode).makeRepeater(delay, interval); const vatRepeater = Far('vatRepeater', { schedule(h) { @@ -46,22 +53,44 @@ export function buildRootObject(vatPowers) { repeaters.set(index, vatRepeater); return vatRepeater; }, - makeNotifier(delaySecs, interval) { - Nat(delaySecs); + makeNotifier(delay, interval) { + delay = Nat(delay); + interval = Nat(interval); assert( - Nat(interval) > 0, + interval > 0, X`makeNotifier's second parameter must be a positive integer: ${interval}`, ); - const index = D(timerNode).makeRepeater(delaySecs, interval); + const index = D(timerNode).makeRepeater(delay, interval); const { notifier, updater } = makeNotifierKit(); const updateHandler = Far('updateHandler', { wake: updater.updateState, }); D(timerNode).schedule(index, updateHandler); + // FIXME: The fact that we never delete the repeater (for the `index`) + // means that there is a resource leak and no way the repeater ever + // stops. + // + // This happens even if every recipient of the notifier permanently + // stops asking for updates, or equivalently, they drop all references + // to the notifier. + // + // To solve this problem, we could elegantly use something like #3854. + return notifier; }, + delay(delay) { + delay = Nat(delay); + const now = timerService.getCurrentTimestamp(); + const baseTime = now + delay; + const promiseKit = makePromiseKit(); + const delayHandler = Far('delayHandler', { + wake: promiseKit.resolve, + }); + timerService.setWakeup(baseTime, delayHandler); + return promiseKit.promise; + }, }); return timerService; } diff --git a/packages/zoe/tools/manualTimer.js b/packages/zoe/tools/manualTimer.js index 89d4b5da924..2d581813c5a 100644 --- a/packages/zoe/tools/manualTimer.js +++ b/packages/zoe/tools/manualTimer.js @@ -9,6 +9,7 @@ import { Far } from '@agoric/marshal'; import './types.js'; import './internal-types.js'; import { makeNotifierKit } from '@agoric/notifier'; +import { makePromiseKit } from '@agoric/promise-kit'; /** * A fake clock that also logs progress. @@ -25,11 +26,11 @@ export default function buildManualTimer(log, startValue = 0n, timeStep = 1n) { // Legacy because the value is mutated after it is stored. const schedule = makeLegacyMap('Timestamp'); - const makeRepeater = (delaySecs, interval, timer) => { - assert.typeof(delaySecs, 'bigint'); + const makeRepeater = (delay, interval, timer) => { + assert.typeof(delay, 'bigint'); assert( - delaySecs % timeStep === 0n, - `timer has a resolution of ${timeStep}; ${delaySecs} is not divisible`, + delay % timeStep === 0n, + `timer has a resolution of ${timeStep}; ${delay} is not divisible`, ); assert.typeof(interval, 'bigint'); assert( @@ -70,7 +71,7 @@ export default function buildManualTimer(log, startValue = 0n, timeStep = 1n) { timer.removeWakeup(repeaterWaker); }, }); - nextWakeup = ticks + delaySecs; + nextWakeup = ticks + delay; timer.setWakeup(nextWakeup, repeaterWaker); return repeater; }; @@ -135,14 +136,14 @@ export default function buildManualTimer(log, startValue = 0n, timeStep = 1n) { createRepeater(delay, interval) { return makeRepeater(delay, interval, timer); }, - makeRepeater(delaySecs, interval) { - return makeRepeater(delaySecs, interval, timer); + makeRepeater(delay, interval) { + return makeRepeater(delay, interval, timer); }, - makeNotifier(delaySecs, interval) { - assert.typeof(delaySecs, 'bigint'); + makeNotifier(delay, interval) { + assert.typeof(delay, 'bigint'); assert( - (delaySecs % timeStep) === 0n, - `timer has a resolution of ${timeStep}; ${delaySecs} is not divisible`, + (delay % timeStep) === 0n, + `timer has a resolution of ${timeStep}; ${delay} is not divisible`, ); assert.typeof(interval, 'bigint'); assert( @@ -158,9 +159,24 @@ export default function buildManualTimer(log, startValue = 0n, timeStep = 1n) { timer.setWakeup(ticks + interval, repeaterWaker); }, }); - timer.setWakeup(ticks + delaySecs, repeaterWaker); + timer.setWakeup(ticks + delay, repeaterWaker); return notifier; }, + delay(delay) { + assert.typeof(delay, 'bigint'); + assert( + (delay % timeStep) === 0n, + `timer has a resolution of ${timeStep}; ${delay} is not divisible`, + ); + const promiseKit = makePromiseKit(); + const delayWaker = Far('delayWaker', { + wake(timestamp) { + promiseKit.resolve(timestamp); + }, + }); + timer.setWakeup(delay, delayWaker); + return promiseKit.promise; + }, }); return timer; } From d6d472445a05b8c3d83fc9621879c3c91bf4d737 Mon Sep 17 00:00:00 2001 From: Michael FIG Date: Mon, 20 Sep 2021 12:17:14 -0600 Subject: [PATCH 3/6] fix(solo): make `localTimerService` in ms, and update correctly --- packages/SwingSet/docs/timer.md | 22 +++++++++++++++++----- packages/solo/src/start.js | 2 +- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/packages/SwingSet/docs/timer.md b/packages/SwingSet/docs/timer.md index 267bda6f449..0367a1b5bc8 100644 --- a/packages/SwingSet/docs/timer.md +++ b/packages/SwingSet/docs/timer.md @@ -41,20 +41,32 @@ measured in milliseconds). const timerService = E(vats.timerWrapper).createTimerService(devices.timer); ``` -Then users in the REPL can use the `localTimerService` or `chainTimerService` -(both in seconds) to schedule wakeups. +Then users in the REPL can use the `localTimerService` (in milliseconds since +the epoch) or `chainTimerService` (in seconds since the epoch) to schedule wakeups. +There is a simple promise-based `delay` function that resolves its returned promise +when at least its first `delay` argument has passed. + +```js +E(home.localTimerService).delay(60_000n); ``` + +This promise will resolve to the current timestamp after 60 seconds from now. + +Alteratively, if you wish to be able to cancel the delay, you can use the more +powerful `setWakeup` method: + +```js timestamp = E(home.localTimerService).getCurrentTimestamp(); handler = Far('waker', { wake(now) { console.log(`woke up ${now}`); } }); -willWakeAt = E(home.localTimerService).setWakeup(timestamp + 60n, handler); +willWakeAt = E(home.localTimerService).setWakeup(timestamp + 60_000n, handler); ``` The handler will fire somewhat after 60 seconds from now. -``` -const repeater = E(home.localTimerService).makeRepeater(20n, 60n); +```js +repeater = E(home.localTimerService).makeRepeater(20_000n, 60_000n); E(repeater).schedule(handler); ``` diff --git a/packages/solo/src/start.js b/packages/solo/src/start.js index ef31ee7d7d8..3fd08c93b2f 100644 --- a/packages/solo/src/start.js +++ b/packages/solo/src/start.js @@ -235,7 +235,7 @@ async function buildSwingset( // other inbound messages. const queuedMoveTimeForward = withInputQueue( async function moveTimeForward() { - const now = Math.floor(Date.now() / intervalMillis); + const now = Date.now(); try { if (timer.poll(now)) { await processKernel(); From 3f49a779f253ff01fe7e71d0295efbfa99b669a9 Mon Sep 17 00:00:00 2001 From: Michael FIG Date: Mon, 20 Sep 2021 12:17:50 -0600 Subject: [PATCH 4/6] fix(sim-chain): update `chainTimerService` correctly --- packages/cosmic-swingset/src/sim-chain.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/cosmic-swingset/src/sim-chain.js b/packages/cosmic-swingset/src/sim-chain.js index d1627b917fb..0ee3ea29cc6 100644 --- a/packages/cosmic-swingset/src/sim-chain.js +++ b/packages/cosmic-swingset/src/sim-chain.js @@ -104,12 +104,11 @@ export async function connectToFakeChain(basedir, GCI, delay, inbound) { const withBlockQueue = makeWithQueue(); const unhandledSimulateBlock = withBlockQueue( async function unqueuedSimulateBlock() { - const actualStart = Date.now(); // Gather up the new messages into the latest block. thisBlock.push(...intoChain); intoChain = []; - blockTime += PRETEND_BLOCK_DELAY; + blockTime = scaleBlockTime(Date.now()); blockHeight += 1; await blockManager( @@ -143,7 +142,6 @@ export async function connectToFakeChain(basedir, GCI, delay, inbound) { // We now advance to the next block. thisBlock = []; - blockTime += scaleBlockTime(Date.now() - actualStart); clearTimeout(nextBlockTimeout); // eslint-disable-next-line no-use-before-define From b45c66d6d5aadcd91bd2e50d31104bce8d4d78f6 Mon Sep 17 00:00:00 2001 From: Michael FIG Date: Mon, 20 Sep 2021 12:28:35 -0600 Subject: [PATCH 5/6] fix(timer): remove deprecated `createRepeater` --- packages/SwingSet/src/vats/types.js | 2 -- packages/SwingSet/src/vats/vat-timerWrapper.js | 7 ------- packages/solo/test/test-home.js | 14 -------------- packages/zoe/tools/manualTimer.js | 3 --- 4 files changed, 26 deletions(-) diff --git a/packages/SwingSet/src/vats/types.js b/packages/SwingSet/src/vats/types.js index f47ed7f7ed7..4f533152004 100644 --- a/packages/SwingSet/src/vats/types.js +++ b/packages/SwingSet/src/vats/types.js @@ -8,8 +8,6 @@ * @property {(waker: ERef) => Array} removeWakeup Remove the waker * from all its scheduled wakeups, whether produced by `timer.setWakeup(h)` or * `repeater.schedule(h)`. - * @property {(delay: RelativeTime, interval: RelativeTime) => TimerRepeater} createRepeater - * DEPRECATED: use makeRepeater instead. * @property {(delay: RelativeTime, interval: RelativeTime) => TimerRepeater} makeRepeater * Create and return a repeater that will schedule `wake()` calls * repeatedly at times that are a multiple of interval following delay. diff --git a/packages/SwingSet/src/vats/vat-timerWrapper.js b/packages/SwingSet/src/vats/vat-timerWrapper.js index 01db70b8e1d..6405cedd7b1 100644 --- a/packages/SwingSet/src/vats/vat-timerWrapper.js +++ b/packages/SwingSet/src/vats/vat-timerWrapper.js @@ -24,13 +24,6 @@ export function buildRootObject(vatPowers) { removeWakeup(handler) { return D(timerNode).removeWakeup(handler); }, - // deprecated in favor of makeRepeater(). - // TODO(#2164): remove before Beta - createRepeater(delay, interval) { - delay = Nat(delay); - interval = Nat(interval); - return timerService.makeRepeater(delay, interval); - }, makeRepeater(delay, interval) { delay = Nat(delay); interval = Nat(interval); diff --git a/packages/solo/test/test-home.js b/packages/solo/test/test-home.js index 18b5c1db796..adc7995a538 100644 --- a/packages/solo/test/test-home.js +++ b/packages/solo/test/test-home.js @@ -166,20 +166,6 @@ function makeHandler() { }); } -// TODO(2164): createRepeater was replaced by makeRepeater. Remove it pre-Beta -test.serial('home.localTimerService createRepeater', async t => { - const { localTimerService } = E.get(home); - const timestamp = await E(localTimerService).getCurrentTimestamp(); - const repeater = E(localTimerService).createRepeater(1n, 1n); - const handler = makeHandler(); - await E(repeater).schedule(handler); - const notifier = E(localTimerService).makeNotifier(1n, 1n); - await E(notifier).getUpdateSince(); - - t.truthy(handler.getCalls() >= 1); - t.truthy(handler.getArgs()[0] > timestamp); -}); - test.serial('home.localTimerService makeRepeater', async t => { const { localTimerService } = E.get(home); const timestamp = await E(localTimerService).getCurrentTimestamp(); diff --git a/packages/zoe/tools/manualTimer.js b/packages/zoe/tools/manualTimer.js index 2d581813c5a..a5bfb9a05c1 100644 --- a/packages/zoe/tools/manualTimer.js +++ b/packages/zoe/tools/manualTimer.js @@ -133,9 +133,6 @@ export default function buildManualTimer(log, startValue = 0n, timeStep = 1n) { } return harden(baseTimes); }, - createRepeater(delay, interval) { - return makeRepeater(delay, interval, timer); - }, makeRepeater(delay, interval) { return makeRepeater(delay, interval, timer); }, From 365471757974502d57139aee883e47f0ef379710 Mon Sep 17 00:00:00 2001 From: Michael FIG Date: Mon, 20 Sep 2021 12:31:31 -0600 Subject: [PATCH 6/6] refactor: remove duplicate manualTimer code from `swingset-runner` --- .../demo/zoeTests/bootstrap.js | 2 +- .../demo/zoeTests/manualTimer.js | 44 ------------------- 2 files changed, 1 insertion(+), 45 deletions(-) delete mode 100644 packages/swingset-runner/demo/zoeTests/manualTimer.js diff --git a/packages/swingset-runner/demo/zoeTests/bootstrap.js b/packages/swingset-runner/demo/zoeTests/bootstrap.js index d2c0ace502c..b649790e6c6 100644 --- a/packages/swingset-runner/demo/zoeTests/bootstrap.js +++ b/packages/swingset-runner/demo/zoeTests/bootstrap.js @@ -1,7 +1,7 @@ import { E } from '@agoric/eventual-send'; import { Far } from '@agoric/marshal'; import { makeIssuerKit, AmountMath } from '@agoric/ertp'; -import buildManualTimer from './manualTimer.js'; +import buildManualTimer from '@agoric/zoe/tools/manualTimer.js'; import { makePrintLog } from './printLog.js'; diff --git a/packages/swingset-runner/demo/zoeTests/manualTimer.js b/packages/swingset-runner/demo/zoeTests/manualTimer.js deleted file mode 100644 index 3be8349ad1c..00000000000 --- a/packages/swingset-runner/demo/zoeTests/manualTimer.js +++ /dev/null @@ -1,44 +0,0 @@ -import { assert } from '@agoric/assert'; -import { E } from '@agoric/eventual-send'; -import { Far } from '@agoric/marshal'; -import { Nat } from '@agoric/nat'; - -// A fake clock that also logs progress in tests. -export default function buildManualTimer(log, startValue = 0n, timeStep = 1n) { - let ticks = Nat(startValue); - const schedule = new Map(); - return Far('timer', { - setWakeup(deadline, handler) { - assert.typeof(deadline, 'bigint'); - assert( - deadline % timeStep === 0n, - `timer has a resolution of ${timeStep}; ${deadline} is not divisible`, - ); - if (deadline <= ticks) { - log(`&& task was past its deadline when scheduled: ${deadline} &&`); - handler.wake(ticks); - return undefined; - } - log(`@@ schedule task for:${deadline}, currently: ${ticks} @@`); - if (!schedule.has(deadline)) { - schedule.set(deadline, []); - } - schedule.get(deadline).push(handler); - return deadline; - }, - // This function will only be called in testing code to advance the clock. - tick(msg) { - ticks += timeStep; - log(`@@ tick:${ticks}${msg ? `: ${msg}` : ''} @@`); - if (schedule.has(ticks)) { - for (const h of schedule.get(ticks)) { - log(`&& running a task scheduled for ${ticks}. &&`); - E(h).wake(ticks); - } - } - }, - getCurrentTimestamp() { - return ticks; - }, - }); -}