From 5da232f33a281afa63902883d2592641db8218fb Mon Sep 17 00:00:00 2001 From: Eric Mastro Date: Tue, 9 May 2023 14:24:31 +1000 Subject: [PATCH] [marketplace] restart sales state machine if slot is filled by other host When a slot is filled by other host, the state machine should not park in the `SaleErrored` state, and instead moves to the `SaleRestart` state, where it calls `onSaleRestart`. The sales module handles `onSaleRestart`, restarting the state machine, getting a new slot index while ignoring the previously attempting slot index. --- codex/contracts/requests.nim | 16 +++++++++++++ codex/sales.nim | 7 ++++-- codex/sales/reservations.nim | 4 ++-- codex/sales/salesagent.nim | 12 +++++++--- codex/sales/salescontext.nim | 2 ++ codex/sales/states/downloading.nim | 5 ++-- codex/sales/states/filled.nim | 15 ++++++++---- codex/sales/states/preparing.nim | 11 +++++---- codex/sales/states/proving.nim | 9 +++++-- codex/sales/states/restart.nim | 25 ++++++++++++++++++++ tests/codex/sales/states/testdownloading.nim | 6 ++--- tests/codex/sales/states/testfilled.nim | 6 ++--- tests/codex/sales/states/testpreparing.nim | 6 ++--- tests/codex/sales/states/testproving.nim | 6 ++--- tests/codex/sales/testsalesagent.nim | 18 ++++++++++++++ 15 files changed, 116 insertions(+), 32 deletions(-) create mode 100644 codex/sales/states/restart.nim diff --git a/codex/contracts/requests.nim b/codex/contracts/requests.nim index 1e8b94a2..c54d197f 100644 --- a/codex/contracts/requests.nim +++ b/codex/contracts/requests.nim @@ -3,6 +3,8 @@ import pkg/contractabi import pkg/nimcrypto import pkg/ethers/fields import pkg/questionable/results +import pkg/json_serialization +import pkg/upraises export contractabi @@ -193,3 +195,17 @@ func price*(request: StorageRequest): UInt256 = func size*(ask: StorageAsk): UInt256 = ask.slots.u256 * ask.slotSize + +proc writeValue*( + writer: var JsonWriter, + value: SlotId | RequestId) {.upraises:[IOError].} = + + mixin writeValue + writer.writeValue value.toArray + +proc readValue*[T: SlotId | RequestId]( + reader: var JsonReader, + value: var T) {.upraises: [SerializationError, IOError].} = + + mixin readValue + value = T reader.readValue(T.distinctBase) diff --git a/codex/sales.nim b/codex/sales.nim index 9b50b9e5..f62bcd1e 100644 --- a/codex/sales.nim +++ b/codex/sales.nim @@ -73,8 +73,6 @@ func new*(_: type Sales, reservations: Reservations.new(repo) )) - - proc handleRequest(sales: Sales, requestId: RequestId, ask: StorageAsk) = @@ -89,6 +87,11 @@ proc handleRequest(sales: Sales, none UInt256, none StorageRequest ) + agent.context.onStartOver = + proc(slotIndex: UInt256) {.gcsafe, upraises:[], async.} = + await agent.stop() + agent.start(SalePreparing(ignoreSlotIndex: some slotIndex)) + agent.context.onIgnored = proc {.gcsafe, upraises:[].} = sales.agents.keepItIf(it != agent) agent.start(SalePreparing()) diff --git a/codex/sales/reservations.nim b/codex/sales/reservations.nim index 91f21112..9651c57f 100644 --- a/codex/sales/reservations.nim +++ b/codex/sales/reservations.nim @@ -97,12 +97,12 @@ proc toErr[E1: ref CatchableError, E2: AvailabilityError]( proc writeValue*( writer: var JsonWriter, - value: SlotId | AvailabilityId) {.upraises:[IOError].} = + value: AvailabilityId) {.upraises:[IOError].} = mixin writeValue writer.writeValue value.toArray -proc readValue*[T: SlotId | AvailabilityId]( +proc readValue*[T: AvailabilityId]( reader: var JsonReader, value: var T) {.upraises: [SerializationError, IOError].} = diff --git a/codex/sales/salesagent.nim b/codex/sales/salesagent.nim index 81858702..f6b50b1e 100644 --- a/codex/sales/salesagent.nim +++ b/codex/sales/salesagent.nim @@ -51,8 +51,11 @@ proc nextRandom(sample: openArray[uint64]): uint64 = let rng = Rng.instance return rng.sample(sample) -proc assignRandomSlotIndex*(agent: SalesAgent, - numSlots: uint64): Future[?!void] {.async.} = +proc assignRandomSlotIndex*( + agent: SalesAgent, + numSlots: uint64, + ignoreSlotIndex: ?UInt256 = none UInt256): Future[?!void] {.async.} = + let market = agent.context.market let data = agent.data @@ -63,6 +66,8 @@ proc assignRandomSlotIndex*(agent: SalesAgent, var idx: UInt256 var sample = toSeq(0'u64..