mirror of
https://github.com/codex-storage/nim-codex.git
synced 2025-02-05 17:43:50 +00:00
Use configSync to avoid async pragma in onStorageRequested
This commit is contained in:
parent
68565a16a5
commit
43f6a9ec0d
@ -51,6 +51,9 @@ proc config(market: OnChainMarket): Future[MarketplaceConfig] {.async.} =
|
||||
|
||||
return resolvedConfig
|
||||
|
||||
proc configSync(market: OnChainMarket): ?MarketplaceConfig =
|
||||
return market.configuration
|
||||
|
||||
proc approveFunds(market: OnChainMarket, amount: UInt256) {.async.} =
|
||||
debug "Approving tokens", amount
|
||||
convertEthersError:
|
||||
@ -79,7 +82,7 @@ method proofTimeout*(market: OnChainMarket): Future[UInt256] {.async.} =
|
||||
|
||||
method repairRewardPercentage*(market: OnChainMarket): Future[uint8] {.async.} =
|
||||
convertEthersError:
|
||||
let config = await market.contract.configuration()
|
||||
let config = await market.config()
|
||||
return config.collateral.repairRewardPercentage
|
||||
|
||||
method proofDowntime*(market: OnChainMarket): Future[uint8] {.async.} =
|
||||
@ -111,12 +114,14 @@ method requestStorage(market: OnChainMarket, request: StorageRequest) {.async.}
|
||||
|
||||
method getRequest*(
|
||||
market: OnChainMarket, id: RequestId
|
||||
): Future[?StorageRequest] {.async.} =
|
||||
convertEthersError:
|
||||
try:
|
||||
return some await market.contract.getRequest(id)
|
||||
except Marketplace_UnknownRequest:
|
||||
return none StorageRequest
|
||||
): Future[?StorageRequest] {.async: (raises: []).} =
|
||||
try:
|
||||
return some await market.contract.getRequest(id)
|
||||
except Marketplace_UnknownRequest:
|
||||
return none StorageRequest
|
||||
except CatchableError as err:
|
||||
warn "Cannot retrieve the request", error = err.msg
|
||||
return none StorageRequest
|
||||
|
||||
method requestState*(
|
||||
market: OnChainMarket, requestId: RequestId
|
||||
@ -128,7 +133,9 @@ method requestState*(
|
||||
except Marketplace_UnknownRequest:
|
||||
return none RequestState
|
||||
|
||||
method slotState*(market: OnChainMarket, slotId: SlotId): Future[SlotState] {.async.} =
|
||||
method slotState*(
|
||||
market: OnChainMarket, slotId: SlotId
|
||||
): Future[SlotState] {.async: (raises: [CatchableError]).} =
|
||||
convertEthersError:
|
||||
let overrides = CallOverrides(blockTag: some BlockTag.pending)
|
||||
return await market.contract.slotState(slotId, overrides)
|
||||
@ -486,22 +493,32 @@ method queryPastStorageRequestedEvents*(
|
||||
|
||||
method slotCollateral*(
|
||||
market: OnChainMarket, requestId: RequestId, slotIndex: UInt256
|
||||
): Future[UInt256] {.async.} =
|
||||
): Future[?UInt256] {.async: (raises: []).} =
|
||||
let slotid = slotId(requestId, slotIndex)
|
||||
let slotState = await market.slotState(slotid)
|
||||
|
||||
return await market.slotCollateral(requestId, slotState)
|
||||
try:
|
||||
let slotState = await market.slotState(slotid)
|
||||
|
||||
without request =? await market.getRequest(requestId):
|
||||
return UInt256.none
|
||||
|
||||
return market.slotCollateral(request.ask.collateralPerSlot, slotState)
|
||||
except CatchableError as err:
|
||||
error "Cannot retrieve the slot state", error = err.msg
|
||||
return UInt256.none
|
||||
|
||||
method slotCollateral*(
|
||||
market: OnChainMarket, requestId: RequestId, slotState: SlotState
|
||||
): Future[UInt256] {.async: (raises: [CancelledError, MarketError]).} =
|
||||
without request =? await market.getRequest(requestId):
|
||||
raiseMarketError("Cannot retrieve the request.")
|
||||
|
||||
market: OnChainMarket, collateralPerSlot: UInt256, slotState: SlotState
|
||||
): ?UInt256 {.raises: [].} =
|
||||
if slotState == SlotState.Repair:
|
||||
let repairRewardPercentage = (await market.repairRewardPercentage).u256
|
||||
return
|
||||
request.ask.collateralPerSlot -
|
||||
(request.ask.collateralPerSlot * repairRewardPercentage).div(100.u256)
|
||||
without repairRewardPercentage =?
|
||||
market.configSync .? collateral .? repairRewardPercentage:
|
||||
return UInt256.none
|
||||
|
||||
return request.ask.collateralPerSlot
|
||||
return (
|
||||
collateralPerSlot - (collateralPerSlot * repairRewardPercentage.u256).div(
|
||||
100.u256
|
||||
)
|
||||
).some
|
||||
|
||||
return collateralPerSlot.some
|
||||
|
@ -100,7 +100,7 @@ method mySlots*(market: Market): Future[seq[SlotId]] {.base, async.} =
|
||||
|
||||
method getRequest*(
|
||||
market: Market, id: RequestId
|
||||
): Future[?StorageRequest] {.base, async.} =
|
||||
): Future[?StorageRequest] {.base, async: (raises: []).} =
|
||||
raiseAssert("not implemented")
|
||||
|
||||
method requestState*(
|
||||
@ -108,7 +108,9 @@ method requestState*(
|
||||
): Future[?RequestState] {.base, async.} =
|
||||
raiseAssert("not implemented")
|
||||
|
||||
method slotState*(market: Market, slotId: SlotId): Future[SlotState] {.base, async.} =
|
||||
method slotState*(
|
||||
market: Market, slotId: SlotId
|
||||
): Future[SlotState] {.base, async: (raises: [CatchableError]).} =
|
||||
raiseAssert("not implemented")
|
||||
|
||||
method getRequestEnd*(
|
||||
@ -271,10 +273,10 @@ method queryPastStorageRequestedEvents*(
|
||||
|
||||
method slotCollateral*(
|
||||
market: Market, requestId: RequestId, slotIndex: UInt256
|
||||
): Future[UInt256] {.base, async.} =
|
||||
): Future[?UInt256] {.base, async: (raises: []).} =
|
||||
raiseAssert("not implemented")
|
||||
|
||||
method slotCollateral*(
|
||||
market: Market, requestId: RequestId, slotState: SlotState
|
||||
): Future[UInt256] {.base, async: (raises: [CancelledError, MarketError]).} =
|
||||
market: Market, collateralPerSlot: UInt256, slotState: SlotState
|
||||
): ?UInt256 {.base, gcsafe, raises: [].} =
|
||||
raiseAssert("not implemented")
|
||||
|
@ -153,8 +153,10 @@ proc cleanUp(
|
||||
# Re-add items back into the queue to prevent small availabilities from
|
||||
# draining the queue. Seen items will be ordered last.
|
||||
if reprocessSlot and request =? data.request:
|
||||
let collateral =
|
||||
await sales.context.market.slotCollateral(data.requestId, data.slotIndex)
|
||||
without collateral =?
|
||||
await sales.context.market.slotCollateral(data.requestId, data.slotIndex):
|
||||
error "Unable to calculate collateral; configuration data may not be retrievable."
|
||||
return
|
||||
|
||||
let queue = sales.context.slotQueue
|
||||
var seenItem = SlotQueueItem.init(
|
||||
@ -288,7 +290,7 @@ proc onAvailabilityAdded(sales: Sales, availability: Availability) {.async.} =
|
||||
|
||||
proc onStorageRequested(
|
||||
sales: Sales, requestId: RequestId, ask: StorageAsk, expiry: UInt256
|
||||
) {.async.} =
|
||||
) {.raises: [].} =
|
||||
logScope:
|
||||
topics = "marketplace sales onStorageRequested"
|
||||
requestId
|
||||
@ -300,7 +302,10 @@ proc onStorageRequested(
|
||||
trace "storage requested, adding slots to queue"
|
||||
|
||||
let market = sales.context.market
|
||||
let collateral = await market.slotCollateral(requestId, SlotState.Free)
|
||||
|
||||
without collateral =? market.slotCollateral(ask.collateralPerSlot, SlotState.Free):
|
||||
error "Unable to calculate collateral; configuration data may not be retrievable."
|
||||
return
|
||||
|
||||
without items =? SlotQueueItem.init(requestId, ask, expiry, collateral).catch, err:
|
||||
if err of SlotsOutOfRangeError:
|
||||
@ -331,31 +336,39 @@ proc onSlotFreed(sales: Sales, requestId: RequestId, slotIndex: UInt256) =
|
||||
let context = sales.context
|
||||
let market = context.market
|
||||
let queue = context.slotQueue
|
||||
var slotQueueItem: SlotQueueItem
|
||||
|
||||
try:
|
||||
without request =? await market.getRequest(requestId):
|
||||
error "unknown request in contract"
|
||||
return
|
||||
without request =? (await market.getRequest(requestId)), err:
|
||||
error "unknown request in contract", error = err.msgDetail
|
||||
return
|
||||
|
||||
# Take the repairing state into consideration to calculate the collateral.
|
||||
# This is particularly needed because it will affect the priority in the queue
|
||||
# and we want to give the user the ability to tweak the parameters.
|
||||
# Adding the repairing state directly in the queue priority calculation
|
||||
# would not allow this flexibility.
|
||||
let collateral = await market.slotCollateral(request.id, SlotState.Repair)
|
||||
# Take the repairing state into consideration to calculate the collateral.
|
||||
# This is particularly needed because it will affect the priority in the queue
|
||||
# and we want to give the user the ability to tweak the parameters.
|
||||
# Adding the repairing state directly in the queue priority calculation
|
||||
# would not allow this flexibility.
|
||||
without collateral =?
|
||||
market.slotCollateral(request.ask.collateralPerSlot, SlotState.Repair):
|
||||
error "Unable to calculate collateral; configuration data may not be retrievable."
|
||||
return
|
||||
|
||||
slotQueueItem =
|
||||
SlotQueueItem.init(request, slotIndex.truncate(uint16), collateral = collateral)
|
||||
without slotQueueItem =?
|
||||
SlotQueueItem.init(request, slotIndex.truncate(uint16), collateral = collateral).catch,
|
||||
err:
|
||||
warn "Too many slots, cannot add to queue", error = err.msgDetail
|
||||
return
|
||||
|
||||
if err =? queue.push(slotQueueItem).errorOption:
|
||||
error "failed to push slot items to queue", error = err.msgDetail
|
||||
except CancelledError:
|
||||
discard # do not propagate as addSlotToQueue was asyncSpawned
|
||||
except CatchableError as e:
|
||||
error "failed to get request from contract and add slots to queue",
|
||||
error = e.msgDetail
|
||||
if err =? queue.push(slotQueueItem).errorOption:
|
||||
if err of SlotQueueItemExistsError:
|
||||
error "Failed to push item to queue becaue it already exists",
|
||||
error = err.msgDetail
|
||||
elif err of QueueNotRunningError:
|
||||
warn "Failed to push item to queue becaue queue is not running",
|
||||
error = err.msgDetail
|
||||
|
||||
# We could get rid of this by adding the storage ask in the SlotFreed event,
|
||||
# so we would need to call getRequest to get the collateralPerSlot.
|
||||
# Or when the request cache is merged, we could assume that the request will be
|
||||
# in the cache.
|
||||
let fut = addSlotToQueue()
|
||||
sales.trackedFutures.track(fut)
|
||||
asyncSpawn fut
|
||||
@ -364,8 +377,13 @@ proc subscribeRequested(sales: Sales) {.async.} =
|
||||
let context = sales.context
|
||||
let market = context.market
|
||||
|
||||
proc onStorageRequested(requestId: RequestId, ask: StorageAsk, expiry: UInt256) =
|
||||
discard sales.onStorageRequested(requestId, ask, expiry)
|
||||
proc onStorageRequested(
|
||||
requestId: RequestId, ask: StorageAsk, expiry: UInt256
|
||||
) {.raises: [].} =
|
||||
sales.onStorageRequested(requestId, ask, expiry)
|
||||
|
||||
# Ensure that the config is loaded and repairRewardPercentage is available
|
||||
discard await market.repairRewardPercentage()
|
||||
|
||||
try:
|
||||
let sub = await market.subscribeRequests(onStorageRequested)
|
||||
|
@ -161,7 +161,7 @@ proc init*(
|
||||
ask: StorageAsk,
|
||||
expiry: UInt256,
|
||||
collateral: UInt256,
|
||||
): seq[SlotQueueItem] =
|
||||
): seq[SlotQueueItem] {.raises: [SlotsOutOfRangeError].} =
|
||||
if not ask.slots.inRange:
|
||||
raise newException(SlotsOutOfRangeError, "Too many slots")
|
||||
|
||||
@ -240,7 +240,7 @@ proc unpause*(self: SlotQueue) =
|
||||
# set unpaused flag to true -- unblocks coroutines waiting on unpaused.wait()
|
||||
self.unpaused.fire()
|
||||
|
||||
proc push*(self: SlotQueue, item: SlotQueueItem): ?!void =
|
||||
proc push*(self: SlotQueue, item: SlotQueueItem): ?!void {.raises: [].} =
|
||||
logScope:
|
||||
requestId = item.requestId
|
||||
slotIndex = item.slotIndex
|
||||
|
@ -35,7 +35,9 @@ method run(state: SaleFilling, machine: Machine): Future[?State] {.async.} =
|
||||
requestId = data.requestId
|
||||
slotIndex = data.slotIndex
|
||||
|
||||
let collateral = await market.slotCollateral(data.requestId, data.slotIndex)
|
||||
without collateral =? await market.slotCollateral(data.requestId, data.slotIndex):
|
||||
error "Unable to calculate collateral; configuration data may not be retrievable."
|
||||
return
|
||||
|
||||
debug "Filling slot"
|
||||
try:
|
||||
|
@ -165,7 +165,7 @@ method mySlots*(market: MockMarket): Future[seq[SlotId]] {.async.} =
|
||||
|
||||
method getRequest*(
|
||||
market: MockMarket, id: RequestId
|
||||
): Future[?StorageRequest] {.async.} =
|
||||
): Future[?StorageRequest] {.async: (raises: []).} =
|
||||
for request in market.requested:
|
||||
if request.id == id:
|
||||
return some request
|
||||
@ -183,10 +183,18 @@ method requestState*(
|
||||
): Future[?RequestState] {.async.} =
|
||||
return market.requestState .? [requestId]
|
||||
|
||||
method slotState*(market: MockMarket, slotId: SlotId): Future[SlotState] {.async.} =
|
||||
if not market.slotState.hasKey(slotId):
|
||||
method slotState*(
|
||||
market: MockMarket, slotId: SlotId
|
||||
): Future[SlotState] {.async: (raises: [CatchableError]).} =
|
||||
if slotId notin market.slotState:
|
||||
return SlotState.Free
|
||||
return market.slotState[slotId]
|
||||
|
||||
try:
|
||||
return market.slotState[slotId]
|
||||
except ref KeyError:
|
||||
# Should never reach that case.
|
||||
# Just returning a random slot state.
|
||||
return SlotState.Repair
|
||||
|
||||
method getRequestEnd*(
|
||||
market: MockMarket, id: RequestId
|
||||
@ -529,21 +537,27 @@ method unsubscribe*(subscription: SlotReservationsFullSubscription) {.async.} =
|
||||
|
||||
method slotCollateral*(
|
||||
market: MockMarket, requestId: RequestId, slotIndex: UInt256
|
||||
): Future[UInt256] {.async.} =
|
||||
): Future[?UInt256] {.async: (raises: []).} =
|
||||
let slotid = slotId(requestId, slotIndex)
|
||||
let state = await slotState(market, slotid)
|
||||
return await market.slotCollateral(requestId, state)
|
||||
|
||||
try:
|
||||
let state = await slotState(market, slotid)
|
||||
|
||||
without request =? await market.getRequest(requestId):
|
||||
return UInt256.none
|
||||
|
||||
return market.slotCollateral(request.ask.collateralPerSlot, state)
|
||||
except CatchableError:
|
||||
return UInt256.none
|
||||
|
||||
method slotCollateral*(
|
||||
market: MockMarket, requestId: RequestId, slotState: SlotState
|
||||
): Future[UInt256] {.async: (raises: [CancelledError, MarketError]).} =
|
||||
without request =? await market.getRequest(requestId):
|
||||
raiseMarketError("Cannot retrieve the request.")
|
||||
|
||||
market: MockMarket, collateralPerSlot: UInt256, slotState: SlotState
|
||||
): ?UInt256 {.raises: [].} =
|
||||
if slotState == SlotState.Repair:
|
||||
let repairRewardPercentage = market.config.collateral.repairRewardPercentage.u256
|
||||
return
|
||||
request.ask.collateralPerSlot -
|
||||
(request.ask.collateralPerSlot * repairRewardPercentage).div(100.u256)
|
||||
|
||||
return request.ask.collateralPerSlot
|
||||
return (
|
||||
collateralPerSlot - (collateralPerSlot * repairRewardPercentage).div(100.u256)
|
||||
).some
|
||||
|
||||
return collateralPerSlot.some
|
||||
|
@ -598,18 +598,24 @@ ethersuite "On-Chain Market":
|
||||
await market.fillSlot(request.id, 0.u256, proof, request.ask.collateralPerSlot)
|
||||
|
||||
let slotId = request.slotId(0.u256)
|
||||
let collateral = await market.slotCollateral(request.id, 0.u256)
|
||||
without collateral =? await market.slotCollateral(request.id, 0.u256):
|
||||
fail()
|
||||
|
||||
check collateral == request.ask.collateralPerSlot
|
||||
|
||||
test "calculates correctly the collateral when the slot is being repaired":
|
||||
# Ensure that the config is loaded and repairRewardPercentage is available
|
||||
discard await market.repairRewardPercentage()
|
||||
|
||||
await market.requestStorage(request)
|
||||
await market.reserveSlot(request.id, 0.u256)
|
||||
await market.fillSlot(request.id, 0.u256, proof, request.ask.collateralPerSlot)
|
||||
await market.freeSlot(slotId(request.id, 0.u256))
|
||||
|
||||
let slotId = request.slotId(0.u256)
|
||||
let collateral = await market.slotCollateral(request.id, 0.u256)
|
||||
|
||||
without collateral =? await market.slotCollateral(request.id, 0.u256):
|
||||
fail()
|
||||
|
||||
# slotCollateral
|
||||
# repairRewardPercentage = 10
|
||||
|
Loading…
x
Reference in New Issue
Block a user