mirror of
https://github.com/logos-storage/logos-storage-nim.git
synced 2026-01-02 13:33:10 +00:00
chore: add missing custom errors (#1134)
* Add missing custom errors * Separate mock state errors * Remove the Option in the error setters * Wrap the contract errors in MarketError * Remove async raises (needs to address it in another PR) * Wrap contract errors into specific error types * Rename SlotNotFreeError to SlotStateMismatchError
This commit is contained in:
parent
54177e9fbf
commit
9d7b521519
@ -249,10 +249,16 @@ method fillSlot(
|
||||
requestId
|
||||
slotIndex
|
||||
|
||||
await market.approveFunds(collateral)
|
||||
trace "calling fillSlot on contract"
|
||||
discard await market.contract.fillSlot(requestId, slotIndex, proof).confirm(1)
|
||||
trace "fillSlot transaction completed"
|
||||
try:
|
||||
await market.approveFunds(collateral)
|
||||
trace "calling fillSlot on contract"
|
||||
discard await market.contract.fillSlot(requestId, slotIndex, proof).confirm(1)
|
||||
trace "fillSlot transaction completed"
|
||||
except Marketplace_SlotNotFree as parent:
|
||||
raise newException(
|
||||
SlotStateMismatchError, "Failed to fill slot because the slot is not free",
|
||||
parent,
|
||||
)
|
||||
|
||||
method freeSlot*(market: OnChainMarket, slotId: SlotId) {.async.} =
|
||||
convertEthersError("Failed to free slot"):
|
||||
@ -327,14 +333,20 @@ method reserveSlot*(
|
||||
market: OnChainMarket, requestId: RequestId, slotIndex: uint64
|
||||
) {.async.} =
|
||||
convertEthersError("Failed to reserve slot"):
|
||||
discard await market.contract
|
||||
.reserveSlot(
|
||||
requestId,
|
||||
slotIndex,
|
||||
# reserveSlot runs out of gas for unknown reason, but 100k gas covers it
|
||||
TransactionOverrides(gasLimit: some 100000.u256),
|
||||
)
|
||||
.confirm(1)
|
||||
try:
|
||||
discard await market.contract
|
||||
.reserveSlot(
|
||||
requestId,
|
||||
slotIndex,
|
||||
# reserveSlot runs out of gas for unknown reason, but 100k gas covers it
|
||||
TransactionOverrides(gasLimit: some 100000.u256),
|
||||
)
|
||||
.confirm(1)
|
||||
except SlotReservations_ReservationNotAllowed:
|
||||
raise newException(
|
||||
SlotReservationNotAllowedError,
|
||||
"Failed to reserve slot because reservation is not allowed",
|
||||
)
|
||||
|
||||
method canReserveSlot*(
|
||||
market: OnChainMarket, requestId: RequestId, slotIndex: uint64
|
||||
|
||||
@ -53,6 +53,7 @@ type
|
||||
Proofs_ProofAlreadyMarkedMissing* = object of SolidityError
|
||||
Proofs_InvalidProbability* = object of SolidityError
|
||||
Periods_InvalidSecondsPerPeriod* = object of SolidityError
|
||||
SlotReservations_ReservationNotAllowed* = object of SolidityError
|
||||
|
||||
proc configuration*(marketplace: Marketplace): MarketplaceConfig {.contract, view.}
|
||||
proc token*(marketplace: Marketplace): Address {.contract, view.}
|
||||
|
||||
@ -18,6 +18,8 @@ export periods
|
||||
type
|
||||
Market* = ref object of RootObj
|
||||
MarketError* = object of CodexError
|
||||
SlotStateMismatchError* = object of MarketError
|
||||
SlotReservationNotAllowedError* = object of MarketError
|
||||
Subscription* = ref object of RootObj
|
||||
OnRequest* =
|
||||
proc(id: RequestId, ask: StorageAsk, expiry: uint64) {.gcsafe, upraises: [].}
|
||||
|
||||
@ -30,6 +30,7 @@ method run*(
|
||||
): Future[?State] {.async: (raises: []).} =
|
||||
let data = SalesAgent(machine).data
|
||||
let market = SalesAgent(machine).context.market
|
||||
|
||||
without (request =? data.request):
|
||||
raiseAssert "Request not set"
|
||||
|
||||
@ -42,17 +43,16 @@ method run*(
|
||||
err:
|
||||
error "Failure attempting to fill slot: unable to calculate collateral",
|
||||
error = err.msg
|
||||
return
|
||||
return some State(SaleErrored(error: err))
|
||||
|
||||
debug "Filling slot"
|
||||
try:
|
||||
await market.fillSlot(data.requestId, data.slotIndex, state.proof, collateral)
|
||||
except SlotStateMismatchError as e:
|
||||
debug "Slot is already filled, ignoring slot"
|
||||
return some State(SaleIgnored(reprocessSlot: false, returnBytes: true))
|
||||
except MarketError as e:
|
||||
if e.msg.contains "Slot is not free":
|
||||
debug "Slot is already filled, ignoring slot"
|
||||
return some State(SaleIgnored(reprocessSlot: false, returnBytes: true))
|
||||
else:
|
||||
return some State(SaleErrored(error: e))
|
||||
return some State(SaleErrored(error: e))
|
||||
# other CatchableErrors are handled "automatically" by the SaleState
|
||||
|
||||
return some State(SaleFilled())
|
||||
|
||||
@ -44,12 +44,11 @@ method run*(
|
||||
try:
|
||||
trace "Reserving slot"
|
||||
await market.reserveSlot(data.requestId, data.slotIndex)
|
||||
except SlotReservationNotAllowedError as e:
|
||||
debug "Slot cannot be reserved, ignoring", error = e.msg
|
||||
return some State(SaleIgnored(reprocessSlot: false, returnBytes: true))
|
||||
except MarketError as e:
|
||||
if e.msg.contains "SlotReservations_ReservationNotAllowed":
|
||||
debug "Slot cannot be reserved, ignoring", error = e.msg
|
||||
return some State(SaleIgnored(reprocessSlot: false, returnBytes: true))
|
||||
else:
|
||||
return some State(SaleErrored(error: e))
|
||||
return some State(SaleErrored(error: e))
|
||||
# other CatchableErrors are handled "automatically" by the SaleState
|
||||
|
||||
trace "Slot successfully reserved"
|
||||
|
||||
@ -46,7 +46,8 @@ type
|
||||
subscriptions: Subscriptions
|
||||
config*: MarketplaceConfig
|
||||
canReserveSlot*: bool
|
||||
reserveSlotThrowError*: ?(ref MarketError)
|
||||
errorOnReserveSlot*: ?(ref MarketError)
|
||||
errorOnFillSlot*: ?(ref CatchableError)
|
||||
clock: ?Clock
|
||||
|
||||
Fulfillment* = object
|
||||
@ -289,6 +290,9 @@ proc fillSlot*(
|
||||
host: Address,
|
||||
collateral = 0.u256,
|
||||
) =
|
||||
if error =? market.errorOnFillSlot:
|
||||
raise error
|
||||
|
||||
let slot = MockSlot(
|
||||
requestId: requestId,
|
||||
slotIndex: slotIndex,
|
||||
@ -370,7 +374,7 @@ method canProofBeMarkedAsMissing*(
|
||||
method reserveSlot*(
|
||||
market: MockMarket, requestId: RequestId, slotIndex: uint64
|
||||
) {.async.} =
|
||||
if error =? market.reserveSlotThrowError:
|
||||
if error =? market.errorOnReserveSlot:
|
||||
raise error
|
||||
|
||||
method canReserveSlot*(
|
||||
@ -381,8 +385,19 @@ method canReserveSlot*(
|
||||
func setCanReserveSlot*(market: MockMarket, canReserveSlot: bool) =
|
||||
market.canReserveSlot = canReserveSlot
|
||||
|
||||
func setReserveSlotThrowError*(market: MockMarket, error: ?(ref MarketError)) =
|
||||
market.reserveSlotThrowError = error
|
||||
func setErrorOnReserveSlot*(market: MockMarket, error: ref MarketError) =
|
||||
market.errorOnReserveSlot =
|
||||
if error.isNil:
|
||||
none (ref MarketError)
|
||||
else:
|
||||
some error
|
||||
|
||||
func setErrorOnFillSlot*(market: MockMarket, error: ref CatchableError) =
|
||||
market.errorOnFillSlot =
|
||||
if error.isNil:
|
||||
none (ref CatchableError)
|
||||
else:
|
||||
some error
|
||||
|
||||
method subscribeRequests*(
|
||||
market: MockMarket, callback: OnRequest
|
||||
|
||||
@ -1,18 +1,31 @@
|
||||
import pkg/unittest2
|
||||
import pkg/questionable
|
||||
import pkg/codex/contracts/requests
|
||||
import pkg/codex/sales/states/filling
|
||||
import pkg/codex/sales/states/cancelled
|
||||
import pkg/codex/sales/states/failed
|
||||
import pkg/codex/sales/states/ignored
|
||||
import pkg/codex/sales/states/errored
|
||||
import pkg/codex/sales/salesagent
|
||||
import pkg/codex/sales/salescontext
|
||||
import ../../../asynctest
|
||||
import ../../examples
|
||||
import ../../helpers
|
||||
import ../../helpers/mockmarket
|
||||
import ../../helpers/mockclock
|
||||
|
||||
suite "sales state 'filling'":
|
||||
let request = StorageRequest.example
|
||||
let slotIndex = request.ask.slots div 2
|
||||
var state: SaleFilling
|
||||
var market: MockMarket
|
||||
var clock: MockClock
|
||||
var agent: SalesAgent
|
||||
|
||||
setup:
|
||||
clock = MockClock.new()
|
||||
market = MockMarket.new()
|
||||
let context = SalesContext(market: market, clock: clock)
|
||||
agent = newSalesAgent(context, request.id, slotIndex, request.some)
|
||||
state = SaleFilling.new()
|
||||
|
||||
test "switches to cancelled state when request expires":
|
||||
@ -22,3 +35,28 @@ suite "sales state 'filling'":
|
||||
test "switches to failed state when request fails":
|
||||
let next = state.onFailed(request)
|
||||
check !next of SaleFailed
|
||||
|
||||
test "run switches to ignored when slot is not free":
|
||||
let error = newException(
|
||||
SlotStateMismatchError, "Failed to fill slot because the slot is not free"
|
||||
)
|
||||
market.setErrorOnFillSlot(error)
|
||||
market.requested.add(request)
|
||||
market.slotState[request.slotId(slotIndex)] = SlotState.Filled
|
||||
|
||||
let next = !(await state.run(agent))
|
||||
check next of SaleIgnored
|
||||
check SaleIgnored(next).reprocessSlot == false
|
||||
check SaleIgnored(next).returnBytes
|
||||
|
||||
test "run switches to errored with other error ":
|
||||
let error = newException(MarketError, "some error")
|
||||
market.setErrorOnFillSlot(error)
|
||||
market.requested.add(request)
|
||||
market.slotState[request.slotId(slotIndex)] = SlotState.Filled
|
||||
|
||||
let next = !(await state.run(agent))
|
||||
check next of SaleErrored
|
||||
|
||||
let errored = SaleErrored(next)
|
||||
check errored.error == error
|
||||
|
||||
@ -54,15 +54,16 @@ asyncchecksuite "sales state 'SlotReserving'":
|
||||
|
||||
test "run switches to errored when slot reservation errors":
|
||||
let error = newException(MarketError, "some error")
|
||||
market.setReserveSlotThrowError(some error)
|
||||
market.setErrorOnReserveSlot(error)
|
||||
let next = !(await state.run(agent))
|
||||
check next of SaleErrored
|
||||
let errored = SaleErrored(next)
|
||||
check errored.error == error
|
||||
|
||||
test "catches reservation not allowed error":
|
||||
let error = newException(MarketError, "SlotReservations_ReservationNotAllowed")
|
||||
market.setReserveSlotThrowError(some error)
|
||||
test "run switches to ignored when reservation is not allowed":
|
||||
let error =
|
||||
newException(SlotReservationNotAllowedError, "Reservation is not allowed")
|
||||
market.setErrorOnReserveSlot(error)
|
||||
let next = !(await state.run(agent))
|
||||
check next of SaleIgnored
|
||||
check SaleIgnored(next).reprocessSlot == false
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user