[contracts] Wrap contracts in Market abstraction

This commit is contained in:
Mark Spanbroek 2022-03-28 17:24:28 +02:00 committed by markspanbroek
parent bd8f4d5d74
commit e78a0fb43e
7 changed files with 95 additions and 14 deletions

View File

@ -2,8 +2,10 @@ import contracts/requests
import contracts/offers
import contracts/storage
import contracts/deployment
import contracts/market
export requests
export offers
export storage
export deployment
export market

View File

@ -0,0 +1,34 @@
import pkg/ethers
import pkg/upraises
import ../market
import ./storage
type
OnChainMarket* = ref object of Market
contract: Storage
signer: Signer
MarketSubscription = market.Subscription
EventSubscription = ethers.Subscription
OnChainMarketSubscription = ref object of MarketSubscription
eventSubscription: EventSubscription
export market
func new*(_: type OnChainMarket, contract: Storage): OnChainMarket =
OnChainMarket(contract: contract, signer: !contract.signer)
method subscribeRequests(market: OnChainMarket,
callback: OnRequest):
Future[MarketSubscription] {.async.} =
proc onEvent(event: StorageRequested) {.upraises:[].} =
callback(event.request)
let subscription = await market.contract.subscribe(StorageRequested, onEvent)
return OnChainMarketSubscription(eventSubscription: subscription)
method requestStorage(market: OnChainMarket, request: StorageRequest) {.async.} =
var request = request
request.client = await market.signer.getAddress()
await market.contract.requestStorage(request)
method unsubscribe*(subscription: OnChainMarketSubscription) {.async.} =
await subscription.eventSubscription.unsubscribe()

View File

@ -1,5 +1,7 @@
import pkg/contractabi
import pkg/nimcrypto
import pkg/ethers/fields
import pkg/questionable/results
export contractabi
@ -14,23 +16,27 @@ type
expiry*: UInt256
nonce*: array[32, byte]
func toTuple(request: StorageRequest): auto =
(
request.client,
request.duration,
request.size,
request.contentHash,
request.proofProbability,
request.maxPrice,
request.expiry,
request.nonce
func fromTuple(_: type StorageRequest, tupl: tuple): StorageRequest =
StorageRequest(
client: tupl[0],
duration: tupl[1],
size: tupl[2],
contentHash: tupl[3],
proofProbability: tupl[4],
maxPrice: tupl[5],
expiry: tupl[6],
nonce: tupl[7]
)
func solidityType*(_: type StorageRequest): string =
solidityType(typeof StorageRequest.default.toTuple)
solidityType(StorageRequest.fieldTypes)
func encode*(encoder: var AbiEncoder, request: StorageRequest) =
encoder.write(request.toTuple)
encoder.write(request.fieldValues)
func decode*(decoder: var AbiDecoder, T: type StorageRequest): ?!T =
let tupl = ?decoder.read(StorageRequest.fieldTypes)
success StorageRequest.fromTuple(tupl)
func id*(request: StorageRequest): array[32, byte] =
let encoding = AbiEncoder.encode(request)

View File

@ -11,6 +11,9 @@ export contract
type
Storage* = ref object of Contract
Id = array[32, byte]
StorageRequested* = object of Event
requestId*: Id
request*: StorageRequest
proc collateralAmount*(storage: Storage): UInt256 {.contract, view.}
proc slashMisses*(storage: Storage): UInt256 {.contract, view.}

View File

@ -1,4 +1,5 @@
import pkg/chronos
import pkg/upraises
import ./contracts/requests
import ./contracts/offers
@ -9,8 +10,8 @@ export offers
type
Market* = ref object of RootObj
Subscription* = ref object of RootObj
OnRequest* = proc(request: StorageRequest) {.gcsafe.}
OnOffer* = proc(offer: StorageOffer) {.gcsafe.}
OnRequest* = proc(request: StorageRequest) {.gcsafe, upraises:[].}
OnOffer* = proc(offer: StorageOffer) {.gcsafe, upraises:[].}
method requestStorage*(market: Market, request: StorageRequest) {.base, async.} =
raiseAssert("not implemented")

View File

@ -0,0 +1,34 @@
import ./ethertest
import dagger/contracts
import dagger/contracts/testtoken
import ./examples
ethersuite "On-Chain Market":
var market: OnChainMarket
var storage: Storage
var token: TestToken
setup:
let deployment = deployment()
storage = Storage.new(!deployment.address(Storage), provider.getSigner())
token = TestToken.new(!deployment.address(TestToken), provider.getSigner())
await token.mint(accounts[0], 1000.u256)
market = OnChainMarket.new(storage)
test "supports storage requests":
var submitted: seq[StorageRequest]
proc onRequest(request: StorageRequest) =
submitted.add(request)
let subscription = await market.subscribeRequests(onRequest)
let request = StorageRequest(
duration: uint16.example.u256,
size: uint32.example.u256,
contentHash: array[32, byte].example
)
await market.requestStorage(request)
check submitted.len == 1
check submitted[0].duration == request.duration
check submitted[0].size == request.size
check submitted[0].contentHash == request.contentHash
await subscription.unsubscribe()

View File

@ -1,4 +1,5 @@
import ./contracts/testCollateral
import ./contracts/testContracts
import ./contracts/testMarket
{.warning[UnusedImport]:off.}