feat(slot-reservations): Add expansionRate parameter to support contract changes

Adds `expansionRate` field to the `StorageRequest` object, to mirror the object in the contracts.

The CodexClient api module uses a default value of 100, which means that all SPs will be available to reserve slots immediately, when the functionality is finally implemented. It was chosen to provide as little disruption to existing as possible, and may change in the future.

The default value for the REST API endpoint was 60, meaning 60% of the total time before expiry will have all addresses eligible to fill the slot.
This commit is contained in:
Eric 2024-09-23 19:06:25 +10:00
parent 4c22934d1f
commit 6e10e3d2cf
No known key found for this signature in database
9 changed files with 50 additions and 12 deletions

View File

@ -19,6 +19,7 @@ type
content* {.serialize.}: StorageContent
expiry* {.serialize.}: UInt256
nonce*: Nonce
expansionRate* {.serialize.}: uint8
StorageAsk* = object
slots* {.serialize.}: uint64
slotSize* {.serialize.}: UInt256
@ -93,7 +94,8 @@ func fromTuple(_: type StorageRequest, tupl: tuple): StorageRequest =
ask: tupl[1],
content: tupl[2],
expiry: tupl[3],
nonce: tupl[4]
nonce: tupl[4],
expansionRate: tupl[5],
)
func fromTuple(_: type Slot, tupl: tuple): Slot =

View File

@ -394,7 +394,8 @@ proc setupRequest(
tolerance: uint,
reward: UInt256,
collateral: UInt256,
expiry: UInt256): Future[?!StorageRequest] {.async.} =
expiry: UInt256,
expansionRate: uint8): Future[?!StorageRequest] {.async.} =
## Setup slots for a given dataset
##
@ -411,6 +412,7 @@ proc setupRequest(
proofProbability = proofProbability
collateral = collateral
expiry = expiry
expansionRate = expansionRate
ecK = ecK
ecM = ecM
@ -474,7 +476,8 @@ proc setupRequest(
cid: $manifestBlk.cid, # TODO: why string?
merkleRoot: verifyRoot
),
expiry: expiry
expiry: expiry,
expansionRate: expansionRate
)
trace "Request created", request = $request
@ -489,7 +492,8 @@ proc requestStorage*(
tolerance: uint,
reward: UInt256,
collateral: UInt256,
expiry: UInt256): Future[?!PurchaseId] {.async.} =
expiry: UInt256,
expansionRate: uint8): Future[?!PurchaseId] {.async.} =
## Initiate a request for storage sequence, this might
## be a multistep procedure.
##
@ -503,6 +507,7 @@ proc requestStorage*(
proofProbability = proofProbability
collateral = collateral
expiry = expiry.truncate(int64)
expansionRate = expansionRate
now = self.clock.now
trace "Received a request for storage!"
@ -520,7 +525,8 @@ proc requestStorage*(
tolerance,
reward,
collateral,
expiry)), err:
expiry,
expansionRate)), err:
trace "Unable to setup request"
return failure err

View File

@ -455,6 +455,7 @@ proc initPurchasingApi(node: CodexNodeRef, router: var RestRouter) =
let nodes = params.nodes |? 1
let tolerance = params.tolerance |? 0
let expansionRate = params.expansionRate |? 60'u8
# prevent underflow
if tolerance > nodes:
@ -473,6 +474,9 @@ proc initPurchasingApi(node: CodexNodeRef, router: var RestRouter) =
if expiry <= 0 or expiry >= params.duration:
return RestApiResponse.error(Http400, "Expiry needs value bigger then zero and smaller then the request's duration", headers = headers)
if expansionRate > 100'u8:
return RestApiResponse.error(Http400, "Expansion rate must be between 0 and 100 (inclusive)", headers = headers)
without purchaseId =? await node.requestStorage(
cid,
params.duration,
@ -481,7 +485,8 @@ proc initPurchasingApi(node: CodexNodeRef, router: var RestRouter) =
tolerance,
params.reward,
params.collateral,
expiry), error:
expiry,
expansionRate), error:
if error of InsufficientBlocksError:
return RestApiResponse.error(Http400,

View File

@ -20,6 +20,7 @@ type
expiry* {.serialize.}: ?UInt256
nodes* {.serialize.}: ?uint
tolerance* {.serialize.}: ?uint
expansionRate* {.serialize.}: ?uint8
RestPurchase* = object
requestId* {.serialize.}: RequestId

View File

@ -164,7 +164,8 @@ asyncchecksuite "Test Node - Basic":
reward = 2.u256,
proofProbability = 3.u256,
expiry = 200.u256,
collateral = 200.u256)).tryGet
collateral = 200.u256,
expansionRate = 100'u8)).tryGet
check:
(await verifiableBlock.cid in localStore) == true

View File

@ -60,6 +60,7 @@ proc example*(_: type StorageRequest): StorageRequest =
merkleRoot: array[32, byte].example
),
expiry:(60 * 60).u256, # 1 hour ,
expansionRate: 100'u8,
nonce: Nonce.example
)

View File

@ -97,7 +97,8 @@ proc requestStorageRaw*(
collateral: UInt256,
expiry: uint = 0,
nodes: uint = 2,
tolerance: uint = 0
tolerance: uint = 0,
expansionRate: uint8 = 100
): Response =
## Call request storage REST endpoint
@ -109,7 +110,8 @@ proc requestStorageRaw*(
"proofProbability": proofProbability,
"collateral": collateral,
"nodes": nodes,
"tolerance": tolerance
"tolerance": tolerance,
"expansionRate": expansionRate
}
if expiry != 0:
@ -126,11 +128,12 @@ proc requestStorage*(
expiry: uint,
collateral: UInt256,
nodes: uint = 2,
tolerance: uint = 0
tolerance: uint = 0,
expansionRate: uint8 = 100
): ?!PurchaseId =
## Call request storage REST endpoint
##
let response = client.requestStorageRaw(cid, duration, reward, proofProbability, collateral, expiry, nodes, tolerance)
let response = client.requestStorageRaw(cid, duration, reward, proofProbability, collateral, expiry, nodes, tolerance, expansionRate)
if response.status != "200 OK":
doAssert(false, response.body)
PurchaseId.fromHex(response.body).catch

View File

@ -105,6 +105,25 @@ twonodessuite "REST API", debug1 = false, debug2 = false:
check responseBefore.status == "400 Bad Request"
check responseBefore.body == "Invalid parameters: `tolerance` cannot be greater than `nodes`"
test "request storage fails when expansionRate is too large":
let data = await RandomChunker.example(blocks=2)
let cid = client1.upload(data).get
let response = client1.requestStorageRaw(
cid,
duration=10.u256,
reward=2.u256,
proofProbability=3.u256,
nodes=2,
tolerance=0,
collateral=200.u256,
expiry=9,
expansionRate=101)
check:
response.status == "400 Bad Request"
response.body == "Expansion rate must be between 0 and 100 (inclusive)"
test "request storage succeeds if nodes and tolerance within range":
let data = await RandomChunker.example(blocks=2)
let cid = client1.upload(data).get

@ -1 +1 @@
Subproject commit d2ba8693e772b83e80746ffadc1efc36c836caf0
Subproject commit 2331ae1f0ada27bb1a9fe61d7432033ef0ab5d81