diff --git a/dagger/node.nim b/dagger/node.nim index de2a5ef0..8ba37409 100644 --- a/dagger/node.nim +++ b/dagger/node.nim @@ -207,14 +207,12 @@ proc store*( return manifest.cid.success -proc requestStorage*( - self: DaggerNodeRef, - cid: Cid, - ppb: uint, - duration: Duration, - nodes: uint, - tolerance: uint, - autoRenew: bool = false): Future[?!Cid] {.async.} = +proc requestStorage*(self: DaggerNodeRef, + cid: Cid, + duration: UInt256, + nodes: uint, + tolerance: uint, + maxPrice: UInt256): Future[?!Cid] {.async.} = ## Initiate a request for storage sequence, this might ## be a multistep procedure. ## @@ -224,7 +222,7 @@ proc requestStorage*( ## - Run the PoR setup on the erasure dataset ## - Call into the marketplace and purchasing contracts ## - trace "Received a request for storage!", cid, ppb, duration, nodes, tolerance, autoRenew + trace "Received a request for storage!", cid, duration, nodes, tolerance, maxPrice without blk =? (await self.blockStore.getBlock(cid)), error: trace "Unable to retrieve manifest block", cid diff --git a/dagger/rest/api.nim b/dagger/rest/api.nim index 301e6f6c..ac9b96c5 100644 --- a/dagger/rest/api.nim +++ b/dagger/rest/api.nim @@ -175,90 +175,35 @@ proc initRestApi*(node: DaggerNodeRef, conf: DaggerConf): RestRouter = if not stream.isNil: await stream.close() - router.api( + router.rawApi( MethodPost, - "/api/dagger/v1/storage/request/{cid}") do ( - cid: Cid, - ppb: Option[uint], - duration: Option[Duration], - nodes: Option[uint], - loss: Option[uint], - renew: Option[bool]) -> RestApiResponse: + "/api/dagger/v1/storage/request/{cid}") do (cid: Cid) -> RestApiResponse: ## Create a request for storage ## - ## Cid - the cid of the previously uploaded dataset - ## ppb - the price per byte the client is willing to pay + ## cid - the cid of a previously uploaded dataset ## duration - the duration of the contract - ## nodeCount - the total amount of the nodes storing the dataset, including `lossTolerance` - ## lossTolerance - the number of nodes losses the user is willing to tolerate - ## autoRenew - should the contract be autorenewed - - ## will fail unless the user has enough funds lockedup - ## + ## maxPrice - the maximum price the client is willing to pay - var - cid = - if cid.isErr: - return RestApiResponse.error(Http400, $cid.error()) - else: - cid.get() + # TODO: store on multiple nodes + let nodes: uint = 1 + let tolerance: uint = 0 - ppb = - if ppb.isNone: - return RestApiResponse.error(Http400, "Missing ppb") - else: - if ppb.get().isErr: - return RestApiResponse.error(Http500, $ppb.get().error) - else: - ppb.get().get() + without cid =? cid.tryGet.catch, error: + return RestApiResponse.error(Http400, error.msg) - duration = - if duration.isNone: - return RestApiResponse.error(Http400, "Missing duration") - else: - if duration.get().isErr: - return RestApiResponse.error(Http500, $duration.get().error) - else: - duration.get().get() + let body = await request.getBody() - nodes = - if nodes.isNone: - return RestApiResponse.error(Http400, "Missing node count") - else: - if nodes.get().isErr: - return RestApiResponse.error(Http500, $nodes.get().error) - else: - nodes.get().get() + without params =? StorageRequestParams.fromJson(body), error: + return RestApiResponse.error(Http400, error.msg) - loss = - if loss.isNone: - return RestApiResponse.error(Http400, "Missing loss tolerance") - else: - if loss.get().isErr: - return RestApiResponse.error(Http500, $loss.get().error) - else: - loss.get().get() + without storageCid =? await node.requestStorage(cid, + params.duration, + nodes, + tolerance, + params.maxPrice), error: + return RestApiResponse.error(Http500, error.msg) - renew = if renew.isNone: - false - else: - if renew.get().isErr: - return RestApiResponse.error(Http500, $renew.get().error) - else: - renew.get().get() - - try: - without storageCid =? (await node.requestStorage( - cid, - ppb, - duration, - nodes, - loss, - renew)), error: - return RestApiResponse.error(Http500, error.msg) - - return RestApiResponse.response($storageCid) - except CatchableError as exc: - return RestApiResponse.error(Http500, exc.msg) + return RestApiResponse.response($storageCid) router.rawApi( MethodPost, diff --git a/dagger/rest/json.nim b/dagger/rest/json.nim index c4453bd9..fad69326 100644 --- a/dagger/rest/json.nim +++ b/dagger/rest/json.nim @@ -4,9 +4,21 @@ import pkg/stew/byteutils import pkg/questionable/results import ../sales +type + StorageRequestParams* = object + duration*: UInt256 + maxPrice*: UInt256 + proc fromJson*(_: type Availability, bytes: seq[byte]): ?!Availability = let json = ?catch parseJson(string.fromBytes(bytes)) let size = ?catch UInt256.fromHex(json["size"].getStr) let duration = ?catch UInt256.fromHex(json["duration"].getStr) let minPrice = ?catch UInt256.fromHex(json["minPrice"].getStr) success Availability.init(size, duration, minPrice) + +proc fromJson*(_: type StorageRequestParams, + bytes: seq[byte]): ?! StorageRequestParams = + let json = ?catch parseJson(string.fromBytes(bytes)) + let duration = ?catch UInt256.fromHex(json["duration"].getStr) + let maxPrice = ?catch UInt256.fromHex(json["maxPrice"].getStr) + success StorageRequestParams(duration: duration, maxPrice: maxPrice) diff --git a/tests/testIntegration.nim b/tests/testIntegration.nim index 063a4a8e..aca6f204 100644 --- a/tests/testIntegration.nim +++ b/tests/testIntegration.nim @@ -6,6 +6,7 @@ import std/httpclient import std/json import pkg/asynctest import pkg/chronos +import pkg/stew/byteutils suite "Integration tests": @@ -43,6 +44,11 @@ suite "Integration tests": let info2 = client.get(baseurl2 & "/info").body check info1 != info2 + test "node accepts file uploads": + let url = baseurl1 & "/upload" + let response = client.post(url, "some file contents") + check response.status == "200 OK" + test "node handles new storage availability": let url = baseurl1 & "/sales/availability" let json = %*{"size": "0x1", "duration": "0x2", "minPrice": "0x3"} @@ -55,3 +61,10 @@ suite "Integration tests": let response = client.get(url) check response.status == "200 OK" check parseJson(response.body) == %*[availability] + + test "node handles storage request": + let cid = client.post(baseurl1 & "/upload", "some file contents").body + let url = baseurl1 & "/storage/request/" & cid + let json = %*{"duration": "0x1", "maxPrice": "0x2"} + let response = client.post(url, $json) + check response.status == "200 OK"