Move until validation to reservations module

This commit is contained in:
Arnaud 2025-02-21 17:03:09 +01:00
parent 5b564b14e1
commit c437ccf9a7
No known key found for this signature in database
GPG Key ID: 69D6CE281FCAE663
9 changed files with 63 additions and 65 deletions

View File

@ -49,32 +49,6 @@ logScope:
declareCounter(codex_api_uploads, "codex API uploads")
declareCounter(codex_api_downloads, "codex API downloads")
proc getLongestRequestEnd(
node: CodexNodeRef, availabilityId: AvailabilityId
): Future[?!SecondsSince1970] {.async: (raises: []).} =
without contracts =? node.contracts.host:
return failure("Sales unavailable")
let
reservations = contracts.sales.context.reservations
market = contracts.sales.context.market
try:
without allReservations =? await reservations.all(Reservation, availabilityId):
return failure("Cannot retrieve the reservations")
echo "all reservations is done"
let requestEnds = allReservations.mapIt(await market.getRequestEnd(it.requestId))
if len(requestEnds) == 0:
return success(0.SecondsSince1970)
return success(requestEnds.max)
except CancelledError, CatchableError:
error "Error when trying to get longest request end",
error = getCurrentExceptionMsg()
return failure("Cannot retrieve the request dates")
proc validate(pattern: string, value: string): int {.gcsafe, raises: [Defect].} =
0
@ -503,6 +477,11 @@ proc initSalesApi(node: CodexNodeRef, router: var RestRouter) =
until = restAv.until |? 0,
)
), error:
if error of CancelledError:
raise error
if error of UntilOutOfBoundsError:
return RestApiResponse.error(Http422, error.msg)
return RestApiResponse.error(Http500, error.msg, headers = headers)
return RestApiResponse.response(

View File

@ -482,7 +482,13 @@ method createReservation*(
)
return failure(error)
if duration > SecondsSince1970.high.uint64:
error "Cannot cast duration to int64", duration = duration
let error = newException(ReservationsError, "Cannot cast duration to int64")
return failure(error)
let validUntil = times.now().utc().toTime().toUnix() + duration.SecondsSince1970
trace "Creating reservation",
availabilityId, slotSize, requestId, slotIndex, validUntil = validUntil
@ -497,7 +503,7 @@ method createReservation*(
availability.freeSize -= slotSize
# adjust the remaining totalRemainingCollateral
availability.totalRemainingCollateral -= slotSize.stuint(256) * collateralPerByte
availability.totalRemainingCollateral -= slotSize.u256 * collateralPerByte
# update availability with reduced size
trace "Updating availability with reduced size"

View File

@ -28,7 +28,7 @@ method createReservation*(
requestId: RequestId,
slotIndex: uint64,
collateralPerByte: UInt256,
duration: UInt256,
duration: uint64,
): Future[?!Reservation] {.async.} =
if self.createReservationThrowBytesOutOfBoundsError:
let error = newException(

View File

@ -53,7 +53,7 @@ asyncchecksuite "Reservations module":
proc createReservation(availability: Availability): Reservation =
let size = rand(1 ..< availability.freeSize.int)
let reservation = waitFor reservations.createReservation(
availability.id, size.uint64, RequestId.example, uint64.example, 1.u256
availability.id, size.uint64, RequestId.example, uint64.example, 1.u256, 30.uint64
)
return reservation.get
@ -136,7 +136,7 @@ asyncchecksuite "Reservations module":
let availability = Availability.example
let created = await reservations.createReservation(
availability.id, uint64.example, RequestId.example, uint64.example, 1.u256,
30.u256,
30.uint64,
)
check created.isErr
check created.error of NotExistsError
@ -149,7 +149,7 @@ asyncchecksuite "Reservations module":
RequestId.example,
uint64.example,
UInt256.example,
UInt256.example,
30.uint64,
)
check created.isErr
check created.error of BytesOutOfBoundsError
@ -163,18 +163,19 @@ asyncchecksuite "Reservations module":
RequestId.example,
uint64.example,
UInt256.example,
UInt256.example,
30.uint64,
)
let two = reservations.createReservation(
availability.id, availability.totalSize, RequestId.example, uint64.example,
UInt256.example, UInt256.example,
UInt256.example, uint64.example,
)
let oneResult = await one
let twoResult = await two
check oneResult.isErr or twoResult.isErr
if oneResult.isErr:
check oneResult.error of BytesOutOfBoundsError
if twoResult.isErr:
@ -284,9 +285,9 @@ asyncchecksuite "Reservations module":
check availability.until == until
test "create an availability fails when trying set until with a negative value":
let totalSize = rand(100000 .. 200000).u256
let totalSize = rand(100000 .. 200000).uint64
let example = Availability.example(collateralPerByte)
let totalCollateral = totalSize * collateralPerByte
let totalCollateral = totalSize.u256 * collateralPerByte
let result = await reservations.createAvailability(
totalSize,

View File

@ -640,7 +640,7 @@ asyncchecksuite "Sales":
createAvailability()
discard await reservations.createReservation(
availability.id, 100.uint64, RequestId.example, 0.uint64, UInt256.example,
UInt256.example,
30.uint64,
)
check (await reservations.all(Reservation)).get.len == 1
await sales.load()

View File

@ -208,7 +208,8 @@ proc postAvailabilityRaw*(
proc postAvailability*(
client: CodexClient,
totalSize, duration, minPricePerBytePerSecond, totalCollateral: UInt256,
totalSize, duration: uint64,
minPricePerBytePerSecond, totalCollateral: UInt256,
enabled: ?bool = bool.none,
until: ?SecondsSince1970 = SecondsSince1970.none,
): ?!Availability =
@ -220,6 +221,7 @@ proc postAvailability*(
enabled = enabled,
until = until,
)
doAssert response.status == "201 Created",
"expected 201 Created, got " & response.status & ", body: " & response.body
Availability.fromJson(response.body)

View File

@ -127,34 +127,36 @@ marketplacesuite "Marketplace":
test "returns an error when trying to update the until date before an existing a request is finished",
marketplaceConfig:
let size = 0xFFFFFF.u256
let size = 0xFFFFFF.uint64
let data = await RandomChunker.example(blocks = blocks)
let marketplace = Marketplace.new(Marketplace.address, ethProvider.getSigner())
let tokenAddress = await marketplace.token()
let token = Erc20Token.new(tokenAddress, ethProvider.getSigner())
let duration = 20 * 60.u256
let duration = 20 * 60.uint64
# host makes storage available
let startBalanceHost = await token.balanceOf(hostAccount)
let availability = host.postAvailability(
totalSize = size,
duration = 20 * 60.u256,
duration = 20 * 60.uint64,
minPricePerBytePerSecond = minPricePerBytePerSecond,
totalCollateral = size * minPricePerBytePerSecond,
totalCollateral = size.u256 * minPricePerBytePerSecond,
).get
# client requests storage
let cid = client.upload(data).get
let id = client.requestStorage(
cid,
duration = duration,
pricePerBytePerSecond = minPricePerBytePerSecond,
proofProbability = 3.u256,
expiry = 10 * 60,
collateralPerByte = collateralPerByte,
nodes = ecNodes,
tolerance = ecTolerance,
).get
let id = (
await client.requestStorage(
cid,
duration = duration,
pricePerBytePerSecond = minPricePerBytePerSecond,
proofProbability = 3.u256,
expiry = 10 * 60.uint64,
collateralPerByte = collateralPerByte,
nodes = ecNodes,
tolerance = ecTolerance,
)
)
check eventually(client.purchaseStateIs(id, "started"), timeout = 10 * 60 * 1000)
let purchase = client.getPurchase(id).get

View File

@ -33,7 +33,7 @@ twonodessuite "REST API":
duration = 2.uint64,
minPricePerBytePerSecond = minPricePerBytePerSecond,
totalCollateral = totalCollateral,
enabled = true,
enabled = true.some,
).get
let space = client1.space().tryGet()
check:

View File

@ -57,20 +57,20 @@ multinodesuite "Sales":
check availability in host.getAvailabilities().get
test "creating availability fails when until is negative", salesConfig:
let totalSize = 12.u256
let totalSize = 12.uint64
let minPricePerBytePerSecond = 1.u256
let totalCollateral = totalSize * minPricePerBytePerSecond
let totalCollateral = totalSize.u256 * minPricePerBytePerSecond
let response = host.postAvailabilityRaw(
totalSize = totalSize,
duration = 2.u256,
duration = 2.uint64,
minPricePerBytePerSecond = minPricePerBytePerSecond,
totalCollateral = totalCollateral,
until = cast[SecondsSince1970](-1).some,
until = -1.SecondsSince1970.some,
)
check:
response.status == "400 Bad Request"
response.body == "Until parameter must be greater or equal 0. Got: -1"
response.status == "422 Unprocessable Entity"
response.body == "Cannot set until to a negative value"
test "updating non-existing availability", salesConfig:
let nonExistingResponse = host.patchAvailabilityRaw(
@ -131,6 +131,9 @@ multinodesuite "Sales":
totalCollateral = 300.u256,
).get
host.patchAvailability(availability.id, totalSize = 100000.uint64.some)
host.restart()
let updatedAvailability = (host.getAvailabilities().get).findItem(availability).get
check updatedAvailability.totalSize == 100000
check updatedAvailability.freeSize == 100000
@ -169,10 +172,16 @@ multinodesuite "Sales":
let utilizedSize = updatedAvailability.totalSize - updatedAvailability.freeSize
let totalSizeResponse =
host.patchAvailabilityRaw(availability.id, totalSize = (utilizedSize - 1).some)
host.restart()
check totalSizeResponse.status == "400 Bad Request"
check "totalSize must be larger then current totalSize" in totalSizeResponse.body
host.patchAvailability(availability.id, totalSize = (originalSize + 20000).some)
host.restart()
let newUpdatedAvailability =
(host.getAvailabilities().get).findItem(availability).get
check newUpdatedAvailability.totalSize == originalSize + 20000
@ -180,16 +189,15 @@ multinodesuite "Sales":
test "updating availability fails with until negative", salesConfig:
let availability = host.postAvailability(
totalSize = 140000.u256,
duration = 200.u256,
totalSize = 140000.uint64,
duration = 200.uint64,
minPricePerBytePerSecond = 3.u256,
totalCollateral = 300.u256,
).get
let response = host.patchAvailabilityRaw(
availability.id, until = cast[SecondsSince1970](-1).some
)
let response =
host.patchAvailabilityRaw(availability.id, until = -1.SecondsSince1970.some)
check:
response.status == "400 Bad Request"
response.body == "Until parameter must be greater or equal 0. Got: -1"
response.status == "422 Unprocessable Entity"
response.body == "Cannot set until to a negative value"