2018-11-23 23:58:49 +00:00
|
|
|
import
|
2018-11-29 01:08:34 +00:00
|
|
|
random,
|
2019-02-06 17:56:04 +00:00
|
|
|
chronos,
|
2019-02-15 16:33:32 +00:00
|
|
|
spec/[datatypes, helpers]
|
2018-11-23 23:58:49 +00:00
|
|
|
|
|
|
|
type
|
2018-12-19 12:58:53 +00:00
|
|
|
Timestamp* = uint64 # Unix epoch timestamp in millisecond resolution
|
2018-11-23 23:58:49 +00:00
|
|
|
|
|
|
|
var
|
|
|
|
detectedClockDrift: int64
|
|
|
|
|
2018-12-19 12:58:53 +00:00
|
|
|
template now*: auto = fastEpochTime()
|
|
|
|
|
2019-01-25 17:35:22 +00:00
|
|
|
# TODO underflow when genesis has not yet happened!
|
2018-11-23 23:58:49 +00:00
|
|
|
proc timeSinceGenesis*(s: BeaconState): Timestamp =
|
|
|
|
Timestamp(int64(fastEpochTime() - s.genesis_time * 1000) -
|
|
|
|
detectedClockDrift)
|
|
|
|
|
2019-02-07 15:38:46 +00:00
|
|
|
proc getSlotFromTime*(s: BeaconState, t = now()): SlotNumber =
|
|
|
|
GENESIS_SLOT + uint64((int64(t - s.genesis_time * 1000) - detectedClockDrift) div
|
2019-02-19 23:07:56 +00:00
|
|
|
int64(SECONDS_PER_SLOT * 1000))
|
2018-11-23 23:58:49 +00:00
|
|
|
|
2019-02-15 16:33:32 +00:00
|
|
|
func slotStart*(s: BeaconState, slot: SlotNumber): Timestamp =
|
2019-02-19 23:07:56 +00:00
|
|
|
(s.genesis_time + (slot * SECONDS_PER_SLOT)) * 1000
|
2018-11-23 23:58:49 +00:00
|
|
|
|
2019-02-15 16:33:32 +00:00
|
|
|
func slotMiddle*(s: BeaconState, slot: SlotNumber): Timestamp =
|
2019-02-19 23:07:56 +00:00
|
|
|
s.slotStart(slot) + SECONDS_PER_SLOT * 500
|
2018-11-23 23:58:49 +00:00
|
|
|
|
2019-02-15 16:33:32 +00:00
|
|
|
func slotEnd*(s: BeaconState, slot: SlotNumber): Timestamp =
|
|
|
|
# TODO this is actually past the end, by nim inclusive semantics (sigh)
|
2018-11-23 23:58:49 +00:00
|
|
|
s.slotStart(slot + 1)
|
|
|
|
|
|
|
|
proc randomTimeInSlot*(s: BeaconState,
|
2019-02-15 16:33:32 +00:00
|
|
|
slot: SlotNumber,
|
2018-11-23 23:58:49 +00:00
|
|
|
interval: HSlice[float, float]): Timestamp =
|
|
|
|
## Returns a random moment within the slot.
|
|
|
|
## The interval must be a sub-interval of [0..1].
|
|
|
|
## Zero marks the begginning of the slot and One marks the end.
|
2019-02-19 23:07:56 +00:00
|
|
|
s.slotStart(slot) + Timestamp(rand(interval) * float(SECONDS_PER_SLOT * 1000))
|
2018-11-23 23:58:49 +00:00
|
|
|
|
|
|
|
proc slotDistanceFromNow*(s: BeaconState): int64 =
|
|
|
|
## Returns how many slots have passed since a particular BeaconState was finalized
|
2019-02-15 16:33:32 +00:00
|
|
|
int64(s.getSlotFromTime() - s.finalized_epoch.get_epoch_start_slot)
|
2018-11-23 23:58:49 +00:00
|
|
|
|
2019-01-25 17:35:22 +00:00
|
|
|
proc synchronizeClock*() {.async.} =
|
2018-11-23 23:58:49 +00:00
|
|
|
## This should determine the offset of the local clock against a global
|
|
|
|
## trusted time (e.g. it can be obtained from multiple time servers).
|
|
|
|
|
|
|
|
# TODO: implement this properly
|
|
|
|
detectedClockDrift = 0
|
|
|
|
|