sales: wait for stable proof challenge

When the block pointer is nearing the
wrap-around point, we wait another period
before calculating a proof.
This commit is contained in:
Mark Spanbroek 2024-02-22 16:27:56 +01:00
parent 5223fe22d1
commit b8dd2543dc
No known key found for this signature in database
GPG Key ID: FBE3E9548D427C00
3 changed files with 41 additions and 13 deletions

View File

@ -23,6 +23,19 @@ method onCancelled*(state: SaleInitialProving, request: StorageRequest): ?State
method onFailed*(state: SaleInitialProving, request: StorageRequest): ?State =
return some State(SaleFailed())
proc waitUntilNextPeriod(clock: Clock, periodicity: Periodicity) {.async.} =
trace "Waiting until next period"
let period = periodicity.periodOf(clock.now().u256)
let periodEnd = periodicity.periodEnd(period).truncate(int64)
await clock.waitUntil(periodEnd + 1)
proc waitForStableChallenge(market: Market, clock: Clock, slotId: SlotId) {.async.} =
let periodicity = await market.periodicity()
let downtime = await market.proofDowntime()
await clock.waitUntilNextPeriod(periodicity)
while (await market.getPointer(slotId)) > (256 - downtime):
await clock.waitUntilNextPeriod(periodicity)
method run*(state: SaleInitialProving, machine: Machine): Future[?State] {.async.} =
let data = SalesAgent(machine).data
let context = SalesAgent(machine).context
@ -35,15 +48,12 @@ method run*(state: SaleInitialProving, machine: Machine): Future[?State] {.async
without onProve =? context.onProve:
raiseAssert "onProve callback not set"
debug "Waiting until next period"
let periodicity = await market.periodicity()
let period = periodicity.periodOf(clock.now().u256)
await clock.waitUntil(periodicity.periodEnd(period).truncate(int64) + 1)
debug "Waiting for a proof challenge that is valid for the entire period"
let slot = Slot(request: request, slotIndex: data.slotIndex)
await waitForStableChallenge(market, clock, slot.id)
debug "Generating initial proof", requestId = data.requestId
let
slot = Slot(request: request, slotIndex: data.slotIndex)
challenge = await context.market.getChallenge(slot.id)
let challenge = await context.market.getChallenge(slot.id)
without proof =? (await onProve(slot, challenge)), err:
error "Failed to generate initial proof", error = err.msg
return some State(SaleErrored(error: err))

View File

@ -29,6 +29,7 @@ type
markedAsMissingProofs*: seq[SlotId]
canBeMarkedAsMissing: HashSet[SlotId]
withdrawn*: seq[RequestId]
proofPointer*: uint8
proofsRequired: HashSet[SlotId]
proofsToBeRequired: HashSet[SlotId]
proofChallenge*: ProofChallenge
@ -117,7 +118,7 @@ method proofDowntime*(market: MockMarket): Future[uint8] {.async.} =
return market.config.proofs.downtime
method getPointer*(market: MockMarket, slotId: SlotId): Future[uint8] {.async.} =
return 0 # TODO
return market.proofPointer
method requestStorage*(market: MockMarket, request: StorageRequest) {.async.} =
market.requested.add(request)

View File

@ -57,13 +57,22 @@ asyncchecksuite "sales state 'initialproving'":
let next = state.onFailed(request)
check !next of SaleFailed
test "switches to filling state when initial proving is complete":
test "waits for the beginning of the period to get the challenge":
let future = state.run(agent)
await sleepAsync(10.millis)
check not future.finished
await allowProofToStart()
discard await future
test "waits another period when the proof pointer is about to wrap around":
market.proofPointer = 250
let future = state.run(agent)
await allowProofToStart()
let next = await future
check !next of SaleFilling
check SaleFilling(!next).proof == proof
await sleepAsync(10.millis)
check not future.finished
market.proofPointer = 100
await allowProofToStart()
discard await future
test "onProve callback provides proof challenge":
market.proofChallenge = ProofChallenge.example
@ -75,6 +84,14 @@ asyncchecksuite "sales state 'initialproving'":
check receivedChallenge == market.proofChallenge
test "switches to filling state when initial proving is complete":
let future = state.run(agent)
await allowProofToStart()
let next = await future
check !next of SaleFilling
check SaleFilling(!next).proof == proof
test "switches to errored state when onProve callback fails":
let onProveFailed: OnProve = proc(slot: Slot, challenge: ProofChallenge): Future[?!Groth16Proof] {.async.} =
return failure("oh no!")