[marketplace] tests for Failed state
This commit is contained in:
parent
980647876f
commit
2b8c8fc42a
|
@ -64,25 +64,6 @@ contract AccountLocks {
|
||||||
require(accountLocks.length == 0, "Account locked");
|
require(accountLocks.length == 0, "Account locked");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes an account lock
|
|
||||||
function _removeAccountLock(address account, bytes32 lockId) internal {
|
|
||||||
require(accounts[account].locks.length > 0, "Account lock doesn't exist");
|
|
||||||
bytes32[] storage accountLocks = accounts[account].locks;
|
|
||||||
uint256 index = 0;
|
|
||||||
while (true) {
|
|
||||||
if (index >= accountLocks.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (accountLocks[index] == lockId) {
|
|
||||||
accountLocks[index] = accountLocks[accountLocks.length - 1];
|
|
||||||
accountLocks.pop();
|
|
||||||
} else {
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeInactiveLocks(bytes32[] storage lockIds) private {
|
function removeInactiveLocks(bytes32[] storage lockIds) private {
|
||||||
uint256 index = 0;
|
uint256 index = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
|
@ -55,8 +55,6 @@ contract Marketplace is Collateral, Proofs {
|
||||||
RequestContext storage context = requestContexts[requestId];
|
RequestContext storage context = requestContexts[requestId];
|
||||||
require(context.state == RequestState.Started, "Invalid state");
|
require(context.state == RequestState.Started, "Invalid state");
|
||||||
|
|
||||||
_removeAccountLock(slot.host, requestId);
|
|
||||||
|
|
||||||
// TODO: burn host's slot collateral except for repair costs + mark proof
|
// TODO: burn host's slot collateral except for repair costs + mark proof
|
||||||
// missing reward
|
// missing reward
|
||||||
// Slot collateral is not yet implemented as the design decision was
|
// Slot collateral is not yet implemented as the design decision was
|
||||||
|
|
|
@ -23,8 +23,4 @@ contract TestCollateral is Collateral {
|
||||||
function unlock(bytes32 id) public {
|
function unlock(bytes32 id) public {
|
||||||
_unlock(id);
|
_unlock(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeAccountLock(address account, bytes32 lockId) public {
|
|
||||||
_removeAccountLock(account, lockId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,10 +110,5 @@ describe("Collateral", function () {
|
||||||
await collateral.unlock(lock.id)
|
await collateral.unlock(lock.id)
|
||||||
await expect(collateral.withdraw()).not.to.be.reverted
|
await expect(collateral.withdraw()).not.to.be.reverted
|
||||||
})
|
})
|
||||||
|
|
||||||
it("withdrawal succeeds when account lock has been removed", async function () {
|
|
||||||
await collateral.removeAccountLock(account0.address, lock.id)
|
|
||||||
await expect(collateral.withdraw()).not.to.be.reverted
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,7 +4,7 @@ const { expect } = require("chai")
|
||||||
const { exampleRequest } = require("./examples")
|
const { exampleRequest } = require("./examples")
|
||||||
const { now, hours } = require("./time")
|
const { now, hours } = require("./time")
|
||||||
const { requestId, slotId, askToArray } = require("./ids")
|
const { requestId, slotId, askToArray } = require("./ids")
|
||||||
const { waitUntilExpired, RequestState } = require("./marketplace")
|
const { waitUntilExpired, waitUntilAllSlotsFilled, RequestState } = require("./marketplace")
|
||||||
const { price, pricePerSlot } = require("./price")
|
const { price, pricePerSlot } = require("./price")
|
||||||
const {
|
const {
|
||||||
snapshot,
|
snapshot,
|
||||||
|
@ -119,13 +119,6 @@ describe("Marketplace", function () {
|
||||||
// await marketplace.fillSlot(slot.request, slot.index, proof)
|
// await marketplace.fillSlot(slot.request, slot.index, proof)
|
||||||
})
|
})
|
||||||
|
|
||||||
async function waitUntilAllSlotsFilled() {
|
|
||||||
const lastSlot = request.ask.slots - 1
|
|
||||||
for (let i = 0; i <= lastSlot; i++) {
|
|
||||||
await marketplace.fillSlot(slot.request, i, proof)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
it("fails to free slot when slot not filled", async function () {
|
it("fails to free slot when slot not filled", async function () {
|
||||||
slot.index = 5
|
slot.index = 5
|
||||||
let nonExistentId = slotId(slot)
|
let nonExistentId = slotId(slot)
|
||||||
|
@ -140,19 +133,34 @@ describe("Marketplace", function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("successfully frees slot", async function () {
|
it("successfully frees slot", async function () {
|
||||||
await waitUntilAllSlotsFilled()
|
await waitUntilAllSlotsFilled(
|
||||||
|
marketplace,
|
||||||
|
request.ask.slots,
|
||||||
|
slot.request,
|
||||||
|
proof
|
||||||
|
)
|
||||||
await expect(marketplace.freeSlot(id)).not.to.be.reverted
|
await expect(marketplace.freeSlot(id)).not.to.be.reverted
|
||||||
})
|
})
|
||||||
|
|
||||||
it("emits event once slot is freed", async function () {
|
it("emits event once slot is freed", async function () {
|
||||||
await waitUntilAllSlotsFilled()
|
await waitUntilAllSlotsFilled(
|
||||||
|
marketplace,
|
||||||
|
request.ask.slots,
|
||||||
|
slot.request,
|
||||||
|
proof
|
||||||
|
)
|
||||||
await expect(await marketplace.freeSlot(id))
|
await expect(await marketplace.freeSlot(id))
|
||||||
.to.emit(marketplace, "SlotFreed")
|
.to.emit(marketplace, "SlotFreed")
|
||||||
.withArgs(slot.request, id)
|
.withArgs(slot.request, id)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("cannot get slot once freed", async function () {
|
it("cannot get slot once freed", async function () {
|
||||||
await waitUntilAllSlotsFilled()
|
await waitUntilAllSlotsFilled(
|
||||||
|
marketplace,
|
||||||
|
request.ask.slots,
|
||||||
|
slot.request,
|
||||||
|
proof
|
||||||
|
)
|
||||||
await marketplace.freeSlot(id)
|
await marketplace.freeSlot(id)
|
||||||
await expect(marketplace.slot(id)).to.be.revertedWith("Slot empty")
|
await expect(marketplace.slot(id)).to.be.revertedWith("Slot empty")
|
||||||
})
|
})
|
||||||
|
@ -410,16 +418,34 @@ describe("Marketplace", function () {
|
||||||
await expect(await marketplace.state(slot.request)).to.equal(
|
await expect(await marketplace.state(slot.request)).to.equal(
|
||||||
RequestState.New
|
RequestState.New
|
||||||
)
|
)
|
||||||
// fill all slots, should change state to RequestState.Started
|
await waitUntilAllSlotsFilled(
|
||||||
const lastSlot = request.ask.slots - 1
|
marketplace,
|
||||||
for (let i = 0; i <= lastSlot; i++) {
|
request.ask.slots,
|
||||||
await marketplace.fillSlot(slot.request, i, proof)
|
slot.request,
|
||||||
}
|
proof
|
||||||
|
)
|
||||||
await expect(await marketplace.state(slot.request)).to.equal(
|
await expect(await marketplace.state(slot.request)).to.equal(
|
||||||
RequestState.Started
|
RequestState.Started
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("state is Failed once too many slots are freed", async function () {
|
||||||
|
await waitUntilAllSlotsFilled(
|
||||||
|
marketplace,
|
||||||
|
request.ask.slots,
|
||||||
|
slot.request,
|
||||||
|
proof
|
||||||
|
)
|
||||||
|
for (let i = 0; i <= request.ask.maxSlotLoss; i++) {
|
||||||
|
slot.index = i
|
||||||
|
let id = slotId(slot)
|
||||||
|
await marketplace.freeSlot(id)
|
||||||
|
}
|
||||||
|
await expect(await marketplace.state(slot.request)).to.equal(
|
||||||
|
RequestState.Failed
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
it("changes state to Cancelled once request is cancelled", async function () {
|
it("changes state to Cancelled once request is cancelled", async function () {
|
||||||
await waitUntilExpired(request.expiry)
|
await waitUntilExpired(request.expiry)
|
||||||
await expect(await marketplace.state(slot.request)).to.equal(
|
await expect(await marketplace.state(slot.request)).to.equal(
|
||||||
|
|
|
@ -8,7 +8,7 @@ const { advanceTime, advanceTimeTo, currentTime, mine } = require("./evm")
|
||||||
const { requestId, slotId } = require("./ids")
|
const { requestId, slotId } = require("./ids")
|
||||||
const { periodic } = require("./time")
|
const { periodic } = require("./time")
|
||||||
const { price } = require("./price")
|
const { price } = require("./price")
|
||||||
const { waitUntilExpired } = require("./marketplace")
|
const { waitUntilExpired, waitUntilAllSlotsFilled } = require("./marketplace")
|
||||||
|
|
||||||
describe("Storage", function () {
|
describe("Storage", function () {
|
||||||
const proof = hexlify(randomBytes(42))
|
const proof = hexlify(randomBytes(42))
|
||||||
|
@ -198,13 +198,6 @@ describe("Storage", function () {
|
||||||
;({ periodOf, periodEnd } = periodic(period))
|
;({ periodOf, periodEnd } = periodic(period))
|
||||||
})
|
})
|
||||||
|
|
||||||
async function waitUntilAllSlotsFilled() {
|
|
||||||
const lastSlot = request.ask.slots - 1
|
|
||||||
for (let i = 0; i <= lastSlot; i++) {
|
|
||||||
await storage.fillSlot(slot.request, i, proof)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function waitUntilProofIsRequired(id) {
|
async function waitUntilProofIsRequired(id) {
|
||||||
await advanceTimeTo(periodEnd(periodOf(await currentTime())))
|
await advanceTimeTo(periodEnd(periodOf(await currentTime())))
|
||||||
while (
|
while (
|
||||||
|
@ -231,7 +224,12 @@ describe("Storage", function () {
|
||||||
it("frees slot when collateral slashed below minimum threshold", async function () {
|
it("frees slot when collateral slashed below minimum threshold", async function () {
|
||||||
const id = slotId(slot)
|
const id = slotId(slot)
|
||||||
|
|
||||||
await waitUntilAllSlotsFilled()
|
await waitUntilAllSlotsFilled(
|
||||||
|
storage,
|
||||||
|
request.ask.slots,
|
||||||
|
slot.request,
|
||||||
|
proof
|
||||||
|
)
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
await markProofAsMissing(id)
|
await markProofAsMissing(id)
|
||||||
|
|
|
@ -10,4 +10,11 @@ async function waitUntilExpired(expiry) {
|
||||||
await ethers.provider.send("hardhat_mine", [ethers.utils.hexValue(expiry)])
|
await ethers.provider.send("hardhat_mine", [ethers.utils.hexValue(expiry)])
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { waitUntilExpired, RequestState }
|
async function waitUntilAllSlotsFilled(contract, numSlots, requestId, proof) {
|
||||||
|
const lastSlot = numSlots - 1
|
||||||
|
for (let i = 0; i <= lastSlot; i++) {
|
||||||
|
await contract.fillSlot(requestId, i, proof)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { waitUntilExpired, waitUntilAllSlotsFilled }
|
||||||
|
|
Loading…
Reference in New Issue