marketplace: fix flaky tests

This commit is contained in:
Mark Spanbroek 2025-02-10 11:32:54 +01:00 committed by markspanbroek
parent e31e39f22c
commit 69e97bd21d
3 changed files with 35 additions and 33 deletions

View File

@ -36,6 +36,7 @@ const {
advanceTime, advanceTime,
advanceTimeTo, advanceTimeTo,
currentTime, currentTime,
setNextBlockTimestamp,
} = require("./evm") } = require("./evm")
const { arrayify } = require("ethers/lib/utils") const { arrayify } = require("ethers/lib/utils")
@ -179,7 +180,9 @@ describe("Marketplace", function () {
it("emits event when storage is requested", async function () { it("emits event when storage is requested", async function () {
await token.approve(marketplace.address, maxPrice(request)) await token.approve(marketplace.address, maxPrice(request))
const expectedExpiry = (await currentTime()) + request.expiry const now = await currentTime()
await setNextBlockTimestamp(now)
const expectedExpiry = now + request.expiry
await expect(marketplace.requestStorage(request)) await expect(marketplace.requestStorage(request))
.to.emit(marketplace, "StorageRequested") .to.emit(marketplace, "StorageRequested")
.withArgs(requestId(request), askToArray(request.ask), expectedExpiry) .withArgs(requestId(request), askToArray(request.ask), expectedExpiry)
@ -384,7 +387,7 @@ describe("Marketplace", function () {
let expired = { ...request, expiry: hours(1) + 1 } let expired = { ...request, expiry: hours(1) + 1 }
await token.approve(marketplace.address, maxPrice(request)) await token.approve(marketplace.address, maxPrice(request))
await marketplace.requestStorage(expired) await marketplace.requestStorage(expired)
await waitUntilCancelled(expired) await waitUntilCancelled(marketplace, expired)
switchAccount(host) switchAccount(host)
await marketplace.reserveSlot(requestId(expired), slot.index) await marketplace.reserveSlot(requestId(expired), slot.index)
await expect( await expect(
@ -534,7 +537,7 @@ describe("Marketplace", function () {
it("sets request end time to the past once cancelled", async function () { it("sets request end time to the past once cancelled", async function () {
await marketplace.reserveSlot(slot.request, slot.index) await marketplace.reserveSlot(slot.request, slot.index)
await marketplace.fillSlot(slot.request, slot.index, proof) await marketplace.fillSlot(slot.request, slot.index, proof)
await waitUntilCancelled(request) await waitUntilCancelled(marketplace, request)
const now = await currentTime() const now = await currentTime()
await expect(await marketplace.requestEnd(requestId(request))).to.be.eq( await expect(await marketplace.requestEnd(requestId(request))).to.be.eq(
now - 1 now - 1
@ -695,7 +698,7 @@ describe("Marketplace", function () {
await marketplace.reserveSlot(slot.request, slot.index) await marketplace.reserveSlot(slot.request, slot.index)
await advanceTimeTo(filledAt) await advanceTimeTo(filledAt)
await marketplace.fillSlot(slot.request, slot.index, proof) await marketplace.fillSlot(slot.request, slot.index, proof)
await waitUntilCancelled(request) await waitUntilCancelled(marketplace, request)
await marketplace.freeSlot(slotId(slot)) await marketplace.freeSlot(slotId(slot))
const expectedPartialPayout = const expectedPartialPayout =
@ -716,7 +719,7 @@ describe("Marketplace", function () {
await marketplace.reserveSlot(slot.request, slot.index) await marketplace.reserveSlot(slot.request, slot.index)
await advanceTimeTo(filledAt) await advanceTimeTo(filledAt)
await marketplace.fillSlot(slot.request, slot.index, proof) await marketplace.fillSlot(slot.request, slot.index, proof)
await waitUntilCancelled(request) await waitUntilCancelled(marketplace, request)
const startBalanceHost = await token.balanceOf(host.address) const startBalanceHost = await token.balanceOf(host.address)
const startBalanceReward = await token.balanceOf( const startBalanceReward = await token.balanceOf(
hostRewardRecipient.address hostRewardRecipient.address
@ -877,7 +880,7 @@ describe("Marketplace", function () {
}) })
it("rejects withdraw when wrong account used", async function () { it("rejects withdraw when wrong account used", async function () {
await waitUntilCancelled(request) await waitUntilCancelled(marketplace, request)
await expect( await expect(
marketplace.withdrawFunds(slot.request, clientWithdrawRecipient.address) marketplace.withdrawFunds(slot.request, clientWithdrawRecipient.address)
).to.be.revertedWith("Marketplace_InvalidClientAddress") ).to.be.revertedWith("Marketplace_InvalidClientAddress")
@ -894,7 +897,7 @@ describe("Marketplace", function () {
await marketplace.reserveSlot(slot.request, i) await marketplace.reserveSlot(slot.request, i)
await marketplace.fillSlot(slot.request, i, proof) await marketplace.fillSlot(slot.request, i, proof)
} }
await waitUntilCancelled(request) await waitUntilCancelled(marketplace, request)
switchAccount(client) switchAccount(client)
await expect( await expect(
marketplace.withdrawFunds(slot.request, clientWithdrawRecipient.address) marketplace.withdrawFunds(slot.request, clientWithdrawRecipient.address)
@ -916,7 +919,7 @@ describe("Marketplace", function () {
}) })
it("emits event once request is cancelled", async function () { it("emits event once request is cancelled", async function () {
await waitUntilCancelled(request) await waitUntilCancelled(marketplace, request)
switchAccount(client) switchAccount(client)
await expect( await expect(
marketplace.withdrawFunds(slot.request, clientWithdrawRecipient.address) marketplace.withdrawFunds(slot.request, clientWithdrawRecipient.address)
@ -956,7 +959,7 @@ describe("Marketplace", function () {
}) })
it("withdraws to the client payout address when request is cancelled", async function () { it("withdraws to the client payout address when request is cancelled", async function () {
await waitUntilCancelled(request) await waitUntilCancelled(marketplace, request)
switchAccount(client) switchAccount(client)
const startBalanceClient = await token.balanceOf(client.address) const startBalanceClient = await token.balanceOf(client.address)
const startBalancePayout = await token.balanceOf( const startBalancePayout = await token.balanceOf(
@ -1008,7 +1011,7 @@ describe("Marketplace", function () {
await marketplace.reserveSlot(slot.request, slot.index) await marketplace.reserveSlot(slot.request, slot.index)
await advanceTimeTo(filledAt) await advanceTimeTo(filledAt)
await marketplace.fillSlot(slot.request, slot.index, proof) await marketplace.fillSlot(slot.request, slot.index, proof)
await waitUntilCancelled(request) await waitUntilCancelled(marketplace, request)
const expectedPartialhostRewardRecipient = const expectedPartialhostRewardRecipient =
(expiresAt - filledAt) * pricePerSlotPerSecond(request) (expiresAt - filledAt) * pricePerSlotPerSecond(request)
@ -1063,12 +1066,12 @@ describe("Marketplace", function () {
}) })
it("changes to 'Cancelled' once request is cancelled", async function () { it("changes to 'Cancelled' once request is cancelled", async function () {
await waitUntilCancelled(request) await waitUntilCancelled(marketplace, request)
expect(await marketplace.requestState(slot.request)).to.equal(Cancelled) expect(await marketplace.requestState(slot.request)).to.equal(Cancelled)
}) })
it("remains 'Cancelled' when client withdraws funds", async function () { it("remains 'Cancelled' when client withdraws funds", async function () {
await waitUntilCancelled(request) await waitUntilCancelled(marketplace, request)
switchAccount(client) switchAccount(client)
await marketplace.withdrawFunds( await marketplace.withdrawFunds(
slot.request, slot.request,
@ -1167,7 +1170,7 @@ describe("Marketplace", function () {
it("changes to 'Cancelled' when request is cancelled", async function () { it("changes to 'Cancelled' when request is cancelled", async function () {
await marketplace.reserveSlot(slot.request, slot.index) await marketplace.reserveSlot(slot.request, slot.index)
await marketplace.fillSlot(slot.request, slot.index, proof) await marketplace.fillSlot(slot.request, slot.index, proof)
await waitUntilCancelled(request) await waitUntilCancelled(marketplace, request)
expect(await marketplace.slotState(slotId(slot))).to.equal(Cancelled) expect(await marketplace.slotState(slotId(slot))).to.equal(Cancelled)
}) })
@ -1273,7 +1276,7 @@ describe("Marketplace", function () {
await marketplace.fillSlot(slot.request, slot.index, proof) await marketplace.fillSlot(slot.request, slot.index, proof)
await waitUntilProofWillBeRequired(id) await waitUntilProofWillBeRequired(id)
await expect(await marketplace.willProofBeRequired(id)).to.be.true await expect(await marketplace.willProofBeRequired(id)).to.be.true
await waitUntilCancelled(request) await waitUntilCancelled(marketplace, request)
await expect(await marketplace.willProofBeRequired(id)).to.be.false await expect(await marketplace.willProofBeRequired(id)).to.be.false
}) })
@ -1283,7 +1286,7 @@ describe("Marketplace", function () {
await marketplace.fillSlot(slot.request, slot.index, proof) await marketplace.fillSlot(slot.request, slot.index, proof)
await waitUntilProofIsRequired(id) await waitUntilProofIsRequired(id)
await expect(await marketplace.isProofRequired(id)).to.be.true await expect(await marketplace.isProofRequired(id)).to.be.true
await waitUntilCancelled(request) await waitUntilCancelled(marketplace, request)
await expect(await marketplace.isProofRequired(id)).to.be.false await expect(await marketplace.isProofRequired(id)).to.be.false
}) })
@ -1294,7 +1297,7 @@ describe("Marketplace", function () {
await waitUntilProofIsRequired(id) await waitUntilProofIsRequired(id)
const challenge1 = await marketplace.getChallenge(id) const challenge1 = await marketplace.getChallenge(id)
expect(BigNumber.from(challenge1).gt(0)) expect(BigNumber.from(challenge1).gt(0))
await waitUntilCancelled(request) await waitUntilCancelled(marketplace, request)
const challenge2 = await marketplace.getChallenge(id) const challenge2 = await marketplace.getChallenge(id)
expect(BigNumber.from(challenge2).isZero()) expect(BigNumber.from(challenge2).isZero())
}) })
@ -1306,7 +1309,7 @@ describe("Marketplace", function () {
await waitUntilProofIsRequired(id) await waitUntilProofIsRequired(id)
const challenge1 = await marketplace.getChallenge(id) const challenge1 = await marketplace.getChallenge(id)
expect(BigNumber.from(challenge1).gt(0)) expect(BigNumber.from(challenge1).gt(0))
await waitUntilCancelled(request) await waitUntilCancelled(marketplace, request)
const challenge2 = await marketplace.getChallenge(id) const challenge2 = await marketplace.getChallenge(id)
expect(BigNumber.from(challenge2).isZero()) expect(BigNumber.from(challenge2).isZero())
}) })
@ -1342,7 +1345,7 @@ describe("Marketplace", function () {
it("fails to mark proof as missing when cancelled", async function () { it("fails to mark proof as missing when cancelled", async function () {
await marketplace.reserveSlot(slot.request, slot.index) await marketplace.reserveSlot(slot.request, slot.index)
await marketplace.fillSlot(slot.request, slot.index, proof) await marketplace.fillSlot(slot.request, slot.index, proof)
await waitUntilCancelled(request) await waitUntilCancelled(marketplace, request)
let missedPeriod = periodOf(await currentTime()) let missedPeriod = periodOf(await currentTime())
await expect( await expect(
marketplace.markProofAsMissing(slotId(slot), missedPeriod) marketplace.markProofAsMissing(slotId(slot), missedPeriod)
@ -1478,13 +1481,13 @@ describe("Marketplace", function () {
it("keeps request in list when cancelled", async function () { it("keeps request in list when cancelled", async function () {
await marketplace.requestStorage(request) await marketplace.requestStorage(request)
await waitUntilCancelled(request) await waitUntilCancelled(marketplace, request)
expect(await marketplace.myRequests()).to.deep.equal([requestId(request)]) expect(await marketplace.myRequests()).to.deep.equal([requestId(request)])
}) })
it("removes request from list when funds are withdrawn", async function () { it("removes request from list when funds are withdrawn", async function () {
await marketplace.requestStorage(request) await marketplace.requestStorage(request)
await waitUntilCancelled(request) await waitUntilCancelled(marketplace, request)
await marketplace.withdrawFunds( await marketplace.withdrawFunds(
requestId(request), requestId(request),
clientWithdrawRecipient.address clientWithdrawRecipient.address
@ -1558,7 +1561,7 @@ describe("Marketplace", function () {
await token.approve(marketplace.address, collateral) await token.approve(marketplace.address, collateral)
await marketplace.reserveSlot(slot.request, slot1.index) await marketplace.reserveSlot(slot.request, slot1.index)
await marketplace.fillSlot(slot.request, slot1.index, proof) await marketplace.fillSlot(slot.request, slot1.index, proof)
await waitUntilCancelled(request) await waitUntilCancelled(marketplace, request)
expect(await marketplace.mySlots()).to.have.members([ expect(await marketplace.mySlots()).to.have.members([
slotId(slot), slotId(slot),
slotId(slot1), slotId(slot1),
@ -1575,7 +1578,7 @@ describe("Marketplace", function () {
it("removes slot when cancelled slot is freed", async function () { it("removes slot when cancelled slot is freed", async function () {
await marketplace.reserveSlot(slot.request, slot.index) await marketplace.reserveSlot(slot.request, slot.index)
await marketplace.fillSlot(slot.request, slot.index, proof) await marketplace.fillSlot(slot.request, slot.index, proof)
await waitUntilCancelled(request) await waitUntilCancelled(marketplace, request)
await marketplace.freeSlot(slotId(slot)) await marketplace.freeSlot(slotId(slot))
expect(await marketplace.mySlots()).to.not.contain(slotId(slot)) expect(await marketplace.mySlots()).to.not.contain(slotId(slot))
}) })

View File

@ -35,10 +35,14 @@ async function advanceTime(seconds) {
} }
async function advanceTimeTo(timestamp) { async function advanceTimeTo(timestamp) {
await ethers.provider.send("evm_setNextBlockTimestamp", [timestamp]) await setNextBlockTimestamp(timestamp)
await mine() await mine()
} }
async function setNextBlockTimestamp(timestamp) {
await ethers.provider.send("evm_setNextBlockTimestamp", [timestamp])
}
module.exports = { module.exports = {
snapshot, snapshot,
revert, revert,
@ -47,4 +51,5 @@ module.exports = {
currentTime, currentTime,
advanceTime, advanceTime,
advanceTimeTo, advanceTimeTo,
setNextBlockTimestamp,
} }

View File

@ -1,18 +1,12 @@
const { advanceTimeTo, currentTime, mine } = require("./evm") const { advanceTimeTo, currentTime } = require("./evm")
const { slotId, requestId } = require("./ids") const { slotId, requestId } = require("./ids")
const { payoutForDuration } = require("./price") const { payoutForDuration } = require("./price")
const { collateralPerSlot } = require("./collateral") const { collateralPerSlot } = require("./collateral")
/** async function waitUntilCancelled(contract, request) {
* @dev This will not advance the time right on the "expiry threshold" but will most probably "overshoot it" const expiry = (await contract.requestExpiry(requestId(request))).toNumber()
* because "currentTime" most probably is not the time at which the request is created, but it is used
* in the next timestamp calculation with `now + expiry`.
* @param request
* @returns {Promise<void>}
*/
async function waitUntilCancelled(request) {
// We do +1, because the expiry check in contract is done as `>` and not `>=`. // We do +1, because the expiry check in contract is done as `>` and not `>=`.
await advanceTimeTo((await currentTime()) + request.expiry + 1) await advanceTimeTo(expiry + 1)
} }
async function waitUntilSlotsFilled(contract, request, proof, token, slots) { async function waitUntilSlotsFilled(contract, request, proof, token, slots) {