[proving] Use clock instead of getPeriod() and waitUntilPeriod()

This commit is contained in:
Mark Spanbroek 2022-05-18 11:18:25 +02:00 committed by markspanbroek
parent 09a7aa3eed
commit cdcab43590
6 changed files with 13 additions and 63 deletions

View File

@ -22,16 +22,6 @@ method periodicity*(proofs: OnChainProofs): Future[Periodicity] {.async.} =
let period = await proofs.storage.proofPeriod()
return Periodicity(seconds: period)
method getCurrentPeriod*(proofs: OnChainProofs): Future[Period] {.async.} =
let periodicity = await proofs.periodicity()
let blk = !await proofs.storage.provider.getBlock(BlockTag.latest)
return periodicity.periodOf(blk.timestamp)
method waitUntilPeriod*(proofs: OnChainProofs,
period: Period) {.async.} =
while (await proofs.getCurrentPeriod()) < period:
await sleepAsync(proofs.pollInterval)
method isProofRequired*(proofs: OnChainProofs,
id: ContractId): Future[bool] {.async.} =
return await proofs.storage.isProofRequired(id)

View File

@ -17,14 +17,6 @@ method periodicity*(proofs: Proofs):
Future[Periodicity] {.base, async.} =
raiseAssert("not implemented")
method getCurrentPeriod*(proofs: Proofs):
Future[Period] {.base, async.} =
raiseAssert("not implemented")
method waitUntilPeriod*(proofs: Proofs,
period: Period) {.base, async.} =
raiseAssert("not implemented")
method isProofRequired*(proofs: Proofs,
id: ContractId): Future[bool] {.base, async.} =
raiseAssert("not implemented")

View File

@ -26,6 +26,14 @@ proc `onProofRequired=`*(proving: Proving, callback: OnProofRequired) =
func add*(proving: Proving, id: ContractId) =
proving.contracts.incl(id)
proc getCurrentPeriod(proving: Proving): Future[Period] {.async.} =
let periodicity = await proving.proofs.periodicity()
return periodicity.periodOf(proving.clock.now().u256)
proc waitUntilPeriod(proving: Proving, period: Period) {.async.} =
let periodicity = await proving.proofs.periodicity()
await proving.clock.waitUntil(periodicity.periodStart(period).truncate(int64))
proc removeEndedContracts(proving: Proving) {.async.} =
let now = proving.clock.now().u256
var ended: HashSet[ContractId]
@ -37,14 +45,14 @@ proc removeEndedContracts(proving: Proving) {.async.} =
proc run(proving: Proving) {.async.} =
try:
while true:
let currentPeriod = await proving.proofs.getCurrentPeriod()
let currentPeriod = await proving.getCurrentPeriod()
await proving.removeEndedContracts()
for id in proving.contracts:
if (await proving.proofs.isProofRequired(id)) or
(await proving.proofs.willProofBeRequired(id)):
if callback =? proving.onProofRequired:
callback(id)
await proving.proofs.waitUntilPeriod(currentPeriod + 1)
await proving.waitUntilPeriod(currentPeriod + 1)
except CatchableError as e:
error "Proving failed", msg = e.msg

View File

@ -21,25 +21,6 @@ ethersuite "On-Chain Proofs":
let periodLength = await storage.proofPeriod()
check periodicity.seconds == periodLength
test "supports waiting until next period":
let periodicity = await proofs.periodicity()
let currentPeriod = await proofs.getCurrentPeriod()
let pollInterval = 200.milliseconds
proofs.pollInterval = pollInterval
proc waitForPoll {.async.} =
await sleepAsync(pollInterval * 2)
let future = proofs.waitUntilPeriod(currentPeriod + 1)
check not future.completed
await provider.advanceTimeTo(periodicity.periodEnd(currentPeriod))
await waitForPoll()
check future.completed
test "supports checking whether proof is required now":
check (await proofs.isProofRequired(contractId)) == false

View File

@ -7,8 +7,6 @@ import pkg/dagger/por/timing/proofs
type
MockProofs* = ref object of Proofs
periodicity: Periodicity
currentPeriod: Period
waiting: Table[Period, seq[Future[void]]]
proofsRequired: HashSet[ContractId]
proofsToBeRequired: HashSet[ContractId]
proofEnds: Table[ContractId, UInt256]
@ -58,25 +56,6 @@ method getProofEnd*(mock: MockProofs,
else:
return UInt256.high
proc advanceToPeriod*(mock: MockProofs, period: Period) =
doAssert period >= mock.currentPeriod
for key in mock.waiting.keys:
if key <= period:
for future in mock.waiting[key]:
future.complete()
mock.waiting[key] = @[]
method getCurrentPeriod*(mock: MockProofs): Future[Period] {.async.} =
return mock.currentPeriod
method waitUntilPeriod*(mock: MockProofs, period: Period) {.async.} =
if period > mock.currentPeriod:
let future = Future[void]()
if not mock.waiting.hasKey(period):
mock.waiting[period] = @[]
mock.waiting[period].add(future)
await future
method submitProof*(mock: MockProofs,
id: ContractId,
proof: seq[byte]) {.async.} =

View File

@ -21,9 +21,9 @@ suite "Proving":
await proving.stop()
proc advanceToNextPeriod(proofs: MockProofs) {.async.} =
let current = await proofs.getCurrentPeriod()
proofs.advanceToPeriod(current + 1)
await sleepAsync(1.milliseconds)
let periodicity = await proofs.periodicity()
clock.advance(periodicity.seconds.truncate(int64))
await sleepAsync(2.seconds)
test "maintains a list of contract ids to watch":
let id1, id2 = ContractId.example