2022-09-27 14:27:40 +00:00
|
|
|
import ./statemachine
|
|
|
|
import ./states/pending
|
2022-11-08 07:10:17 +00:00
|
|
|
import ./states/unknown
|
2022-09-27 08:28:36 +00:00
|
|
|
import ./purchaseid
|
|
|
|
|
2022-11-08 07:10:17 +00:00
|
|
|
# Purchase is implemented as a state machine.
|
2022-09-27 14:27:40 +00:00
|
|
|
#
|
2022-11-08 07:10:17 +00:00
|
|
|
# It can either be a new (pending) purchase that still needs to be submitted
|
|
|
|
# on-chain, or it is a purchase that was previously submitted on-chain, and
|
|
|
|
# we're just restoring its (unknown) state after a node restart.
|
2022-09-27 14:27:40 +00:00
|
|
|
#
|
2022-11-08 07:10:17 +00:00
|
|
|
# |
|
|
|
|
# v
|
|
|
|
# ------------------------- unknown
|
|
|
|
# | / /
|
|
|
|
# v v /
|
|
|
|
# pending ----> submitted ----> started ---------> finished <----/
|
|
|
|
# \ \ /
|
|
|
|
# \ ------------> failed <----/
|
|
|
|
# \ /
|
|
|
|
# --> cancelled <-----------------------
|
2022-09-27 08:28:36 +00:00
|
|
|
|
2022-09-27 14:27:40 +00:00
|
|
|
export Purchase
|
|
|
|
export purchaseid
|
2022-11-08 07:10:17 +00:00
|
|
|
export statemachine
|
2022-09-27 08:28:36 +00:00
|
|
|
|
2023-06-22 15:11:18 +00:00
|
|
|
func new*(
|
|
|
|
_: type Purchase,
|
|
|
|
requestId: RequestId,
|
|
|
|
market: Market,
|
|
|
|
clock: Clock
|
|
|
|
): Purchase =
|
|
|
|
## create a new instance of a Purchase
|
2023-07-31 05:09:34 +00:00
|
|
|
##
|
|
|
|
var purchase = Purchase.new()
|
2024-01-11 16:45:23 +00:00
|
|
|
{.cast(noSideEffect).}:
|
|
|
|
purchase.future = newFuture[void]()
|
2023-07-31 05:09:34 +00:00
|
|
|
purchase.requestId = requestId
|
|
|
|
purchase.market = market
|
|
|
|
purchase.clock = clock
|
|
|
|
|
|
|
|
return purchase
|
2022-09-27 08:28:36 +00:00
|
|
|
|
2023-06-22 15:11:18 +00:00
|
|
|
func new*(
|
|
|
|
_: type Purchase,
|
|
|
|
request: StorageRequest,
|
|
|
|
market: Market,
|
|
|
|
clock: Clock
|
|
|
|
): Purchase =
|
|
|
|
## Create a new purchase using the given market and clock
|
2022-11-08 07:10:17 +00:00
|
|
|
let purchase = Purchase.new(request.id, market, clock)
|
|
|
|
purchase.request = some request
|
|
|
|
return purchase
|
|
|
|
|
2022-09-27 08:28:36 +00:00
|
|
|
proc start*(purchase: Purchase) =
|
2023-06-05 08:48:06 +00:00
|
|
|
purchase.start(PurchasePending())
|
2022-09-27 08:28:36 +00:00
|
|
|
|
2022-11-08 07:10:17 +00:00
|
|
|
proc load*(purchase: Purchase) =
|
2023-06-05 08:48:06 +00:00
|
|
|
purchase.start(PurchaseUnknown())
|
2022-11-08 07:10:17 +00:00
|
|
|
|
2022-09-27 08:28:36 +00:00
|
|
|
proc wait*(purchase: Purchase) {.async.} =
|
|
|
|
await purchase.future
|
|
|
|
|
|
|
|
func id*(purchase: Purchase): PurchaseId =
|
2022-11-08 07:10:17 +00:00
|
|
|
PurchaseId(purchase.requestId)
|
2022-09-27 08:28:36 +00:00
|
|
|
|
|
|
|
func finished*(purchase: Purchase): bool =
|
|
|
|
purchase.future.finished
|
|
|
|
|
|
|
|
func error*(purchase: Purchase): ?(ref CatchableError) =
|
|
|
|
if purchase.future.failed:
|
|
|
|
some purchase.future.error
|
|
|
|
else:
|
|
|
|
none (ref CatchableError)
|
2023-06-05 08:48:06 +00:00
|
|
|
|
|
|
|
func state*(purchase: Purchase): ?string =
|
|
|
|
proc description(state: State): string =
|
|
|
|
$state
|
|
|
|
purchase.query(description)
|