diff --git a/codex/sales/states/preparing.nim b/codex/sales/states/preparing.nim index d7f38f5b0..c92ec7166 100644 --- a/codex/sales/states/preparing.nim +++ b/codex/sales/states/preparing.nim @@ -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") @@ -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) @@ -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" @@ -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()) diff --git a/tests/codex/helpers/mockreservations.nim b/tests/codex/helpers/mockreservations.nim index cbc95bc18..64b52676d 100644 --- a/tests/codex/helpers/mockreservations.nim +++ b/tests/codex/helpers/mockreservations.nim @@ -6,6 +6,7 @@ import pkg/questionable/results type MockReservations* = ref object of Reservations createReservationThrowBytesOutOfBoundsError: bool + createReservationThrowError: ?(ref CatchableError) proc new*( T: type MockReservations, @@ -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, @@ -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) diff --git a/tests/codex/sales/states/testpreparing.nim b/tests/codex/sales/states/testpreparing.nim index c095d99e1..22d2ef7cf 100644 --- a/tests/codex/sales/states/testpreparing.nim +++ b/tests/codex/sales/states/testpreparing.nim @@ -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 @@ -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