mirror of
https://github.com/status-im/nim-dagger.git
synced 2025-02-06 20:04:59 +00:00
Add availability enabled parameter
This commit is contained in:
parent
58a962add8
commit
b80b1f85be
@ -439,8 +439,11 @@ proc initSalesApi(node: CodexNodeRef, router: var RestRouter) =
|
||||
|
||||
without availability =? (
|
||||
await reservations.createAvailability(
|
||||
restAv.totalSize, restAv.duration, restAv.minPricePerBytePerSecond,
|
||||
restAv.totalSize,
|
||||
restAv.duration,
|
||||
restAv.minPricePerBytePerSecond,
|
||||
restAv.totalCollateral,
|
||||
enabled = restAv.enabled |? true,
|
||||
)
|
||||
), error:
|
||||
return RestApiResponse.error(Http500, error.msg, headers = headers)
|
||||
@ -526,6 +529,8 @@ proc initSalesApi(node: CodexNodeRef, router: var RestRouter) =
|
||||
if totalCollateral =? restAv.totalCollateral:
|
||||
availability.totalCollateral = totalCollateral
|
||||
|
||||
availability.enabled = restAv.enabled |? true
|
||||
|
||||
if err =? (await reservations.update(availability)).errorOption:
|
||||
return RestApiResponse.error(Http500, err.msg)
|
||||
|
||||
|
@ -33,6 +33,7 @@ type
|
||||
minPricePerBytePerSecond* {.serialize.}: UInt256
|
||||
totalCollateral* {.serialize.}: UInt256
|
||||
freeSize* {.serialize.}: ?UInt256
|
||||
enabled* {.serialize.}: ?bool
|
||||
|
||||
RestSalesAgent* = object
|
||||
state* {.serialize.}: string
|
||||
|
@ -271,7 +271,9 @@ proc load*(sales: Sales) {.async.} =
|
||||
agent.start(SaleUnknown())
|
||||
sales.agents.add agent
|
||||
|
||||
proc onAvailabilityAdded(sales: Sales, availability: Availability) {.async.} =
|
||||
proc onAvailabilityAdded(
|
||||
sales: Sales, availability: Availability
|
||||
) {.async: (raises: []).} =
|
||||
## When availabilities are modified or added, the queue should be unpaused if
|
||||
## it was paused and any slots in the queue should have their `seen` flag
|
||||
## cleared.
|
||||
@ -483,7 +485,7 @@ proc startSlotQueue(sales: Sales) =
|
||||
|
||||
slotQueue.start()
|
||||
|
||||
proc onAvailabilityAdded(availability: Availability) {.async.} =
|
||||
proc onAvailabilityAdded(availability: Availability) {.async: (raises: []).} =
|
||||
await sales.onAvailabilityAdded(availability)
|
||||
|
||||
reservations.onAvailabilityAdded = onAvailabilityAdded
|
||||
|
@ -70,6 +70,10 @@ type
|
||||
minPricePerBytePerSecond* {.serialize.}: UInt256
|
||||
totalCollateral {.serialize.}: UInt256
|
||||
totalRemainingCollateral* {.serialize.}: UInt256
|
||||
# If false, the availability will not be able to receive new slots.
|
||||
# If it is turned on and the availability is already hosting slots,
|
||||
# it will not affect those existing slots.
|
||||
enabled* {.serialize.}: bool
|
||||
|
||||
Reservation* = ref object
|
||||
id* {.serialize.}: ReservationId
|
||||
@ -86,8 +90,9 @@ type
|
||||
|
||||
GetNext* = proc(): Future[?seq[byte]] {.upraises: [], gcsafe, closure.}
|
||||
IterDispose* = proc(): Future[?!void] {.gcsafe, closure.}
|
||||
OnAvailabilityAdded* =
|
||||
proc(availability: Availability): Future[void] {.upraises: [], gcsafe.}
|
||||
OnAvailabilityAdded* = proc(availability: Availability): Future[void] {.
|
||||
upraises: [], gcsafe, async: (raises: [])
|
||||
.}
|
||||
StorableIter* = ref object
|
||||
finished*: bool
|
||||
next*: GetNext
|
||||
@ -128,6 +133,7 @@ proc init*(
|
||||
duration: UInt256,
|
||||
minPricePerBytePerSecond: UInt256,
|
||||
totalCollateral: UInt256,
|
||||
enabled: bool,
|
||||
): Availability =
|
||||
var id: array[32, byte]
|
||||
doAssert randomBytes(id) == 32
|
||||
@ -139,6 +145,7 @@ proc init*(
|
||||
minPricePerBytePerSecond: minPricePerBytePerSecond,
|
||||
totalCollateral: totalCollateral,
|
||||
totalRemainingCollateral: totalCollateral,
|
||||
enabled: enabled,
|
||||
)
|
||||
|
||||
func totalCollateral*(self: Availability): UInt256 {.inline.} =
|
||||
@ -268,18 +275,8 @@ proc updateAvailability(
|
||||
trace "Creating new Availability"
|
||||
let res = await self.updateImpl(obj)
|
||||
# inform subscribers that Availability has been added
|
||||
if onAvailabilityAdded =? self.onAvailabilityAdded:
|
||||
# when chronos v4 is implemented, and OnAvailabilityAdded is annotated
|
||||
# with async:(raises:[]), we can remove this try/catch as we know, with
|
||||
# certainty, that nothing will be raised
|
||||
try:
|
||||
await onAvailabilityAdded(obj)
|
||||
except CancelledError as e:
|
||||
raise e
|
||||
except CatchableError as e:
|
||||
# we don't have any insight into types of exceptions that
|
||||
# `onAvailabilityAdded` can raise because it is caller-defined
|
||||
warn "Unknown error during 'onAvailabilityAdded' callback", error = e.msg
|
||||
if obj.enabled and onAvailabilityAdded =? self.onAvailabilityAdded:
|
||||
await onAvailabilityAdded(obj)
|
||||
return res
|
||||
else:
|
||||
return failure(err)
|
||||
@ -304,22 +301,11 @@ proc updateAvailability(
|
||||
|
||||
let res = await self.updateImpl(obj)
|
||||
|
||||
if oldAvailability.freeSize < obj.freeSize: # availability added
|
||||
if obj.enabled and oldAvailability.freeSize < obj.freeSize: # availability added
|
||||
# inform subscribers that Availability has been modified (with increased
|
||||
# size)
|
||||
if onAvailabilityAdded =? self.onAvailabilityAdded:
|
||||
# when chronos v4 is implemented, and OnAvailabilityAdded is annotated
|
||||
# with async:(raises:[]), we can remove this try/catch as we know, with
|
||||
# certainty, that nothing will be raised
|
||||
try:
|
||||
await onAvailabilityAdded(obj)
|
||||
except CancelledError as e:
|
||||
raise e
|
||||
except CatchableError as e:
|
||||
# we don't have any insight into types of exceptions that
|
||||
# `onAvailabilityAdded` can raise because it is caller-defined
|
||||
warn "Unknown error during 'onAvailabilityAdded' callback", error = e.msg
|
||||
|
||||
await onAvailabilityAdded(obj)
|
||||
return res
|
||||
|
||||
proc update*(self: Reservations, obj: Reservation): Future[?!void] {.async.} =
|
||||
@ -393,12 +379,14 @@ proc createAvailability*(
|
||||
duration: UInt256,
|
||||
minPricePerBytePerSecond: UInt256,
|
||||
totalCollateral: UInt256,
|
||||
enabled: bool,
|
||||
): Future[?!Availability] {.async.} =
|
||||
trace "creating availability",
|
||||
size, duration, minPricePerBytePerSecond, totalCollateral
|
||||
size, duration, minPricePerBytePerSecond, totalCollateral, enabled
|
||||
|
||||
let availability =
|
||||
Availability.init(size, size, duration, minPricePerBytePerSecond, totalCollateral)
|
||||
let availability = Availability.init(
|
||||
size, size, duration, minPricePerBytePerSecond, totalCollateral, enabled
|
||||
)
|
||||
let bytes = availability.freeSize.truncate(uint)
|
||||
|
||||
if reserveErr =? (await self.repo.reserve(bytes.NBytes)).errorOption:
|
||||
@ -651,11 +639,13 @@ proc findAvailability*(
|
||||
|
||||
for item in storables.items:
|
||||
if bytes =? (await item) and availability =? Availability.fromJson(bytes):
|
||||
if size <= availability.freeSize and duration <= availability.duration and
|
||||
if availability.enabled and size <= availability.freeSize and
|
||||
duration <= availability.duration and
|
||||
collateralPerByte <= availability.maxCollateralPerByte and
|
||||
pricePerBytePerSecond >= availability.minPricePerBytePerSecond:
|
||||
trace "availability matched",
|
||||
id = availability.id,
|
||||
enabled = availability.enabled,
|
||||
size,
|
||||
availFreeSize = availability.freeSize,
|
||||
duration,
|
||||
@ -675,6 +665,7 @@ proc findAvailability*(
|
||||
|
||||
trace "availability did not match",
|
||||
id = availability.id,
|
||||
enabled = availability.enabled,
|
||||
size,
|
||||
availFreeSize = availability.freeSize,
|
||||
duration,
|
||||
|
@ -163,6 +163,10 @@ components:
|
||||
totalCollateral:
|
||||
type: string
|
||||
description: Total collateral (in amount of tokens) that can be used for matching requests
|
||||
enabled:
|
||||
type: boolean
|
||||
description: Enable the ability to receive sales on this availability.
|
||||
default: true
|
||||
|
||||
SalesAvailabilityREAD:
|
||||
allOf:
|
||||
|
@ -65,6 +65,7 @@ proc example*(
|
||||
duration = uint16.example.u256,
|
||||
minPricePerBytePerSecond = uint8.example.u256,
|
||||
totalCollateral = totalSize * collateralPerByte,
|
||||
enabled = true,
|
||||
)
|
||||
|
||||
proc example*(_: type Reservation): Reservation =
|
||||
|
@ -39,6 +39,7 @@ asyncchecksuite "sales state 'preparing'":
|
||||
duration = request.ask.duration + 60.u256,
|
||||
minPricePerBytePerSecond = request.ask.pricePerBytePerSecond,
|
||||
totalCollateral = request.ask.collateralPerSlot * request.ask.slots.u256,
|
||||
enabled = true,
|
||||
)
|
||||
let repoDs = SQLiteDatastore.new(Memory).tryGet()
|
||||
let metaDs = SQLiteDatastore.new(Memory).tryGet()
|
||||
@ -67,10 +68,10 @@ asyncchecksuite "sales state 'preparing'":
|
||||
let next = state.onSlotFilled(request.id, slotIndex)
|
||||
check !next of SaleFilled
|
||||
|
||||
proc createAvailability() {.async.} =
|
||||
proc createAvailability(enabled = true) {.async.} =
|
||||
let a = await reservations.createAvailability(
|
||||
availability.totalSize, availability.duration,
|
||||
availability.minPricePerBytePerSecond, availability.totalCollateral,
|
||||
availability.minPricePerBytePerSecond, availability.totalCollateral, enabled,
|
||||
)
|
||||
availability = a.get
|
||||
|
||||
@ -81,6 +82,11 @@ asyncchecksuite "sales state 'preparing'":
|
||||
check ignored.reprocessSlot
|
||||
check ignored.returnBytes == false
|
||||
|
||||
test "run switches to ignored when a availability is not enabled":
|
||||
await createAvailability(enabled = false)
|
||||
let next = !(await state.run(agent))
|
||||
check next of SaleIgnored
|
||||
|
||||
test "run switches to slot reserving state after reservation created":
|
||||
await createAvailability()
|
||||
let next = await state.run(agent)
|
||||
|
@ -39,12 +39,13 @@ asyncchecksuite "Reservations module":
|
||||
await repoTmp.destroyDb()
|
||||
await metaTmp.destroyDb()
|
||||
|
||||
proc createAvailability(): Availability =
|
||||
proc createAvailability(enabled = true): Availability =
|
||||
let example = Availability.example(collateralPerByte)
|
||||
let totalSize = rand(100000 .. 200000).u256
|
||||
let totalCollateral = totalSize * collateralPerByte
|
||||
let availability = waitFor reservations.createAvailability(
|
||||
totalSize, example.duration, example.minPricePerBytePerSecond, totalCollateral
|
||||
totalSize, example.duration, example.minPricePerBytePerSecond, totalCollateral,
|
||||
enabled,
|
||||
)
|
||||
return availability.get
|
||||
|
||||
@ -64,8 +65,8 @@ asyncchecksuite "Reservations module":
|
||||
check (await reservations.all(Availability)).get.len == 0
|
||||
|
||||
test "generates unique ids for storage availability":
|
||||
let availability1 = Availability.init(1.u256, 2.u256, 3.u256, 4.u256, 5.u256)
|
||||
let availability2 = Availability.init(1.u256, 2.u256, 3.u256, 4.u256, 5.u256)
|
||||
let availability1 = Availability.init(1.u256, 2.u256, 3.u256, 4.u256, 5.u256, true)
|
||||
let availability2 = Availability.init(1.u256, 2.u256, 3.u256, 4.u256, 5.u256, true)
|
||||
check availability1.id != availability2.id
|
||||
|
||||
test "can reserve available storage":
|
||||
@ -285,7 +286,9 @@ asyncchecksuite "Reservations module":
|
||||
|
||||
test "onAvailabilityAdded called when availability is created":
|
||||
var added: Availability
|
||||
reservations.onAvailabilityAdded = proc(a: Availability) {.async.} =
|
||||
reservations.onAvailabilityAdded = proc(
|
||||
a: Availability
|
||||
) {.gcsafe, async: (raises: []).} =
|
||||
added = a
|
||||
|
||||
let availability = createAvailability()
|
||||
@ -295,7 +298,9 @@ asyncchecksuite "Reservations module":
|
||||
test "onAvailabilityAdded called when availability size is increased":
|
||||
var availability = createAvailability()
|
||||
var added: Availability
|
||||
reservations.onAvailabilityAdded = proc(a: Availability) {.async.} =
|
||||
reservations.onAvailabilityAdded = proc(
|
||||
a: Availability
|
||||
) {.gcsafe, async: (raises: []).} =
|
||||
added = a
|
||||
availability.freeSize += 1.u256
|
||||
discard await reservations.update(availability)
|
||||
@ -305,7 +310,21 @@ asyncchecksuite "Reservations module":
|
||||
test "onAvailabilityAdded is not called when availability size is decreased":
|
||||
var availability = createAvailability()
|
||||
var called = false
|
||||
reservations.onAvailabilityAdded = proc(a: Availability) {.async.} =
|
||||
reservations.onAvailabilityAdded = proc(
|
||||
a: Availability
|
||||
) {.gcsafe, async: (raises: []).} =
|
||||
called = true
|
||||
availability.freeSize -= 1.u256
|
||||
discard await reservations.update(availability)
|
||||
|
||||
check not called
|
||||
|
||||
test "onAvailabilityAdded is not called when enabled is false":
|
||||
var availability = createAvailability(enabled = false)
|
||||
var called = false
|
||||
reservations.onAvailabilityAdded = proc(
|
||||
a: Availability
|
||||
) {.gcsafe, async: (raises: []).} =
|
||||
called = true
|
||||
availability.freeSize -= 1.u256
|
||||
discard await reservations.update(availability)
|
||||
@ -323,6 +342,16 @@ asyncchecksuite "Reservations module":
|
||||
check found.isSome
|
||||
check found.get == availability
|
||||
|
||||
test "availabilities cannot be found when it is not enabled":
|
||||
let availability = createAvailability(enabled = false)
|
||||
|
||||
let found = await reservations.findAvailability(
|
||||
availability.freeSize, availability.duration,
|
||||
availability.minPricePerBytePerSecond, collateralPerByte,
|
||||
)
|
||||
|
||||
check found.isNone
|
||||
|
||||
test "non-matching availabilities are not found":
|
||||
let availability = createAvailability()
|
||||
|
||||
@ -364,6 +393,7 @@ asyncchecksuite "Reservations module":
|
||||
UInt256.example,
|
||||
UInt256.example,
|
||||
UInt256.example,
|
||||
enabled = true,
|
||||
)
|
||||
check created.isErr
|
||||
check created.error of ReserveFailedError
|
||||
|
@ -149,6 +149,7 @@ asyncchecksuite "Sales":
|
||||
duration = 60.u256,
|
||||
minPricePerBytePerSecond = minPricePerBytePerSecond,
|
||||
totalCollateral = totalCollateral,
|
||||
enabled = true,
|
||||
)
|
||||
request = StorageRequest(
|
||||
ask: StorageAsk(
|
||||
@ -216,10 +217,10 @@ asyncchecksuite "Sales":
|
||||
let key = availability.id.key.get
|
||||
(waitFor reservations.get(key, Availability)).get
|
||||
|
||||
proc createAvailability() =
|
||||
proc createAvailability(enabled = true) =
|
||||
let a = waitFor reservations.createAvailability(
|
||||
availability.totalSize, availability.duration,
|
||||
availability.minPricePerBytePerSecond, availability.totalCollateral,
|
||||
availability.minPricePerBytePerSecond, availability.totalCollateral, enabled,
|
||||
)
|
||||
availability = a.get # update id
|
||||
|
||||
@ -412,6 +413,20 @@ asyncchecksuite "Sales":
|
||||
market.slotState[request.slotId(3.u256)] = SlotState.Filled
|
||||
check wasIgnored()
|
||||
|
||||
test "ignores request when availability is not enabled":
|
||||
createAvailability(enabled = false)
|
||||
await market.requestStorage(request)
|
||||
check wasIgnored()
|
||||
|
||||
test "ignores request when availability was disabled after the request storage is created":
|
||||
createAvailability(enabled = true)
|
||||
await market.requestStorage(request)
|
||||
|
||||
availability.enabled = false
|
||||
discard await reservations.update(availability)
|
||||
|
||||
check wasIgnored()
|
||||
|
||||
test "retrieves and stores data locally":
|
||||
var storingRequest: StorageRequest
|
||||
var storingSlot: UInt256
|
||||
|
@ -175,6 +175,7 @@ proc getSlots*(client: CodexClient): ?!seq[Slot] =
|
||||
proc postAvailability*(
|
||||
client: CodexClient,
|
||||
totalSize, duration, minPricePerBytePerSecond, totalCollateral: UInt256,
|
||||
enabled: ?bool = bool.none,
|
||||
): ?!Availability =
|
||||
## Post sales availability endpoint
|
||||
##
|
||||
@ -185,6 +186,7 @@ proc postAvailability*(
|
||||
"duration": duration,
|
||||
"minPricePerBytePerSecond": minPricePerBytePerSecond,
|
||||
"totalCollateral": totalCollateral,
|
||||
"enabled": enabled |? true,
|
||||
}
|
||||
let response = client.http.post(url, $json)
|
||||
doAssert response.status == "201 Created",
|
||||
@ -196,6 +198,7 @@ proc patchAvailabilityRaw*(
|
||||
availabilityId: AvailabilityId,
|
||||
totalSize, freeSize, duration, minPricePerBytePerSecond, totalCollateral: ?UInt256 =
|
||||
UInt256.none,
|
||||
enabled: ?bool = bool.none,
|
||||
): Response =
|
||||
## Updates availability
|
||||
##
|
||||
@ -219,6 +222,9 @@ proc patchAvailabilityRaw*(
|
||||
if totalCollateral =? totalCollateral:
|
||||
json["totalCollateral"] = %totalCollateral
|
||||
|
||||
if enabled =? enabled:
|
||||
json["enabled"] = %enabled
|
||||
|
||||
client.http.patch(url, $json)
|
||||
|
||||
proc patchAvailability*(
|
||||
@ -226,6 +232,7 @@ proc patchAvailability*(
|
||||
availabilityId: AvailabilityId,
|
||||
totalSize, duration, minPricePerBytePerSecond, totalCollateral: ?UInt256 =
|
||||
UInt256.none,
|
||||
enabled: ?bool = bool.none,
|
||||
): void =
|
||||
let response = client.patchAvailabilityRaw(
|
||||
availabilityId,
|
||||
@ -233,6 +240,7 @@ proc patchAvailability*(
|
||||
duration = duration,
|
||||
minPricePerBytePerSecond = minPricePerBytePerSecond,
|
||||
totalCollateral = totalCollateral,
|
||||
enabled = enabled,
|
||||
)
|
||||
doAssert response.status == "200 OK", "expected 200 OK, got " & response.status
|
||||
|
||||
|
@ -266,7 +266,8 @@ marketplacesuite "Simulate invalid proofs":
|
||||
# totalSize=slotSize, # should match 1 slot only
|
||||
# duration=totalPeriods.periods.u256,
|
||||
# minPricePerBytePerSecond=minPricePerBytePerSecond,
|
||||
# totalCollateral=slotSize * minPricePerBytePerSecond
|
||||
# totalCollateral=slotSize * minPricePerBytePerSecond,
|
||||
# enabled = true.some
|
||||
# )
|
||||
|
||||
# let cid = client0.upload(data).get
|
||||
|
@ -29,6 +29,7 @@ twonodessuite "REST API":
|
||||
duration = 2.u256,
|
||||
minPricePerBytePerSecond = minPricePerBytePerSecond,
|
||||
totalCollateral = totalCollateral,
|
||||
enabled = true.some,
|
||||
).get
|
||||
let space = client1.space().tryGet()
|
||||
check:
|
||||
@ -37,6 +38,19 @@ twonodessuite "REST API":
|
||||
space.quotaUsedBytes == 65598.NBytes
|
||||
space.quotaReservedBytes == 12.NBytes
|
||||
|
||||
test "created correctly an availability when not enabled by default", twoNodesConfig:
|
||||
let totalSize = 12.u256
|
||||
let minPricePerBytePerSecond = 1.u256
|
||||
let totalCollateral = totalSize * minPricePerBytePerSecond
|
||||
let availability = client1.postAvailability(
|
||||
totalSize = totalSize,
|
||||
duration = 2.u256,
|
||||
minPricePerBytePerSecond = minPricePerBytePerSecond,
|
||||
totalCollateral = totalCollateral,
|
||||
enabled = false.some,
|
||||
).get
|
||||
check availability.enabled == false
|
||||
|
||||
test "node lists local files", twoNodesConfig:
|
||||
let content1 = "some file contents"
|
||||
let content2 = "some other contents"
|
||||
|
@ -108,6 +108,18 @@ multinodesuite "Sales":
|
||||
check updatedAvailability.totalSize == 100000
|
||||
check updatedAvailability.freeSize == 100000
|
||||
|
||||
test "updating availability - updating enabled", salesConfig:
|
||||
let availability = host.postAvailability(
|
||||
totalSize = 140000.u256,
|
||||
duration = 200.u256,
|
||||
minPricePerBytePerSecond = 3.u256,
|
||||
totalCollateral = 300.u256,
|
||||
enabled = true.some,
|
||||
).get
|
||||
host.patchAvailability(availability.id, enabled = false.some)
|
||||
let updatedAvailability = (host.getAvailabilities().get).findItem(availability).get
|
||||
check updatedAvailability.enabled == false
|
||||
|
||||
test "updating availability - updating totalSize does not allow bellow utilized",
|
||||
salesConfig:
|
||||
let originalSize = 0xFFFFFF.u256
|
||||
|
Loading…
x
Reference in New Issue
Block a user