[clock] Replace Market.waitUntil() with Clock.waitUntil()

This commit is contained in:
Mark Spanbroek 2022-05-18 10:19:32 +02:00 committed by markspanbroek
parent 2992229c3a
commit 09a7aa3eed
9 changed files with 15 additions and 68 deletions

View File

@ -1,6 +1,12 @@
import pkg/chronos
type type
Clock* = ref object of RootObj Clock* = ref object of RootObj
SecondsSince1970* = int64 SecondsSince1970* = int64
method now*(clock: Clock): SecondsSince1970 {.base.} = method now*(clock: Clock): SecondsSince1970 {.base.} =
raiseAssert "not implemented" raiseAssert "not implemented"
proc waitUntil*(clock: Clock, time: SecondsSince1970) {.async.} =
while clock.now() < time:
await sleepAsync(1.seconds)

View File

@ -10,21 +10,17 @@ type
OnChainMarket* = ref object of Market OnChainMarket* = ref object of Market
contract: Storage contract: Storage
signer: Signer signer: Signer
pollInterval*: Duration
MarketSubscription = market.Subscription MarketSubscription = market.Subscription
EventSubscription = ethers.Subscription EventSubscription = ethers.Subscription
OnChainMarketSubscription = ref object of MarketSubscription OnChainMarketSubscription = ref object of MarketSubscription
eventSubscription: EventSubscription eventSubscription: EventSubscription
const DefaultPollInterval = 3.seconds
func new*(_: type OnChainMarket, contract: Storage): OnChainMarket = func new*(_: type OnChainMarket, contract: Storage): OnChainMarket =
without signer =? contract.signer: without signer =? contract.signer:
raiseAssert("Storage contract should have a signer") raiseAssert("Storage contract should have a signer")
OnChainMarket( OnChainMarket(
contract: contract, contract: contract,
signer: signer, signer: signer,
pollInterval: DefaultPollInterval
) )
method requestStorage(market: OnChainMarket, method requestStorage(market: OnChainMarket,
@ -46,15 +42,6 @@ method offerStorage(market: OnChainMarket,
method selectOffer(market: OnChainMarket, offerId: array[32, byte]) {.async.} = method selectOffer(market: OnChainMarket, offerId: array[32, byte]) {.async.} =
await market.contract.selectOffer(offerId) await market.contract.selectOffer(offerId)
method getTime(market: OnChainMarket): Future[UInt256] {.async.} =
let provider = market.contract.provider
let blck = !await provider.getBlock(BlockTag.latest)
return blck.timestamp
method waitUntil*(market: OnChainMarket, expiry: UInt256) {.async.} =
while not ((time =? await market.getTime()) and (time >= expiry)):
await sleepAsync(market.pollInterval)
method subscribeRequests(market: OnChainMarket, method subscribeRequests(market: OnChainMarket,
callback: OnRequest): callback: OnRequest):
Future[MarketSubscription] {.async.} = Future[MarketSubscription] {.async.} =

View File

@ -27,12 +27,6 @@ method offerStorage*(market: Market,
method selectOffer*(market: Market, id: array[32, byte]) {.base, async.} = method selectOffer*(market: Market, id: array[32, byte]) {.base, async.} =
raiseAssert("not implemented") raiseAssert("not implemented")
method getTime*(market: Market): Future[UInt256] {.base, async.} =
raiseAssert("not implemented")
method waitUntil*(market: Market, expiry: UInt256) {.base, async.} =
raiseAssert("not implemented")
method subscribeRequests*(market: Market, method subscribeRequests*(market: Market,
callback: OnRequest): callback: OnRequest):
Future[Subscription] {.base, async.} = Future[Subscription] {.base, async.} =

View File

@ -88,7 +88,7 @@ proc run(purchase: Purchase) {.async.} =
let market = purchase.market let market = purchase.market
purchase.request = await market.requestStorage(purchase.request) purchase.request = await market.requestStorage(purchase.request)
let subscription = await market.subscribeOffers(purchase.request.id, onOffer) let subscription = await market.subscribeOffers(purchase.request.id, onOffer)
await market.waitUntil(purchase.request.expiry) await purchase.clock.waitUntil(purchase.request.expiry.truncate(int64))
await purchase.selectOffer() await purchase.selectOffer()
await subscription.unsubscribe() await subscription.unsubscribe()

View File

@ -114,7 +114,7 @@ proc subscribeSelect(negotiation: Negotiation) {.async.} =
proc waitForExpiry(negotiation: Negotiation) {.async.} = proc waitForExpiry(negotiation: Negotiation) {.async.} =
without offer =? negotiation.offer: without offer =? negotiation.offer:
return return
await negotiation.sales.market.waitUntil(offer.expiry) await negotiation.sales.clock.waitUntil(offer.expiry.truncate(int64))
negotiation.finish(success = false) negotiation.finish(success = false)
proc start(negotiation: Negotiation) {.async.} = proc start(negotiation: Negotiation) {.async.} =

View File

@ -154,23 +154,3 @@ ethersuite "On-Chain Market":
check selected == @[offer.id] check selected == @[offer.id]
await subscription.unsubscribe() await subscription.unsubscribe()
test "can retrieve current block time":
let latestBlock = !await provider.getBlock(BlockTag.latest)
check (await market.getTime()) == latestBlock.timestamp
test "supports waiting for expiry of a request or offer":
let pollInterval = 200.milliseconds
market.pollInterval = pollInterval
proc waitForPoll {.async.} =
await sleepAsync(pollInterval * 2)
let future = market.waitUntil(request.expiry)
check not future.completed
await provider.advanceTimeTo(request.expiry - 1)
await waitForPoll()
check not future.completed
await provider.advanceTimeTo(request.expiry)
await waitForPoll()
check future.completed

View File

@ -106,23 +106,3 @@ method unsubscribe*(subscription: OfferSubscription) {.async.} =
method unsubscribe*(subscription: SelectSubscription) {.async.} = method unsubscribe*(subscription: SelectSubscription) {.async.} =
subscription.market.subscriptions.onSelect.keepItIf(it != subscription) subscription.market.subscriptions.onSelect.keepItIf(it != subscription)
func `<`(a, b: Expiry): bool =
a.expiry < b.expiry
method getTime*(market: MockMarket): Future[UInt256] {.async.} =
return market.time
method waitUntil*(market: MockMarket, expiry: UInt256): Future[void] =
let future = Future[void]()
if expiry > market.time:
market.waiting.push(Expiry(future: future, expiry: expiry))
else:
future.complete()
future
proc advanceTimeTo*(market: MockMarket, time: UInt256) =
doAssert(time >= market.time)
market.time = time
while market.waiting.len > 0 and market.waiting[0].expiry <= time:
market.waiting.pop().future.complete()

View File

@ -27,7 +27,7 @@ suite "Purchasing":
proc purchaseAndWait(request: StorageRequest) {.async.} = proc purchaseAndWait(request: StorageRequest) {.async.} =
let purchase = purchasing.purchase(request) let purchase = purchasing.purchase(request)
market.advanceTimeTo(market.requested[^1].expiry) clock.set(market.requested[^1].expiry.truncate(int64))
await purchase.wait() await purchase.wait()
test "submits a storage request when asked": test "submits a storage request when asked":
@ -90,7 +90,7 @@ suite "Purchasing":
offer2.price = 10.u256 offer2.price = 10.u256
discard await market.offerStorage(offer1) discard await market.offerStorage(offer1)
discard await market.offerStorage(offer2) discard await market.offerStorage(offer2)
market.advanceTimeTo(request.expiry) clock.set(request.expiry.truncate(int64))
await purchase.wait() await purchase.wait()
check market.selected[0] == offer2.id check market.selected[0] == offer2.id
@ -104,7 +104,7 @@ suite "Purchasing":
offer2.expiry = expired offer2.expiry = expired
discard await market.offerStorage(offer1) discard await market.offerStorage(offer1)
discard await market.offerStorage(offer2) discard await market.offerStorage(offer2)
market.advanceTimeTo(request.expiry) clock.set(request.expiry.truncate(int64))
await purchase.wait() await purchase.wait()
check market.selected[0] == offer1.id check market.selected[0] == offer1.id
@ -121,6 +121,6 @@ suite "Purchasing":
offer2.expiry = getTime().toUnix().u256 + expiryMargin - 1 offer2.expiry = getTime().toUnix().u256 + expiryMargin - 1
discard await market.offerStorage(offer1) discard await market.offerStorage(offer1)
discard await market.offerStorage(offer2) discard await market.offerStorage(offer2)
market.advanceTimeTo(request.expiry) clock.set(request.expiry.truncate(int64))
await purchase.wait() await purchase.wait()
check market.selected[0] == offer1.id check market.selected[0] == offer1.id

View File

@ -74,7 +74,7 @@ suite "Sales":
test "sets expiry time of offer": test "sets expiry time of offer":
sales.add(availability) sales.add(availability)
let now = getTime().toUnix().u256 let now = clock.now().u256
discard await market.requestStorage(request) discard await market.requestStorage(request)
check market.offered[0].expiry == now + sales.offerExpiryInterval check market.offered[0].expiry == now + sales.offerExpiryInterval
@ -111,6 +111,6 @@ suite "Sales":
sales.add(availability) sales.add(availability)
discard await market.requestStorage(request) discard await market.requestStorage(request)
let offer = market.offered[0] let offer = market.offered[0]
market.advanceTimeTo(offer.expiry) clock.set(offer.expiry.truncate(int64))
await sleepAsync(chronos.seconds(1)) await sleepAsync(chronos.seconds(2))
check sales.available.contains(availability) check sales.available.contains(availability)