Skip to content

Commit

Permalink
docs: improved TimerService type documentation for auto-gen docs (#9131)
Browse files Browse the repository at this point in the history
* docs: improved TimerService type documentation for auto-gen docs

* docs: correct types to brands in one place

* docs: improvements from review

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
Chris-Hibbert and mergify[bot] authored Mar 25, 2024
1 parent 5c28f49 commit 247cc9b
Showing 1 changed file with 51 additions and 4 deletions.
55 changes: 51 additions & 4 deletions packages/time/src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import type { RankComparison } from '@endo/marshal';
// meant to be globally accessible as a side-effect of importing this module.
/**
* The TimerBrand is a unique object that represents the kind of Time
* used in Timestamp/RelativeTime records. Time from different sources
* is not comparable.
* used in Timestamp/RelativeTime records. Times from different sources
* are not comparable.
*
* Do not call `isMyTimerService(myTimerService)` on an untrusted
* brand, because that will leak your closely-held timer authority. If
* the goal is to check the suitability of a client-provided
* Timestamp, use coerceTimestampRecord() or add/subtract it to a
* known-good Timestamp, or extact its brand and === against
* known-good Timestamp, or extract its brand and === against
* `timerService.getTimerBrand()`.
*
* TODO Not all Timestamps are labeled with the TimerBrand (in much
Expand Down Expand Up @@ -52,11 +52,21 @@ export type TimestampValue = bigint;
*/
export type RelativeTimeValue = bigint;

/**
* The canonical representation of a typed absolute time. It bundles the brand
* with the time, as represented by a TimerService, which might represent time
* since the epoch, or blockheight on a particular chain.
*/
export type TimestampRecord = {
timerBrand: TimerBrand;
absValue: bigint;
};

/**
* The canonical representation of a typed relative time. It bundles the brand
* with an elapsed time, as represented by a TimerService, which might represent
* time since the epoch, or blockheight on a particular chain.
*/
export type RelativeTimeRecord = {
timerBrand: TimerBrand;
relValue: bigint;
Expand Down Expand Up @@ -87,7 +97,8 @@ export type RelativeTime = RelativeTimeRecord | RelativeTimeValue;
/**
* A CancelToken is an arbitrary marker object, passed in with
* each API call that creates a wakeup or repeater, and passed to
* cancel() to cancel them all.
* cancel() to cancel them all. Multiple wakeups can rely on the same
* CancelToken so they can be cancelled collectively.
*/
export type CancelToken = object;

Expand Down Expand Up @@ -171,6 +182,11 @@ export interface TimerService {
getTimerBrand: () => TimerBrand;
}

/**
* Read-only access to a TimeService's current time. This allows reading the
* current time (e.g. to see if a deadline has passed) without the ability to
* schedule events.
*/
export interface Clock {
/**
* Retrieve the latest timestamp
Expand All @@ -182,6 +198,11 @@ export interface Clock {
getTimerBrand: () => TimerBrand;
}

/**
* The interface that must be implemented by objects which are to be invoked at
* scheduled times. Used by `TimerService.repeatAfter()`,
* `TimerService.setWakeup()`, and `TimerRepeater.schedule()`.
*/
export interface TimerWaker {
/**
* The timestamp passed to `wake()` is the time that the call was scheduled
Expand All @@ -190,6 +211,12 @@ export interface TimerWaker {
wake: (timestamp: TimestampRecord) => void;
}

/**
* Provides the ability to schedule wake() calls repeatedly at a regular
* interval, or to disable all future use of this TimerRepeater. Created by the
* deprecated makeRepeater(), new code should use repeatAfter(), which doesn't
* have a control object and doesn't require a second schedule step
*/
export interface TimerRepeater {
/**
* Returns the time scheduled for
Expand All @@ -205,6 +232,26 @@ export interface TimerRepeater {
disable: () => void;
}

/**
* TimeMath supports simple arithmetic on typed Time values, enforcing that
* values are combined in type-compatible ways. You can add 3 minutes to 3pm,
* or 5 minutes to a half hour, but it makes no sense to add 3pm and 5pm.
* Subtracting two Timestamps does produce a useful difference.
*
* The brands prevent you from accidentally combining time values from different
* TimerServices. Some chains track time in blocks, others follow wall clock
* time, some do both. Every local computer has its own unique notion of wall
* clock time. Even when these clocks are talking about the same thing (UTC),
* they can all drift in different ways. Using the correct brands lets you be
* precise about which particular source of time you mean, preventing confusion
* or attacks when the clocks diverge. Thus it is an error to e.g. use a time
* you got from chain A to schedule an event on chain B.
*
* The basic types are `RelativeTimeRecord` (durations) and `TimestampRecord`. The numeric
* values can be extracted from the typed values, but it's usually better to
* maintain values as their canonical typed form so these operations can be
* applied.
*/
export type TimeMathType = {
/**
* Validates that the operand represents a `Timestamp` and returns the bigint
Expand Down

0 comments on commit 247cc9b

Please sign in to comment.