Takes into account that <<earliest>> block available is not necessarily the genesis block

This commit is contained in:
Marcin Czenko 2024-10-09 18:55:10 +02:00
parent a6ffc65ea3
commit ea0f967596
No known key found for this signature in database
GPG Key ID: 33DEA0C8E30937C0
2 changed files with 25 additions and 12 deletions

View File

@ -432,7 +432,7 @@ proc binarySearchFindClosestBlock*(provider: Provider,
await provider.blockNumberAndTimestamp(BlockTag.init(low))
let (_, highTimestamp) =
await provider.blockNumberAndTimestamp(BlockTag.init(high))
trace "[binarySearchFindClosestBlock]:", epochTime = epochTime,
debug "[binarySearchFindClosestBlock]:", epochTime = epochTime,
lowTimestamp = lowTimestamp, highTimestamp = highTimestamp, low = low, high = high
if abs(lowTimestamp.truncate(int) - epochTime) <
abs(highTimestamp.truncate(int) - epochTime):
@ -442,9 +442,10 @@ proc binarySearchFindClosestBlock*(provider: Provider,
proc binarySearchBlockNumberForEpoch*(provider: Provider,
epochTime: UInt256,
latestBlockNumber: UInt256):
latestBlockNumber: UInt256,
earliestBlockNumber: UInt256):
Future[UInt256] {.async.} =
var low = 0.u256
var low = earliestBlockNumber
var high = latestBlockNumber
debug "[binarySearchBlockNumberForEpoch]:", low = low, high = high
@ -472,18 +473,22 @@ proc blockNumberForEpoch*(provider: Provider, epochTime: int64): Future[UInt256]
let epochTimeUInt256 = epochTime.u256
let (latestBlockNumber, latestBlockTimestamp) =
await provider.blockNumberAndTimestamp(BlockTag.latest)
let (earliestBlockNumber, earliestBlockTimestamp) =
await provider.blockNumberAndTimestamp(BlockTag.earliest)
debug "[blockNumberForEpoch]:", latestBlockNumber = latestBlockNumber,
latestBlockTimestamp = latestBlockTimestamp
debug "[blockNumberForEpoch]:", earliestBlockNumber = earliestBlockNumber,
earliestBlockTimestamp = earliestBlockTimestamp
let timeDiff = latestBlockTimestamp - epochTimeUInt256
let blockDiff = timeDiff div avgBlockTime
if blockDiff >= latestBlockNumber:
return 0.u256
if blockDiff >= latestBlockNumber - earliestBlockNumber:
return earliestBlockNumber
return await provider.binarySearchBlockNumberForEpoch(
epochTimeUInt256, latestBlockNumber)
epochTimeUInt256, latestBlockNumber, earliestBlockNumber)
method queryPastSlotFilledEvents*(
market: OnChainMarket,

View File

@ -512,17 +512,25 @@ ethersuite "On-Chain Market":
check expected == simulatedBlockTime
check actual == expected
test "blockNumberForEpoch returns the earliest block when block height " &
"is less than the given epoch time":
let (_, timestampEarliest) =
test "blockNumberForEpoch returns the earliest block when retained history " &
"is shorter than the given epoch time":
# create predictable conditions for computing average block time
let averageBlockTime = 10.u256
await ethProvider.mineNBlocks(1)
await ethProvider.advanceTime(averageBlockTime)
let (earliestBlockNumber, earliestTimestamp) =
await ethProvider.blockNumberAndTimestamp(BlockTag.earliest)
let fromTime = timestampEarliest - 1
let fromTime = earliestTimestamp - 1
let expected = await ethProvider.blockNumberForEpoch(
let actual = await ethProvider.blockNumberForEpoch(
fromTime.truncate(int64))
check expected == 0.u256
# Notice this could fail in a network where "earliest" block is
# not the genesis block - we run the tests agains local network
# so we know the earliest block is the same as genesis block
# earliestBlockNumber is 0.u256 in our case.
check actual == earliestBlockNumber
test "blockNumberForEpoch finds closest blockNumber for given epoch time":
proc createBlockHistory(n: int, blockTime: int):