diff --git a/main/guides/coreeval/permissions.md b/main/guides/coreeval/permissions.md index 2ad68fd04..9d6ce81fb 100644 --- a/main/guides/coreeval/permissions.md +++ b/main/guides/coreeval/permissions.md @@ -49,7 +49,8 @@ In the top level promise space, we have: - **chainStorage**: to make storage nodes to [write to vstorage](../zoe/pub-to-storage). **Warning: this includes access to over-write previously allocated storage nodes.** -- **chainTimerService**: for getting the current [timer](../../reference/repl/timerServices) and setting timer wake-ups; for example, at the conclusion of a governance vote. +- **chainTimerService**: for getting the current timer and setting timer wake-ups; for example, at the conclusion of a governance vote. + See [Timer Service API](../../reference/repl/timerServices). **Note: this includes access to schedule infinitely repeating events.** - **namesByAddress**: for [looking up objects published under an address](../integration/name-services#namesbyaddress-namesbyaddressadmin-and-depositfacet-per-account-namespace); in particular, diff --git a/main/reference/repl/timerServices.md b/main/reference/repl/timerServices.md index d31196b20..3846220b5 100644 --- a/main/reference/repl/timerServices.md +++ b/main/reference/repl/timerServices.md @@ -1,188 +1,19 @@ -# Timer Services - -## TimerService objects +# Timer Services -`home` has two timer service objects: -- `localTimerService` is from the local vat **with units of 1 millisecond**. -- `chainTimerService` is from the chain (if present) **with units of 1 second**. +## chainTimerService -In general, you should use the chain timer for contracts. But it's more efficient to -use the local timer for objects that don't need consensus or consistency. -For example, people might want it for testing. +The `chainTimerService` is based on block times with units of 1 second. + +The timer service lets you: -Both timer services let you: - Schedule `wake()` calls. - Remove scheduled `wake()` calls. -- Create a repeater for scheduling of events at regular intervals. - -The local service lets you get a monotonically increasing timestamp for each instance -of the local chain. The chain service lets you get the start time of the current block. - -Both timer services present an identical API, but apply a different interpretation to -the following data types. - -### `Timestamp` - -A `BigInt` representing an absolute instant in time in a `TimerService`, using units and a basis dependent upon the service. - -### `RelativeTime` +- Create a repeater for scheduling of events at regular intervals. -A `BigInt` representing the difference between two `Timestamp`s of the same `TimerService`. - -## TimerService methods - -The following methods provide basic TimerService functionality. - -### `E(home.TimerService).getCurrentTimestamp()` -- Returns: `{ Promise }` - -Returns a promise that resolves with the current timestamp. +For testing, use ```js -command[1] E(home.chainTimerService).getCurrentTimestamp() -history[1] 1632170301n // in seconds since epoch -command[2] E(home.localTimerService).getCurrentTimestamp() -history[2] 1632170301546n // in milliseconds since epoch +import buildManualTimer from '@agoric/zoe/tools/manualTimer.js'; ``` -A chain block might be executed more than once in case of restart or replay or -cross-verification, but each such execution will receive the same input state -and observe the same response, even if running a minute or a month later. - -### `E(home.TimerService).delay(delay)` -- `delay` `{ RelativeTime }` -- Returns: `{ Promise }` - -Returns a promise that resolves with the current timestamp after the `delay` -has elapsed. - -```js -command[3] E(home.localTimerService).delay(3_000n) -history[3] unresolved Promise -history[3] 1632170321864n // about 3 seconds later, in milliseconds since epoch -``` - -### `E(home.TimerService).makeNotifier(delay, interval)` -- `delay` `{ RelativeTime }` -- `interval` `{ RelativeTime }` -- Returns: `{ Promise> }` - -Creates a `Notifier` object and returns a promise that resolves with it. -The notifier repeatedly delivers updates at times -that are a multiple of the specified `interval`, with the first update happening -after the specified `delay` has elapsed. - -```js -command[4] E(home.localTimerService).makeNotifier(5_000n, 10_000n) -history[4] [Alleged: presence o-129]{} -command[5] E(history[4]).getUpdateSince() -history[5] {"updateCount":1,"value":1632163863000n} -``` - -## Advanced TimerService objects - -These are more complex objects that are only used for the following advanced methods. - -### `TimerWaker` object - -A `TimerWaker` has one method, `wake()` -- `wake(timestamp)` - - `timestamp` `{ Timestamp }` - - Returns `{ void }` - - The provided `timestamp` is the time for which the call to `wake()` was scheduled. - -### `TimerRepeater` object - -A `TimerRepeater` has an associated interval and two methods, `schedule()` and `disable()`: -- `schedule(waker)` - - `waker` `{ TimerWaker }` - - Returns `{ Timestamp }` - - The `waker` argument is any object with a `wake()` method. Returns the - time indicating the time the waker is next scheduled to be called. The waker continues - to be scheduled every interval until the repeater is disabled. -- `disable()` - - Returns `{ void }` - - Disables this repeater, so `schedule()` can't be called again and wakers already - scheduled with this repeater won't be rescheduled after they are called. - -## Advanced TimerService methods - -### `E(home.TimerService).setWakeup(baseTime, waker)` -- `baseTime` `{ Timestamp }` -- `waker` `{ TimerWaker }` -- Returns: `{ Promise }` - -Calls the specified `waker` when the current timestamp is at least `baseTime`. -**NOTE: `baseTime` is an absolute, not relative time.** - -Returns a promise that resolves with the time at which the call is scheduled to happen. - -```js -command[3] handler = harden({ wake: now => { console.log(`woke up ${now}`); }}) -history[3] {"wake":[Function wake]} -command[4] willWakeAt = E(home.localTimerService).setWakeup(1632170399207n + 3_000n, handler) -history[4] 1632170402207n -// Written to console a few seconds later -woke up 1632170402207n -``` - -### `E(home.TimerService).removeWakeup(waker)` -- `waker` `{ TimerWaker }` -- Returns: `{ Promise }` - -Cancels all scheduled wakeups of the specified `waker`, whether -created by `setWakeup()` or `repeater.schedule()`. - -Returns a promise for an array of Timestamps representing when the cancelled wakeup calls were scheduled to happen. - -```js -command[5] timeList = E(home.localTimerService).removeWakeup(handler) -history[5] unresolved Promise -``` - -### `E(home.TimerService).makeRepeater(delay, interval)` -- `delay`: `{ RelativeTime }` -- `interval`: `{ RelativeTime }` -- Returns: `{ Promise }` - -Creates a `Repeater` object and returns a promise that resolves with it. -The repeater schedules `wake()` calls repeatedly at -times that are a multiple of the specified `interval`, with the first update happening -after the specified `delay` has elapsed. Since block times are coarse-grained, -the actual calls when using `chainTimerService` may occur less frequently than the specified -`interval`. -```js -command[6] E(home.localTimerService).makeRepeater(5_000n, 10_000n) -history[6] [Alleged: presence o-124]{} -``` - -A longer example of creating and using Repeaters: - -```js -command[3] makeWakeCounter = () => { - let count = 0; - return Far('counter', { getCount() { return count; }, wake(_t) { count += 1; }, }); -} -history[3] [Function makeWakeCounter] -command[4] c1 = makeWakeCounter() -history[4] [Object Alleged: counter]{"getCount":[Function getCount],"wake":[Function wake]} -command[5] c2 = makeWakeCounter() -history[5] [Object Alleged: counter]{"getCount":[Function getCount],"wake":[Function wake]} -command[6] tl = home.localTimerService -history[6] [Object Alleged: timerService]{} -command[7] tc = home.chainTimerService -history[7] [Object Alleged: timerService]{} -command[8] rl = E(tl).makeRepeater(7n, 1500n) -history[8] [Object Alleged: vatRepeater]{} -command[9] rc = E(tc).makeRepeater(7n, 15n) -history[9] [Object Alleged: vatRepeater]{} -command[10] E(rl).schedule(c1) -history[10] 1571783040007n -command[11] E(rc).schedule(c2) -history[11] 1571783051n -... -command[22] E(tl).getCurrentTimestamp().then(t => [t, c1.getCount()]) -history[22] [1571783069041n,20] -command[23] E(tc).getCurrentTimestamp().then(t => [t, c2.getCount()]) -history[23] [1571783070n,2] -``` +See package [@agoric/time](https://agoric-sdk.pages.dev/modules/_agoric_time) for details.