mirror of
https://github.com/status-im/codex-contracts-eth.git
synced 2025-03-03 17:40:48 +00:00
Merge pull request #22 from status-im/list-of-active-requests
List of active requests
This commit is contained in:
commit
a4057d712f
@ -3,10 +3,13 @@ pragma solidity ^0.8.8;
|
|||||||
|
|
||||||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||||
import "@openzeppelin/contracts/utils/math/Math.sol";
|
import "@openzeppelin/contracts/utils/math/Math.sol";
|
||||||
|
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
|
||||||
import "./Collateral.sol";
|
import "./Collateral.sol";
|
||||||
import "./Proofs.sol";
|
import "./Proofs.sol";
|
||||||
|
|
||||||
contract Marketplace is Collateral, Proofs {
|
contract Marketplace is Collateral, Proofs {
|
||||||
|
using EnumerableSet for EnumerableSet.Bytes32Set;
|
||||||
|
|
||||||
type RequestId is bytes32;
|
type RequestId is bytes32;
|
||||||
type SlotId is bytes32;
|
type SlotId is bytes32;
|
||||||
|
|
||||||
@ -15,6 +18,7 @@ contract Marketplace is Collateral, Proofs {
|
|||||||
mapping(RequestId => Request) private requests;
|
mapping(RequestId => Request) private requests;
|
||||||
mapping(RequestId => RequestContext) private requestContexts;
|
mapping(RequestId => RequestContext) private requestContexts;
|
||||||
mapping(SlotId => Slot) private slots;
|
mapping(SlotId => Slot) private slots;
|
||||||
|
mapping(address => EnumerableSet.Bytes32Set) private activeRequests;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
IERC20 _token,
|
IERC20 _token,
|
||||||
@ -30,6 +34,10 @@ contract Marketplace is Collateral, Proofs {
|
|||||||
collateral = _collateral;
|
collateral = _collateral;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function myRequests() public view returns (RequestId[] memory) {
|
||||||
|
return _toRequestIds(activeRequests[msg.sender].values());
|
||||||
|
}
|
||||||
|
|
||||||
function requestStorage(Request calldata request)
|
function requestStorage(Request calldata request)
|
||||||
public
|
public
|
||||||
marketplaceInvariant
|
marketplaceInvariant
|
||||||
@ -45,6 +53,7 @@ contract Marketplace is Collateral, Proofs {
|
|||||||
context.endsAt = block.timestamp + request.ask.duration;
|
context.endsAt = block.timestamp + request.ask.duration;
|
||||||
_setProofEnd(_toEndId(id), context.endsAt);
|
_setProofEnd(_toEndId(id), context.endsAt);
|
||||||
|
|
||||||
|
activeRequests[request.client].add(RequestId.unwrap(id));
|
||||||
|
|
||||||
_createLock(_toLockId(id), request.expiry);
|
_createLock(_toLockId(id), request.expiry);
|
||||||
|
|
||||||
@ -73,10 +82,7 @@ contract Marketplace is Collateral, Proofs {
|
|||||||
_lock(msg.sender, lockId);
|
_lock(msg.sender, lockId);
|
||||||
|
|
||||||
ProofId proofId = _toProofId(slotId);
|
ProofId proofId = _toProofId(slotId);
|
||||||
_expectProofs(
|
_expectProofs(proofId, _toEndId(requestId), request.ask.proofProbability);
|
||||||
proofId,
|
|
||||||
_toEndId(requestId),
|
|
||||||
request.ask.proofProbability);
|
|
||||||
_submitProof(proofId, proof);
|
_submitProof(proofId, proof);
|
||||||
|
|
||||||
slot.host = msg.sender;
|
slot.host = msg.sender;
|
||||||
@ -92,9 +98,11 @@ contract Marketplace is Collateral, Proofs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _freeSlot(
|
function _freeSlot(SlotId slotId)
|
||||||
SlotId slotId
|
internal
|
||||||
) internal slotMustAcceptProofs(slotId) marketplaceInvariant {
|
slotMustAcceptProofs(slotId)
|
||||||
|
marketplaceInvariant
|
||||||
|
{
|
||||||
Slot storage slot = _slot(slotId);
|
Slot storage slot = _slot(slotId);
|
||||||
RequestId requestId = slot.requestId;
|
RequestId requestId = slot.requestId;
|
||||||
RequestContext storage context = requestContexts[requestId];
|
RequestContext storage context = requestContexts[requestId];
|
||||||
@ -113,12 +121,14 @@ contract Marketplace is Collateral, Proofs {
|
|||||||
|
|
||||||
Request storage request = _request(requestId);
|
Request storage request = _request(requestId);
|
||||||
uint256 slotsLost = request.ask.slots - context.slotsFilled;
|
uint256 slotsLost = request.ask.slots - context.slotsFilled;
|
||||||
if (slotsLost > request.ask.maxSlotLoss &&
|
if (
|
||||||
context.state == RequestState.Started) {
|
slotsLost > request.ask.maxSlotLoss &&
|
||||||
|
context.state == RequestState.Started
|
||||||
|
) {
|
||||||
context.state = RequestState.Failed;
|
context.state = RequestState.Failed;
|
||||||
_setProofEnd(_toEndId(requestId), block.timestamp - 1);
|
_setProofEnd(_toEndId(requestId), block.timestamp - 1);
|
||||||
context.endsAt = block.timestamp - 1;
|
context.endsAt = block.timestamp - 1;
|
||||||
|
activeRequests[request.client].remove(RequestId.unwrap(requestId));
|
||||||
emit RequestFailed(requestId);
|
emit RequestFailed(requestId);
|
||||||
|
|
||||||
// TODO: burn all remaining slot collateral (note: slot collateral not
|
// TODO: burn all remaining slot collateral (note: slot collateral not
|
||||||
@ -126,13 +136,16 @@ contract Marketplace is Collateral, Proofs {
|
|||||||
// TODO: send client remaining funds
|
// TODO: send client remaining funds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function payoutSlot(RequestId requestId, uint256 slotIndex)
|
function payoutSlot(RequestId requestId, uint256 slotIndex)
|
||||||
public
|
public
|
||||||
marketplaceInvariant
|
marketplaceInvariant
|
||||||
{
|
{
|
||||||
require(_isFinished(requestId), "Contract not ended");
|
require(_isFinished(requestId), "Contract not ended");
|
||||||
RequestContext storage context = _context(requestId);
|
RequestContext storage context = _context(requestId);
|
||||||
|
Request storage request = _request(requestId);
|
||||||
context.state = RequestState.Finished;
|
context.state = RequestState.Finished;
|
||||||
|
activeRequests[request.client].remove(RequestId.unwrap(requestId));
|
||||||
SlotId slotId = _toSlotId(requestId, slotIndex);
|
SlotId slotId = _toSlotId(requestId, slotIndex);
|
||||||
Slot storage slot = _slot(slotId);
|
Slot storage slot = _slot(slotId);
|
||||||
require(!slot.hostPaid, "Already paid");
|
require(!slot.hostPaid, "Already paid");
|
||||||
@ -156,6 +169,7 @@ contract Marketplace is Collateral, Proofs {
|
|||||||
// Update request state to Cancelled. Handle in the withdraw transaction
|
// Update request state to Cancelled. Handle in the withdraw transaction
|
||||||
// as there needs to be someone to pay for the gas to update the state
|
// as there needs to be someone to pay for the gas to update the state
|
||||||
context.state = RequestState.Cancelled;
|
context.state = RequestState.Cancelled;
|
||||||
|
activeRequests[request.client].remove(RequestId.unwrap(requestId));
|
||||||
emit RequestCancelled(requestId);
|
emit RequestCancelled(requestId);
|
||||||
|
|
||||||
// TODO: To be changed once we start paying out hosts for the time they
|
// TODO: To be changed once we start paying out hosts for the time they
|
||||||
@ -175,10 +189,8 @@ contract Marketplace is Collateral, Proofs {
|
|||||||
RequestContext storage context = _context(requestId);
|
RequestContext storage context = _context(requestId);
|
||||||
return
|
return
|
||||||
context.state == RequestState.Cancelled ||
|
context.state == RequestState.Cancelled ||
|
||||||
(
|
(context.state == RequestState.New &&
|
||||||
context.state == RequestState.New &&
|
block.timestamp > _request(requestId).expiry);
|
||||||
block.timestamp > _request(requestId).expiry
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @notice Return true if the request state is RequestState.Finished or if the request duration has elapsed and the request was started.
|
/// @notice Return true if the request state is RequestState.Finished or if the request duration has elapsed and the request was started.
|
||||||
@ -189,10 +201,8 @@ contract Marketplace is Collateral, Proofs {
|
|||||||
RequestContext memory context = _context(requestId);
|
RequestContext memory context = _context(requestId);
|
||||||
return
|
return
|
||||||
context.state == RequestState.Finished ||
|
context.state == RequestState.Finished ||
|
||||||
(
|
(context.state == RequestState.Started &&
|
||||||
context.state == RequestState.Started &&
|
block.timestamp > context.endsAt);
|
||||||
block.timestamp > context.endsAt
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @notice Return id of request that slot belongs to
|
/// @notice Return id of request that slot belongs to
|
||||||
@ -255,9 +265,12 @@ contract Marketplace is Collateral, Proofs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function proofEnd(SlotId slotId) public view returns (uint256) {
|
function proofEnd(SlotId slotId) public view returns (uint256) {
|
||||||
Slot memory slot = _slot(slotId);
|
return requestEnd(_slot(slotId).requestId);
|
||||||
uint256 end = _end(_toEndId(slot.requestId));
|
}
|
||||||
if (_slotAcceptsProofs(slotId)) {
|
|
||||||
|
function requestEnd(RequestId requestId) public view returns (uint256) {
|
||||||
|
uint256 end = _end(_toEndId(requestId));
|
||||||
|
if (_requestAcceptsProofs(requestId)) {
|
||||||
return end;
|
return end;
|
||||||
} else {
|
} else {
|
||||||
return Math.min(end, block.timestamp - 1);
|
return Math.min(end, block.timestamp - 1);
|
||||||
@ -267,8 +280,8 @@ contract Marketplace is Collateral, Proofs {
|
|||||||
function _price(
|
function _price(
|
||||||
uint64 numSlots,
|
uint64 numSlots,
|
||||||
uint256 duration,
|
uint256 duration,
|
||||||
uint256 reward) internal pure returns (uint256) {
|
uint256 reward
|
||||||
|
) internal pure returns (uint256) {
|
||||||
return numSlots * duration * reward;
|
return numSlots * duration * reward;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,7 +319,11 @@ contract Marketplace is Collateral, Proofs {
|
|||||||
/// @notice returns true when the request is accepting proof submissions from hosts occupying slots.
|
/// @notice returns true when the request is accepting proof submissions from hosts occupying slots.
|
||||||
/// @dev Request state must be new or started, and must not be cancelled, finished, or failed.
|
/// @dev Request state must be new or started, and must not be cancelled, finished, or failed.
|
||||||
/// @param requestId id of the request for which to obtain state info
|
/// @param requestId id of the request for which to obtain state info
|
||||||
function _requestAcceptsProofs(RequestId requestId) internal view returns (bool) {
|
function _requestAcceptsProofs(RequestId requestId)
|
||||||
|
internal
|
||||||
|
view
|
||||||
|
returns (bool)
|
||||||
|
{
|
||||||
RequestState s = state(requestId);
|
RequestState s = state(requestId);
|
||||||
return s == RequestState.New || s == RequestState.Started;
|
return s == RequestState.New || s == RequestState.Started;
|
||||||
}
|
}
|
||||||
@ -319,9 +336,18 @@ contract Marketplace is Collateral, Proofs {
|
|||||||
return RequestId.wrap(keccak256(abi.encode(request)));
|
return RequestId.wrap(keccak256(abi.encode(request)));
|
||||||
}
|
}
|
||||||
|
|
||||||
function _toSlotId(
|
function _toRequestIds(bytes32[] memory array)
|
||||||
RequestId requestId,
|
private
|
||||||
uint256 slotIndex)
|
pure
|
||||||
|
returns (RequestId[] memory result)
|
||||||
|
{
|
||||||
|
// solhint-disable-next-line no-inline-assembly
|
||||||
|
assembly {
|
||||||
|
result := array
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _toSlotId(RequestId requestId, uint256 slotIndex)
|
||||||
internal
|
internal
|
||||||
pure
|
pure
|
||||||
returns (SlotId)
|
returns (SlotId)
|
||||||
@ -379,11 +405,11 @@ contract Marketplace is Collateral, Proofs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum RequestState {
|
enum RequestState {
|
||||||
New, // [default] waiting to fill slots
|
New, // [default] waiting to fill slots
|
||||||
Started, // all slots filled, accepting regular proofs
|
Started, // all slots filled, accepting regular proofs
|
||||||
Cancelled, // not enough slots filled before expiry
|
Cancelled, // not enough slots filled before expiry
|
||||||
Finished, // successfully completed
|
Finished, // successfully completed
|
||||||
Failed // too many nodes have failed to provide proofs, data lost
|
Failed // too many nodes have failed to provide proofs, data lost
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RequestContext {
|
struct RequestContext {
|
||||||
|
@ -9,7 +9,7 @@ const {
|
|||||||
waitUntilStarted,
|
waitUntilStarted,
|
||||||
waitUntilFinished,
|
waitUntilFinished,
|
||||||
waitUntilFailed,
|
waitUntilFailed,
|
||||||
RequestState
|
RequestState,
|
||||||
} = require("./marketplace")
|
} = require("./marketplace")
|
||||||
const { price, pricePerSlot } = require("./price")
|
const { price, pricePerSlot } = require("./price")
|
||||||
const {
|
const {
|
||||||
@ -178,8 +178,8 @@ describe("Marketplace", function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("is rejected when request is finished", async function () {
|
it("is rejected when request is finished", async function () {
|
||||||
const lastSlot = await waitUntilStarted(marketplace, request, slot, proof)
|
await waitUntilStarted(marketplace, request, slot, proof)
|
||||||
await waitUntilFinished(marketplace, lastSlot)
|
await waitUntilFinished(marketplace, requestId(request))
|
||||||
await expect(
|
await expect(
|
||||||
marketplace.fillSlot(slot.request, slot.index, proof)
|
marketplace.fillSlot(slot.request, slot.index, proof)
|
||||||
).to.be.revertedWith("Request not accepting proofs")
|
).to.be.revertedWith("Request not accepting proofs")
|
||||||
@ -261,8 +261,8 @@ describe("Marketplace", function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("checks that proof end time is in the past once finished", async function () {
|
it("checks that proof end time is in the past once finished", async function () {
|
||||||
const lastSlot = await waitUntilStarted(marketplace, request, slot, proof)
|
await waitUntilStarted(marketplace, request, slot, proof)
|
||||||
await waitUntilFinished(marketplace, lastSlot)
|
await waitUntilFinished(marketplace, requestId(request))
|
||||||
const now = await currentTime()
|
const now = await currentTime()
|
||||||
// in the process of calling currentTime and proofEnd,
|
// in the process of calling currentTime and proofEnd,
|
||||||
// block.timestamp has advanced by 1, so the expected proof end time will
|
// block.timestamp has advanced by 1, so the expected proof end time will
|
||||||
@ -271,6 +271,72 @@ describe("Marketplace", function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("request end", function () {
|
||||||
|
var requestTime
|
||||||
|
beforeEach(async function () {
|
||||||
|
switchAccount(client)
|
||||||
|
await token.approve(marketplace.address, price(request))
|
||||||
|
await marketplace.requestStorage(request)
|
||||||
|
requestTime = await currentTime()
|
||||||
|
switchAccount(host)
|
||||||
|
await token.approve(marketplace.address, collateral)
|
||||||
|
await marketplace.deposit(collateral)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("shares request end time for all slots in request", async function () {
|
||||||
|
const lastSlot = request.ask.slots - 1
|
||||||
|
for (let i = 0; i < lastSlot; i++) {
|
||||||
|
await marketplace.fillSlot(slot.request, i, proof)
|
||||||
|
}
|
||||||
|
advanceTime(minutes(10))
|
||||||
|
await marketplace.fillSlot(slot.request, lastSlot, proof)
|
||||||
|
let slot0 = { ...slot, index: 0 }
|
||||||
|
let end = await marketplace.requestEnd(requestId(request))
|
||||||
|
for (let i = 1; i <= lastSlot; i++) {
|
||||||
|
let sloti = { ...slot, index: i }
|
||||||
|
await expect((await marketplace.proofEnd(slotId(sloti))) === end)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it("sets the request end time to now + duration", async function () {
|
||||||
|
await marketplace.fillSlot(slot.request, slot.index, proof)
|
||||||
|
await expect(
|
||||||
|
(await marketplace.requestEnd(requestId(request))).toNumber()
|
||||||
|
).to.be.closeTo(requestTime + request.ask.duration, 1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("sets request end time to the past once failed", async function () {
|
||||||
|
await waitUntilStarted(marketplace, request, slot, proof)
|
||||||
|
await waitUntilFailed(marketplace, request, slot)
|
||||||
|
let slot0 = { ...slot, index: request.ask.maxSlotLoss + 1 }
|
||||||
|
const now = await currentTime()
|
||||||
|
await expect(await marketplace.requestEnd(requestId(request))).to.be.eq(
|
||||||
|
now - 1
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("sets request end time to the past once cancelled", async function () {
|
||||||
|
await marketplace.fillSlot(slot.request, slot.index, proof)
|
||||||
|
await waitUntilCancelled(request)
|
||||||
|
const now = await currentTime()
|
||||||
|
await expect(await marketplace.requestEnd(requestId(request))).to.be.eq(
|
||||||
|
now - 1
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("checks that request end time is in the past once finished", async function () {
|
||||||
|
await waitUntilStarted(marketplace, request, slot, proof)
|
||||||
|
await waitUntilFinished(marketplace, requestId(request))
|
||||||
|
const now = await currentTime()
|
||||||
|
// in the process of calling currentTime and proofEnd,
|
||||||
|
// block.timestamp has advanced by 1, so the expected proof end time will
|
||||||
|
// be block.timestamp - 1.
|
||||||
|
await expect(await marketplace.requestEnd(requestId(request))).to.be.eq(
|
||||||
|
now - 1
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe("freeing a slot", function () {
|
describe("freeing a slot", function () {
|
||||||
var id
|
var id
|
||||||
beforeEach(async function () {
|
beforeEach(async function () {
|
||||||
@ -302,8 +368,8 @@ describe("Marketplace", function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("fails to free slot when finished", async function () {
|
it("fails to free slot when finished", async function () {
|
||||||
const lastSlot = await waitUntilStarted(marketplace, request, slot, proof)
|
await waitUntilStarted(marketplace, request, slot, proof)
|
||||||
await waitUntilFinished(marketplace, lastSlot)
|
await waitUntilFinished(marketplace, requestId(request))
|
||||||
await expect(marketplace.freeSlot(slotId(slot))).to.be.revertedWith(
|
await expect(marketplace.freeSlot(slotId(slot))).to.be.revertedWith(
|
||||||
"Slot not accepting proofs"
|
"Slot not accepting proofs"
|
||||||
)
|
)
|
||||||
@ -339,8 +405,8 @@ describe("Marketplace", function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("pays the host", async function () {
|
it("pays the host", async function () {
|
||||||
const lastSlot = await waitUntilStarted(marketplace, request, slot, proof)
|
await waitUntilStarted(marketplace, request, slot, proof)
|
||||||
await waitUntilFinished(marketplace, lastSlot)
|
await waitUntilFinished(marketplace, requestId(request))
|
||||||
const startBalance = await token.balanceOf(host.address)
|
const startBalance = await token.balanceOf(host.address)
|
||||||
await marketplace.payoutSlot(slot.request, slot.index)
|
await marketplace.payoutSlot(slot.request, slot.index)
|
||||||
const endBalance = await token.balanceOf(host.address)
|
const endBalance = await token.balanceOf(host.address)
|
||||||
@ -355,8 +421,8 @@ describe("Marketplace", function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("can only be done once", async function () {
|
it("can only be done once", async function () {
|
||||||
const lastSlot = await waitUntilStarted(marketplace, request, slot, proof)
|
await waitUntilStarted(marketplace, request, slot, proof)
|
||||||
await waitUntilFinished(marketplace, lastSlot)
|
await waitUntilFinished(marketplace, requestId(request))
|
||||||
await marketplace.payoutSlot(slot.request, slot.index)
|
await marketplace.payoutSlot(slot.request, slot.index)
|
||||||
await expect(
|
await expect(
|
||||||
marketplace.payoutSlot(slot.request, slot.index)
|
marketplace.payoutSlot(slot.request, slot.index)
|
||||||
@ -364,8 +430,8 @@ describe("Marketplace", function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("cannot be filled again", async function () {
|
it("cannot be filled again", async function () {
|
||||||
const lastSlot = await waitUntilStarted(marketplace, request, slot, proof)
|
await waitUntilStarted(marketplace, request, slot, proof)
|
||||||
await waitUntilFinished(marketplace, lastSlot)
|
await waitUntilFinished(marketplace, requestId(request))
|
||||||
await marketplace.payoutSlot(slot.request, slot.index)
|
await marketplace.payoutSlot(slot.request, slot.index)
|
||||||
await expect(marketplace.fillSlot(slot.request, slot.index, proof)).to.be
|
await expect(marketplace.fillSlot(slot.request, slot.index, proof)).to.be
|
||||||
.reverted
|
.reverted
|
||||||
@ -507,8 +573,8 @@ describe("Marketplace", function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("state is Finished once slot is paid out", async function () {
|
it("state is Finished once slot is paid out", async function () {
|
||||||
const lastSlot = await waitUntilStarted(marketplace, request, slot, proof)
|
await waitUntilStarted(marketplace, request, slot, proof)
|
||||||
await waitUntilFinished(marketplace, lastSlot)
|
await waitUntilFinished(marketplace, requestId(request))
|
||||||
await marketplace.payoutSlot(slot.request, slot.index)
|
await marketplace.payoutSlot(slot.request, slot.index)
|
||||||
await expect(await marketplace.state(slot.request)).to.equal(
|
await expect(await marketplace.state(slot.request)).to.equal(
|
||||||
RequestState.Finished
|
RequestState.Finished
|
||||||
@ -595,26 +661,16 @@ describe("Marketplace", function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("fails when request Finished (isFinished is true)", async function () {
|
it("fails when request Finished (isFinished is true)", async function () {
|
||||||
const lastSlot = await waitUntilStarted(
|
await waitUntilStarted(marketplace, request, slot, proof)
|
||||||
marketplace,
|
await waitUntilFinished(marketplace, requestId(request))
|
||||||
request,
|
|
||||||
slot,
|
|
||||||
proof
|
|
||||||
)
|
|
||||||
await waitUntilFinished(marketplace, lastSlot)
|
|
||||||
await expect(
|
await expect(
|
||||||
marketplace.testAcceptsProofs(slotId(slot))
|
marketplace.testAcceptsProofs(slotId(slot))
|
||||||
).to.be.revertedWith("Slot not accepting proofs")
|
).to.be.revertedWith("Slot not accepting proofs")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("fails when request Finished (state set to Finished)", async function () {
|
it("fails when request Finished (state set to Finished)", async function () {
|
||||||
const lastSlot = await waitUntilStarted(
|
await waitUntilStarted(marketplace, request, slot, proof)
|
||||||
marketplace,
|
await waitUntilFinished(marketplace, requestId(request))
|
||||||
request,
|
|
||||||
slot,
|
|
||||||
proof
|
|
||||||
)
|
|
||||||
await waitUntilFinished(marketplace, lastSlot)
|
|
||||||
await marketplace.payoutSlot(slot.request, slot.index)
|
await marketplace.payoutSlot(slot.request, slot.index)
|
||||||
await expect(
|
await expect(
|
||||||
marketplace.testAcceptsProofs(slotId(slot))
|
marketplace.testAcceptsProofs(slotId(slot))
|
||||||
@ -634,4 +690,45 @@ describe("Marketplace", function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("list of active requests", function () {
|
||||||
|
beforeEach(async function () {
|
||||||
|
switchAccount(host)
|
||||||
|
await token.approve(marketplace.address, collateral)
|
||||||
|
await marketplace.deposit(collateral)
|
||||||
|
switchAccount(client)
|
||||||
|
await token.approve(marketplace.address, price(request))
|
||||||
|
})
|
||||||
|
|
||||||
|
it("adds request to list when requesting storage", async function () {
|
||||||
|
await marketplace.requestStorage(request)
|
||||||
|
expect(await marketplace.myRequests()).to.deep.equal([requestId(request)])
|
||||||
|
})
|
||||||
|
|
||||||
|
it("removes request from list when funds are withdrawn", async function () {
|
||||||
|
await marketplace.requestStorage(request)
|
||||||
|
await waitUntilCancelled(request)
|
||||||
|
await marketplace.withdrawFunds(requestId(request))
|
||||||
|
expect(await marketplace.myRequests()).to.deep.equal([])
|
||||||
|
})
|
||||||
|
|
||||||
|
it("removes request from list when request fails", async function () {
|
||||||
|
await marketplace.requestStorage(request)
|
||||||
|
switchAccount(host)
|
||||||
|
await waitUntilStarted(marketplace, request, slot, proof)
|
||||||
|
await waitUntilFailed(marketplace, request, slot)
|
||||||
|
switchAccount(client)
|
||||||
|
expect(await marketplace.myRequests()).to.deep.equal([])
|
||||||
|
})
|
||||||
|
|
||||||
|
it("removes request from list when request finishes", async function () {
|
||||||
|
await marketplace.requestStorage(request)
|
||||||
|
switchAccount(host)
|
||||||
|
await waitUntilStarted(marketplace, request, slot, proof)
|
||||||
|
await waitUntilFinished(marketplace, requestId(request))
|
||||||
|
await marketplace.payoutSlot(slot.request, slot.index)
|
||||||
|
switchAccount(client)
|
||||||
|
expect(await marketplace.myRequests()).to.deep.equal([])
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -76,7 +76,7 @@ describe("Storage", function () {
|
|||||||
describe("ending the contract", function () {
|
describe("ending the contract", function () {
|
||||||
it("unlocks the host collateral", async function () {
|
it("unlocks the host collateral", async function () {
|
||||||
await storage.fillSlot(slot.request, slot.index, proof)
|
await storage.fillSlot(slot.request, slot.index, proof)
|
||||||
await waitUntilFinished(storage, slot)
|
await waitUntilFinished(storage, slot.request)
|
||||||
await expect(storage.withdraw()).not.to.be.reverted
|
await expect(storage.withdraw()).not.to.be.reverted
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -6,16 +6,13 @@ async function waitUntilCancelled(request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function waitUntilStarted(contract, request, slot, proof) {
|
async function waitUntilStarted(contract, request, slot, proof) {
|
||||||
const lastSlotIdx = request.ask.slots - 1
|
for (let i = 0; i < request.ask.slots; i++) {
|
||||||
for (let i = 0; i <= lastSlotIdx; i++) {
|
|
||||||
await contract.fillSlot(slot.request, i, proof)
|
await contract.fillSlot(slot.request, i, proof)
|
||||||
}
|
}
|
||||||
return { ...slot, index: lastSlotIdx }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function waitUntilFinished(contract, lastSlot) {
|
async function waitUntilFinished(contract, requestId) {
|
||||||
const lastSlotId = slotId(lastSlot)
|
const end = (await contract.requestEnd(requestId)).toNumber()
|
||||||
const end = (await contract.proofEnd(lastSlotId)).toNumber()
|
|
||||||
await advanceTimeTo(end + 1)
|
await advanceTimeTo(end + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user