2022-05-16 13:38:52 +00:00
|
|
|
import std/times
|
|
|
|
import pkg/ethers
|
|
|
|
import pkg/chronos
|
|
|
|
import pkg/stint
|
2022-05-17 09:50:52 +00:00
|
|
|
import ../clock
|
2022-05-16 13:38:52 +00:00
|
|
|
|
2022-05-17 14:42:03 +00:00
|
|
|
export clock
|
|
|
|
|
2022-05-16 13:38:52 +00:00
|
|
|
type
|
2022-05-17 09:50:52 +00:00
|
|
|
OnChainClock* = ref object of Clock
|
2022-05-16 13:38:52 +00:00
|
|
|
provider: Provider
|
|
|
|
subscription: Subscription
|
2022-09-29 08:47:20 +00:00
|
|
|
offset: float
|
2022-05-16 13:38:52 +00:00
|
|
|
started: bool
|
|
|
|
|
2022-05-17 09:50:52 +00:00
|
|
|
proc new*(_: type OnChainClock, provider: Provider): OnChainClock =
|
|
|
|
OnChainClock(provider: provider)
|
2022-05-16 13:38:52 +00:00
|
|
|
|
2022-05-17 09:50:52 +00:00
|
|
|
proc start*(clock: OnChainClock) {.async.} =
|
2022-05-16 13:38:52 +00:00
|
|
|
if clock.started:
|
|
|
|
return
|
|
|
|
clock.started = true
|
|
|
|
|
2022-06-02 22:09:53 +00:00
|
|
|
proc onBlock(blck: Block) {.async, upraises:[].} =
|
2022-09-29 08:47:20 +00:00
|
|
|
let blockTime = blck.timestamp.truncate(int64).float
|
|
|
|
let computerTime = epochTime()
|
2022-05-16 13:38:52 +00:00
|
|
|
clock.offset = blockTime - computerTime
|
|
|
|
|
2022-05-17 17:49:39 +00:00
|
|
|
if latestBlock =? (await clock.provider.getBlock(BlockTag.latest)):
|
2022-06-02 22:09:53 +00:00
|
|
|
await onBlock(latestBlock)
|
2022-05-16 13:38:52 +00:00
|
|
|
|
|
|
|
clock.subscription = await clock.provider.subscribe(onBlock)
|
|
|
|
|
2022-05-17 09:50:52 +00:00
|
|
|
proc stop*(clock: OnChainClock) {.async.} =
|
2022-05-16 13:38:52 +00:00
|
|
|
if not clock.started:
|
|
|
|
return
|
|
|
|
clock.started = false
|
|
|
|
|
|
|
|
await clock.subscription.unsubscribe()
|
|
|
|
|
2022-05-17 09:50:52 +00:00
|
|
|
method now*(clock: OnChainClock): SecondsSince1970 =
|
2022-05-16 13:38:52 +00:00
|
|
|
doAssert clock.started, "clock should be started before calling now()"
|
2022-09-29 08:47:20 +00:00
|
|
|
int64(epochTime() + clock.offset)
|