Allow anyone to mark missing proofs

This commit is contained in:
Mark Spanbroek 2021-10-19 09:37:03 +02:00
parent 973b70734f
commit 4913edb6ce
2 changed files with 59 additions and 8 deletions

View File

@ -14,6 +14,7 @@ contract StorageContract {
uint public immutable proofMarker; // indicates when a proof is required uint public immutable proofMarker; // indicates when a proof is required
mapping(uint => bool) proofReceived; // whether proof for a block was received mapping(uint => bool) proofReceived; // whether proof for a block was received
uint public missingProofs;
constructor(uint _duration, constructor(uint _duration,
uint _size, uint _size,
@ -111,14 +112,22 @@ contract StorageContract {
return hash != 0 && uint(hash) % proofPeriod == proofMarker; return hash != 0 && uint(hash) % proofPeriod == proofMarker;
} }
function isProofTimedOut(uint blocknumber) internal view returns (bool) {
return block.number >= blocknumber + proofTimeout;
}
function submitProof(uint blocknumber, bool proof) public { function submitProof(uint blocknumber, bool proof) public {
require(proof, "Invalid proof"); // TODO: replace bool by actual proof require(proof, "Invalid proof"); // TODO: replace bool by actual proof
require(isProofRequired(blocknumber), "No proof required for this block"); require(isProofRequired(blocknumber), "No proof required for this block");
require( require(!isProofTimedOut(blocknumber), "Proof not allowed after timeout");
block.number < blocknumber + proofTimeout,
"Proof not allowed after timeout"
);
require(!proofReceived[blocknumber], "Proof already submitted"); require(!proofReceived[blocknumber], "Proof already submitted");
proofReceived[blocknumber] = true; proofReceived[blocknumber] = true;
} }
function markProofAsMissing(uint blocknumber) public {
require(isProofTimedOut(blocknumber), "Proof has not timed out yet");
require(!proofReceived[blocknumber], "Proof was submitted, not missing");
require(isProofRequired(blocknumber), "Proof was not required");
missingProofs += 1;
}
} }

View File

@ -174,6 +174,12 @@ describe("Storage Contract", function () {
} }
} }
async function mineUntilProofTimeout() {
for (let i=0; i<proofTimeout; i++) {
mineBlock()
}
}
beforeEach(async function () { beforeEach(async function () {
contract = await StorageContract.deploy( contract = await StorageContract.deploy(
duration, duration,
@ -238,9 +244,7 @@ describe("Storage Contract", function () {
it("fails proof submission when proof is too late", async function () { it("fails proof submission when proof is too late", async function () {
await mineUntilProofIsRequired() await mineUntilProofIsRequired()
let blocknumber = await minedBlockNumber() let blocknumber = await minedBlockNumber()
for (let i=0; i<proofTimeout; i++) { await mineUntilProofTimeout()
mineBlock()
}
await expect( await expect(
contract.submitProof(blocknumber, true) contract.submitProof(blocknumber, true)
).to.be.revertedWith("Proof not allowed after timeout") ).to.be.revertedWith("Proof not allowed after timeout")
@ -254,13 +258,51 @@ describe("Storage Contract", function () {
contract.submitProof(blocknumber, true) contract.submitProof(blocknumber, true)
).to.be.revertedWith("Proof already submitted") ).to.be.revertedWith("Proof already submitted")
}) })
it("marks a proof as missing", async function () {
expect(await contract.missingProofs()).to.equal(0)
await mineUntilProofIsRequired()
let blocknumber = await minedBlockNumber()
await mineUntilProofTimeout()
await contract.markProofAsMissing(blocknumber)
expect(await contract.missingProofs()).to.equal(1)
})
it("does not mark a proof as missing before timeout", async function () {
await mineUntilProofIsRequired()
let blocknumber = await minedBlockNumber()
await mineBlock()
await expect(
contract.markProofAsMissing(blocknumber)
).to.be.revertedWith("Proof has not timed out yet")
})
it("does not mark a submitted proof as missing", async function () {
await mineUntilProofIsRequired()
let blocknumber = await minedBlockNumber()
await contract.submitProof(blocknumber, true)
await mineUntilProofTimeout()
await expect(
contract.markProofAsMissing(blocknumber)
).to.be.revertedWith("Proof was submitted, not missing")
})
it("does not mark proof as missing when not required", async function () {
while (await contract.isProofRequired(await minedBlockNumber())) {
mineBlock()
}
let blocknumber = await minedBlockNumber()
await mineUntilProofTimeout()
await expect(
contract.markProofAsMissing(blocknumber)
).to.be.revertedWith("Proof was not required")
})
}) })
}) })
// TODO: implement checking of actual proofs of storage, instead of dummy bool // TODO: implement checking of actual proofs of storage, instead of dummy bool
// TODO: payment on constructor // TODO: payment on constructor
// TODO: contract start and timeout // TODO: contract start and timeout
// TODO: missed proofs
// TODO: only allow proofs after start of contract // TODO: only allow proofs after start of contract
// TODO: payout // TODO: payout
// TODO: stake // TODO: stake