clock: fix on-chain clock for hardhat

Only use 'latest' block for updates
Only update the first time you see a block
This commit is contained in:
Mark Spanbroek 2024-03-03 06:45:12 +01:00
parent 6915f134c8
commit 1067908b02
No known key found for this signature in database
GPG Key ID: FBE3E9548D427C00
2 changed files with 23 additions and 8 deletions

View File

@ -15,24 +15,39 @@ type
provider: Provider
subscription: Subscription
offset: times.Duration
blockNumber: UInt256
started: bool
newBlock: AsyncEvent
proc new*(_: type OnChainClock, provider: Provider): OnChainClock =
OnChainClock(provider: provider, newBlock: newAsyncEvent())
proc update(clock: OnChainClock, blck: Block) =
if number =? blck.number and number > clock.blockNumber:
let blockTime = initTime(blck.timestamp.truncate(int64), 0)
let computerTime = getTime()
clock.offset = blockTime - computerTime
clock.blockNumber = number
trace "updated clock", blockTime=blck.timestamp, blockNumber=number, offset=clock.offset
clock.newBlock.fire()
proc update(clock: OnChainClock) {.async.} =
try:
if latest =? (await clock.provider.getBlock(BlockTag.latest)):
clock.update(latest)
except CatchableError as error:
debug "error updating clock: ", error=error.msg
discard
method start*(clock: OnChainClock) {.async.} =
if clock.started:
return
proc onBlock(blck: Block) =
let blockTime = initTime(blck.timestamp.truncate(int64), 0)
let computerTime = getTime()
clock.offset = blockTime - computerTime
clock.newBlock.fire()
proc onBlock(_: Block) =
# ignore block parameter; hardhat may call this with pending blocks
asyncSpawn clock.update()
if latestBlock =? (await clock.provider.getBlock(BlockTag.latest)):
onBlock(latestBlock)
await clock.update()
clock.subscription = await clock.provider.subscribe(onBlock)
clock.started = true

View File

@ -23,7 +23,7 @@ ethersuite "On-Chain Clock":
let future = (getTime() + 42.years).toUnix
discard await ethProvider.send("evm_setNextBlockTimestamp", @[%future])
discard await ethProvider.send("evm_mine")
check clock.now() == future
check eventually clock.now() == future
test "can wait until a certain time is reached by the chain":
let future = clock.now() + 42 # seconds