From 3acb702c1d1c00e53a74a0bb6ab7c6d2b4dbb17e Mon Sep 17 00:00:00 2001 From: Eric Mastro Date: Thu, 12 Jan 2023 17:47:48 +1100 Subject: [PATCH] [marketplace] WIP reservations basic reserve/release and put/delete --- codex/sales/reservations.nim | 64 +++++++++++++++++++++++++++++++----- codex/sales/statemachine.nim | 8 ++--- 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/codex/sales/reservations.nim b/codex/sales/reservations.nim index 7dff28ae..8e4b0bf6 100644 --- a/codex/sales/reservations.nim +++ b/codex/sales/reservations.nim @@ -7,25 +7,73 @@ ## This file may not be copied, modified, or distributed except according to ## those terms. +import pkg/chronos import pkg/upraises +import pkg/json_serialization +import pkg/stint push: {.upraises: [].} import pkg/datastore +import pkg/stew/byteutils import ../stores +import ../namespaces type + Availability* = object + id*: array[32, byte] + size*: UInt256 + duration*: UInt256 + minPrice*: UInt256 Reservations* = object - repoStore: RepoStore - dataStore: Datastore + availability: RepoStore + state: Datastore + NotAvailableError* = object of CodexError + +const + SalesKey = (CodexMetaKey / "sales").tryGet # TODO: move to sales module + ReservationsKey = (SalesKey / "reservations").tryGet proc new*(_: type Reservations, repo: RepoStore, data: Datastore): Reservations = - let r = Reservations(repoStore: repo, dataStore: data) + let r = Reservations(availability: repo, state: data) return r -proc isAvailable(self: Reservations): Future[bool] {.async.} = - # TODO: query RepoStore - return true +proc available*(self: Reservations): Future[uint] {.async.} = + # TODO: query RepoStore when API is ready + return 100_000_000.uint -proc reserve*(self: Reservations, bytes: uint): Future[?!void] {.async.} = - return self.repoStore.reserve(bytes) \ No newline at end of file +proc available*(self: Reservations, bytes: uint): Future[bool] {.async.} = + return bytes < (await self.available) + +proc key(availability: Availability): Key = + (ReservationsKey / $availability.id).tryGet + +proc reserve*(self: Reservations, + availability: Availability): Future[?!void] {.async.} = + + # TODO: reconcile data sizes -- availability uses UInt256 and RepoStore + # uses uint, thus the need to truncate + if err =? (await self.availability.reserve( + availability.size.truncate(uint))).errorOption: + return failure(err) + + if err =? (await self.state.put( + availability.key, + @(availability.toJson.toBytes))).errorOption: + return failure(err) + + return success() + +proc release*(self: Reservations, + availability: Availability): Future[?!void] {.async.} = + + # TODO: reconcile data sizes -- availability uses UInt256 and RepoStore + # uses uint, thus the need to truncate + if err =? (await self.availability.release( + availability.size.truncate(uint))).errorOption: + return failure(err) + + if err =? (await self.state.delete(availability.key)).errorOption: + return failure(err) + + return success() diff --git a/codex/sales/statemachine.nim b/codex/sales/statemachine.nim index 2c0af540..0b8542d1 100644 --- a/codex/sales/statemachine.nim +++ b/codex/sales/statemachine.nim @@ -7,6 +7,7 @@ import ../utils/statemachine import ../market import ../clock import ../proving +import ../reservations import ../contracts/requests export market @@ -39,12 +40,7 @@ type cancelled*: Future[void] SaleState* = ref object of AsyncState SaleError* = ref object of CodexError - Availability* = object - id*: array[32, byte] - size*: UInt256 - duration*: UInt256 - minPrice*: UInt256 - AvailabilityChange* = proc(availability: Availability) {.gcsafe, upraises: [].} + # TODO: when availability changes introduced, make availability non-optional (if we need to keep it at all) RequestEvent* = proc(state: SaleState, request: StorageRequest): Future[void] {.gcsafe, upraises: [].} OnStore* = proc(request: StorageRequest,