marketplace: better tests for repair

Co-Authored-By: Adam Uhlíř <adam@uhlir.dev>
This commit is contained in:
Mark Spanbroek 2025-06-12 15:50:09 +02:00
parent d7554ce0d2
commit b5ab3869b9
2 changed files with 82 additions and 55 deletions

View File

@ -22,6 +22,7 @@ const {
waitUntilFailed,
waitUntilSlotFailed,
patchOverloads,
waitUntilSlotFilled,
} = require("./marketplace")
const {
maxPrice,
@ -305,28 +306,6 @@ describe("Marketplace", function () {
expect(startBalance - endBalance).to.eq(collateralPerSlot(request))
})
describe("when repairing a slot", function () {
beforeEach(async function () {
await marketplace.reserveSlot(slot.request, slot.index)
await marketplace.fillSlot(slot.request, slot.index, proof)
await advanceTime(config.proofs.period + 1)
await marketplace.freeSlot(slotId(slot))
})
it("tops up the host collateral with the repair reward", async function () {
const collateral = collateralPerSlot(request)
const reward = repairReward(config, collateral)
await token.approve(marketplace.address, collateral)
await marketplace.reserveSlot(slot.request, slot.index)
const startBalance = await marketplace.getSlotBalance(slotId(slot))
await marketplace.fillSlot(slot.request, slot.index, proof)
const endBalance = await marketplace.getSlotBalance(slotId(slot))
expect(endBalance - startBalance).to.equal(collateral + reward)
})
})
it("updates the slot's current collateral", async function () {
await marketplace.reserveSlot(slot.request, slot.index)
await marketplace.fillSlot(slot.request, slot.index, proof)
@ -568,29 +547,6 @@ describe("Marketplace", function () {
.withArgs(slot.request, slot.index)
})
it("can reserve and fill a freed slot", async function () {
// Make a reservation from another host
switchAccount(host2)
collateral = collateralPerSlot(request)
await token.approve(marketplace.address, collateral)
await marketplace.reserveSlot(slot.request, slot.index)
// Switch host and free the slot
switchAccount(host)
await waitUntilStarted(marketplace, request, proof, token)
await marketplace.freeSlot(id)
// At this point, the slot should be freed and in a repair state.
// Another host should be able to make a reservation for this
// slot and fill it.
switchAccount(host2)
await marketplace.reserveSlot(slot.request, slot.index)
let currPeriod = periodOf(await currentTime())
await advanceTimeTo(periodEnd(currPeriod) + 1)
await token.approve(marketplace.address, collateral)
await marketplace.fillSlot(slot.request, slot.index, proof)
})
it("updates the slot's current collateral", async function () {
await waitUntilStarted(marketplace, request, proof, token)
await marketplace.freeSlot(id)
@ -1340,6 +1296,72 @@ describe("Marketplace", function () {
})
})
describe("repairing a slot", function () {
beforeEach(async function () {
switchAccount(client)
await token.approve(marketplace.address, maxPrice(request))
await marketplace.requestStorage(request)
switchAccount(host)
await waitUntilStarted(marketplace, request, proof, token)
await advanceTime(config.proofs.period + 1)
await marketplace.freeSlot(slotId(slot))
switchAccount(host2)
})
it("can reserve and fill a freed slot", async function () {
const collateral = collateralPerSlot(request)
await token.approve(marketplace.address, collateral)
await marketplace.reserveSlot(slot.request, slot.index)
await token.approve(marketplace.address, collateral)
await marketplace.fillSlot(slot.request, slot.index, proof)
})
it("tops up the host collateral with the repair reward", async function () {
const collateral = collateralPerSlot(request)
const reward = repairReward(config, collateral)
await token.approve(marketplace.address, collateral)
await marketplace.reserveSlot(slot.request, slot.index)
const startBalance = await marketplace.getSlotBalance(slotId(slot))
await marketplace.fillSlot(slot.request, slot.index, proof)
const endBalance = await marketplace.getSlotBalance(slotId(slot))
expect(endBalance - startBalance).to.equal(collateral + reward)
})
it("pays the host that repaired when the request finishes", async function () {
const collateral = collateralPerSlot(request)
const reward = repairReward(config, collateral)
const payout = await waitUntilSlotFilled(
marketplace,
request,
proof,
token,
slot.index
)
await waitUntilFinished(marketplace, slot.request)
const startBalance = await token.balanceOf(host2.address)
await marketplace.freeSlot(slotId(slot))
const endBalance = await token.balanceOf(host2.address)
expect(endBalance - startBalance).to.equal(collateral + reward + payout)
})
it("burns payment and collateral of the host that failed", async function () {
const collateral = collateralPerSlot(request)
await token.approve(marketplace.address, collateral)
await marketplace.reserveSlot(slot.request, slot.index)
await marketplace.fillSlot(slot.request, slot.index, proof)
await waitUntilFinished(marketplace, slot.request)
switchAccount(host)
await expect(marketplace.freeSlot(slotId(slot))).to.be.revertedWith(
"InvalidSlotHost"
)
})
})
describe("list of active requests", function () {
beforeEach(async function () {
switchAccount(host)

View File

@ -9,23 +9,27 @@ async function waitUntilCancelled(contract, request) {
await advanceTimeTo(expiry + 1)
}
async function waitUntilSlotsFilled(contract, request, proof, token, slots) {
async function waitUntilSlotFilled(contract, request, proof, token, slotIndex) {
let collateral = collateralPerSlot(request)
await token.approve(contract.address, collateral * slots.length)
await token.approve(contract.address, collateral)
await contract.reserveSlot(requestId(request), slotIndex)
await contract.fillSlot(requestId(request), slotIndex, proof)
const start = await currentTime()
const end = await contract.requestEnd(requestId(request))
return payoutForDuration(request, start, end)
}
let requestEnd = await contract.requestEnd(requestId(request))
async function waitUntilSlotsFilled(contract, request, proof, token, slots) {
const payouts = []
for (let slotIndex of slots) {
await contract.reserveSlot(requestId(request), slotIndex)
await contract.fillSlot(requestId(request), slotIndex, proof)
payouts[slotIndex] = payoutForDuration(
payouts[slotIndex] = await waitUntilSlotFilled(
contract,
request,
await currentTime(),
requestEnd
proof,
token,
slotIndex
)
}
return payouts
}
@ -99,6 +103,7 @@ function patchOverloads(contract) {
module.exports = {
waitUntilCancelled,
waitUntilStarted,
waitUntilSlotFilled,
waitUntilSlotsFilled,
waitUntilFinished,
waitUntilFailed,