feat: repair is rewarded (#1022)
* feat: repair is rewarded * chore: update contracts repo * feat: proving loop handles repair case * test: assert repair state * chore: update contracts repo * fix: upon unknown state of repair go to error
This commit is contained in:
parent
d10072bf67
commit
19af79786e
|
@ -84,6 +84,11 @@ method proofTimeout*(market: OnChainMarket): Future[UInt256] {.async.} =
|
||||||
let config = await market.config()
|
let config = await market.config()
|
||||||
return config.proofs.timeout
|
return config.proofs.timeout
|
||||||
|
|
||||||
|
method repairRewardPercentage*(market: OnChainMarket): Future[uint8] {.async.} =
|
||||||
|
convertEthersError:
|
||||||
|
let config = await market.contract.configuration()
|
||||||
|
return config.collateral.repairRewardPercentage
|
||||||
|
|
||||||
method proofDowntime*(market: OnChainMarket): Future[uint8] {.async.} =
|
method proofDowntime*(market: OnChainMarket): Future[uint8] {.async.} =
|
||||||
convertEthersError:
|
convertEthersError:
|
||||||
let config = await market.config()
|
let config = await market.config()
|
||||||
|
|
|
@ -49,6 +49,7 @@ type
|
||||||
Failed
|
Failed
|
||||||
Paid
|
Paid
|
||||||
Cancelled
|
Cancelled
|
||||||
|
Repair
|
||||||
|
|
||||||
proc `==`*(x, y: Nonce): bool {.borrow.}
|
proc `==`*(x, y: Nonce): bool {.borrow.}
|
||||||
proc `==`*(x, y: RequestId): bool {.borrow.}
|
proc `==`*(x, y: RequestId): bool {.borrow.}
|
||||||
|
|
|
@ -67,6 +67,9 @@ method periodicity*(market: Market): Future[Periodicity] {.base, async.} =
|
||||||
method proofTimeout*(market: Market): Future[UInt256] {.base, async.} =
|
method proofTimeout*(market: Market): Future[UInt256] {.base, async.} =
|
||||||
raiseAssert("not implemented")
|
raiseAssert("not implemented")
|
||||||
|
|
||||||
|
method repairRewardPercentage*(market: Market): Future[uint8] {.base, async.} =
|
||||||
|
raiseAssert("not implemented")
|
||||||
|
|
||||||
method proofDowntime*(market: Market): Future[uint8] {.base, async.} =
|
method proofDowntime*(market: Market): Future[uint8] {.base, async.} =
|
||||||
raiseAssert("not implemented")
|
raiseAssert("not implemented")
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import pkg/stint
|
||||||
import ../../logutils
|
import ../../logutils
|
||||||
import ../../market
|
import ../../market
|
||||||
import ../statemachine
|
import ../statemachine
|
||||||
|
@ -27,13 +28,23 @@ method onFailed*(state: SaleFilling, request: StorageRequest): ?State =
|
||||||
method run(state: SaleFilling, machine: Machine): Future[?State] {.async.} =
|
method run(state: SaleFilling, machine: Machine): Future[?State] {.async.} =
|
||||||
let data = SalesAgent(machine).data
|
let data = SalesAgent(machine).data
|
||||||
let market = SalesAgent(machine).context.market
|
let market = SalesAgent(machine).context.market
|
||||||
without (collateral =? data.request.?ask.?collateral):
|
without (fullCollateral =? data.request.?ask.?collateral):
|
||||||
raiseAssert "Request not set"
|
raiseAssert "Request not set"
|
||||||
|
|
||||||
logScope:
|
logScope:
|
||||||
requestId = data.requestId
|
requestId = data.requestId
|
||||||
slotIndex = data.slotIndex
|
slotIndex = data.slotIndex
|
||||||
|
|
||||||
|
let slotState = await market.slotState(slotId(data.requestId, data.slotIndex))
|
||||||
|
var collateral: Uint256
|
||||||
|
|
||||||
|
if slotState == SlotState.Repair:
|
||||||
|
# When repairing the node gets "discount" on the collateral that it needs to
|
||||||
|
let repairRewardPercentage = (await market.repairRewardPercentage).u256
|
||||||
|
collateral = fullCollateral - ((fullCollateral * repairRewardPercentage)).div(100.u256)
|
||||||
|
else:
|
||||||
|
collateral = fullCollateral
|
||||||
|
|
||||||
debug "Filling slot"
|
debug "Filling slot"
|
||||||
try:
|
try:
|
||||||
await market.fillSlot(data.requestId, data.slotIndex, state.proof, collateral)
|
await market.fillSlot(data.requestId, data.slotIndex, state.proof, collateral)
|
||||||
|
|
|
@ -49,7 +49,7 @@ method run*(state: SalePreparing, machine: Machine): Future[?State] {.async.} =
|
||||||
|
|
||||||
let slotId = slotId(data.requestId, data.slotIndex)
|
let slotId = slotId(data.requestId, data.slotIndex)
|
||||||
let state = await market.slotState(slotId)
|
let state = await market.slotState(slotId)
|
||||||
if state != SlotState.Free:
|
if state != SlotState.Free and state != SlotState.Repair:
|
||||||
return some State(SaleIgnored(reprocessSlot: false, returnBytes: false))
|
return some State(SaleIgnored(reprocessSlot: false, returnBytes: false))
|
||||||
|
|
||||||
# TODO: Once implemented, check to ensure the host is allowed to fill the slot,
|
# TODO: Once implemented, check to ensure the host is allowed to fill the slot,
|
||||||
|
|
|
@ -16,6 +16,7 @@ logScope:
|
||||||
topics = "marketplace sales proving"
|
topics = "marketplace sales proving"
|
||||||
|
|
||||||
type
|
type
|
||||||
|
SlotFreedError* = object of CatchableError
|
||||||
SlotNotFilledError* = object of CatchableError
|
SlotNotFilledError* = object of CatchableError
|
||||||
SaleProving* = ref object of ErrorHandlingState
|
SaleProving* = ref object of ErrorHandlingState
|
||||||
loop: Future[void]
|
loop: Future[void]
|
||||||
|
@ -82,6 +83,10 @@ proc proveLoop(
|
||||||
of SlotState.Cancelled:
|
of SlotState.Cancelled:
|
||||||
debug "Slot reached cancelled state"
|
debug "Slot reached cancelled state"
|
||||||
# do nothing, let onCancelled callback take care of it
|
# do nothing, let onCancelled callback take care of it
|
||||||
|
of SlotState.Repair:
|
||||||
|
warn "Slot was forcible freed"
|
||||||
|
let message = "Slot was forcible freed and host was removed from its hosting"
|
||||||
|
raise newException(SlotFreedError, message)
|
||||||
of SlotState.Failed:
|
of SlotState.Failed:
|
||||||
debug "Slot reached failed state"
|
debug "Slot reached failed state"
|
||||||
# do nothing, let onFailed callback take care of it
|
# do nothing, let onFailed callback take care of it
|
||||||
|
|
|
@ -5,6 +5,7 @@ import ./filled
|
||||||
import ./finished
|
import ./finished
|
||||||
import ./failed
|
import ./failed
|
||||||
import ./errored
|
import ./errored
|
||||||
|
import ./proving
|
||||||
import ./cancelled
|
import ./cancelled
|
||||||
import ./payout
|
import ./payout
|
||||||
|
|
||||||
|
@ -38,7 +39,7 @@ method run*(state: SaleUnknown, machine: Machine): Future[?State] {.async.} =
|
||||||
case slotState
|
case slotState
|
||||||
of SlotState.Free:
|
of SlotState.Free:
|
||||||
let error = newException(UnexpectedSlotError,
|
let error = newException(UnexpectedSlotError,
|
||||||
"slot state on chain should not be 'free'")
|
"Slot state on chain should not be 'free'")
|
||||||
return some State(SaleErrored(error: error))
|
return some State(SaleErrored(error: error))
|
||||||
of SlotState.Filled:
|
of SlotState.Filled:
|
||||||
return some State(SaleFilled())
|
return some State(SaleFilled())
|
||||||
|
@ -50,3 +51,7 @@ method run*(state: SaleUnknown, machine: Machine): Future[?State] {.async.} =
|
||||||
return some State(SaleFailed())
|
return some State(SaleFailed())
|
||||||
of SlotState.Cancelled:
|
of SlotState.Cancelled:
|
||||||
return some State(SaleCancelled())
|
return some State(SaleCancelled())
|
||||||
|
of SlotState.Repair:
|
||||||
|
let error = newException(SlotFreedError,
|
||||||
|
"Slot was forcible freed and host was removed from its hosting")
|
||||||
|
return some State(SaleErrored(error: error))
|
||||||
|
|
|
@ -125,6 +125,9 @@ method proofTimeout*(market: MockMarket): Future[UInt256] {.async.} =
|
||||||
method proofDowntime*(market: MockMarket): Future[uint8] {.async.} =
|
method proofDowntime*(market: MockMarket): Future[uint8] {.async.} =
|
||||||
return market.config.proofs.downtime
|
return market.config.proofs.downtime
|
||||||
|
|
||||||
|
method repairRewardPercentage*(market: MockMarket): Future[uint8] {.async.} =
|
||||||
|
return market.config.collateral.repairRewardPercentage
|
||||||
|
|
||||||
method getPointer*(market: MockMarket, slotId: SlotId): Future[uint8] {.async.} =
|
method getPointer*(market: MockMarket, slotId: SlotId): Future[uint8] {.async.} =
|
||||||
return market.proofPointer
|
return market.proofPointer
|
||||||
|
|
||||||
|
|
|
@ -303,7 +303,7 @@ ethersuite "On-Chain Market":
|
||||||
let slotId = request.slotId(slotIndex.u256)
|
let slotId = request.slotId(slotIndex.u256)
|
||||||
while true:
|
while true:
|
||||||
let slotState = await marketplace.slotState(slotId)
|
let slotState = await marketplace.slotState(slotId)
|
||||||
if slotState == SlotState.Free:
|
if slotState == SlotState.Repair or slotState == SlotState.Failed:
|
||||||
break
|
break
|
||||||
await waitUntilProofRequired(slotId)
|
await waitUntilProofRequired(slotId)
|
||||||
let missingPeriod = periodicity.periodOf(await ethProvider.currentTime())
|
let missingPeriod = periodicity.periodOf(await ethProvider.currentTime())
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 945f6008c8817abd7ca43a40368d33bb1e014c14
|
Subproject commit dfab6102e71d2acaff86af45b87be2536530c624
|
Loading…
Reference in New Issue