feat: slots rest api (#443)
Co-authored-by: markspanbroek <mark@spanbroek.net>
This commit is contained in:
parent
219c7704b9
commit
4cd8dd2e05
|
@ -1,4 +1,5 @@
|
||||||
import std/strutils
|
import std/strutils
|
||||||
|
import std/strformat
|
||||||
import pkg/chronicles
|
import pkg/chronicles
|
||||||
import pkg/ethers
|
import pkg/ethers
|
||||||
import pkg/ethers/testing
|
import pkg/ethers/testing
|
||||||
|
@ -52,7 +53,10 @@ method myRequests*(market: OnChainMarket): Future[seq[RequestId]] {.async.} =
|
||||||
return await market.contract.myRequests
|
return await market.contract.myRequests
|
||||||
|
|
||||||
method mySlots*(market: OnChainMarket): Future[seq[SlotId]] {.async.} =
|
method mySlots*(market: OnChainMarket): Future[seq[SlotId]] {.async.} =
|
||||||
return await market.contract.mySlots()
|
let slots = await market.contract.mySlots()
|
||||||
|
debug "Fetched my slots", numSlots=len(slots)
|
||||||
|
|
||||||
|
return slots
|
||||||
|
|
||||||
method requestStorage(market: OnChainMarket, request: StorageRequest){.async.} =
|
method requestStorage(market: OnChainMarket, request: StorageRequest){.async.} =
|
||||||
debug "Requesting storage"
|
debug "Requesting storage"
|
||||||
|
|
|
@ -56,6 +56,7 @@ proc prove(proving: Proving, slot: Slot) {.async.} =
|
||||||
without onProve =? proving.onProve:
|
without onProve =? proving.onProve:
|
||||||
raiseAssert "onProve callback not set"
|
raiseAssert "onProve callback not set"
|
||||||
try:
|
try:
|
||||||
|
debug "Proving slot"
|
||||||
let proof = await onProve(slot)
|
let proof = await onProve(slot)
|
||||||
await proving.market.submitProof(slot.id, proof)
|
await proving.market.submitProof(slot.id, proof)
|
||||||
except CatchableError as e:
|
except CatchableError as e:
|
||||||
|
|
|
@ -313,6 +313,17 @@ proc initRestApi*(node: CodexNodeRef, conf: CodexConf): RestRouter =
|
||||||
trace "debug/peer returning peer record"
|
trace "debug/peer returning peer record"
|
||||||
return RestApiResponse.response($json)
|
return RestApiResponse.response($json)
|
||||||
|
|
||||||
|
router.api(
|
||||||
|
MethodGet,
|
||||||
|
"/api/codex/v1/sales/slots") do () -> RestApiResponse:
|
||||||
|
## Returns active slots for the host
|
||||||
|
|
||||||
|
without contracts =? node.contracts.host:
|
||||||
|
return RestApiResponse.error(Http503, "Sales unavailable")
|
||||||
|
|
||||||
|
let json = %(await contracts.sales.mySlots())
|
||||||
|
return RestApiResponse.response($json, contentType="application/json")
|
||||||
|
|
||||||
router.api(
|
router.api(
|
||||||
MethodGet,
|
MethodGet,
|
||||||
"/api/codex/v1/sales/availability") do () -> RestApiResponse:
|
"/api/codex/v1/sales/availability") do () -> RestApiResponse:
|
||||||
|
|
|
@ -55,6 +55,13 @@ func `%`*(arr: openArray[byte]): JsonNode =
|
||||||
func `%`*(id: RequestId | SlotId | Nonce | AvailabilityId): JsonNode =
|
func `%`*(id: RequestId | SlotId | Nonce | AvailabilityId): JsonNode =
|
||||||
% id.toArray
|
% id.toArray
|
||||||
|
|
||||||
|
func `%`*(obj: StorageRequest | Slot): JsonNode =
|
||||||
|
let jsonObj = newJObject()
|
||||||
|
for k, v in obj.fieldPairs: jsonObj[k] = %v
|
||||||
|
jsonObj["id"] = %(obj.id)
|
||||||
|
|
||||||
|
return jsonObj
|
||||||
|
|
||||||
func `%`*(purchase: Purchase): JsonNode =
|
func `%`*(purchase: Purchase): JsonNode =
|
||||||
%*{
|
%*{
|
||||||
"state": purchase.state |? "none",
|
"state": purchase.state |? "none",
|
||||||
|
|
|
@ -100,20 +100,28 @@ proc handleRequest(sales: Sales,
|
||||||
agent.start(SaleDownloading())
|
agent.start(SaleDownloading())
|
||||||
sales.agents.add agent
|
sales.agents.add agent
|
||||||
|
|
||||||
proc load*(sales: Sales) {.async.} =
|
proc mySlots*(sales: Sales): Future[seq[Slot]] {.async.} =
|
||||||
let market = sales.context.market
|
let market = sales.context.market
|
||||||
|
|
||||||
let slotIds = await market.mySlots()
|
let slotIds = await market.mySlots()
|
||||||
|
var slots: seq[Slot] = @[]
|
||||||
|
|
||||||
for slotId in slotIds:
|
for slotId in slotIds:
|
||||||
if slot =? (await market.getActiveSlot(slotId)):
|
if slot =? (await market.getActiveSlot(slotId)):
|
||||||
let agent = newSalesAgent(
|
slots.add slot
|
||||||
sales.context,
|
|
||||||
slot.request.id,
|
return slots
|
||||||
slot.slotIndex,
|
|
||||||
some slot.request)
|
proc load*(sales: Sales) {.async.} =
|
||||||
agent.start(SaleUnknown())
|
let slots = await sales.mySlots()
|
||||||
sales.agents.add agent
|
|
||||||
|
for slot in slots:
|
||||||
|
let agent = newSalesAgent(
|
||||||
|
sales.context,
|
||||||
|
slot.request.id,
|
||||||
|
slot.slotIndex,
|
||||||
|
some slot.request)
|
||||||
|
agent.start(SaleUnknown())
|
||||||
|
sales.agents.add agent
|
||||||
|
|
||||||
proc start*(sales: Sales) {.async.} =
|
proc start*(sales: Sales) {.async.} =
|
||||||
doAssert sales.subscription.isNone, "Sales already started"
|
doAssert sales.subscription.isNone, "Sales already started"
|
||||||
|
|
37
openapi.yaml
37
openapi.yaml
|
@ -116,6 +116,18 @@ components:
|
||||||
type: string
|
type: string
|
||||||
description: Maximum collateral user is willing to pay per filled Slot (in amount of tokens)
|
description: Maximum collateral user is willing to pay per filled Slot (in amount of tokens)
|
||||||
|
|
||||||
|
Slot:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
description: Slot ID
|
||||||
|
request:
|
||||||
|
$ref: "#/components/schemas/StorageRequest"
|
||||||
|
slotIndex:
|
||||||
|
type: string
|
||||||
|
description: Slot Index as hexadecimal string
|
||||||
|
|
||||||
StorageRequestCreation:
|
StorageRequestCreation:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
|
@ -166,6 +178,9 @@ components:
|
||||||
StorageRequest:
|
StorageRequest:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
description: Request ID
|
||||||
client:
|
client:
|
||||||
$ref: "#/components/schemas/EthereumAddress"
|
$ref: "#/components/schemas/EthereumAddress"
|
||||||
ask:
|
ask:
|
||||||
|
@ -286,14 +301,32 @@ paths:
|
||||||
"500":
|
"500":
|
||||||
description: Well it was bad-bad and the upload did not work out
|
description: Well it was bad-bad and the upload did not work out
|
||||||
|
|
||||||
|
"/sales/slots":
|
||||||
|
get:
|
||||||
|
summary: "Returns active slots"
|
||||||
|
tags: [ Marketplace ]
|
||||||
|
operationId: getActiveSlots
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Retrieved active slots
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/Slot"
|
||||||
|
|
||||||
|
"503":
|
||||||
|
description: Sales are unavailable
|
||||||
|
|
||||||
"/sales/availability":
|
"/sales/availability":
|
||||||
get:
|
get:
|
||||||
summary: "Returns storage that is for sale"
|
summary: "Returns storage that is for sale"
|
||||||
tags: [ Marketplace ]
|
tags: [ Marketplace ]
|
||||||
operationId: getsOfferedStorage
|
operationId: getOfferedStorage
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: Retrieved content specified by CID
|
description: Retrieved storage availabilities of the node
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
|
|
|
@ -50,6 +50,11 @@ proc getPurchase*(client: CodexClient, purchase: string): JsonNode =
|
||||||
let body = client.http.getContent(url)
|
let body = client.http.getContent(url)
|
||||||
parseJson(body).catch |? nil
|
parseJson(body).catch |? nil
|
||||||
|
|
||||||
|
proc getSlots*(client: CodexClient): JsonNode =
|
||||||
|
let url = client.baseurl & "/sales/slots"
|
||||||
|
let body = client.http.getContent(url)
|
||||||
|
parseJson(body).catch |? nil
|
||||||
|
|
||||||
proc postAvailability*(client: CodexClient,
|
proc postAvailability*(client: CodexClient,
|
||||||
size, duration, minPrice: uint64, maxCollateral: uint64): JsonNode =
|
size, duration, minPrice: uint64, maxCollateral: uint64): JsonNode =
|
||||||
let url = client.baseurl & "/sales/availability"
|
let url = client.baseurl & "/sales/availability"
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 5a4f786757124c903ab46499689db8273ee5ac80
|
Subproject commit 18e225607cc6add166b93df6ac4229936a641318
|
Loading…
Reference in New Issue