[clock] waitUntil() completes immediately when block arrives (#475)

Previously it could take up to one second to complete
the future. This messed with the timings in the
integration tests and made them less predictable.
This commit is contained in:
markspanbroek 2023-07-13 11:19:45 +02:00 committed by GitHub
parent 6dd7e55719
commit 3879ec8e3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 25 additions and 7 deletions

View File

@ -10,9 +10,8 @@ type
method now*(clock: Clock): SecondsSince1970 {.base, upraises: [].} =
raiseAssert "not implemented"
method waitUntil*(clock: Clock, time: SecondsSince1970) {.base,async.} =
while clock.now() < time:
await sleepAsync(1.seconds)
method waitUntil*(clock: Clock, time: SecondsSince1970) {.base, async.} =
raiseAssert "not implemented"
proc withTimeout*(future: Future[void],
clock: Clock,

View File

@ -12,9 +12,10 @@ type
subscription: Subscription
offset: times.Duration
started: bool
newBlock: AsyncEvent
proc new*(_: type OnChainClock, provider: Provider): OnChainClock =
OnChainClock(provider: provider)
OnChainClock(provider: provider, newBlock: newAsyncEvent())
proc start*(clock: OnChainClock) {.async.} =
if clock.started:
@ -25,6 +26,7 @@ proc start*(clock: OnChainClock) {.async.} =
let blockTime = initTime(blck.timestamp.truncate(int64), 0)
let computerTime = getTime()
clock.offset = blockTime - computerTime
clock.newBlock.fire()
if latestBlock =? (await clock.provider.getBlock(BlockTag.latest)):
await onBlock(latestBlock)
@ -41,3 +43,8 @@ proc stop*(clock: OnChainClock) {.async.} =
method now*(clock: OnChainClock): SecondsSince1970 =
doAssert clock.started, "clock should be started before calling now()"
toUnix(getTime() + clock.offset)
method waitUntil*(clock: OnChainClock, time: SecondsSince1970) {.async.} =
while (let difference = time - clock.now(); difference > 0):
clock.newBlock.clear()
discard await clock.newBlock.wait().withTimeout(chronos.seconds(difference))

View File

@ -29,6 +29,18 @@ ethersuite "On-Chain Clock":
await sleepAsync(chronos.seconds(1))
check clock.now() > past
test "can wait until a certain time is reached by the chain":
let future = clock.now() + 42 # seconds
let waiting = clock.waitUntil(future)
discard await provider.send("evm_setNextBlockTimestamp", @[%future])
discard await provider.send("evm_mine")
check await waiting.withTimeout(chronos.milliseconds(100))
test "can wait until a certain time is reached by the wall-clock":
let future = clock.now() + 1 # seconds
let waiting = clock.waitUntil(future)
check await waiting.withTimeout(chronos.seconds(2))
test "raises when not started":
expect AssertionDefect:
discard OnChainClock.new(provider).now()

View File

@ -94,7 +94,7 @@ twonodessuite "Proving integration test", debug1=false, debug2=false:
break
else:
await advanceToNextPeriod()
await sleepAsync(1.seconds)
await sleepAsync(100.milliseconds)
check slotWasFreed
@ -186,7 +186,7 @@ multinodesuite "Simulate invalid proofs",
break
else:
await advanceToNextPeriod()
await sleepAsync(1.seconds)
await sleepAsync(100.milliseconds)
check slotWasFreed
@ -210,7 +210,7 @@ multinodesuite "Simulate invalid proofs",
break
else:
await advanceToNextPeriod()
await sleepAsync(1.seconds)
await sleepAsync(100.milliseconds)
check not slotWasFreed