[marketplace] WIP reservations basic reserve/release and put/delete

This commit is contained in:
Eric Mastro 2023-01-12 17:47:48 +11:00
parent 065f89eebb
commit 3acb702c1d
No known key found for this signature in database
GPG Key ID: 141E3048D95A4E63
2 changed files with 58 additions and 14 deletions

View File

@ -7,25 +7,73 @@
## This file may not be copied, modified, or distributed except according to ## This file may not be copied, modified, or distributed except according to
## those terms. ## those terms.
import pkg/chronos
import pkg/upraises import pkg/upraises
import pkg/json_serialization
import pkg/stint
push: {.upraises: [].} push: {.upraises: [].}
import pkg/datastore import pkg/datastore
import pkg/stew/byteutils
import ../stores import ../stores
import ../namespaces
type type
Availability* = object
id*: array[32, byte]
size*: UInt256
duration*: UInt256
minPrice*: UInt256
Reservations* = object Reservations* = object
repoStore: RepoStore availability: RepoStore
dataStore: Datastore 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 = 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 return r
proc isAvailable(self: Reservations): Future[bool] {.async.} = proc available*(self: Reservations): Future[uint] {.async.} =
# TODO: query RepoStore # TODO: query RepoStore when API is ready
return true return 100_000_000.uint
proc reserve*(self: Reservations, bytes: uint): Future[?!void] {.async.} = proc available*(self: Reservations, bytes: uint): Future[bool] {.async.} =
return self.repoStore.reserve(bytes) 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()

View File

@ -7,6 +7,7 @@ import ../utils/statemachine
import ../market import ../market
import ../clock import ../clock
import ../proving import ../proving
import ../reservations
import ../contracts/requests import ../contracts/requests
export market export market
@ -39,12 +40,7 @@ type
cancelled*: Future[void] cancelled*: Future[void]
SaleState* = ref object of AsyncState SaleState* = ref object of AsyncState
SaleError* = ref object of CodexError 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) # 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: [].} RequestEvent* = proc(state: SaleState, request: StorageRequest): Future[void] {.gcsafe, upraises: [].}
OnStore* = proc(request: StorageRequest, OnStore* = proc(request: StorageRequest,