[marketplace] support latest contracts changes (#327)

* [marketplace] support removal of Storage contract

* [marketplace] change submod dep dagger-contracts to codex-contracts-eth
This commit is contained in:
Eric Mastro 2023-01-19 16:58:04 +11:00 committed by GitHub
parent b1cf8e5239
commit df729be261
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 171 additions and 168 deletions

View File

@ -46,7 +46,7 @@ jobs:
run: make -j${ncpu} test run: make -j${ncpu} test
- name: Start Ethereum node with Codex contracts - name: Start Ethereum node with Codex contracts
working-directory: vendor/dagger-contracts working-directory: vendor/codex-contracts-eth
run: | run: |
if [[ '${{ matrix.os }}' == 'windows' ]]; then if [[ '${{ matrix.os }}' == 'windows' ]]; then
export PATH="${PATH}:/c/program files/nodejs" export PATH="${PATH}:/c/program files/nodejs"

7
.gitmodules vendored
View File

@ -133,10 +133,6 @@
url = https://github.com/status-im/nim-websock.git url = https://github.com/status-im/nim-websock.git
ignore = untracked ignore = untracked
branch = master branch = master
[submodule "vendor/dagger-contracts"]
path = vendor/dagger-contracts
url = https://github.com/status-im/dagger-contracts
ignore = dirty
[submodule "vendor/nim-contract-abi"] [submodule "vendor/nim-contract-abi"]
path = vendor/nim-contract-abi path = vendor/nim-contract-abi
url = https://github.com/status-im/nim-contract-abi url = https://github.com/status-im/nim-contract-abi
@ -182,3 +178,6 @@
[submodule "vendor/nim-eth"] [submodule "vendor/nim-eth"]
path = vendor/nim-eth path = vendor/nim-eth
url = https://github.com/status-im/nim-eth url = https://github.com/status-im/nim-eth
[submodule "vendor/codex-contracts-eth"]
path = vendor/codex-contracts-eth
url = https://github.com/status-im/codex-contracts-eth

View File

@ -132,7 +132,7 @@ $ nvm install --lts
In that same terminal run In that same terminal run
```text ```text
$ cd repos/nim-codex/vendor/dagger-contracts && npm install && npm start $ cd repos/nim-codex/vendor/codex-contracts-eth && npm install && npm start
``` ```
Those commands install and launch a [Hardhat](https://hardhat.org/) environment with nim-codex's Ethereum contracts. Those commands install and launch a [Hardhat](https://hardhat.org/) environment with nim-codex's Ethereum contracts.

View File

@ -1,12 +1,12 @@
import contracts/requests import contracts/requests
import contracts/storage import contracts/marketplace
import contracts/deployment import contracts/deployment
import contracts/market import contracts/market
import contracts/proofs import contracts/proofs
import contracts/interactions import contracts/interactions
export requests export requests
export storage export marketplace
export deployment export deployment
export market export market
export proofs export proofs

View File

@ -20,7 +20,7 @@ import ethers
let address = # fill in address where the contract was deployed let address = # fill in address where the contract was deployed
let provider = JsonRpcProvider.new("ws://localhost:8545") let provider = JsonRpcProvider.new("ws://localhost:8545")
let storage = Storage.new(address, provider) let marketplace = Marketplace.new(address, provider)
``` ```
Setup client and host so that they can sign transactions; here we use the first Setup client and host so that they can sign transactions; here we use the first
@ -39,7 +39,7 @@ Hosts need to put up collateral before participating in storage contracts.
A host can learn about the amount of collateral that is required: A host can learn about the amount of collateral that is required:
```nim ```nim
let collateralAmount = await storage.collateralAmount() let collateral = await marketplace.collateral()
``` ```
The host then needs to prepare a payment to the smart contract by calling the The host then needs to prepare a payment to the smart contract by calling the
@ -50,7 +50,7 @@ After preparing the payment, the host can deposit collateral:
```nim ```nim
await storage await storage
.connect(host) .connect(host)
.deposit(collateralAmount) .deposit(collateral)
``` ```
When a host is not participating in storage offers or contracts, it can withdraw When a host is not participating in storage offers or contracts, it can withdraw
@ -176,6 +176,6 @@ await storage
.markProofAsMissing(id, period) .markProofAsMissing(id, period)
``` ```
[1]: https://github.com/status-im/dagger-contracts/ [1]: https://github.com/status-im/codex-contracts-eth/
[2]: https://ethereum.org/en/developers/docs/standards/tokens/erc-20/ [2]: https://ethereum.org/en/developers/docs/standards/tokens/erc-20/
[3]: https://github.com/status-im/codex-research/blob/main/design/storage-proof-timing.md [3]: https://github.com/status-im/codex-research/blob/main/design/storage-proof-timing.md

View File

@ -6,7 +6,7 @@ import pkg/questionable
type Deployment* = object type Deployment* = object
json: JsonNode json: JsonNode
const defaultFile = "vendor" / "dagger-contracts" / "deployment-localhost.json" const defaultFile = "vendor" / "codex-contracts-eth" / "deployment-localhost.json"
## Reads deployment information from a json file. It expects a file that has ## Reads deployment information from a json file. It expects a file that has
## been exported with Hardhat deploy. ## been exported with Hardhat deploy.

View File

@ -4,7 +4,7 @@ import ../purchasing
import ../sales import ../sales
import ../proving import ../proving
import ./deployment import ./deployment
import ./storage import ./marketplace
import ./market import ./market
import ./proofs import ./proofs
import ./clock import ./clock
@ -25,11 +25,11 @@ proc new*(_: type ContractInteractions,
signer: Signer, signer: Signer,
deployment: Deployment): ?ContractInteractions = deployment: Deployment): ?ContractInteractions =
without address =? deployment.address(Storage): without address =? deployment.address(Marketplace):
error "Unable to determine address of the Storage smart contract" error "Unable to determine address of the Marketplace smart contract"
return none ContractInteractions return none ContractInteractions
let contract = Storage.new(address, signer) let contract = Marketplace.new(address, signer)
let market = OnChainMarket.new(contract) let market = OnChainMarket.new(contract)
let proofs = OnChainProofs.new(contract) let proofs = OnChainProofs.new(contract)
let clock = OnChainClock.new(signer.provider) let clock = OnChainClock.new(signer.provider)

View File

@ -4,22 +4,22 @@ import pkg/ethers/testing
import pkg/upraises import pkg/upraises
import pkg/questionable import pkg/questionable
import ../market import ../market
import ./storage import ./marketplace
export market export market
type type
OnChainMarket* = ref object of Market OnChainMarket* = ref object of Market
contract: Storage contract: Marketplace
signer: Signer signer: Signer
MarketSubscription = market.Subscription MarketSubscription = market.Subscription
EventSubscription = ethers.Subscription EventSubscription = ethers.Subscription
OnChainMarketSubscription = ref object of MarketSubscription OnChainMarketSubscription = ref object of MarketSubscription
eventSubscription: EventSubscription eventSubscription: EventSubscription
func new*(_: type OnChainMarket, contract: Storage): OnChainMarket = func new*(_: type OnChainMarket, contract: Marketplace): OnChainMarket =
without signer =? contract.signer: without signer =? contract.signer:
raiseAssert("Storage contract should have a signer") raiseAssert("Marketplace contract should have a signer")
OnChainMarket( OnChainMarket(
contract: contract, contract: contract,
signer: signer, signer: signer,

View File

@ -0,0 +1,62 @@
import pkg/ethers
import pkg/json_rpc/rpcclient
import pkg/stint
import pkg/chronos
import ../clock
import ./requests
export stint
export ethers
type
Marketplace* = ref object of Contract
StorageRequested* = object of Event
requestId*: RequestId
ask*: StorageAsk
SlotFilled* = object of Event
requestId* {.indexed.}: RequestId
slotIndex* {.indexed.}: UInt256
slotId*: SlotId
RequestFulfilled* = object of Event
requestId* {.indexed.}: RequestId
RequestCancelled* = object of Event
requestId* {.indexed.}: RequestId
RequestFailed* = object of Event
requestId* {.indexed.}: RequestId
ProofSubmitted* = object of Event
id*: SlotId
proof*: seq[byte]
proc collateral*(marketplace: Marketplace): UInt256 {.contract, view.}
proc slashMisses*(marketplace: Marketplace): UInt256 {.contract, view.}
proc slashPercentage*(marketplace: Marketplace): UInt256 {.contract, view.}
proc minCollateralThreshold*(marketplace: Marketplace): UInt256 {.contract, view.}
proc deposit*(marketplace: Marketplace, amount: UInt256) {.contract.}
proc withdraw*(marketplace: Marketplace) {.contract.}
proc balanceOf*(marketplace: Marketplace, account: Address): UInt256 {.contract, view.}
proc requestStorage*(marketplace: Marketplace, request: StorageRequest) {.contract.}
proc fillSlot*(marketplace: Marketplace, requestId: RequestId, slotIndex: UInt256, proof: seq[byte]) {.contract.}
proc withdrawFunds*(marketplace: Marketplace, requestId: RequestId) {.contract.}
proc freeSlot*(marketplace: Marketplace, id: SlotId) {.contract.}
proc getRequest*(marketplace: Marketplace, id: RequestId): StorageRequest {.contract, view.}
proc getHost*(marketplace: Marketplace, id: SlotId): Address {.contract, view.}
proc myRequests*(marketplace: Marketplace): seq[RequestId] {.contract, view.}
proc state*(marketplace: Marketplace, requestId: RequestId): RequestState {.contract, view.}
proc requestEnd*(marketplace: Marketplace, requestId: RequestId): SecondsSince1970 {.contract, view.}
proc proofPeriod*(marketplace: Marketplace): UInt256 {.contract, view.}
proc proofTimeout*(marketplace: Marketplace): UInt256 {.contract, view.}
proc proofEnd*(marketplace: Marketplace, id: SlotId): UInt256 {.contract, view.}
proc missingProofs*(marketplace: Marketplace, id: SlotId): UInt256 {.contract, view.}
proc isProofRequired*(marketplace: Marketplace, id: SlotId): bool {.contract, view.}
proc willProofBeRequired*(marketplace: Marketplace, id: SlotId): bool {.contract, view.}
proc getChallenge*(marketplace: Marketplace, id: SlotId): array[32, byte] {.contract, view.}
proc getPointer*(marketplace: Marketplace, id: SlotId): uint8 {.contract, view.}
proc submitProof*(marketplace: Marketplace, id: SlotId, proof: seq[byte]) {.contract.}
proc markProofAsMissing*(marketplace: Marketplace, id: SlotId, period: UInt256) {.contract.}

View File

@ -2,13 +2,13 @@ import std/strutils
import pkg/ethers import pkg/ethers
import pkg/ethers/testing import pkg/ethers/testing
import ../storageproofs/timing/proofs import ../storageproofs/timing/proofs
import ./storage import ./marketplace
export proofs export proofs
type type
OnChainProofs* = ref object of Proofs OnChainProofs* = ref object of Proofs
storage: Storage marketplace: Marketplace
pollInterval*: Duration pollInterval*: Duration
ProofsSubscription = proofs.Subscription ProofsSubscription = proofs.Subscription
EventSubscription = ethers.Subscription EventSubscription = ethers.Subscription
@ -17,17 +17,17 @@ type
const DefaultPollInterval = 3.seconds const DefaultPollInterval = 3.seconds
proc new*(_: type OnChainProofs, storage: Storage): OnChainProofs = proc new*(_: type OnChainProofs, marketplace: Marketplace): OnChainProofs =
OnChainProofs(storage: storage, pollInterval: DefaultPollInterval) OnChainProofs(marketplace: marketplace, pollInterval: DefaultPollInterval)
method periodicity*(proofs: OnChainProofs): Future[Periodicity] {.async.} = method periodicity*(proofs: OnChainProofs): Future[Periodicity] {.async.} =
let period = await proofs.storage.proofPeriod() let period = await proofs.marketplace.proofPeriod()
return Periodicity(seconds: period) return Periodicity(seconds: period)
method isProofRequired*(proofs: OnChainProofs, method isProofRequired*(proofs: OnChainProofs,
id: SlotId): Future[bool] {.async.} = id: SlotId): Future[bool] {.async.} =
try: try:
return await proofs.storage.isProofRequired(id) return await proofs.marketplace.isProofRequired(id)
except ProviderError as e: except ProviderError as e:
if e.revertReason.contains("Slot empty"): if e.revertReason.contains("Slot empty"):
return false return false
@ -36,7 +36,7 @@ method isProofRequired*(proofs: OnChainProofs,
method willProofBeRequired*(proofs: OnChainProofs, method willProofBeRequired*(proofs: OnChainProofs,
id: SlotId): Future[bool] {.async.} = id: SlotId): Future[bool] {.async.} =
try: try:
return await proofs.storage.willProofBeRequired(id) return await proofs.marketplace.willProofBeRequired(id)
except ProviderError as e: except ProviderError as e:
if e.revertReason.contains("Slot empty"): if e.revertReason.contains("Slot empty"):
return false return false
@ -45,7 +45,7 @@ method willProofBeRequired*(proofs: OnChainProofs,
method getProofEnd*(proofs: OnChainProofs, method getProofEnd*(proofs: OnChainProofs,
id: SlotId): Future[UInt256] {.async.} = id: SlotId): Future[UInt256] {.async.} =
try: try:
return await proofs.storage.proofEnd(id) return await proofs.marketplace.proofEnd(id)
except ProviderError as e: except ProviderError as e:
if e.revertReason.contains("Slot empty"): if e.revertReason.contains("Slot empty"):
return 0.u256 return 0.u256
@ -54,14 +54,14 @@ method getProofEnd*(proofs: OnChainProofs,
method submitProof*(proofs: OnChainProofs, method submitProof*(proofs: OnChainProofs,
id: SlotId, id: SlotId,
proof: seq[byte]) {.async.} = proof: seq[byte]) {.async.} =
await proofs.storage.submitProof(id, proof) await proofs.marketplace.submitProof(id, proof)
method subscribeProofSubmission*(proofs: OnChainProofs, method subscribeProofSubmission*(proofs: OnChainProofs,
callback: OnProofSubmitted): callback: OnProofSubmitted):
Future[ProofsSubscription] {.async.} = Future[ProofsSubscription] {.async.} =
proc onEvent(event: ProofSubmitted) {.upraises: [].} = proc onEvent(event: ProofSubmitted) {.upraises: [].} =
callback(event.id, event.proof) callback(event.id, event.proof)
let subscription = await proofs.storage.subscribe(ProofSubmitted, onEvent) let subscription = await proofs.marketplace.subscribe(ProofSubmitted, onEvent)
return OnChainProofsSubscription(eventSubscription: subscription) return OnChainProofsSubscription(eventSubscription: subscription)
method unsubscribe*(subscription: OnChainProofsSubscription) {.async, upraises:[].} = method unsubscribe*(subscription: OnChainProofsSubscription) {.async, upraises:[].} =

View File

@ -1,62 +0,0 @@
import pkg/ethers
import pkg/json_rpc/rpcclient
import pkg/stint
import pkg/chronos
import ../clock
import ./requests
export stint
export ethers
type
Storage* = ref object of Contract
StorageRequested* = object of Event
requestId*: RequestId
ask*: StorageAsk
SlotFilled* = object of Event
requestId* {.indexed.}: RequestId
slotIndex* {.indexed.}: UInt256
slotId*: SlotId
RequestFulfilled* = object of Event
requestId* {.indexed.}: RequestId
RequestCancelled* = object of Event
requestId* {.indexed.}: RequestId
RequestFailed* = object of Event
requestId* {.indexed.}: RequestId
ProofSubmitted* = object of Event
id*: SlotId
proof*: seq[byte]
proc collateralAmount*(storage: Storage): UInt256 {.contract, view.}
proc slashMisses*(storage: Storage): UInt256 {.contract, view.}
proc slashPercentage*(storage: Storage): UInt256 {.contract, view.}
proc minCollateralThreshold*(storage: Storage): UInt256 {.contract, view.}
proc deposit*(storage: Storage, amount: UInt256) {.contract.}
proc withdraw*(storage: Storage) {.contract.}
proc balanceOf*(storage: Storage, account: Address): UInt256 {.contract, view.}
proc requestStorage*(storage: Storage, request: StorageRequest) {.contract.}
proc fillSlot*(storage: Storage, requestId: RequestId, slotIndex: UInt256, proof: seq[byte]) {.contract.}
proc withdrawFunds*(storage: Storage, requestId: RequestId) {.contract.}
proc payoutSlot*(storage: Storage, requestId: RequestId, slotIndex: UInt256) {.contract.}
proc getRequest*(storage: Storage, id: RequestId): StorageRequest {.contract, view.}
proc getHost*(storage: Storage, id: SlotId): Address {.contract, view.}
proc myRequests*(storage: Storage): seq[RequestId] {.contract, view.}
proc state*(storage: Storage, requestId: RequestId): RequestState {.contract, view.}
proc requestEnd*(storage: Storage, requestId: RequestId): SecondsSince1970 {.contract, view.}
proc proofPeriod*(storage: Storage): UInt256 {.contract, view.}
proc proofTimeout*(storage: Storage): UInt256 {.contract, view.}
proc proofEnd*(storage: Storage, id: SlotId): UInt256 {.contract, view.}
proc missingProofs*(storage: Storage, id: SlotId): UInt256 {.contract, view.}
proc isProofRequired*(storage: Storage, id: SlotId): bool {.contract, view.}
proc willProofBeRequired*(storage: Storage, id: SlotId): bool {.contract, view.}
proc getChallenge*(storage: Storage, id: SlotId): array[32, byte] {.contract, view.}
proc getPointer*(storage: Storage, id: SlotId): uint8 {.contract, view.}
proc submitProof*(storage: Storage, id: SlotId, proof: seq[byte]) {.contract.}
proc markProofAsMissing*(storage: Storage, id: SlotId, period: UInt256) {.contract.}

View File

@ -6,27 +6,27 @@ import ../ethertest
ethersuite "Collateral": ethersuite "Collateral":
let collateralAmount = 100.u256 let collateral = 100.u256
var storage: Storage var marketplace: Marketplace
var token: TestToken var token: TestToken
setup: setup:
let deployment = deployment() let deployment = deployment()
storage = Storage.new(!deployment.address(Storage), provider.getSigner()) marketplace = Marketplace.new(!deployment.address(Marketplace), 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)
test "increases collateral": test "increases collateral":
await token.approve(storage.address, collateralAmount) await token.approve(marketplace.address, collateral)
await storage.deposit(collateralAmount) await marketplace.deposit(collateral)
let collateral = await storage.balanceOf(accounts[0]) let balance = await marketplace.balanceOf(accounts[0])
check collateral == collateralAmount check balance == collateral
test "withdraws collateral": test "withdraws collateral":
await token.approve(storage.address, collateralAmount) await token.approve(marketplace.address, collateral)
await storage.deposit(collateralAmount) await marketplace.deposit(collateral)
let balanceBefore = await token.balanceOf(accounts[0]) let balanceBefore = await token.balanceOf(accounts[0])
await storage.withdraw() await marketplace.withdraw()
let balanceAfter = await token.balanceOf(accounts[0]) let balanceAfter = await token.balanceOf(accounts[0])
check (balanceAfter - balanceBefore) == collateralAmount check (balanceAfter - balanceBefore) == collateral

View File

@ -8,19 +8,19 @@ import ../ethertest
import ./examples import ./examples
import ./time import ./time
ethersuite "Storage contracts": ethersuite "Marketplace contracts":
let proof = exampleProof() let proof = exampleProof()
var client, host: Signer var client, host: Signer
var storage: Storage var marketplace: Marketplace
var token: TestToken var token: TestToken
var collateralAmount: UInt256 var collateral: UInt256
var periodicity: Periodicity var periodicity: Periodicity
var request: StorageRequest var request: StorageRequest
var slotId: SlotId var slotId: SlotId
proc switchAccount(account: Signer) = proc switchAccount(account: Signer) =
storage = storage.connect(account) marketplace = marketplace.connect(account)
token = token.connect(account) token = token.connect(account)
setup: setup:
@ -28,44 +28,44 @@ ethersuite "Storage contracts":
host = provider.getSigner(accounts[1]) host = provider.getSigner(accounts[1])
let deployment = deployment() let deployment = deployment()
storage = Storage.new(!deployment.address(Storage), provider.getSigner()) marketplace = Marketplace.new(!deployment.address(Marketplace), provider.getSigner())
token = TestToken.new(!deployment.address(TestToken), provider.getSigner()) token = TestToken.new(!deployment.address(TestToken), provider.getSigner())
await token.mint(await client.getAddress(), 1_000_000_000.u256) await token.mint(await client.getAddress(), 1_000_000_000.u256)
await token.mint(await host.getAddress(), 1000_000_000.u256) await token.mint(await host.getAddress(), 1000_000_000.u256)
collateralAmount = await storage.collateralAmount() collateral = await marketplace.collateral()
periodicity = Periodicity(seconds: await storage.proofPeriod()) periodicity = Periodicity(seconds: await marketplace.proofPeriod())
request = StorageRequest.example request = StorageRequest.example
request.client = await client.getAddress() request.client = await client.getAddress()
switchAccount(client) switchAccount(client)
await token.approve(storage.address, request.price) await token.approve(marketplace.address, request.price)
await storage.requestStorage(request) await marketplace.requestStorage(request)
switchAccount(host) switchAccount(host)
await token.approve(storage.address, collateralAmount) await token.approve(marketplace.address, collateral)
await storage.deposit(collateralAmount) await marketplace.deposit(collateral)
await storage.fillSlot(request.id, 0.u256, proof) await marketplace.fillSlot(request.id, 0.u256, proof)
slotId = request.slotId(0.u256) slotId = request.slotId(0.u256)
proc waitUntilProofRequired(slotId: SlotId) {.async.} = proc waitUntilProofRequired(slotId: SlotId) {.async.} =
let currentPeriod = periodicity.periodOf(await provider.currentTime()) let currentPeriod = periodicity.periodOf(await provider.currentTime())
await provider.advanceTimeTo(periodicity.periodEnd(currentPeriod)) await provider.advanceTimeTo(periodicity.periodEnd(currentPeriod))
while not ( while not (
(await storage.isProofRequired(slotId)) and (await marketplace.isProofRequired(slotId)) and
(await storage.getPointer(slotId)) < 250 (await marketplace.getPointer(slotId)) < 250
): ):
await provider.advanceTime(periodicity.seconds) await provider.advanceTime(periodicity.seconds)
proc startContract() {.async.} = proc startContract() {.async.} =
for slotIndex in 1..<request.ask.slots: for slotIndex in 1..<request.ask.slots:
await storage.fillSlot(request.id, slotIndex.u256, proof) await marketplace.fillSlot(request.id, slotIndex.u256, proof)
test "accept storage proofs": test "accept marketplace proofs":
switchAccount(host) switchAccount(host)
await waitUntilProofRequired(slotId) await waitUntilProofRequired(slotId)
await storage.submitProof(slotId, proof) await marketplace.submitProof(slotId, proof)
test "can mark missing proofs": test "can mark missing proofs":
switchAccount(host) switchAccount(host)
@ -73,20 +73,24 @@ ethersuite "Storage contracts":
let missingPeriod = periodicity.periodOf(await provider.currentTime()) let missingPeriod = periodicity.periodOf(await provider.currentTime())
await provider.advanceTime(periodicity.seconds) await provider.advanceTime(periodicity.seconds)
switchAccount(client) switchAccount(client)
await storage.markProofAsMissing(slotId, missingPeriod) await marketplace.markProofAsMissing(slotId, missingPeriod)
test "can be paid out at the end": test "can be paid out at the end":
switchAccount(host) switchAccount(host)
let address = await host.getAddress()
await startContract() await startContract()
let requestEnd = await storage.requestEnd(request.id) let requestEnd = await marketplace.requestEnd(request.id)
await provider.advanceTimeTo(requestEnd.u256) await provider.advanceTimeTo(requestEnd.u256)
await storage.payoutSlot(request.id, 0.u256) let startBalance = await token.balanceOf(address)
await marketplace.freeSlot(slotId)
let endBalance = await token.balanceOf(address)
check endBalance == (startBalance + request.ask.duration * request.ask.reward)
test "cannot mark proofs missing for cancelled request": test "cannot mark proofs missing for cancelled request":
await provider.advanceTimeTo(request.expiry + 1) await provider.advanceTimeTo(request.expiry + 1)
switchAccount(client) switchAccount(client)
let missingPeriod = periodicity.periodOf(await provider.currentTime()) let missingPeriod = periodicity.periodOf(await provider.currentTime())
await provider.advanceTime(periodicity.seconds) await provider.advanceTime(periodicity.seconds)
check await storage check await marketplace
.markProofAsMissing(slotId, missingPeriod) .markProofAsMissing(slotId, missingPeriod)
.reverts("Slot not accepting proofs") .reverts("Slot not accepting proofs")

View File

@ -3,7 +3,7 @@ import codex/contracts
import ../ethertest import ../ethertest
import ./examples import ./examples
ethersuite "Storage Contract Interactions": ethersuite "Marketplace Contract Interactions":
let account = Address.example let account = Address.example
@ -20,7 +20,7 @@ ethersuite "Storage Contract Interactions":
test "can be instantiated with a provider url": test "can be instantiated with a provider url":
let url = "http://localhost:8545" let url = "http://localhost:8545"
let account = Address.example let account = Address.example
let deployment = "vendor" / "dagger-contracts" / "deployment-localhost.json" let deployment = "vendor" / "codex-contracts-eth" / "deployment-localhost.json"
check ContractInteractions.new(url, account).isSome check ContractInteractions.new(url, account).isSome
check ContractInteractions.new(url, account, deployment).isSome check ContractInteractions.new(url, account, deployment).isSome

View File

@ -12,7 +12,7 @@ ethersuite "On-Chain Market":
let proof = exampleProof() let proof = exampleProof()
var market: OnChainMarket var market: OnChainMarket
var storage: Storage var marketplace: Marketplace
var token: TestToken var token: TestToken
var request: StorageRequest var request: StorageRequest
var slotIndex: UInt256 var slotIndex: UInt256
@ -20,16 +20,16 @@ ethersuite "On-Chain Market":
setup: setup:
let deployment = deployment() let deployment = deployment()
storage = Storage.new(!deployment.address(Storage), provider.getSigner()) marketplace = Marketplace.new(!deployment.address(Marketplace), provider.getSigner())
token = TestToken.new(!deployment.address(TestToken), provider.getSigner()) token = TestToken.new(!deployment.address(TestToken), provider.getSigner())
await token.mint(accounts[0], 1_000_000_000.u256) await token.mint(accounts[0], 1_000_000_000.u256)
let collateral = await storage.collateralAmount() let collateral = await marketplace.collateral()
await token.approve(storage.address, collateral) await token.approve(marketplace.address, collateral)
await storage.deposit(collateral) await marketplace.deposit(collateral)
market = OnChainMarket.new(storage) market = OnChainMarket.new(marketplace)
periodicity = Periodicity(seconds: await storage.proofPeriod()) periodicity = Periodicity(seconds: await marketplace.proofPeriod())
request = StorageRequest.example request = StorageRequest.example
request.client = accounts[0] request.client = accounts[0]
@ -40,32 +40,32 @@ ethersuite "On-Chain Market":
let currentPeriod = periodicity.periodOf(await provider.currentTime()) let currentPeriod = periodicity.periodOf(await provider.currentTime())
await provider.advanceTimeTo(periodicity.periodEnd(currentPeriod)) await provider.advanceTimeTo(periodicity.periodEnd(currentPeriod))
while not ( while not (
(await storage.isProofRequired(slotId)) and (await marketplace.isProofRequired(slotId)) and
(await storage.getPointer(slotId)) < 250 (await marketplace.getPointer(slotId)) < 250
): ):
await provider.advanceTime(periodicity.seconds) await provider.advanceTime(periodicity.seconds)
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 = marketplace.connect(provider)
expect AssertionError: expect AssertionError:
discard OnChainMarket.new(storageWithoutSigner) discard OnChainMarket.new(storageWithoutSigner)
test "knows signer address": test "knows signer address":
check (await market.getSigner()) == (await provider.getSigner().getAddress()) check (await market.getSigner()) == (await provider.getSigner().getAddress())
test "supports storage requests": test "supports marketplace requests":
await token.approve(storage.address, request.price) await token.approve(marketplace.address, request.price)
await market.requestStorage(request) await market.requestStorage(request)
test "can retrieve previously submitted requests": test "can retrieve previously submitted requests":
check (await market.getRequest(request.id)) == none StorageRequest check (await market.getRequest(request.id)) == none StorageRequest
await token.approve(storage.address, request.price) await token.approve(marketplace.address, request.price)
await market.requestStorage(request) await market.requestStorage(request)
let r = await market.getRequest(request.id) let r = await market.getRequest(request.id)
check (r) == some request check (r) == some request
test "supports withdrawing of funds": test "supports withdrawing of funds":
await token.approve(storage.address, request.price) await token.approve(marketplace.address, request.price)
await market.requestStorage(request) await market.requestStorage(request)
await provider.advanceTimeTo(request.expiry) await provider.advanceTimeTo(request.expiry)
await market.withdrawFunds(request.id) await market.withdrawFunds(request.id)
@ -77,26 +77,26 @@ ethersuite "On-Chain Market":
receivedIds.add(id) receivedIds.add(id)
receivedAsks.add(ask) receivedAsks.add(ask)
let subscription = await market.subscribeRequests(onRequest) let subscription = await market.subscribeRequests(onRequest)
await token.approve(storage.address, request.price) await token.approve(marketplace.address, request.price)
await market.requestStorage(request) await market.requestStorage(request)
check receivedIds == @[request.id] check receivedIds == @[request.id]
check receivedAsks == @[request.ask] check receivedAsks == @[request.ask]
await subscription.unsubscribe() await subscription.unsubscribe()
test "supports filling of slots": test "supports filling of slots":
await token.approve(storage.address, request.price) await token.approve(marketplace.address, request.price)
await market.requestStorage(request) await market.requestStorage(request)
await market.fillSlot(request.id, slotIndex, proof) await market.fillSlot(request.id, slotIndex, proof)
test "can retrieve host that filled slot": test "can retrieve host that filled slot":
await token.approve(storage.address, request.price) await token.approve(marketplace.address, request.price)
await market.requestStorage(request) await market.requestStorage(request)
check (await market.getHost(request.id, slotIndex)) == none Address check (await market.getHost(request.id, slotIndex)) == none Address
await market.fillSlot(request.id, slotIndex, proof) await market.fillSlot(request.id, slotIndex, proof)
check (await market.getHost(request.id, slotIndex)) == some accounts[0] check (await market.getHost(request.id, slotIndex)) == some accounts[0]
test "support slot filled subscriptions": test "support slot filled subscriptions":
await token.approve(storage.address, request.price) await token.approve(marketplace.address, request.price)
await market.requestStorage(request) await market.requestStorage(request)
var receivedIds: seq[RequestId] var receivedIds: seq[RequestId]
var receivedSlotIndices: seq[UInt256] var receivedSlotIndices: seq[UInt256]
@ -111,7 +111,7 @@ ethersuite "On-Chain Market":
test "subscribes only to a certain slot": test "subscribes only to a certain slot":
var otherSlot = slotIndex - 1 var otherSlot = slotIndex - 1
await token.approve(storage.address, request.price) await token.approve(marketplace.address, request.price)
await market.requestStorage(request) await market.requestStorage(request)
var receivedSlotIndices: seq[UInt256] var receivedSlotIndices: seq[UInt256]
proc onSlotFilled(requestId: RequestId, slotIndex: UInt256) = proc onSlotFilled(requestId: RequestId, slotIndex: UInt256) =
@ -124,7 +124,7 @@ ethersuite "On-Chain Market":
await subscription.unsubscribe() await subscription.unsubscribe()
test "support fulfillment subscriptions": test "support fulfillment subscriptions":
await token.approve(storage.address, request.price) await token.approve(marketplace.address, request.price)
await market.requestStorage(request) await market.requestStorage(request)
var receivedIds: seq[RequestId] var receivedIds: seq[RequestId]
proc onFulfillment(id: RequestId) = proc onFulfillment(id: RequestId) =
@ -139,9 +139,9 @@ ethersuite "On-Chain Market":
var otherRequest = StorageRequest.example var otherRequest = StorageRequest.example
otherRequest.client = accounts[0] otherRequest.client = accounts[0]
await token.approve(storage.address, request.price) await token.approve(marketplace.address, request.price)
await market.requestStorage(request) await market.requestStorage(request)
await token.approve(storage.address, otherRequest.price) await token.approve(marketplace.address, otherRequest.price)
await market.requestStorage(otherRequest) await market.requestStorage(otherRequest)
var receivedIds: seq[RequestId] var receivedIds: seq[RequestId]
@ -160,7 +160,7 @@ ethersuite "On-Chain Market":
await subscription.unsubscribe() await subscription.unsubscribe()
test "support request cancelled subscriptions": test "support request cancelled subscriptions":
await token.approve(storage.address, request.price) await token.approve(marketplace.address, request.price)
await market.requestStorage(request) await market.requestStorage(request)
var receivedIds: seq[RequestId] var receivedIds: seq[RequestId]
@ -174,7 +174,7 @@ ethersuite "On-Chain Market":
await subscription.unsubscribe() await subscription.unsubscribe()
test "support request failed subscriptions": test "support request failed subscriptions":
await token.approve(storage.address, request.price) await token.approve(marketplace.address, request.price)
await market.requestStorage(request) await market.requestStorage(request)
var receivedIds: seq[RequestId] var receivedIds: seq[RequestId]
@ -191,7 +191,7 @@ ethersuite "On-Chain Market":
await waitUntilProofRequired(slotId) await waitUntilProofRequired(slotId)
let missingPeriod = periodicity.periodOf(await provider.currentTime()) let missingPeriod = periodicity.periodOf(await provider.currentTime())
await provider.advanceTime(periodicity.seconds) await provider.advanceTime(periodicity.seconds)
await storage.markProofAsMissing(slotId, missingPeriod) await marketplace.markProofAsMissing(slotId, missingPeriod)
except ProviderError as e: except ProviderError as e:
if e.revertReason == "Slot empty": if e.revertReason == "Slot empty":
break break
@ -201,9 +201,9 @@ ethersuite "On-Chain Market":
test "subscribes only to a certain request cancellation": test "subscribes only to a certain request cancellation":
var otherRequest = request var otherRequest = request
otherRequest.nonce = Nonce.example otherRequest.nonce = Nonce.example
await token.approve(storage.address, request.price) await token.approve(marketplace.address, request.price)
await market.requestStorage(request) await market.requestStorage(request)
await token.approve(storage.address, otherRequest.price) await token.approve(marketplace.address, otherRequest.price)
await market.requestStorage(otherRequest) await market.requestStorage(otherRequest)
var receivedIds: seq[RequestId] var receivedIds: seq[RequestId]
@ -222,16 +222,16 @@ ethersuite "On-Chain Market":
check isNone await market.getRequest(request.id) check isNone await market.getRequest(request.id)
test "can retrieve active requests": test "can retrieve active requests":
await token.approve(storage.address, request.price) await token.approve(marketplace.address, request.price)
await market.requestStorage(request) await market.requestStorage(request)
var request2 = StorageRequest.example var request2 = StorageRequest.example
request2.client = accounts[0] request2.client = accounts[0]
await token.approve(storage.address, request2.price) await token.approve(marketplace.address, request2.price)
await market.requestStorage(request2) await market.requestStorage(request2)
check (await market.myRequests()) == @[request.id, request2.id] check (await market.myRequests()) == @[request.id, request2.id]
test "can retrieve request state": test "can retrieve request state":
await token.approve(storage.address, request.price) await token.approve(marketplace.address, request.price)
await market.requestStorage(request) await market.requestStorage(request)
for slotIndex in 0..<request.ask.slots: for slotIndex in 0..<request.ask.slots:
await market.fillSlot(request.id, slotIndex.u256, proof) await market.fillSlot(request.id, slotIndex.u256, proof)

View File

@ -9,16 +9,16 @@ ethersuite "On-Chain Proofs":
let proof = exampleProof() let proof = exampleProof()
var proofs: OnChainProofs var proofs: OnChainProofs
var storage: Storage var marketplace: Marketplace
setup: setup:
let deployment = deployment() let deployment = deployment()
storage = Storage.new(!deployment.address(Storage), provider.getSigner()) marketplace = Marketplace.new(!deployment.address(Marketplace), provider.getSigner())
proofs = OnChainProofs.new(storage) proofs = OnChainProofs.new(marketplace)
test "can retrieve proof periodicity": test "can retrieve proof periodicity":
let periodicity = await proofs.periodicity() let periodicity = await proofs.periodicity()
let periodLength = await storage.proofPeriod() let periodLength = await marketplace.proofPeriod()
check periodicity.seconds == periodLength check periodicity.seconds == periodLength
test "supports checking whether proof is required now": test "supports checking whether proof is required now":

View File

@ -3,13 +3,13 @@ import codex/contracts/testtoken
proc mint*(signer: Signer, amount = 1_000_000.u256) {.async.} = proc mint*(signer: Signer, amount = 1_000_000.u256) {.async.} =
## Mints a considerable amount of tokens and approves them for transfer to ## Mints a considerable amount of tokens and approves them for transfer to
## the Storage contract. ## the Marketplace contract.
let token = TestToken.new(!deployment().address(TestToken), signer) let token = TestToken.new(!deployment().address(TestToken), signer)
let storage = Storage.new(!deployment().address(Storage), signer) let marketplace = Marketplace.new(!deployment().address(Marketplace), signer)
await token.mint(await signer.getAddress(), amount) await token.mint(await signer.getAddress(), amount)
await token.approve(storage.address, amount) await token.approve(marketplace.address, amount)
proc deposit*(signer: Signer) {.async.} = proc deposit*(signer: Signer) {.async.} =
## Deposits sufficient collateral into the Storage contract. ## Deposits sufficient collateral into the Marketplace contract.
let storage = Storage.new(!deployment().address(Storage), signer) let marketplace = Marketplace.new(!deployment().address(Marketplace), signer)
await storage.deposit(await storage.collateralAmount()) await marketplace.deposit(await marketplace.collateral())

1
vendor/codex-contracts-eth vendored Submodule

@ -0,0 +1 @@
Subproject commit ce335d0568b4d056def6570f7d5d5c0d6a840083

@ -1 +0,0 @@
Subproject commit 61b8f5fc352838866b0fe27b936323de45bf269c