[Storage] Move isProofRequired() et al to Marketplace

This commit is contained in:
Mark Spanbroek 2023-01-09 15:15:11 +01:00 committed by markspanbroek
parent c9cf47f327
commit 31d109f0d3
4 changed files with 115 additions and 105 deletions

View File

@ -318,6 +318,31 @@ contract Marketplace is Collateral, Proofs {
}
}
function isProofRequired(SlotId slotId) public view returns (bool) {
if (!_slotAcceptsProofs(slotId)) {
return false;
}
return _isProofRequired(slotId);
}
function willProofBeRequired(SlotId slotId) public view returns (bool) {
if (!_slotAcceptsProofs(slotId)) {
return false;
}
return _willProofBeRequired(slotId);
}
function getChallenge(SlotId slotId) public view returns (bytes32) {
if (!_slotAcceptsProofs(slotId)) {
return bytes32(0);
}
return _getChallenge(slotId);
}
function getPointer(SlotId slotId) public view returns (uint8) {
return _getPointer(slotId);
}
function _price(
uint64 numSlots,
uint256 duration,

View File

@ -35,31 +35,6 @@ contract Storage is Marketplace {
minCollateralThreshold = _minCollateralThreshold;
}
function isProofRequired(SlotId slotId) public view returns (bool) {
if (!_slotAcceptsProofs(slotId)) {
return false;
}
return _isProofRequired(slotId);
}
function willProofBeRequired(SlotId slotId) public view returns (bool) {
if (!_slotAcceptsProofs(slotId)) {
return false;
}
return _willProofBeRequired(slotId);
}
function getChallenge(SlotId slotId) public view returns (bytes32) {
if (!_slotAcceptsProofs(slotId)) {
return bytes32(0);
}
return _getChallenge(slotId);
}
function getPointer(SlotId slotId) public view returns (uint8) {
return _getPointer(slotId);
}
function submitProof(SlotId slotId, bytes calldata proof) public {
_submitProof(slotId, proof);
}

View File

@ -1,9 +1,10 @@
const { ethers } = require("hardhat")
const { hexlify, randomBytes } = ethers.utils
const { AddressZero } = ethers.constants
const { BigNumber } = ethers
const { expect } = require("chai")
const { exampleRequest } = require("./examples")
const { hours, minutes } = require("./time")
const { periodic, hours, minutes } = require("./time")
const { requestId, slotId, askToArray } = require("./ids")
const {
waitUntilCancelled,
@ -17,14 +18,16 @@ const { price, pricePerSlot } = require("./price")
const {
snapshot,
revert,
mine,
ensureMinimumBlockHeight,
advanceTime,
advanceTimeTo,
currentTime,
} = require("./evm")
describe("Marketplace", function () {
const collateral = 100
const proofPeriod = 30 * 60
const proofPeriod = 10
const proofTimeout = 5
const proofDowntime = 64
const proof = hexlify(randomBytes(42))
@ -674,6 +677,81 @@ describe("Marketplace", function () {
)
})
})
describe("proof requirements", function () {
let period, periodOf, periodEnd
beforeEach(async function () {
period = (await marketplace.proofPeriod()).toNumber()
;({ periodOf, periodEnd } = periodic(period))
switchAccount(client)
await token.approve(marketplace.address, price(request))
await marketplace.requestStorage(request)
switchAccount(host)
await token.approve(marketplace.address, collateral)
await marketplace.deposit(collateral)
})
async function waitUntilProofWillBeRequired(id) {
while (!(await marketplace.willProofBeRequired(id))) {
await mine()
}
}
async function waitUntilProofIsRequired(id) {
await advanceTimeTo(periodEnd(periodOf(await currentTime())))
while (
!(
(await marketplace.isProofRequired(id)) &&
(await marketplace.getPointer(id)) < 250
)
) {
await advanceTime(period)
}
}
it("will not require proofs once cancelled", async function () {
const id = slotId(slot)
await marketplace.fillSlot(slot.request, slot.index, proof)
await waitUntilProofWillBeRequired(id)
await expect(await marketplace.willProofBeRequired(id)).to.be.true
await advanceTimeTo(request.expiry + 1)
await expect(await marketplace.willProofBeRequired(id)).to.be.false
})
it("does not require proofs once cancelled", async function () {
const id = slotId(slot)
await marketplace.fillSlot(slot.request, slot.index, proof)
await waitUntilProofIsRequired(id)
await expect(await marketplace.isProofRequired(id)).to.be.true
await advanceTimeTo(request.expiry + 1)
await expect(await marketplace.isProofRequired(id)).to.be.false
})
it("does not provide challenges once cancelled", async function () {
const id = slotId(slot)
await marketplace.fillSlot(slot.request, slot.index, proof)
await waitUntilProofIsRequired(id)
const challenge1 = await marketplace.getChallenge(id)
expect(BigNumber.from(challenge1).gt(0))
await advanceTimeTo(request.expiry + 1)
const challenge2 = await marketplace.getChallenge(id)
expect(BigNumber.from(challenge2).isZero())
})
it("does not provide pointer once cancelled", async function () {
const id = slotId(slot)
await marketplace.fillSlot(slot.request, slot.index, proof)
await waitUntilProofIsRequired(id)
const challenge1 = await marketplace.getChallenge(id)
expect(BigNumber.from(challenge1).gt(0))
await advanceTimeTo(request.expiry + 1)
const challenge2 = await marketplace.getChallenge(id)
expect(BigNumber.from(challenge2).isZero())
})
})
describe("modifiers", function () {
beforeEach(async function () {
switchAccount(client)

View File

@ -1,10 +1,9 @@
const { expect } = require("chai")
const { ethers, deployments } = require("hardhat")
const { BigNumber } = ethers
const { hexlify, randomBytes } = ethers.utils
const { AddressZero } = ethers.constants
const { exampleRequest } = require("./examples")
const { advanceTime, advanceTimeTo, currentTime, mine } = require("./evm")
const { advanceTime, advanceTimeTo, currentTime } = require("./evm")
const { requestId, slotId } = require("./ids")
const { periodic } = require("./time")
const { price } = require("./price")
@ -88,6 +87,15 @@ describe("Storage", function () {
}
}
it("fails to mark proof as missing when cancelled", async function () {
await storage.fillSlot(slot.request, slot.index, proof)
await waitUntilCancelled(request)
let missedPeriod = periodOf(await currentTime())
await expect(
storage.markProofAsMissing(slotId(slot), missedPeriod)
).to.be.revertedWith("Slot not accepting proofs")
})
describe("slashing when missing proofs", function () {
it("reduces collateral when too many proofs are missing", async function () {
const id = slotId(slot)
@ -130,82 +138,6 @@ describe("Storage", function () {
})
})
})
describe("contract state", function () {
let period, periodOf, periodEnd
beforeEach(async function () {
period = (await storage.proofPeriod()).toNumber()
;({ periodOf, periodEnd } = periodic(period))
})
async function waitUntilProofWillBeRequired(id) {
while (!(await storage.willProofBeRequired(id))) {
await mine()
}
}
async function waitUntilProofIsRequired(id) {
await advanceTimeTo(periodEnd(periodOf(await currentTime())))
while (
!(
(await storage.isProofRequired(id)) &&
(await storage.getPointer(id)) < 250
)
) {
await advanceTime(period)
}
}
it("fails to mark proof as missing when cancelled", async function () {
await storage.fillSlot(slot.request, slot.index, proof)
await waitUntilCancelled(request)
let missedPeriod = periodOf(await currentTime())
await expect(
storage.markProofAsMissing(slotId(slot), missedPeriod)
).to.be.revertedWith("Slot not accepting proofs")
})
it("will not require proofs once cancelled", async function () {
const id = slotId(slot)
await storage.fillSlot(slot.request, slot.index, proof)
await waitUntilProofWillBeRequired(id)
await expect(await storage.willProofBeRequired(id)).to.be.true
await advanceTimeTo(request.expiry + 1)
await expect(await storage.willProofBeRequired(id)).to.be.false
})
it("does not require proofs once cancelled", async function () {
const id = slotId(slot)
await storage.fillSlot(slot.request, slot.index, proof)
await waitUntilProofIsRequired(id)
await expect(await storage.isProofRequired(id)).to.be.true
await advanceTimeTo(request.expiry + 1)
await expect(await storage.isProofRequired(id)).to.be.false
})
it("does not provide challenges once cancelled", async function () {
const id = slotId(slot)
await storage.fillSlot(slot.request, slot.index, proof)
await waitUntilProofIsRequired(id)
const challenge1 = await storage.getChallenge(id)
expect(BigNumber.from(challenge1).gt(0))
await advanceTimeTo(request.expiry + 1)
const challenge2 = await storage.getChallenge(id)
expect(BigNumber.from(challenge2).isZero())
})
it("does not provide pointer once cancelled", async function () {
const id = slotId(slot)
await storage.fillSlot(slot.request, slot.index, proof)
await waitUntilProofIsRequired(id)
const challenge1 = await storage.getChallenge(id)
expect(BigNumber.from(challenge1).gt(0))
await advanceTimeTo(request.expiry + 1)
const challenge2 = await storage.getChallenge(id)
expect(BigNumber.from(challenge2).isZero())
})
})
})
// TODO: implement checking of actual proofs of storage, instead of dummy bool