[market] submit storage offers
This commit is contained in:
parent
e52153e2ba
commit
9f76e714a2
|
@ -20,6 +20,16 @@ func new*(_: type OnChainMarket, contract: Storage): OnChainMarket =
|
||||||
raiseAssert("Storage contract should have a signer")
|
raiseAssert("Storage contract should have a signer")
|
||||||
OnChainMarket(contract: contract, signer: signer)
|
OnChainMarket(contract: contract, signer: signer)
|
||||||
|
|
||||||
|
method requestStorage(market: OnChainMarket, request: StorageRequest) {.async.} =
|
||||||
|
var request = request
|
||||||
|
request.client = await market.signer.getAddress()
|
||||||
|
await market.contract.requestStorage(request)
|
||||||
|
|
||||||
|
method offerStorage(market: OnChainMarket, offer: StorageOffer) {.async.} =
|
||||||
|
var offer = offer
|
||||||
|
offer.host = await market.signer.getAddress()
|
||||||
|
await market.contract.offerStorage(offer)
|
||||||
|
|
||||||
method subscribeRequests(market: OnChainMarket,
|
method subscribeRequests(market: OnChainMarket,
|
||||||
callback: OnRequest):
|
callback: OnRequest):
|
||||||
Future[MarketSubscription] {.async.} =
|
Future[MarketSubscription] {.async.} =
|
||||||
|
@ -28,10 +38,14 @@ method subscribeRequests(market: OnChainMarket,
|
||||||
let subscription = await market.contract.subscribe(StorageRequested, onEvent)
|
let subscription = await market.contract.subscribe(StorageRequested, onEvent)
|
||||||
return OnChainMarketSubscription(eventSubscription: subscription)
|
return OnChainMarketSubscription(eventSubscription: subscription)
|
||||||
|
|
||||||
method requestStorage(market: OnChainMarket, request: StorageRequest) {.async.} =
|
method subscribeOffers(market: OnChainMarket,
|
||||||
var request = request
|
requestId: array[32, byte],
|
||||||
request.client = await market.signer.getAddress()
|
callback: OnOffer):
|
||||||
await market.contract.requestStorage(request)
|
Future[MarketSubscription] {.async.} =
|
||||||
|
proc onEvent(event: StorageOffered) {.upraises:[].} =
|
||||||
|
callback(event.offer)
|
||||||
|
let subscription = await market.contract.subscribe(StorageOffered, onEvent)
|
||||||
|
return OnChainMarketSubscription(eventSubscription: subscription)
|
||||||
|
|
||||||
method unsubscribe*(subscription: OnChainMarketSubscription) {.async.} =
|
method unsubscribe*(subscription: OnChainMarketSubscription) {.async.} =
|
||||||
await subscription.eventSubscription.unsubscribe()
|
await subscription.eventSubscription.unsubscribe()
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import pkg/contractabi
|
import pkg/contractabi
|
||||||
import pkg/nimcrypto
|
import pkg/nimcrypto
|
||||||
|
import pkg/ethers/fields
|
||||||
|
import pkg/questionable/results
|
||||||
|
|
||||||
export contractabi
|
export contractabi
|
||||||
|
|
||||||
|
@ -10,19 +12,23 @@ type
|
||||||
price*: UInt256
|
price*: UInt256
|
||||||
expiry*: UInt256
|
expiry*: UInt256
|
||||||
|
|
||||||
func toTuple(offer: StorageOffer): auto =
|
func fromTuple(_: type StorageOffer, tupl: tuple): StorageOffer =
|
||||||
(
|
StorageOffer(
|
||||||
offer.host,
|
host: tupl[0],
|
||||||
offer.requestId,
|
requestId: tupl[1],
|
||||||
offer.price,
|
price: tupl[2],
|
||||||
offer.expiry
|
expiry: tupl[3]
|
||||||
)
|
)
|
||||||
|
|
||||||
func solidityType*(_: type StorageOffer): string =
|
func solidityType*(_: type StorageOffer): string =
|
||||||
solidityType(typeof StorageOffer.default.toTuple)
|
solidityType(StorageOffer.fieldTypes)
|
||||||
|
|
||||||
func encode*(encoder: var AbiEncoder, offer: StorageOffer) =
|
func encode*(encoder: var AbiEncoder, offer: StorageOffer) =
|
||||||
encoder.write(offer.toTuple)
|
encoder.write(offer.fieldValues)
|
||||||
|
|
||||||
|
func decode*(decoder: var AbiDecoder, T: type StorageOffer): ?!T =
|
||||||
|
let tupl = ?decoder.read(StorageOffer.fieldTypes)
|
||||||
|
success StorageOffer.fromTuple(tupl)
|
||||||
|
|
||||||
func id*(offer: StorageOffer): array[32, byte] =
|
func id*(offer: StorageOffer): array[32, byte] =
|
||||||
let encoding = AbiEncoder.encode(offer)
|
let encoding = AbiEncoder.encode(offer)
|
||||||
|
|
|
@ -6,7 +6,7 @@ import ./requests
|
||||||
import ./offers
|
import ./offers
|
||||||
|
|
||||||
export stint
|
export stint
|
||||||
export contract
|
export ethers
|
||||||
|
|
||||||
type
|
type
|
||||||
Storage* = ref object of Contract
|
Storage* = ref object of Contract
|
||||||
|
@ -14,6 +14,10 @@ type
|
||||||
StorageRequested* = object of Event
|
StorageRequested* = object of Event
|
||||||
requestId*: Id
|
requestId*: Id
|
||||||
request*: StorageRequest
|
request*: StorageRequest
|
||||||
|
StorageOffered* = object of Event
|
||||||
|
offerId*: Id
|
||||||
|
offer*: StorageOffer
|
||||||
|
requestId* {.indexed.}: Id
|
||||||
|
|
||||||
proc collateralAmount*(storage: Storage): UInt256 {.contract, view.}
|
proc collateralAmount*(storage: Storage): UInt256 {.contract, view.}
|
||||||
proc slashMisses*(storage: Storage): UInt256 {.contract, view.}
|
proc slashMisses*(storage: Storage): UInt256 {.contract, view.}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import std/times
|
||||||
import ./ethertest
|
import ./ethertest
|
||||||
import dagger/contracts
|
import dagger/contracts
|
||||||
import dagger/contracts/testtoken
|
import dagger/contracts/testtoken
|
||||||
|
@ -8,14 +9,28 @@ ethersuite "On-Chain Market":
|
||||||
var market: OnChainMarket
|
var market: OnChainMarket
|
||||||
var storage: Storage
|
var storage: Storage
|
||||||
var token: TestToken
|
var token: TestToken
|
||||||
|
var request: StorageRequest
|
||||||
|
var offer: StorageOffer
|
||||||
|
|
||||||
setup:
|
setup:
|
||||||
let deployment = deployment()
|
let deployment = deployment()
|
||||||
storage = Storage.new(!deployment.address(Storage), provider.getSigner())
|
storage = Storage.new(!deployment.address(Storage), provider.getSigner())
|
||||||
token = TestToken.new(!deployment.address(TestToken), provider.getSigner())
|
token = TestToken.new(!deployment.address(TestToken), provider.getSigner())
|
||||||
await token.mint(accounts[0], 1000.u256)
|
await token.mint(accounts[0], 1000.u256)
|
||||||
|
|
||||||
|
let collateral = await storage.collateralAmount()
|
||||||
|
await token.approve(storage.address, collateral)
|
||||||
|
await storage.deposit(collateral)
|
||||||
|
|
||||||
market = OnChainMarket.new(storage)
|
market = OnChainMarket.new(storage)
|
||||||
|
|
||||||
|
request = StorageRequest.example
|
||||||
|
offer = StorageOffer.example
|
||||||
|
request.client = accounts[0]
|
||||||
|
offer.host = accounts[0]
|
||||||
|
offer.requestId = request.id
|
||||||
|
offer.price = request.maxPrice
|
||||||
|
|
||||||
test "fails to instantiate when contract does not have a signer":
|
test "fails to instantiate when contract does not have a signer":
|
||||||
let storageWithoutSigner = storage.connect(provider)
|
let storageWithoutSigner = storage.connect(provider)
|
||||||
expect AssertionError:
|
expect AssertionError:
|
||||||
|
@ -26,14 +41,55 @@ ethersuite "On-Chain Market":
|
||||||
proc onRequest(request: StorageRequest) =
|
proc onRequest(request: StorageRequest) =
|
||||||
submitted.add(request)
|
submitted.add(request)
|
||||||
let subscription = await market.subscribeRequests(onRequest)
|
let subscription = await market.subscribeRequests(onRequest)
|
||||||
let request = StorageRequest(
|
await token.approve(storage.address, request.maxPrice)
|
||||||
duration: uint16.example.u256,
|
|
||||||
size: uint32.example.u256,
|
|
||||||
contentHash: array[32, byte].example
|
|
||||||
)
|
|
||||||
await market.requestStorage(request)
|
await market.requestStorage(request)
|
||||||
check submitted.len == 1
|
|
||||||
check submitted[0].duration == request.duration
|
check submitted == @[request]
|
||||||
check submitted[0].size == request.size
|
|
||||||
check submitted[0].contentHash == request.contentHash
|
|
||||||
await subscription.unsubscribe()
|
await subscription.unsubscribe()
|
||||||
|
|
||||||
|
test "sets client address when submitting storage request":
|
||||||
|
var requestWithoutClient = request
|
||||||
|
requestWithoutClient.client = Address.default
|
||||||
|
|
||||||
|
var submitted: StorageRequest
|
||||||
|
proc onRequest(request: StorageRequest) =
|
||||||
|
submitted = request
|
||||||
|
let subscription = await market.subscribeRequests(onRequest)
|
||||||
|
await token.approve(storage.address, request.maxPrice)
|
||||||
|
|
||||||
|
await market.requestStorage(requestWithoutClient)
|
||||||
|
|
||||||
|
check submitted.client == accounts[0]
|
||||||
|
|
||||||
|
test "supports storage offers":
|
||||||
|
await token.approve(storage.address, request.maxPrice)
|
||||||
|
await market.requestStorage(request)
|
||||||
|
|
||||||
|
var submitted: seq[StorageOffer]
|
||||||
|
proc onOffer(offer: StorageOffer) =
|
||||||
|
submitted.add(offer)
|
||||||
|
let subscription = await market.subscribeOffers(request.id, onOffer)
|
||||||
|
|
||||||
|
await market.offerStorage(offer)
|
||||||
|
|
||||||
|
check submitted == @[offer]
|
||||||
|
|
||||||
|
await subscription.unsubscribe()
|
||||||
|
|
||||||
|
test "sets host address when submitting storage offer":
|
||||||
|
var offerWithoutHost = offer
|
||||||
|
offerWithoutHost.host = Address.default
|
||||||
|
|
||||||
|
await token.approve(storage.address, request.maxPrice)
|
||||||
|
await market.requestStorage(request)
|
||||||
|
|
||||||
|
var submitted: StorageOffer
|
||||||
|
proc onOffer(offer: StorageOffer) =
|
||||||
|
submitted = offer
|
||||||
|
let subscription = await market.subscribeOffers(request.id, onOffer)
|
||||||
|
|
||||||
|
await market.offerStorage(offerWithoutHost)
|
||||||
|
|
||||||
|
check submitted.host == accounts[0]
|
||||||
|
|
Loading…
Reference in New Issue