Created
March 21, 2019 13:40
-
-
Save arnetheduck/652a6823e5cec510f8572895d850bbee to your computer and use it in GitHub Desktop.
starting point, beacon clock
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import | |
chronos, | |
spec/[datatypes] | |
type | |
ChronosTime* = uint64 | |
## Unix epoch timestamp in millisecond resolution | |
# TODO fetch from chronos and make distinct | |
ChronosClock* = object | |
## The chronos clock follows unix time but measures time in milliseconds | |
## genesis for the chronos clock is constant and the same as normal unix. | |
## It is currently broken, in the sense that it should be using a monotonic | |
## clock, since | |
BeaconClock* = object | |
genesis: ChronosTime | |
## The beacon clock represents time as it passes on a beacon chain. Beacon | |
## time is locked to unix time, starting at a particular offset set during | |
## beacon chain instantiation. | |
## | |
## Time on the beacon chain determines what actions should be taken and | |
## which blocks are valid - in particular, blocks are not valid if they | |
## come from the future as seen from the local clock. | |
## | |
## https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#beacon-chain-processing | |
## | |
# TODO replace time in chronos with a proper unit type, then this code can | |
# follow: | |
# https://github.com/status-im/nim-chronos/issues/15 | |
# TODO consider NTP and network-adjusted timestamps as outlined here: | |
# https://ethresear.ch/t/network-adjusted-timestamps/4187 | |
const | |
chronosPerSecond* = 1000'u64 | |
chronosPerSlot* = chronosPerSecond * SECONDS_PER_SLOT ## Chronos time units per slot | |
func now*(T: type ChronosClock): ChronosTime = chronos.fastEpochTime() | |
func init*(T: type BeaconClock, state: BeaconState): T = | |
## Initialize time from a beacon state. The genesis time of a beacon state is | |
## constant throughout its lifetime, so the state from any slot will do, | |
## including the genesis state. | |
let | |
ctGenesis = ChronosTime(state.genesis_time * chronosPerSecond) | |
# GENESIS_SLOT offsets slot time, but to simplify calculations, we apply that | |
# offset to genesis instead of applying it at every time conversion | |
ctGenesisSlotOffset = GENESIS_SLOT * chronosPerSlot | |
doAssert ctGenesis > ctGenesisSlotOffset, | |
"Genesis underflow, fix BeaconClock" | |
T(genesis: ctGenesis - ctGenesisSlotOffset) | |
func toSlot*(c: BeaconClock, t: ChronosTime): Slot = | |
doAssert t > c.genesis, | |
"Cannot represent time before genesis, fix BeaconClock" | |
Slot((t - c.genesis) div chronosPerSlot) | |
func toChronosTime*(c: BeaconClock, s: Slot): ChronosTime = | |
ChronosTime(s.uint64 * chronosPerSlot + c.genesis) | |
func now*(c: BeaconClock): Slot = | |
## Current time, in slots - this may end up being less than GENESIS_SLOT(!) | |
toSlot(c, ChronosClock.now()) | |
func slotStart*(c: BeaconClock, slot: Slot): ChronosTime = | |
c.toChronosTime(slot) | |
func slotMiddle*(c: BeaconClock, slot: Slot): ChronosTime = | |
c.toChronosTime(slot) + (chronosPerSlot div 2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment