mirror of
https://github.com/codex-storage/nim-codex.git
synced 2025-01-31 15:16:12 +00:00
sales: calculate initial proof at start of period
reason: this ensures that the period (and therefore the challenge) doesn't change while we're calculating the proof
This commit is contained in:
parent
2a1ef5d9e6
commit
0aa7590c96
@ -1,4 +1,5 @@
|
||||
import pkg/questionable/results
|
||||
import ../../clock
|
||||
import ../../logutils
|
||||
import ../statemachine
|
||||
import ../salesagent
|
||||
@ -25,6 +26,8 @@ method onFailed*(state: SaleInitialProving, request: StorageRequest): ?State =
|
||||
method run*(state: SaleInitialProving, machine: Machine): Future[?State] {.async.} =
|
||||
let data = SalesAgent(machine).data
|
||||
let context = SalesAgent(machine).context
|
||||
let market = context.market
|
||||
let clock = context.clock
|
||||
|
||||
without request =? data.request:
|
||||
raiseAssert "no sale request"
|
||||
@ -32,6 +35,11 @@ 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 "Generating initial proof", requestId = data.requestId
|
||||
let
|
||||
slot = Slot(request: request, slotIndex: data.slotIndex)
|
||||
|
8
tests/codex/sales/helpers/periods.nim
Normal file
8
tests/codex/sales/helpers/periods.nim
Normal file
@ -0,0 +1,8 @@
|
||||
import pkg/codex/market
|
||||
import ../../helpers/mockclock
|
||||
|
||||
proc advanceToNextPeriod*(clock: MockClock, market: Market) {.async.} =
|
||||
let periodicity = await market.periodicity()
|
||||
let period = periodicity.periodOf(clock.now().u256)
|
||||
let periodEnd = periodicity.periodEnd(period)
|
||||
clock.set((periodEnd + 1).truncate(int))
|
@ -14,12 +14,15 @@ import ../../../asynctest
|
||||
import ../../examples
|
||||
import ../../helpers
|
||||
import ../../helpers/mockmarket
|
||||
import ../../helpers/mockclock
|
||||
import ../helpers/periods
|
||||
|
||||
asyncchecksuite "sales state 'initialproving'":
|
||||
let proof = Groth16Proof.example
|
||||
let request = StorageRequest.example
|
||||
let slotIndex = (request.ask.slots div 2).u256
|
||||
let market = MockMarket.new()
|
||||
let clock = MockClock.new()
|
||||
|
||||
var state: SaleInitialProving
|
||||
var agent: SalesAgent
|
||||
@ -31,7 +34,8 @@ asyncchecksuite "sales state 'initialproving'":
|
||||
return success(proof)
|
||||
let context = SalesContext(
|
||||
onProve: onProve.some,
|
||||
market: market
|
||||
market: market,
|
||||
clock: clock
|
||||
)
|
||||
agent = newSalesAgent(context,
|
||||
request.id,
|
||||
@ -39,6 +43,12 @@ asyncchecksuite "sales state 'initialproving'":
|
||||
request.some)
|
||||
state = SaleInitialProving.new()
|
||||
|
||||
proc allowProofToStart {.async.} =
|
||||
# wait until we're in initialproving state
|
||||
await sleepAsync(10.millis)
|
||||
# it won't start proving until the next period
|
||||
await clock.advanceToNextPeriod(market)
|
||||
|
||||
test "switches to cancelled state when request expires":
|
||||
let next = state.onCancelled(request)
|
||||
check !next of SaleCancelled
|
||||
@ -48,7 +58,10 @@ asyncchecksuite "sales state 'initialproving'":
|
||||
check !next of SaleFailed
|
||||
|
||||
test "switches to filling state when initial proving is complete":
|
||||
let next = await state.run(agent)
|
||||
let future = state.run(agent)
|
||||
await allowProofToStart()
|
||||
let next = await future
|
||||
|
||||
check !next of SaleFilling
|
||||
check SaleFilling(!next).proof == proof
|
||||
|
||||
@ -56,6 +69,9 @@ asyncchecksuite "sales state 'initialproving'":
|
||||
market.proofChallenge = ProofChallenge.example
|
||||
|
||||
let future = state.run(agent)
|
||||
await allowProofToStart()
|
||||
|
||||
discard await future
|
||||
|
||||
check receivedChallenge == market.proofChallenge
|
||||
|
||||
@ -65,12 +81,16 @@ asyncchecksuite "sales state 'initialproving'":
|
||||
|
||||
let proofFailedContext = SalesContext(
|
||||
onProve: onProveFailed.some,
|
||||
market: market
|
||||
market: market,
|
||||
clock: clock
|
||||
)
|
||||
agent = newSalesAgent(proofFailedContext,
|
||||
request.id,
|
||||
slotIndex,
|
||||
request.some)
|
||||
|
||||
let next = await state.run(agent)
|
||||
let future = state.run(agent)
|
||||
await allowProofToStart()
|
||||
let next = await future
|
||||
|
||||
check !next of SaleErrored
|
||||
|
@ -19,6 +19,7 @@ import ../helpers/mockmarket
|
||||
import ../helpers/mockclock
|
||||
import ../helpers/always
|
||||
import ../examples
|
||||
import ./helpers/periods
|
||||
|
||||
asyncchecksuite "Sales - start":
|
||||
let proof = Groth16Proof.example
|
||||
@ -176,6 +177,12 @@ asyncchecksuite "Sales":
|
||||
await sales.stop()
|
||||
await repo.stop()
|
||||
|
||||
proc allowRequestToStart {.async.} =
|
||||
# wait until we're in initialproving state
|
||||
await sleepAsync(10.millis)
|
||||
# it won't start proving until the next period
|
||||
await clock.advanceToNextPeriod(market)
|
||||
|
||||
proc getAvailability: Availability =
|
||||
let key = availability.id.key.get
|
||||
(waitFor reservations.get(key, Availability)).get
|
||||
@ -311,7 +318,8 @@ asyncchecksuite "Sales":
|
||||
createAvailability()
|
||||
let origSize = availability.size
|
||||
await market.requestStorage(request)
|
||||
await sold # allow proving to start
|
||||
await allowRequestToStart()
|
||||
await sold
|
||||
|
||||
# complete request
|
||||
market.slotState[request.slotId(slotIndex)] = SlotState.Finished
|
||||
@ -379,6 +387,8 @@ asyncchecksuite "Sales":
|
||||
saleFailed = true
|
||||
createAvailability()
|
||||
await market.requestStorage(request)
|
||||
await allowRequestToStart()
|
||||
|
||||
check eventually saleFailed
|
||||
|
||||
test "makes storage available again when data retrieval fails":
|
||||
@ -400,12 +410,16 @@ asyncchecksuite "Sales":
|
||||
return success(Groth16Proof.example)
|
||||
createAvailability()
|
||||
await market.requestStorage(request)
|
||||
await allowRequestToStart()
|
||||
|
||||
check eventually provingRequest == request
|
||||
check provingSlot < request.ask.slots.u256
|
||||
|
||||
test "fills a slot":
|
||||
createAvailability()
|
||||
await market.requestStorage(request)
|
||||
await allowRequestToStart()
|
||||
|
||||
check eventually market.filled.len > 0
|
||||
check market.filled[0].requestId == request.id
|
||||
check market.filled[0].slotIndex < request.ask.slots.u256
|
||||
@ -421,6 +435,8 @@ asyncchecksuite "Sales":
|
||||
soldSlotIndex = slotIndex
|
||||
createAvailability()
|
||||
await market.requestStorage(request)
|
||||
await allowRequestToStart()
|
||||
|
||||
check eventually soldRequest == request
|
||||
check soldSlotIndex < request.ask.slots.u256
|
||||
|
||||
@ -437,6 +453,8 @@ asyncchecksuite "Sales":
|
||||
clearedSlotIndex = slotIndex
|
||||
createAvailability()
|
||||
await market.requestStorage(request)
|
||||
await allowRequestToStart()
|
||||
|
||||
check eventually clearedRequest == request
|
||||
check clearedSlotIndex < request.ask.slots.u256
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user