mirror of
https://github.com/logos-storage/logos-storage-nim.git
synced 2026-01-03 05:53:07 +00:00
formatting
This commit is contained in:
parent
0326399f7d
commit
307d85a700
@ -109,9 +109,8 @@ proc bootstrapInteractions(s: CodexServer): Future[void] {.async.} =
|
||||
quit QuitFailure
|
||||
|
||||
let marketplace = Marketplace.new(marketplaceAddress, signer)
|
||||
without market =? await OnChainMarket.load(
|
||||
marketplace, config.marketplaceRequestCacheSize
|
||||
), error:
|
||||
without market =?
|
||||
await OnChainMarket.load(marketplace, config.marketplaceRequestCacheSize), error:
|
||||
fatal "Cannot load market", error = error.msg
|
||||
quit QuitFailure
|
||||
|
||||
|
||||
@ -51,13 +51,10 @@ proc load*(
|
||||
|
||||
var requestCache = newLruCache[string, StorageRequest](int(requestCacheSize))
|
||||
|
||||
let market = OnChainMarket(
|
||||
contract: contract,
|
||||
signer: signer,
|
||||
requestCache: requestCache,
|
||||
)
|
||||
let market =
|
||||
OnChainMarket(contract: contract, signer: signer, requestCache: requestCache)
|
||||
|
||||
market.configuration = ? await market.loadConfig()
|
||||
market.configuration = ?await market.loadConfig()
|
||||
|
||||
return success market
|
||||
|
||||
@ -114,7 +111,7 @@ method periodicity*(market: OnChainMarket): Periodicity =
|
||||
let period = market.configuration.proofs.period
|
||||
return Periodicity(seconds: period)
|
||||
|
||||
method proofTimeout*(market: OnChainMarket): StorageDuration =
|
||||
method proofTimeout*(market: OnChainMarket): StorageDuration =
|
||||
return market.configuration.proofs.timeout
|
||||
|
||||
method repairRewardPercentage*(market: OnChainMarket): uint8 =
|
||||
|
||||
@ -55,9 +55,7 @@ type
|
||||
|
||||
proc configuration*(marketplace: Marketplace): MarketplaceConfig {.contract, view.}
|
||||
proc token*(marketplace: Marketplace): Address {.contract, view.}
|
||||
proc currentCollateral*(
|
||||
marketplace: Marketplace, id: SlotId
|
||||
): Tokens {.contract, view.}
|
||||
proc currentCollateral*(marketplace: Marketplace, id: SlotId): Tokens {.contract, view.}
|
||||
|
||||
proc requestStorage*(
|
||||
marketplace: Marketplace, request: StorageRequest
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import ../clock
|
||||
import ./requests
|
||||
|
||||
type
|
||||
Periodicity* = object
|
||||
seconds*: StorageDuration
|
||||
type Periodicity* = object
|
||||
seconds*: StorageDuration
|
||||
|
||||
func periodOf*(periodicity: Periodicity, timestamp: StorageTimestamp): ProofPeriod =
|
||||
ProofPeriod.init(timestamp.u40 div periodicity.seconds.u40)
|
||||
|
||||
@ -6,8 +6,10 @@ from ../clock import SecondsSince1970
|
||||
type
|
||||
StorageTimestamp* = object
|
||||
value: StUint[40]
|
||||
|
||||
StorageDuration* = object
|
||||
value: StUint[40]
|
||||
|
||||
ProofPeriod* = object
|
||||
value: StUint[40]
|
||||
|
||||
@ -43,7 +45,7 @@ func `'StorageDuration`*(value: static string): StorageDuration =
|
||||
StorageDuration(value: parsed)
|
||||
|
||||
func `'StorageTimestamp`*(value: static string): StorageTimestamp =
|
||||
const parsed =parse(value, StUint[40])
|
||||
const parsed = parse(value, StUint[40])
|
||||
StorageTimestamp(value: parsed)
|
||||
|
||||
func init*(_: type StorageDuration, value: StUint[40]): StorageDuration =
|
||||
@ -158,11 +160,10 @@ func `%`*(value: StorageDuration | StorageTimestamp | ProofPeriod): JsonNode =
|
||||
%value.value
|
||||
|
||||
func fromJson*(_: type StorageDuration, json: JsonNode): ?!StorageDuration =
|
||||
success StorageDuration(value: ? StUint[40].fromJson(json))
|
||||
success StorageDuration(value: ?StUint[40].fromJson(json))
|
||||
|
||||
func fromJson*(_: type StorageTimestamp, json: JsonNode): ?!StorageTimestamp =
|
||||
success StorageTimestamp(value: ? StUint[40].fromJson(json))
|
||||
success StorageTimestamp(value: ?StUint[40].fromJson(json))
|
||||
|
||||
func fromJson*(_: type ProofPeriod, json: JsonNode): ?!ProofPeriod =
|
||||
success ProofPeriod(value: ? StUint[40].fromJson(json))
|
||||
|
||||
success ProofPeriod(value: ?StUint[40].fromJson(json))
|
||||
|
||||
@ -6,6 +6,7 @@ import ./timestamps
|
||||
type
|
||||
TokensPerSecond* = object
|
||||
value: StUint[96]
|
||||
|
||||
Tokens* = object
|
||||
value: StUint[128]
|
||||
|
||||
@ -101,8 +102,7 @@ func `%`*(value: TokensPerSecond | Tokens): JsonNode =
|
||||
%value.value
|
||||
|
||||
func fromJson*(_: type TokensPerSecond, json: JsonNode): ?!TokensPerSecond =
|
||||
success TokensPerSecond(value: ? StUint[96].fromJson(json))
|
||||
success TokensPerSecond(value: ?StUint[96].fromJson(json))
|
||||
|
||||
func fromJson*(_: type Tokens, json: JsonNode): ?!Tokens =
|
||||
success Tokens(value: ? UInt128.fromJson(json))
|
||||
|
||||
success Tokens(value: ?UInt128.fromJson(json))
|
||||
|
||||
@ -21,8 +21,9 @@ type
|
||||
SlotStateMismatchError* = object of MarketError
|
||||
SlotReservationNotAllowedError* = object of MarketError
|
||||
Subscription* = ref object of RootObj
|
||||
OnRequest* =
|
||||
proc(id: RequestId, ask: StorageAsk, expiry: StorageTimestamp) {.gcsafe, upraises: [].}
|
||||
OnRequest* = proc(id: RequestId, ask: StorageAsk, expiry: StorageTimestamp) {.
|
||||
gcsafe, upraises: []
|
||||
.}
|
||||
OnFulfillment* = proc(requestId: RequestId) {.gcsafe, upraises: [].}
|
||||
OnSlotFilled* = proc(requestId: RequestId, slotIndex: uint64) {.gcsafe, upraises: [].}
|
||||
OnSlotFreed* = proc(requestId: RequestId, slotIndex: uint64) {.gcsafe, upraises: [].}
|
||||
@ -65,19 +66,21 @@ method getSigner*(
|
||||
): Future[Address] {.base, async: (raises: [CancelledError, MarketError]).} =
|
||||
raiseAssert("not implemented")
|
||||
|
||||
method zkeyHash*(market: Market): string {.base, gcsafe, raises:[].} =
|
||||
method zkeyHash*(market: Market): string {.base, gcsafe, raises: [].} =
|
||||
raiseAssert("not implemented")
|
||||
|
||||
method periodicity*(market: Market): Periodicity {.base, gcsafe, raises:[].} =
|
||||
method periodicity*(market: Market): Periodicity {.base, gcsafe, raises: [].} =
|
||||
raiseAssert("not implemented")
|
||||
|
||||
method proofTimeout*(market: Market): StorageDuration {.base, gcsafe, raises:[].} =
|
||||
method proofTimeout*(market: Market): StorageDuration {.base, gcsafe, raises: [].} =
|
||||
raiseAssert("not implemented")
|
||||
|
||||
method repairRewardPercentage*(market: Market): uint8 {.base, gcsafe, raises:[].} =
|
||||
method repairRewardPercentage*(market: Market): uint8 {.base, gcsafe, raises: [].} =
|
||||
raiseAssert("not implemented")
|
||||
|
||||
method requestDurationLimit*(market: Market): StorageDuration {.base, gcsafe, raises:[].} =
|
||||
method requestDurationLimit*(
|
||||
market: Market
|
||||
): StorageDuration {.base, gcsafe, raises: [].} =
|
||||
raiseAssert("not implemented")
|
||||
|
||||
method proofDowntime*(market: Market): uint8 {.base, gcsafe, raises: [].} =
|
||||
|
||||
@ -341,9 +341,9 @@ proc onSlotFreed(sales: Sales, requestId: RequestId, slotIndex: uint64) =
|
||||
|
||||
without slotQueueItem =?
|
||||
SlotQueueItem.init(request, slotIndex.uint16, collateral, repairReward).catch,
|
||||
err:
|
||||
warn "Too many slots, cannot add to queue", error = err.msgDetail
|
||||
return
|
||||
err:
|
||||
warn "Too many slots, cannot add to queue", error = err.msgDetail
|
||||
return
|
||||
|
||||
if err =? queue.push(slotQueueItem).errorOption:
|
||||
if err of SlotQueueItemExistsError:
|
||||
|
||||
@ -30,7 +30,7 @@ type
|
||||
expiry: StorageTimestamp,
|
||||
slot: uint64,
|
||||
blocksCb: BlocksCb,
|
||||
isRepairing: bool
|
||||
isRepairing: bool,
|
||||
): Future[?!void] {.gcsafe, upraises: [].}
|
||||
OnProve* = proc(slot: Slot, challenge: ProofChallenge): Future[?!Groth16Proof] {.
|
||||
gcsafe, upraises: []
|
||||
|
||||
@ -173,7 +173,9 @@ proc init*(
|
||||
repairReward = 0'Tokens,
|
||||
seen = false,
|
||||
): SlotQueueItem =
|
||||
SlotQueueItem.init(requestId, slotIndex, ask, some expiry, collateral, repairReward, seen)
|
||||
SlotQueueItem.init(
|
||||
requestId, slotIndex, ask, some expiry, collateral, repairReward, seen
|
||||
)
|
||||
|
||||
proc init*(
|
||||
_: type SlotQueueItem,
|
||||
@ -188,7 +190,7 @@ proc init*(
|
||||
slotSize: request.ask.slotSize,
|
||||
duration: request.ask.duration,
|
||||
pricePerBytePerSecond: request.ask.pricePerBytePerSecond,
|
||||
collateral: collateral
|
||||
collateral: collateral,
|
||||
)
|
||||
|
||||
proc init(
|
||||
|
||||
@ -51,10 +51,7 @@ method run*(
|
||||
onClear(request, data.slotIndex)
|
||||
|
||||
if onCleanUp =? agent.onCleanUp:
|
||||
await onCleanUp(
|
||||
reprocessSlot = false,
|
||||
returnedCollateral = returnedCollateral,
|
||||
)
|
||||
await onCleanUp(reprocessSlot = false, returnedCollateral = returnedCollateral)
|
||||
|
||||
warn "Sale cancelled due to timeout",
|
||||
requestId = data.requestId, slotIndex = data.slotIndex
|
||||
|
||||
@ -81,7 +81,8 @@ method run*(
|
||||
expiry = await market.requestExpiresAt(requestId)
|
||||
|
||||
trace "Starting download"
|
||||
if err =? (await onStore(request, expiry, data.slotIndex, onBlocks, isRepairing)).errorOption:
|
||||
if err =?
|
||||
(await onStore(request, expiry, data.slotIndex, onBlocks, isRepairing)).errorOption:
|
||||
return some State(SaleErrored(error: err, reprocessSlot: false))
|
||||
|
||||
trace "Download complete"
|
||||
|
||||
@ -72,11 +72,8 @@ method run*(
|
||||
|
||||
without availability =?
|
||||
await reservations.findAvailability(
|
||||
request.ask.slotSize,
|
||||
request.ask.duration,
|
||||
request.ask.pricePerBytePerSecond,
|
||||
request.ask.collateralPerByte,
|
||||
requestEnd
|
||||
request.ask.slotSize, request.ask.duration, request.ask.pricePerBytePerSecond,
|
||||
request.ask.collateralPerByte, requestEnd,
|
||||
):
|
||||
debug "No availability found for request, ignoring"
|
||||
|
||||
@ -86,12 +83,8 @@ method run*(
|
||||
|
||||
without reservation =?
|
||||
await reservations.createReservation(
|
||||
availability.id,
|
||||
request.ask.slotSize,
|
||||
request.id,
|
||||
data.slotIndex,
|
||||
request.ask.collateralPerByte,
|
||||
requestEnd
|
||||
availability.id, request.ask.slotSize, request.id, data.slotIndex,
|
||||
request.ask.collateralPerByte, requestEnd,
|
||||
), error:
|
||||
trace "Creation of reservation failed"
|
||||
# Race condition:
|
||||
|
||||
@ -20,7 +20,9 @@ when codex_enable_proof_failures:
|
||||
failEveryNProofs*: int
|
||||
proofCount: int
|
||||
|
||||
proc onSubmitProofError(error: ref CatchableError, period: ProofPeriod, slotId: SlotId) =
|
||||
proc onSubmitProofError(
|
||||
error: ref CatchableError, period: ProofPeriod, slotId: SlotId
|
||||
) =
|
||||
error "Submitting invalid proof failed", period, slotId, msg = error.msgDetail
|
||||
|
||||
method prove*(
|
||||
|
||||
@ -501,7 +501,11 @@ method queryPastStorageRequestedEvents*(
|
||||
): Future[seq[StorageRequested]] {.async.} =
|
||||
return market.requested.map(
|
||||
request =>
|
||||
StorageRequested(requestId: request.id, ask: request.ask, expiry: market.requestExpiry[request.id])
|
||||
StorageRequested(
|
||||
requestId: request.id,
|
||||
ask: request.ask,
|
||||
expiry: market.requestExpiry[request.id],
|
||||
)
|
||||
)
|
||||
|
||||
method queryPastStorageRequestedEvents*(
|
||||
@ -509,7 +513,11 @@ method queryPastStorageRequestedEvents*(
|
||||
): Future[seq[StorageRequested]] {.async.} =
|
||||
return market.requested.map(
|
||||
request =>
|
||||
StorageRequested(requestId: request.id, ask: request.ask, expiry: market.requestExpiry[request.id])
|
||||
StorageRequested(
|
||||
requestId: request.id,
|
||||
ask: request.ask,
|
||||
expiry: market.requestExpiry[request.id],
|
||||
)
|
||||
)
|
||||
|
||||
method queryPastSlotFilledEvents*(
|
||||
|
||||
@ -124,7 +124,11 @@ asyncchecksuite "Test Node - Host contracts":
|
||||
fetchedBytes += blk.data.len.uint
|
||||
return success()
|
||||
|
||||
(await onStore(request, StorageTimestamp.init(expiry), 1.uint64, onBlocks, isRepairing = false)).tryGet()
|
||||
(
|
||||
await onStore(
|
||||
request, StorageTimestamp.init(expiry), 1.uint64, onBlocks, isRepairing = false
|
||||
)
|
||||
).tryGet()
|
||||
check fetchedBytes == 12 * DefaultBlockSize.uint
|
||||
|
||||
let indexer = verifiable.protectedStrategy.init(
|
||||
|
||||
@ -34,8 +34,7 @@ asyncchecksuite "sales state 'preparing'":
|
||||
var reservations: MockReservations
|
||||
|
||||
setup:
|
||||
let collateral =
|
||||
request.ask.collateralPerSlot * request.ask.slots
|
||||
let collateral = request.ask.collateralPerSlot * request.ask.slots
|
||||
availability = Availability.init(
|
||||
totalSize = request.ask.slotSize + 100.uint64,
|
||||
freeSize = request.ask.slotSize + 100.uint64,
|
||||
|
||||
@ -69,22 +69,12 @@ asyncchecksuite "Reservations module":
|
||||
|
||||
test "generates unique ids for storage availability":
|
||||
let availability1 = Availability.init(
|
||||
1.uint64,
|
||||
2.uint64,
|
||||
3'StorageDuration,
|
||||
4'TokensPerSecond,
|
||||
5'Tokens,
|
||||
true,
|
||||
0'StorageTimestamp
|
||||
1.uint64, 2.uint64, 3'StorageDuration, 4'TokensPerSecond, 5'Tokens, true,
|
||||
0'StorageTimestamp,
|
||||
)
|
||||
let availability2 = Availability.init(
|
||||
1.uint64,
|
||||
2.uint64,
|
||||
3'StorageDuration,
|
||||
4'TokensPerSecond,
|
||||
5'Tokens,
|
||||
true,
|
||||
0'StorageTimestamp
|
||||
1.uint64, 2.uint64, 3'StorageDuration, 4'TokensPerSecond, 5'Tokens, true,
|
||||
0'StorageTimestamp,
|
||||
)
|
||||
check availability1.id != availability2.id
|
||||
|
||||
@ -185,7 +175,7 @@ asyncchecksuite "Reservations module":
|
||||
|
||||
let two = reservations.createReservation(
|
||||
availability.id, availability.totalSize, RequestId.example, uint64.example,
|
||||
Tokens.example, validUntil
|
||||
Tokens.example, validUntil,
|
||||
)
|
||||
|
||||
let oneResult = await one
|
||||
|
||||
@ -66,7 +66,7 @@ asyncchecksuite "Sales - start":
|
||||
expiry: StorageTimestamp,
|
||||
slot: uint64,
|
||||
onBatch: BatchProc,
|
||||
isRepairing = false
|
||||
isRepairing = false,
|
||||
): Future[?!void] {.async.} =
|
||||
return success()
|
||||
|
||||
@ -187,7 +187,7 @@ asyncchecksuite "Sales":
|
||||
expiry: StorageTimestamp,
|
||||
slot: uint64,
|
||||
onBatch: BatchProc,
|
||||
isRepairing = false
|
||||
isRepairing = false,
|
||||
): Future[?!void] {.async.} =
|
||||
return success()
|
||||
|
||||
@ -372,7 +372,11 @@ asyncchecksuite "Sales":
|
||||
|
||||
test "availability size is reduced by request slot size when fully downloaded":
|
||||
sales.onStore = proc(
|
||||
request: StorageRequest, expiry: StorageTimestamp, slot: uint64, onBatch: BatchProc, isRepairing = false
|
||||
request: StorageRequest,
|
||||
expiry: StorageTimestamp,
|
||||
slot: uint64,
|
||||
onBatch: BatchProc,
|
||||
isRepairing = false,
|
||||
): Future[?!void] {.async.} =
|
||||
let blk = bt.Block.new(@[1.byte]).get
|
||||
await onBatch(blk.repeat(request.ask.slotSize.int))
|
||||
@ -385,7 +389,11 @@ asyncchecksuite "Sales":
|
||||
test "bytes are returned to availability once finished":
|
||||
var slotIndex = 0.uint64
|
||||
sales.onStore = proc(
|
||||
request: StorageRequest, expiry: StorageTimestamp, slot: uint64, onBatch: BatchProc, isRepairing = false
|
||||
request: StorageRequest,
|
||||
expiry: StorageTimestamp,
|
||||
slot: uint64,
|
||||
onBatch: BatchProc,
|
||||
isRepairing = false,
|
||||
): Future[?!void] {.async.} =
|
||||
slotIndex = slot
|
||||
let blk = bt.Block.new(@[1.byte]).get
|
||||
@ -455,14 +463,17 @@ asyncchecksuite "Sales":
|
||||
check wasIgnored()
|
||||
|
||||
test "retrieves request when availability until terminates after the duration":
|
||||
let requestEnd =
|
||||
StorageTimestamp.init(getTime().toUnix()) + request.ask.duration
|
||||
let requestEnd = StorageTimestamp.init(getTime().toUnix()) + request.ask.duration
|
||||
let until = requestEnd + 1'StorageDuration
|
||||
createAvailability(until = until)
|
||||
|
||||
var storingRequest: StorageRequest
|
||||
sales.onStore = proc(
|
||||
request: StorageRequest, expiry: StorageTimestamp, slot: uint64, onBatch: BatchProc, isRepairing = false
|
||||
request: StorageRequest,
|
||||
expiry: StorageTimestamp,
|
||||
slot: uint64,
|
||||
onBatch: BatchProc,
|
||||
isRepairing = false,
|
||||
): Future[?!void] {.async.} =
|
||||
storingRequest = request
|
||||
return success()
|
||||
@ -475,7 +486,11 @@ asyncchecksuite "Sales":
|
||||
var storingRequest: StorageRequest
|
||||
var storingSlot: uint64
|
||||
sales.onStore = proc(
|
||||
request: StorageRequest, expiry: StorageTimestamp, slot: uint64, onBatch: BatchProc, isRepairing = false
|
||||
request: StorageRequest,
|
||||
expiry: StorageTimestamp,
|
||||
slot: uint64,
|
||||
onBatch: BatchProc,
|
||||
isRepairing = false,
|
||||
): Future[?!void] {.async.} =
|
||||
storingRequest = request
|
||||
storingSlot = slot
|
||||
@ -488,7 +503,11 @@ asyncchecksuite "Sales":
|
||||
test "makes storage available again when data retrieval fails":
|
||||
let error = newException(IOError, "data retrieval failed")
|
||||
sales.onStore = proc(
|
||||
request: StorageRequest, expiry: StorageTimestamp, slot: uint64, onBatch: BatchProc, isRepairing = false
|
||||
request: StorageRequest,
|
||||
expiry: StorageTimestamp,
|
||||
slot: uint64,
|
||||
onBatch: BatchProc,
|
||||
isRepairing = false,
|
||||
): Future[?!void] {.async.} =
|
||||
return failure(error)
|
||||
createAvailability()
|
||||
@ -557,7 +576,11 @@ asyncchecksuite "Sales":
|
||||
test "makes storage available again when other host fills the slot":
|
||||
let otherHost = Address.example
|
||||
sales.onStore = proc(
|
||||
request: StorageRequest, expiry: StorageTimestamp, slot: uint64, onBatch: BatchProc, isRepairing = false
|
||||
request: StorageRequest,
|
||||
expiry: StorageTimestamp,
|
||||
slot: uint64,
|
||||
onBatch: BatchProc,
|
||||
isRepairing = false,
|
||||
): Future[?!void] {.async.} =
|
||||
await sleepAsync(chronos.hours(1))
|
||||
return success()
|
||||
@ -570,7 +593,11 @@ asyncchecksuite "Sales":
|
||||
test "makes storage available again when request expires":
|
||||
let origSize = availability.freeSize
|
||||
sales.onStore = proc(
|
||||
request: StorageRequest, expiry: StorageTimestamp, slot: uint64, onBatch: BatchProc, isRepairing = false
|
||||
request: StorageRequest,
|
||||
expiry: StorageTimestamp,
|
||||
slot: uint64,
|
||||
onBatch: BatchProc,
|
||||
isRepairing = false,
|
||||
): Future[?!void] {.async.} =
|
||||
await sleepAsync(chronos.hours(1))
|
||||
return success()
|
||||
@ -595,7 +622,11 @@ asyncchecksuite "Sales":
|
||||
|
||||
let origSize = availability.freeSize
|
||||
sales.onStore = proc(
|
||||
request: StorageRequest, expiry: StorageTimestamp, slot: uint64, onBatch: BatchProc, isRepairing = false
|
||||
request: StorageRequest,
|
||||
expiry: StorageTimestamp,
|
||||
slot: uint64,
|
||||
onBatch: BatchProc,
|
||||
isRepairing = false,
|
||||
): Future[?!void] {.async.} =
|
||||
await sleepAsync(chronos.hours(1))
|
||||
return success()
|
||||
|
||||
@ -176,10 +176,8 @@ suite "Slot queue":
|
||||
check requestB.ask.pricePerSlot == 100000'Tokens * requestB.ask.slotSize
|
||||
requestB.ask.collateralPerByte = 1'Tokens
|
||||
|
||||
let itemA =
|
||||
SlotQueueItem.init(requestA, 0, requestA.ask.collateralPerSlot)
|
||||
let itemB =
|
||||
SlotQueueItem.init(requestB, 0, requestB.ask.collateralPerSlot)
|
||||
let itemA = SlotQueueItem.init(requestA, 0, requestA.ask.collateralPerSlot)
|
||||
let itemB = SlotQueueItem.init(requestB, 0, requestB.ask.collateralPerSlot)
|
||||
check itemB < itemA # B higher priority than A
|
||||
check itemA > itemB
|
||||
|
||||
@ -316,10 +314,7 @@ suite "Slot queue":
|
||||
var checked = 0
|
||||
for slotIndex in 0'u16 ..< request.ask.slots.uint16:
|
||||
check items.anyIt(
|
||||
it ==
|
||||
SlotQueueItem.init(
|
||||
request, slotIndex, request.ask.collateralPerSlot
|
||||
)
|
||||
it == SlotQueueItem.init(request, slotIndex, request.ask.collateralPerSlot)
|
||||
)
|
||||
inc checked
|
||||
check checked == items.len
|
||||
@ -352,10 +347,7 @@ suite "Slot queue":
|
||||
let uint64Slots = uint64(maxUInt16)
|
||||
request.ask.slots = uint64Slots
|
||||
let items = SlotQueueItem.init(
|
||||
request.id,
|
||||
request.ask,
|
||||
0'StorageTimestamp,
|
||||
request.ask.collateralPerSlot,
|
||||
request.id, request.ask, 0'StorageTimestamp, request.ask.collateralPerSlot
|
||||
)
|
||||
check items.len.uint16 == maxUInt16
|
||||
|
||||
@ -366,10 +358,7 @@ suite "Slot queue":
|
||||
request.ask.slots = uint64Slots
|
||||
expect SlotsOutOfRangeError:
|
||||
discard SlotQueueItem.init(
|
||||
request.id,
|
||||
request.ask,
|
||||
0'StorageTimestamp,
|
||||
request.ask.collateralPerSlot,
|
||||
request.id, request.ask, 0'StorageTimestamp, request.ask.collateralPerSlot
|
||||
)
|
||||
|
||||
test "cannot push duplicate items":
|
||||
@ -411,10 +400,8 @@ suite "Slot queue":
|
||||
let request0 = StorageRequest.example
|
||||
var request1 = StorageRequest.example
|
||||
request1.ask.collateralPerByte += 1'Tokens
|
||||
let items0 =
|
||||
SlotQueueItem.init(request0, request0.ask.collateralPerSlot)
|
||||
let items1 =
|
||||
SlotQueueItem.init(request1, request1.ask.collateralPerSlot)
|
||||
let items0 = SlotQueueItem.init(request0, request0.ask.collateralPerSlot)
|
||||
let items1 = SlotQueueItem.init(request1, request1.ask.collateralPerSlot)
|
||||
check queue.push(items0).isOk
|
||||
check queue.push(items1).isOk
|
||||
let last = items1[items1.high]
|
||||
@ -427,10 +414,8 @@ suite "Slot queue":
|
||||
let request0 = StorageRequest.example
|
||||
var request1 = StorageRequest.example
|
||||
request1.ask.collateralPerByte += 1'Tokens
|
||||
let items0 =
|
||||
SlotQueueItem.init(request0, request0.ask.collateralPerSlot)
|
||||
let items1 =
|
||||
SlotQueueItem.init(request1, request1.ask.collateralPerSlot)
|
||||
let items0 = SlotQueueItem.init(request0, request0.ask.collateralPerSlot)
|
||||
let items1 = SlotQueueItem.init(request1, request1.ask.collateralPerSlot)
|
||||
check queue.push(items0).isOk
|
||||
check queue.push(items1).isOk
|
||||
queue.delete(request1.id)
|
||||
@ -449,55 +434,45 @@ suite "Slot queue":
|
||||
request3.ask.collateralPerByte = request2.ask.collateralPerByte + 1
|
||||
request4.ask.collateralPerByte = request3.ask.collateralPerByte + 1
|
||||
request5.ask.collateralPerByte = request4.ask.collateralPerByte + 1
|
||||
let item0 =
|
||||
SlotQueueItem.init(request0, 0, request0.ask.collateralPerSlot)
|
||||
let item1 =
|
||||
SlotQueueItem.init(request1, 0, request1.ask.collateralPerSlot)
|
||||
let item2 =
|
||||
SlotQueueItem.init(request2, 0, request2.ask.collateralPerSlot)
|
||||
let item3 =
|
||||
SlotQueueItem.init(request3, 0, request3.ask.collateralPerSlot)
|
||||
let item4 =
|
||||
SlotQueueItem.init(request4, 0, request4.ask.collateralPerSlot)
|
||||
let item5 =
|
||||
SlotQueueItem.init(request5, 0, request5.ask.collateralPerSlot)
|
||||
let item0 = SlotQueueItem.init(request0, 0, request0.ask.collateralPerSlot)
|
||||
let item1 = SlotQueueItem.init(request1, 0, request1.ask.collateralPerSlot)
|
||||
let item2 = SlotQueueItem.init(request2, 0, request2.ask.collateralPerSlot)
|
||||
let item3 = SlotQueueItem.init(request3, 0, request3.ask.collateralPerSlot)
|
||||
let item4 = SlotQueueItem.init(request4, 0, request4.ask.collateralPerSlot)
|
||||
let item5 = SlotQueueItem.init(request5, 0, request5.ask.collateralPerSlot)
|
||||
check queue.contains(item5) == false
|
||||
check queue.push(@[item0, item1, item2, item3, item4, item5]).isOk
|
||||
check queue.contains(item5)
|
||||
|
||||
test "sorts items by profitability descending (higher pricePerBytePerSecond == higher priority == goes first in the list)":
|
||||
var request = StorageRequest.example
|
||||
let item0 =
|
||||
SlotQueueItem.init(request, 0, request.ask.collateralPerSlot)
|
||||
let item0 = SlotQueueItem.init(request, 0, request.ask.collateralPerSlot)
|
||||
request.ask.pricePerBytePerSecond += 1'TokensPerSecond
|
||||
let item1 =
|
||||
SlotQueueItem.init(request, 1, request.ask.collateralPerSlot)
|
||||
let item1 = SlotQueueItem.init(request, 1, request.ask.collateralPerSlot)
|
||||
check item1 < item0
|
||||
|
||||
test "sorts items by collateral ascending (higher required collateral = lower priority == comes later in the list)":
|
||||
var request = StorageRequest.example
|
||||
let item0 =
|
||||
SlotQueueItem.init(request, 0, request.ask.collateralPerSlot)
|
||||
let item1 = SlotQueueItem.init(
|
||||
request, 1, request.ask.collateralPerSlot + 1'Tokens
|
||||
)
|
||||
let item0 = SlotQueueItem.init(request, 0, request.ask.collateralPerSlot)
|
||||
let item1 = SlotQueueItem.init(request, 1, request.ask.collateralPerSlot +
|
||||
1'Tokens)
|
||||
check item1 > item0
|
||||
|
||||
test "sorts items by expiry descending (longer expiry = higher priority)":
|
||||
var request = StorageRequest.example
|
||||
let item0 =
|
||||
SlotQueueItem.init(request.id, 0, request.ask, 3'StorageTimestamp, request.ask.collateralPerSlot)
|
||||
let item1 =
|
||||
SlotQueueItem.init(request.id, 1, request.ask, 7'StorageTimestamp, request.ask.collateralPerSlot)
|
||||
let item0 = SlotQueueItem.init(
|
||||
request.id, 0, request.ask, 3'StorageTimestamp, request.ask.collateralPerSlot
|
||||
)
|
||||
let item1 = SlotQueueItem.init(
|
||||
request.id, 1, request.ask, 7'StorageTimestamp, request.ask.collateralPerSlot
|
||||
)
|
||||
check item1 < item0
|
||||
|
||||
test "sorts items by slot size descending (bigger dataset = higher profitability = higher priority)":
|
||||
var request = StorageRequest.example
|
||||
let item0 =
|
||||
SlotQueueItem.init(request, 0, request.ask.collateralPerSlot)
|
||||
let item0 = SlotQueueItem.init(request, 0, request.ask.collateralPerSlot)
|
||||
request.ask.slotSize += 1
|
||||
let item1 =
|
||||
SlotQueueItem.init(request, 1, request.ask.collateralPerSlot)
|
||||
let item1 = SlotQueueItem.init(request, 1, request.ask.collateralPerSlot)
|
||||
check item1 < item0
|
||||
|
||||
test "should call callback once an item is added":
|
||||
@ -518,17 +493,13 @@ suite "Slot queue":
|
||||
# sleeping after push allows the slotqueue loop to iterate,
|
||||
# calling the callback for each pushed/updated item
|
||||
var request = StorageRequest.example
|
||||
let item0 =
|
||||
SlotQueueItem.init(request, 0, request.ask.collateralPerSlot)
|
||||
let item0 = SlotQueueItem.init(request, 0, request.ask.collateralPerSlot)
|
||||
request.ask.pricePerBytePerSecond += 1'TokensPerSecond
|
||||
let item1 =
|
||||
SlotQueueItem.init(request, 1, request.ask.collateralPerSlot)
|
||||
let item1 = SlotQueueItem.init(request, 1, request.ask.collateralPerSlot)
|
||||
request.ask.pricePerBytePerSecond += 1'TokensPerSecond
|
||||
let item2 =
|
||||
SlotQueueItem.init(request, 2, request.ask.collateralPerSlot)
|
||||
let item2 = SlotQueueItem.init(request, 2, request.ask.collateralPerSlot)
|
||||
request.ask.pricePerBytePerSecond += 1'TokensPerSecond
|
||||
let item3 =
|
||||
SlotQueueItem.init(request, 3, request.ask.collateralPerSlot)
|
||||
let item3 = SlotQueueItem.init(request, 3, request.ask.collateralPerSlot)
|
||||
|
||||
check queue.push(item0).isOk
|
||||
await sleepAsync(1.millis)
|
||||
@ -553,17 +524,13 @@ suite "Slot queue":
|
||||
# sleeping after push allows the slotqueue loop to iterate,
|
||||
# calling the callback for each pushed/updated item
|
||||
var request = StorageRequest.example
|
||||
let item0 =
|
||||
SlotQueueItem.init(request, 0, request.ask.collateralPerSlot)
|
||||
let item0 = SlotQueueItem.init(request, 0, request.ask.collateralPerSlot)
|
||||
request.ask.pricePerBytePerSecond += 1'TokensPerSecond
|
||||
let item1 =
|
||||
SlotQueueItem.init(request, 1, request.ask.collateralPerSlot)
|
||||
let item1 = SlotQueueItem.init(request, 1, request.ask.collateralPerSlot)
|
||||
request.ask.pricePerBytePerSecond += 1'TokensPerSecond
|
||||
let item2 =
|
||||
SlotQueueItem.init(request, 2, request.ask.collateralPerSlot)
|
||||
let item2 = SlotQueueItem.init(request, 2, request.ask.collateralPerSlot)
|
||||
request.ask.pricePerBytePerSecond += 1'TokensPerSecond
|
||||
let item3 =
|
||||
SlotQueueItem.init(request, 3, request.ask.collateralPerSlot)
|
||||
let item3 = SlotQueueItem.init(request, 3, request.ask.collateralPerSlot)
|
||||
|
||||
check queue.push(item0).isOk
|
||||
check queue.push(item1).isOk
|
||||
|
||||
@ -30,20 +30,22 @@ ethersuite "On-Chain Market":
|
||||
var host: Signer
|
||||
var otherHost: Signer
|
||||
|
||||
proc expectedPayout(request: StorageRequest, start, finish: StorageTimestamp): Tokens =
|
||||
proc expectedPayout(
|
||||
request: StorageRequest, start, finish: StorageTimestamp
|
||||
): Tokens =
|
||||
return request.ask.pricePerSlotPerSecond * start.until(finish)
|
||||
|
||||
proc switchAccount(account: Signer) {.async.} =
|
||||
marketplace = marketplace.connect(account)
|
||||
token = token.connect(account)
|
||||
market = ! await OnChainMarket.load(marketplace)
|
||||
market = !await OnChainMarket.load(marketplace)
|
||||
|
||||
setup:
|
||||
let address = Marketplace.address(dummyVerifier = true)
|
||||
marketplace = Marketplace.new(address, ethProvider.getSigner())
|
||||
let config = await marketplace.configuration()
|
||||
|
||||
market = ! await OnChainMarket.load(marketplace)
|
||||
market = !await OnChainMarket.load(marketplace)
|
||||
let tokenAddress = await marketplace.token()
|
||||
token = Erc20Token.new(tokenAddress, ethProvider.getSigner())
|
||||
|
||||
@ -535,7 +537,8 @@ ethersuite "On-Chain Market":
|
||||
let endBalance = await token.balanceOf(address)
|
||||
|
||||
let expectedPayout = request.expectedPayout(filledAt, requestEnd)
|
||||
check (endBalance - startBalance) == (expectedPayout + request.ask.collateralPerSlot).u256
|
||||
check (endBalance - startBalance) ==
|
||||
(expectedPayout + request.ask.collateralPerSlot).u256
|
||||
|
||||
test "the request is added to cache after the first access":
|
||||
await market.requestStorage(request)
|
||||
|
||||
@ -255,8 +255,14 @@ proc requestStorageRaw*(
|
||||
tolerance: uint = 1,
|
||||
): Future[HttpClientResponseRef] {.async: (raises: [CancelledError, HttpError]).} =
|
||||
return await client.requestStorageRaw(
|
||||
cid, duration, pricePerBytePerSecond, proofProbability, collateralPerByte,
|
||||
some expiry, nodes, tolerance
|
||||
cid,
|
||||
duration,
|
||||
pricePerBytePerSecond,
|
||||
proofProbability,
|
||||
collateralPerByte,
|
||||
some expiry,
|
||||
nodes,
|
||||
tolerance,
|
||||
)
|
||||
|
||||
proc requestStorage*(
|
||||
@ -295,8 +301,14 @@ proc requestStorage*(
|
||||
tolerance: uint = 1,
|
||||
): Future[?!PurchaseId] {.async: (raises: [CancelledError, HttpError]).} =
|
||||
return await client.requestStorage(
|
||||
cid, duration, pricePerBytePerSecond, proofProbability, some expiry,
|
||||
collateralPerByte, nodes, tolerance
|
||||
cid,
|
||||
duration,
|
||||
pricePerBytePerSecond,
|
||||
proofProbability,
|
||||
some expiry,
|
||||
collateralPerByte,
|
||||
nodes,
|
||||
tolerance,
|
||||
)
|
||||
|
||||
proc getPurchase*(
|
||||
|
||||
@ -213,7 +213,8 @@ marketplacesuite "Marketplace payouts":
|
||||
check eventually (
|
||||
let endBalanceProvider = (await token.balanceOf(provider.ethAccount))
|
||||
endBalanceProvider > startBalanceProvider and
|
||||
endBalanceProvider < startBalanceProvider + expiry.u256 * pricePerSlotPerSecond.u256
|
||||
endBalanceProvider <
|
||||
startBalanceProvider + expiry.u256 * pricePerSlotPerSecond.u256
|
||||
)
|
||||
check eventually(
|
||||
(
|
||||
|
||||
@ -43,10 +43,7 @@ marketplacesuite "Hosts submit regular proofs":
|
||||
let datasetSize =
|
||||
datasetSize(blocks = blocks, nodes = ecNodes, tolerance = ecTolerance)
|
||||
await createAvailabilities(
|
||||
datasetSize,
|
||||
duration,
|
||||
collateralPerByte,
|
||||
minPricePerBytePerSecond,
|
||||
datasetSize, duration, collateralPerByte, minPricePerBytePerSecond
|
||||
)
|
||||
|
||||
let cid = (await client0.upload(data)).get
|
||||
@ -65,7 +62,8 @@ marketplacesuite "Hosts submit regular proofs":
|
||||
let slotSize = slotSize(blocks, ecNodes, ecTolerance)
|
||||
|
||||
check eventually(
|
||||
await client0.purchaseStateIs(purchaseId, "started"), timeout = expiry.u64.int * 1000
|
||||
await client0.purchaseStateIs(purchaseId, "started"),
|
||||
timeout = expiry.u64.int * 1000,
|
||||
)
|
||||
|
||||
var proofWasSubmitted = false
|
||||
@ -120,10 +118,7 @@ marketplacesuite "Simulate invalid proofs":
|
||||
let datasetSize =
|
||||
datasetSize(blocks = blocks, nodes = ecNodes, tolerance = ecTolerance)
|
||||
await createAvailabilities(
|
||||
datasetSize,
|
||||
duration,
|
||||
collateralPerByte,
|
||||
minPricePerBytePerSecond,
|
||||
datasetSize, duration, collateralPerByte, minPricePerBytePerSecond
|
||||
)
|
||||
|
||||
let cid = (await client0.upload(data)).get
|
||||
@ -141,7 +136,8 @@ marketplacesuite "Simulate invalid proofs":
|
||||
let requestId = (await client0.requestId(purchaseId)).get
|
||||
|
||||
check eventually(
|
||||
await client0.purchaseStateIs(purchaseId, "started"), timeout = expiry.u64.int * 1000
|
||||
await client0.purchaseStateIs(purchaseId, "started"),
|
||||
timeout = expiry.u64.int * 1000,
|
||||
)
|
||||
|
||||
var slotWasFreed = false
|
||||
@ -185,10 +181,7 @@ marketplacesuite "Simulate invalid proofs":
|
||||
let datasetSize =
|
||||
datasetSize(blocks = blocks, nodes = ecNodes, tolerance = ecTolerance)
|
||||
await createAvailabilities(
|
||||
datasetSize,
|
||||
duration,
|
||||
collateralPerByte,
|
||||
minPricePerBytePerSecond,
|
||||
datasetSize, duration, collateralPerByte, minPricePerBytePerSecond
|
||||
)
|
||||
|
||||
let cid = (await client0.upload(data)).get
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
|
||||
import std/importutils
|
||||
import std/net
|
||||
import std/sequtils
|
||||
|
||||
@ -69,7 +69,7 @@ multinodesuite "Rest API validation":
|
||||
expiry = 30'StorageDuration,
|
||||
collateralPerByte = 1'Tokens,
|
||||
nodes = nodes.uint,
|
||||
tolerance =tolerance.uint,
|
||||
tolerance = tolerance.uint,
|
||||
)
|
||||
)
|
||||
|
||||
@ -241,7 +241,8 @@ multinodesuite "Rest API validation":
|
||||
|
||||
let response = await client.requestStorageRaw(
|
||||
cid,
|
||||
duration = StorageDuration.init(31'u32 * 24 * 60 * 60), # 31 days TODO: this should not be hardcoded, but waits for https://github.com/codex-storage/nim-codex/issues/1056
|
||||
duration = StorageDuration.init(31'u32 * 24 * 60 * 60),
|
||||
# 31 days TODO: this should not be hardcoded, but waits for https://github.com/codex-storage/nim-codex/issues/1056
|
||||
pricePerBytePerSecond = 1'TokensPerSecond,
|
||||
proofProbability = 3.u256,
|
||||
expiry = 30'StorageDuration,
|
||||
@ -306,8 +307,7 @@ multinodesuite "Rest API validation":
|
||||
)
|
||||
|
||||
check response.status == 422
|
||||
check (await response.body) ==
|
||||
"Price per byte per second must be greater than zero"
|
||||
check (await response.body) == "Price per byte per second must be greater than zero"
|
||||
|
||||
test "request storage fails if collareral per byte is zero", config:
|
||||
let data = await RandomChunker.example(blocks = 2)
|
||||
|
||||
@ -86,7 +86,8 @@ multinodesuite "Sales":
|
||||
let updatedAvailability =
|
||||
((await host.getAvailabilities()).get).findItem(availability).get
|
||||
check updatedAvailability.duration == 100'StorageDuration
|
||||
check updatedAvailability.minPricePerBytePerSecond == 2'TokensPerSecond
|
||||
check updatedAvailability.minPricePerBytePerSecond ==
|
||||
2'TokensPerSecond
|
||||
check updatedAvailability.totalCollateral == 200'Tokens
|
||||
check updatedAvailability.totalSize == 140000.uint64
|
||||
check updatedAvailability.freeSize == 140000.uint64
|
||||
|
||||
@ -100,10 +100,7 @@ marketplacesuite "Validation":
|
||||
let datasetSize =
|
||||
datasetSize(blocks = blocks, nodes = ecNodes, tolerance = ecTolerance)
|
||||
await createAvailabilities(
|
||||
datasetSize,
|
||||
duration,
|
||||
collateralPerByte,
|
||||
minPricePerBytePerSecond,
|
||||
datasetSize, duration, collateralPerByte, minPricePerBytePerSecond
|
||||
)
|
||||
|
||||
let cid = (await client0.upload(data)).get
|
||||
@ -170,10 +167,7 @@ marketplacesuite "Validation":
|
||||
let datasetSize =
|
||||
datasetSize(blocks = blocks, nodes = ecNodes, tolerance = ecTolerance)
|
||||
await createAvailabilities(
|
||||
datasetSize,
|
||||
duration,
|
||||
collateralPerByte,
|
||||
minPricePerBytePerSecond,
|
||||
datasetSize, duration, collateralPerByte, minPricePerBytePerSecond
|
||||
)
|
||||
|
||||
let cid = (await client0.upload(data)).get
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user