[WIP sales] Handle other host fulfilling request
This commit is contained in:
parent
7f864570bd
commit
9438aba5d2
|
@ -34,6 +34,7 @@ type
|
||||||
request: ?StorageRequest
|
request: ?StorageRequest
|
||||||
offer: ?StorageOffer
|
offer: ?StorageOffer
|
||||||
subscription: ?Subscription
|
subscription: ?Subscription
|
||||||
|
running: ?Future[void]
|
||||||
waiting: ?Future[void]
|
waiting: ?Future[void]
|
||||||
finished: bool
|
finished: bool
|
||||||
Retrieve = proc(cid: string): Future[void] {.gcsafe, upraises: [].}
|
Retrieve = proc(cid: string): Future[void] {.gcsafe, upraises: [].}
|
||||||
|
@ -77,18 +78,6 @@ func findAvailability(sales: Sales, ask: StorageAsk): ?Availability =
|
||||||
ask.maxPrice >= availability.minPrice:
|
ask.maxPrice >= availability.minPrice:
|
||||||
return some availability
|
return some availability
|
||||||
|
|
||||||
proc createOffer(negotiation: Negotiation): StorageOffer =
|
|
||||||
let sales = negotiation.sales
|
|
||||||
StorageOffer(
|
|
||||||
requestId: negotiation.requestId,
|
|
||||||
price: negotiation.ask.maxPrice,
|
|
||||||
expiry: sales.clock.now().u256 + sales.offerExpiryInterval
|
|
||||||
)
|
|
||||||
|
|
||||||
proc sendOffer(negotiation: Negotiation) {.async.} =
|
|
||||||
let offer = negotiation.createOffer()
|
|
||||||
# negotiation.offer = some await negotiation.sales.market.offerStorage(offer)
|
|
||||||
|
|
||||||
proc finish(negotiation: Negotiation, success: bool) =
|
proc finish(negotiation: Negotiation, success: bool) =
|
||||||
if negotiation.finished:
|
if negotiation.finished:
|
||||||
return
|
return
|
||||||
|
@ -98,6 +87,9 @@ proc finish(negotiation: Negotiation, success: bool) =
|
||||||
if subscription =? negotiation.subscription:
|
if subscription =? negotiation.subscription:
|
||||||
asyncSpawn subscription.unsubscribe()
|
asyncSpawn subscription.unsubscribe()
|
||||||
|
|
||||||
|
if running =? negotiation.running:
|
||||||
|
running.cancel()
|
||||||
|
|
||||||
if waiting =? negotiation.waiting:
|
if waiting =? negotiation.waiting:
|
||||||
waiting.cancel()
|
waiting.cancel()
|
||||||
|
|
||||||
|
@ -107,20 +99,21 @@ proc finish(negotiation: Negotiation, success: bool) =
|
||||||
else:
|
else:
|
||||||
negotiation.sales.add(negotiation.availability)
|
negotiation.sales.add(negotiation.availability)
|
||||||
|
|
||||||
proc onSelect(negotiation: Negotiation, offerId: array[32, byte]) =
|
proc onFulfill(negotiation: Negotiation, requestId: array[32, byte]) {.async.} =
|
||||||
if offer =? negotiation.offer and offer.id == offerId:
|
try:
|
||||||
negotiation.finish(success = true)
|
let market = negotiation.sales.market
|
||||||
else:
|
let host = await market.getHost(requestId)
|
||||||
|
let me = await market.getSigner()
|
||||||
|
negotiation.finish(success = (host == me.some))
|
||||||
|
except CatchableError:
|
||||||
negotiation.finish(success = false)
|
negotiation.finish(success = false)
|
||||||
|
|
||||||
proc subscribeSelect(negotiation: Negotiation) {.async.} =
|
proc subscribeFulfill(negotiation: Negotiation) {.async.} =
|
||||||
without offer =? negotiation.offer:
|
proc onFulfill(requestId: array[32, byte]) {.gcsafe, upraises:[].} =
|
||||||
return
|
asyncSpawn negotiation.onFulfill(requestId)
|
||||||
proc onSelect(offerId: array[32, byte]) {.gcsafe, upraises:[].} =
|
|
||||||
negotiation.onSelect(offerId)
|
|
||||||
let market = negotiation.sales.market
|
let market = negotiation.sales.market
|
||||||
# let subscription = await market.subscribeSelection(offer.requestId, onSelect)
|
let subscription = await market.subscribeFulfillment(negotiation.requestId, onFulfill)
|
||||||
# negotiation.subscription = some subscription
|
negotiation.subscription = some subscription
|
||||||
|
|
||||||
proc waitForExpiry(negotiation: Negotiation) {.async.} =
|
proc waitForExpiry(negotiation: Negotiation) {.async.} =
|
||||||
without offer =? negotiation.offer:
|
without offer =? negotiation.offer:
|
||||||
|
@ -129,19 +122,21 @@ proc waitForExpiry(negotiation: Negotiation) {.async.} =
|
||||||
negotiation.finish(success = false)
|
negotiation.finish(success = false)
|
||||||
|
|
||||||
proc start(negotiation: Negotiation) {.async.} =
|
proc start(negotiation: Negotiation) {.async.} =
|
||||||
let sales = negotiation.sales
|
|
||||||
let market = sales.market
|
|
||||||
let availability = negotiation.availability
|
|
||||||
|
|
||||||
without retrieve =? sales.retrieve:
|
|
||||||
raiseAssert "retrieve proc not set"
|
|
||||||
|
|
||||||
without prove =? sales.prove:
|
|
||||||
raiseAssert "prove proc not set"
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
let sales = negotiation.sales
|
||||||
|
let market = sales.market
|
||||||
|
let availability = negotiation.availability
|
||||||
|
|
||||||
|
without retrieve =? sales.retrieve:
|
||||||
|
raiseAssert "retrieve proc not set"
|
||||||
|
|
||||||
|
without prove =? sales.prove:
|
||||||
|
raiseAssert "prove proc not set"
|
||||||
|
|
||||||
sales.remove(availability)
|
sales.remove(availability)
|
||||||
|
|
||||||
|
await negotiation.subscribeFulfill()
|
||||||
|
|
||||||
negotiation.request = await market.getRequest(negotiation.requestId)
|
negotiation.request = await market.getRequest(negotiation.requestId)
|
||||||
without request =? negotiation.request:
|
without request =? negotiation.request:
|
||||||
negotiation.finish(success = false)
|
negotiation.finish(success = false)
|
||||||
|
@ -150,11 +145,10 @@ proc start(negotiation: Negotiation) {.async.} =
|
||||||
await retrieve(request.content.cid)
|
await retrieve(request.content.cid)
|
||||||
let proof = await prove(request.content.cid)
|
let proof = await prove(request.content.cid)
|
||||||
await market.fulfillRequest(request.id, proof)
|
await market.fulfillRequest(request.id, proof)
|
||||||
negotiation.finish(success = true)
|
|
||||||
|
|
||||||
await negotiation.sendOffer()
|
|
||||||
await negotiation.subscribeSelect()
|
|
||||||
negotiation.waiting = some negotiation.waitForExpiry()
|
negotiation.waiting = some negotiation.waitForExpiry()
|
||||||
|
except CancelledError:
|
||||||
|
raise
|
||||||
except CatchableError as e:
|
except CatchableError as e:
|
||||||
error "Negotiation failed", msg = e.msg
|
error "Negotiation failed", msg = e.msg
|
||||||
negotiation.finish(success = false)
|
negotiation.finish(success = false)
|
||||||
|
@ -170,7 +164,7 @@ proc handleRequest(sales: Sales, requestId: array[32, byte], ask: StorageAsk) =
|
||||||
availability: availability
|
availability: availability
|
||||||
)
|
)
|
||||||
|
|
||||||
asyncSpawn negotiation.start()
|
negotiation.running = some negotiation.start()
|
||||||
|
|
||||||
proc start*(sales: Sales) {.async.} =
|
proc start*(sales: Sales) {.async.} =
|
||||||
doAssert sales.subscription.isNone, "Sales already started"
|
doAssert sales.subscription.isNone, "Sales already started"
|
||||||
|
|
|
@ -34,7 +34,8 @@ method requestStorage*(market: MockMarket,
|
||||||
request: StorageRequest):
|
request: StorageRequest):
|
||||||
Future[StorageRequest] {.async.} =
|
Future[StorageRequest] {.async.} =
|
||||||
market.requested.add(request)
|
market.requested.add(request)
|
||||||
for subscription in market.subscriptions.onRequest:
|
var subscriptions = market.subscriptions.onRequest
|
||||||
|
for subscription in subscriptions:
|
||||||
subscription.callback(request.id, request.ask)
|
subscription.callback(request.id, request.ask)
|
||||||
return request
|
return request
|
||||||
|
|
||||||
|
@ -58,7 +59,8 @@ proc fulfillRequest*(market: MockMarket,
|
||||||
host: Address) =
|
host: Address) =
|
||||||
let fulfillment = Fulfillment(requestId: requestId, proof: proof, host: host)
|
let fulfillment = Fulfillment(requestId: requestId, proof: proof, host: host)
|
||||||
market.fulfilled.add(fulfillment)
|
market.fulfilled.add(fulfillment)
|
||||||
for subscription in market.subscriptions.onFulfillment:
|
var subscriptions = market.subscriptions.onFulfillment
|
||||||
|
for subscription in subscriptions:
|
||||||
if subscription.requestId == requestId:
|
if subscription.requestId == requestId:
|
||||||
subscription.callback(requestId)
|
subscription.callback(requestId)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import std/times
|
|
||||||
import pkg/asynctest
|
import pkg/asynctest
|
||||||
import pkg/chronos
|
import pkg/chronos
|
||||||
import pkg/codex/sales
|
import pkg/codex/sales
|
||||||
|
@ -114,24 +113,13 @@ suite "Sales":
|
||||||
check soldAvailability == availability
|
check soldAvailability == availability
|
||||||
check soldRequest == request
|
check soldRequest == request
|
||||||
|
|
||||||
# test "does not call onSale when a different offer is selected":
|
test "makes storage available again when other host fulfills request":
|
||||||
# var didSell: bool
|
let otherHost = Address.example
|
||||||
# sales.onSale = proc(offer: StorageOffer) =
|
sales.retrieve = proc(_: string) {.async.} = await sleepAsync(1.hours)
|
||||||
# didSell = true
|
sales.add(availability)
|
||||||
# sales.add(availability)
|
discard await market.requestStorage(request)
|
||||||
# let request = await market.requestStorage(request)
|
market.fulfillRequest(request.id, proof, otherHost)
|
||||||
# var otherOffer = StorageOffer(requestId: request.id, price: 1.u256)
|
check sales.available == @[availability]
|
||||||
# otherOffer = await market.offerStorage(otherOffer)
|
|
||||||
# await market.selectOffer(otherOffer.id)
|
|
||||||
# check not didSell
|
|
||||||
|
|
||||||
# test "makes storage available again when different offer is selected":
|
|
||||||
# sales.add(availability)
|
|
||||||
# let request = await market.requestStorage(request)
|
|
||||||
# var otherOffer = StorageOffer(requestId: request.id, price: 1.u256)
|
|
||||||
# otherOffer = await market.offerStorage(otherOffer)
|
|
||||||
# await market.selectOffer(otherOffer.id)
|
|
||||||
# check sales.available.contains(availability)
|
|
||||||
|
|
||||||
# test "makes storage available again when offer expires":
|
# test "makes storage available again when offer expires":
|
||||||
# sales.add(availability)
|
# sales.add(availability)
|
||||||
|
|
Loading…
Reference in New Issue