[purchasing] Update to latest dagger-contracts
This commit is contained in:
parent
b7ab9481d9
commit
4b5cfe8e41
|
@ -3,6 +3,7 @@ import pkg/chronos
|
|||
type
|
||||
Clock* = ref object of RootObj
|
||||
SecondsSince1970* = int64
|
||||
Timeout* = object of CatchableError
|
||||
|
||||
method now*(clock: Clock): SecondsSince1970 {.base.} =
|
||||
raiseAssert "not implemented"
|
||||
|
@ -10,3 +11,15 @@ method now*(clock: Clock): SecondsSince1970 {.base.} =
|
|||
proc waitUntil*(clock: Clock, time: SecondsSince1970) {.async.} =
|
||||
while clock.now() < time:
|
||||
await sleepAsync(1.seconds)
|
||||
|
||||
proc withTimeout*(future: Future[void],
|
||||
clock: Clock,
|
||||
expiry: SecondsSince1970) {.async.} =
|
||||
let timeout = clock.waitUntil(expiry)
|
||||
try:
|
||||
await future or timeout
|
||||
finally:
|
||||
await timeout.cancelAndWait()
|
||||
if not future.completed:
|
||||
await future.cancelAndWait()
|
||||
raise newException(Timeout, "Timed out")
|
||||
|
|
|
@ -25,6 +25,7 @@ type
|
|||
request*: StorageRequest
|
||||
offers*: seq[StorageOffer]
|
||||
selected*: ?StorageOffer
|
||||
PurchaseTimeout* = Timeout
|
||||
|
||||
const DefaultProofProbability = 100.u256
|
||||
const DefaultRequestExpiryInterval = (10 * 60).u256
|
||||
|
@ -69,29 +70,30 @@ func getPurchase*(purchasing: Purchasing, id: array[32, byte]): ?Purchase =
|
|||
else:
|
||||
none Purchase
|
||||
|
||||
proc selectOffer(purchase: Purchase) {.async.} =
|
||||
var cheapest: ?StorageOffer
|
||||
for offer in purchase.offers:
|
||||
without purchase.clock.now().u256 < offer.expiry - purchase.offerExpiryMargin:
|
||||
continue
|
||||
without current =? cheapest:
|
||||
cheapest = some offer
|
||||
continue
|
||||
if current.price > offer.price:
|
||||
cheapest = some offer
|
||||
if cheapest =? cheapest:
|
||||
await purchase.market.selectOffer(cheapest.id)
|
||||
purchase.selected = some cheapest
|
||||
|
||||
proc run(purchase: Purchase) {.async.} =
|
||||
proc onOffer(offer: StorageOffer) =
|
||||
purchase.offers.add(offer)
|
||||
let market = purchase.market
|
||||
purchase.request = await market.requestStorage(purchase.request)
|
||||
let subscription = await market.subscribeOffers(purchase.request.id, onOffer)
|
||||
await purchase.clock.waitUntil(purchase.request.expiry.truncate(int64))
|
||||
await purchase.selectOffer()
|
||||
await subscription.unsubscribe()
|
||||
let clock = purchase.clock
|
||||
|
||||
proc requestStorage {.async.} =
|
||||
purchase.request = await market.requestStorage(purchase.request)
|
||||
|
||||
proc waitUntilFulfilled {.async.} =
|
||||
let done = newFuture[void]()
|
||||
proc callback(_: array[32, byte]) =
|
||||
done.complete()
|
||||
let request = purchase.request
|
||||
let subscription = await market.subscribeFulfillment(request.id, callback)
|
||||
try:
|
||||
await done
|
||||
finally:
|
||||
await subscription.unsubscribe()
|
||||
|
||||
proc withTimeout(future: Future[void]) {.async.} =
|
||||
let expiry = purchase.request.expiry.truncate(int64)
|
||||
await future.withTimeout(clock, expiry)
|
||||
|
||||
await requestStorage()
|
||||
await waitUntilFulfilled().withTimeout()
|
||||
|
||||
proc start(purchase: Purchase) =
|
||||
purchase.future = purchase.run()
|
||||
|
|
|
@ -25,13 +25,8 @@ suite "Purchasing":
|
|||
)
|
||||
)
|
||||
|
||||
proc purchaseAndWait(request: StorageRequest) {.async.} =
|
||||
let purchase = purchasing.purchase(request)
|
||||
clock.set(market.requested[^1].expiry.truncate(int64))
|
||||
await purchase.wait()
|
||||
|
||||
test "submits a storage request when asked":
|
||||
await purchaseAndWait(request)
|
||||
discard purchasing.purchase(request)
|
||||
let submitted = market.requested[0]
|
||||
check submitted.ask.duration == request.ask.duration
|
||||
check submitted.ask.size == request.ask.size
|
||||
|
@ -48,12 +43,12 @@ suite "Purchasing":
|
|||
|
||||
test "can change default value for proof probability":
|
||||
purchasing.proofProbability = 42.u256
|
||||
await purchaseAndWait(request)
|
||||
discard purchasing.purchase(request)
|
||||
check market.requested[0].ask.proofProbability == 42.u256
|
||||
|
||||
test "can override proof probability per request":
|
||||
request.ask.proofProbability = 42.u256
|
||||
await purchaseAndWait(request)
|
||||
discard purchasing.purchase(request)
|
||||
check market.requested[0].ask.proofProbability == 42.u256
|
||||
|
||||
test "has a default value for request expiration interval":
|
||||
|
@ -62,66 +57,31 @@ suite "Purchasing":
|
|||
test "can change default value for request expiration interval":
|
||||
purchasing.requestExpiryInterval = 42.u256
|
||||
let start = getTime().toUnix()
|
||||
await purchaseAndWait(request)
|
||||
discard purchasing.purchase(request)
|
||||
check market.requested[0].expiry == (start + 42).u256
|
||||
|
||||
test "can override expiry time per request":
|
||||
let expiry = (getTime().toUnix() + 42).u256
|
||||
request.expiry = expiry
|
||||
await purchaseAndWait(request)
|
||||
discard purchasing.purchase(request)
|
||||
check market.requested[0].expiry == expiry
|
||||
|
||||
test "includes a random nonce in every storage request":
|
||||
await purchaseAndWait(request)
|
||||
await purchaseAndWait(request)
|
||||
discard purchasing.purchase(request)
|
||||
discard purchasing.purchase(request)
|
||||
check market.requested[0].nonce != market.requested[1].nonce
|
||||
|
||||
proc createOffer(request: StorageRequest): StorageOffer =
|
||||
StorageOffer(
|
||||
requestId: request.id,
|
||||
expiry: (getTime() + initDuration(hours = 1)).toUnix().u256
|
||||
)
|
||||
|
||||
test "selects the cheapest offer":
|
||||
test "succeeds when request is fulfilled":
|
||||
let purchase = purchasing.purchase(request)
|
||||
let request = market.requested[0]
|
||||
var offer1, offer2 = createOffer(request)
|
||||
offer1.price = 20.u256
|
||||
offer2.price = 10.u256
|
||||
discard await market.offerStorage(offer1)
|
||||
discard await market.offerStorage(offer2)
|
||||
clock.set(request.expiry.truncate(int64))
|
||||
let proof = seq[byte].example
|
||||
await market.fulfillRequest(request.id, proof)
|
||||
await purchase.wait()
|
||||
check purchase.selected == some offer2
|
||||
check market.selected[0] == offer2.id
|
||||
check purchase.error.isNone
|
||||
|
||||
test "ignores offers that expired":
|
||||
let expired = (getTime() - initTimeInterval(hours = 1)).toUnix().u256
|
||||
test "fails when request times out":
|
||||
let purchase = purchasing.purchase(request)
|
||||
let request = market.requested[0]
|
||||
var offer1, offer2 = request.createOffer()
|
||||
offer1.price = 20.u256
|
||||
offer2.price = 10.u256
|
||||
offer2.expiry = expired
|
||||
discard await market.offerStorage(offer1)
|
||||
discard await market.offerStorage(offer2)
|
||||
clock.set(request.expiry.truncate(int64))
|
||||
await purchase.wait()
|
||||
check market.selected[0] == offer1.id
|
||||
|
||||
test "has a default expiration margin for offers":
|
||||
check purchasing.offerExpiryMargin != 0.u256
|
||||
|
||||
test "ignores offers that are about to expire":
|
||||
let expiryMargin = purchasing.offerExpiryMargin
|
||||
let purchase = purchasing.purchase(request)
|
||||
let request = market.requested[0]
|
||||
var offer1, offer2 = request.createOffer()
|
||||
offer1.price = 20.u256
|
||||
offer2.price = 10.u256
|
||||
offer2.expiry = getTime().toUnix().u256 + expiryMargin - 1
|
||||
discard await market.offerStorage(offer1)
|
||||
discard await market.offerStorage(offer2)
|
||||
clock.set(request.expiry.truncate(int64))
|
||||
await purchase.wait()
|
||||
check market.selected[0] == offer1.id
|
||||
expect PurchaseTimeout:
|
||||
await purchase.wait()
|
||||
|
|
Loading…
Reference in New Issue