[marketplace] test & fix slotState()

This commit is contained in:
Mark Spanbroek 2023-01-18 15:26:21 +01:00 committed by markspanbroek
parent 70d8967f26
commit b62eeb564a
7 changed files with 104 additions and 22 deletions

View File

@ -247,24 +247,25 @@ contract Marketplace is Collateral, Proofs, StateRetrieval {
}
}
function slotState(SlotId slotId) internal view override returns (SlotState) {
function slotState(SlotId slotId) public view override returns (SlotState) {
Slot storage slot = slots[slotId];
if (RequestId.unwrap(slot.requestId) == 0) {
return SlotState.Free;
}
RequestState reqState = requestState(slot.requestId);
if (slot.state == SlotState.Paid) {
return SlotState.Paid;
} else if (
slot.state == SlotState.Failed || reqState == RequestState.Failed
) {
return SlotState.Failed;
} else if (
slot.state == SlotState.Finished ||
reqState == RequestState.Finished ||
reqState == RequestState.Cancelled
) {
return SlotState.Finished;
} else {
return slot.state;
}
if (reqState == RequestState.Cancelled) {
return SlotState.Finished;
}
if (reqState == RequestState.Finished) {
return SlotState.Finished;
}
if (reqState == RequestState.Failed) {
return SlotState.Failed;
}
return slot.state;
}
struct RequestContext {

View File

@ -19,7 +19,7 @@ abstract contract Proofs is Periods {
mapping(SlotId => mapping(Period => bool)) private received;
mapping(SlotId => mapping(Period => bool)) private missing;
function slotState(SlotId id) internal view virtual returns (SlotState);
function slotState(SlotId id) public view virtual returns (SlotState);
function missingProofs(SlotId slotId) public view returns (uint256) {
return missed[slotId];

View File

@ -46,10 +46,10 @@ enum RequestState {
}
enum SlotState {
Free, // [default] not filled yet, or host has freed slot
Free, // [default] not filled yet, or host has vacated the slot
Filled, // host has filled slot
Finished, // successfully completed
Failed, // host has missed too many proofs
Failed, // the request has failed
Paid // host has been paid
}

View File

@ -8,10 +8,9 @@ contract TestMarketplace is Marketplace {
constructor(
IERC20 token,
MarketplaceConfig memory config
) Marketplace(token, config) // solhint-disable-next-line no-empty-blocks
{
}
)
Marketplace(token, config) // solhint-disable-next-line no-empty-blocks
{}
function forciblyFreeSlot(SlotId slotId) public {
_forciblyFreeSlot(slotId);

View File

@ -10,7 +10,7 @@ contract TestProofs is Proofs {
// solhint-disable-next-line no-empty-blocks
constructor(ProofConfig memory config) Proofs(config) {}
function slotState(SlotId slotId) internal view override returns (SlotState) {
function slotState(SlotId slotId) public view override returns (SlotState) {
return states[slotId];
}

View File

@ -6,7 +6,7 @@ const { expect } = require("chai")
const { exampleConfiguration, exampleRequest } = require("./examples")
const { periodic, hours } = require("./time")
const { requestId, slotId, askToArray } = require("./ids")
const { RequestState } = require("./requests")
const { RequestState, SlotState } = require("./requests")
const {
waitUntilCancelled,
waitUntilStarted,
@ -548,6 +548,86 @@ describe("Marketplace", function () {
})
})
describe("slot state", function () {
const { Free, Filled, Finished, Failed, Paid } = SlotState
let period, periodEnd
beforeEach(async function () {
period = config.proofs.period
;({ periodOf, periodEnd } = periodic(period))
switchAccount(client)
await token.approve(marketplace.address, price(request))
await marketplace.requestStorage(request)
switchAccount(host)
await token.approve(marketplace.address, config.collateral.initialAmount)
await marketplace.deposit(config.collateral.initialAmount)
})
async function waitUntilProofIsRequired(id) {
await advanceTimeTo(periodEnd(periodOf(await currentTime())))
while (
!(
(await marketplace.isProofRequired(id)) &&
(await marketplace.getPointer(id)) < 250
)
) {
await advanceTime(period)
}
}
it("is 'Free' initially", async function () {
expect(await marketplace.slotState(slotId(slot))).to.equal(Free)
})
it("changes to 'Filled' when slot is filled", async function () {
await marketplace.fillSlot(slot.request, slot.index, proof)
expect(await marketplace.slotState(slotId(slot))).to.equal(Filled)
})
it("changes to 'Finished' when request finishes", async function () {
await waitUntilStarted(marketplace, request, proof)
await waitUntilFinished(marketplace, slot.request)
expect(await marketplace.slotState(slotId(slot))).to.equal(Finished)
})
it("changes to 'Finished' when request is cancelled", async function () {
await marketplace.fillSlot(slot.request, slot.index, proof)
await waitUntilCancelled(request)
expect(await marketplace.slotState(slotId(slot))).to.equal(Finished)
})
it("changes to 'Free' when host frees the slot", async function () {
await marketplace.fillSlot(slot.request, slot.index, proof)
await marketplace.freeSlot(slotId(slot))
expect(await marketplace.slotState(slotId(slot))).to.equal(Free)
})
it("changes to 'Free' when too many proofs are missed", async function () {
await waitUntilStarted(marketplace, request, proof)
while ((await marketplace.slotState(slotId(slot))) === Filled) {
await waitUntilProofIsRequired(slotId(slot))
const missedPeriod = periodOf(await currentTime())
await advanceTime(period)
await marketplace.markProofAsMissing(slotId(slot), missedPeriod)
}
expect(await marketplace.slotState(slotId(slot))).to.equal(Free)
})
it("changes to 'Failed' when request fails", async function () {
await waitUntilStarted(marketplace, request, proof)
await waitUntilSlotFailed(marketplace, request, slot)
expect(await marketplace.slotState(slotId(slot))).to.equal(Failed)
})
it("changes to 'Paid' when host has been paid", async function () {
await waitUntilStarted(marketplace, request, proof)
await waitUntilFinished(marketplace, slot.request)
await marketplace.freeSlot(slotId(slot))
expect(await marketplace.slotState(slotId(slot))).to.equal(Paid)
})
})
describe("proof requirements", function () {
let period, periodOf, periodEnd

View File

@ -10,6 +10,8 @@ const SlotState = {
Free: 0,
Filled: 1,
Finished: 2,
Failed: 3,
Paid: 4,
}
module.exports = { RequestState, SlotState }