Skip to content

Commit

Permalink
Update SalePreparing
Browse files Browse the repository at this point in the history
Specify `reprocessSlot` and `returnBytes` when moving to `SaleIgnored` from `SalePreparing`.

Update tests to include test for a raised CatchableError.
  • Loading branch information
emizzle committed Sep 26, 2024
1 parent 189c1c4 commit a210a63
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 13 deletions.
10 changes: 5 additions & 5 deletions codex/sales/states/preparing.nim
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import ./cancelled
import ./failed
import ./filled
import ./ignored
import ./downloading
import ./slotreserving
import ./errored

declareCounter(codex_reservations_availability_mismatch, "codex reservations availability_mismatch")
Expand Down Expand Up @@ -50,7 +50,7 @@ method run*(state: SalePreparing, machine: Machine): Future[?State] {.async.} =
let slotId = slotId(data.requestId, data.slotIndex)
let state = await market.slotState(slotId)
if state != SlotState.Free:
return some State(SaleIgnored())
return some State(SaleIgnored(reprocessSlot: false, returnBytes: false))

# TODO: Once implemented, check to ensure the host is allowed to fill the slot,
# due to the [sliding window mechanism](https://github.com/codex-storage/codex-research/blob/master/design/marketplace.md#dispersal)
Expand All @@ -71,7 +71,7 @@ method run*(state: SalePreparing, machine: Machine): Future[?State] {.async.} =
request.ask.collateral):
debug "No availability found for request, ignoring"

return some State(SaleIgnored())
return some State(SaleIgnored(reprocessSlot: true))

info "Availability found for request, creating reservation"

Expand All @@ -88,11 +88,11 @@ method run*(state: SalePreparing, machine: Machine): Future[?State] {.async.} =
if error of BytesOutOfBoundsError:
# Lets monitor how often this happen and if it is often we can make it more inteligent to handle it
codex_reservations_availability_mismatch.inc()
return some State(SaleIgnored())
return some State(SaleIgnored(reprocessSlot: true))

return some State(SaleErrored(error: error))

trace "Reservation created succesfully"

data.reservation = some reservation
return some State(SaleDownloading())
return some State(SaleSlotReserving())
13 changes: 12 additions & 1 deletion tests/codex/helpers/mockreservations.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import pkg/questionable/results
type
MockReservations* = ref object of Reservations
createReservationThrowBytesOutOfBoundsError: bool
createReservationThrowError: ?(ref CatchableError)

proc new*(
T: type MockReservations,
Expand All @@ -14,9 +15,16 @@ proc new*(
## Create a mock clock instance
MockReservations(availabilityLock: newAsyncLock(), repo: repo)

proc setCreateReservationThrowBytesOutOfBoundsError*(self: MockReservations, flag: bool) =
proc setCreateReservationThrowBytesOutOfBoundsError*(
self: MockReservations, flag: bool) =

self.createReservationThrowBytesOutOfBoundsError = flag

proc setCreateReservationThrowError*(
self: MockReservations, error: ?(ref CatchableError)) =

self.createReservationThrowError = error

method createReservation*(
self: MockReservations,
availabilityId: AvailabilityId,
Expand All @@ -29,5 +37,8 @@ method createReservation*(
"trying to reserve an amount of bytes that is greater than the total size of the Availability")
return failure(error)

elif error =? self.createReservationThrowError:
return failure(error)

return await procCall createReservation(Reservations(self), availabilityId, slotSize, requestId, slotIndex)

30 changes: 23 additions & 7 deletions tests/codex/sales/states/testpreparing.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import pkg/datastore
import pkg/stew/byteutils
import pkg/codex/contracts/requests
import pkg/codex/sales/states/preparing
import pkg/codex/sales/states/downloading
import pkg/codex/sales/states/slotreserving
import pkg/codex/sales/states/cancelled
import pkg/codex/sales/states/failed
import pkg/codex/sales/states/filled
Expand Down Expand Up @@ -84,17 +84,33 @@ asyncchecksuite "sales state 'preparing'":
availability = a.get

test "run switches to ignored when no availability":
let next = await state.run(agent)
check !next of SaleIgnored
let next = !(await state.run(agent))
check next of SaleIgnored
let ignored = SaleIgnored(next)
check ignored.reprocessSlot
check ignored.returnBytes == false

test "run switches to downloading when reserved":
test "run switches to slot reserving state after reservation created":
await createAvailability()
let next = await state.run(agent)
check !next of SaleDownloading
check !next of SaleSlotReserving

test "run switches to ignored when reserve fails with BytesOutOfBounds":
await createAvailability()
reservations.setCreateReservationThrowBytesOutOfBoundsError(true)

let next = await state.run(agent)
check !next of SaleIgnored
let next = !(await state.run(agent))
check next of SaleIgnored
let ignored = SaleIgnored(next)
check ignored.reprocessSlot
check ignored.returnBytes == false

test "run switches to errored when reserve fails with other error":
await createAvailability()
let error = newException(CatchableError, "some error")
reservations.setCreateReservationThrowError(some error)

let next = !(await state.run(agent))
check next of SaleErrored
let errored = SaleErrored(next)
check errored.error == error

0 comments on commit a210a63

Please sign in to comment.