From 2784800c3e22cb5af6fceb06464552a87c4788e9 Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Wed, 3 Nov 2021 13:24:50 +0100 Subject: [PATCH] Add end time to proofs based on contract duration --- contracts/Proofs.sol | 13 ++++++++++++- contracts/Storage.sol | 2 +- contracts/TestProofs.sol | 13 +++++++++++-- test/Proofs.test.js | 34 +++++++++++++++++++++------------- 4 files changed, 45 insertions(+), 17 deletions(-) diff --git a/contracts/Proofs.sol b/contracts/Proofs.sol index e856c50..6562418 100644 --- a/contracts/Proofs.sol +++ b/contracts/Proofs.sol @@ -6,6 +6,7 @@ contract Proofs { mapping(bytes32=>bool) private ids; mapping(bytes32=>uint) private periods; mapping(bytes32=>uint) private timeouts; + mapping(bytes32=>uint) private ends; mapping(bytes32=>uint) private markers; mapping(bytes32=>uint) private missed; mapping(bytes32=>mapping(uint=>bool)) private received; @@ -19,6 +20,10 @@ contract Proofs { return timeouts[id]; } + function _end(bytes32 id) internal view returns (uint) { + return ends[id]; + } + function _missed(bytes32 id) internal view returns (uint) { return missed[id]; } @@ -30,12 +35,18 @@ contract Proofs { require(timeout <= 128, "Invalid proof timeout, needs to be <= 128"); } - function _expectProofs(bytes32 id, uint period, uint timeout) internal { + function _expectProofs( + bytes32 id, + uint period, + uint timeout, + uint duration + ) internal { require(!ids[id], "Proof id already in use"); _checkTimeout(timeout); ids[id] = true; periods[id] = period; timeouts[id] = timeout; + ends[id] = block.number + duration + 2 * timeout; markers[id] = uint(blockhash(block.number - 1)) % period; } diff --git a/contracts/Storage.sol b/contracts/Storage.sol index e5bc2b4..1b42779 100644 --- a/contracts/Storage.sol +++ b/contracts/Storage.sol @@ -43,7 +43,7 @@ contract Storage is Contracts, Proofs, Stakes { requestSignature, bidSignature ); - _expectProofs(id, _proofPeriod, _proofTimeout); + _expectProofs(id, _proofPeriod, _proofTimeout, _duration); } function duration(bytes32 contractId) public view returns (uint) { diff --git a/contracts/TestProofs.sol b/contracts/TestProofs.sol index 07b33dd..125b057 100644 --- a/contracts/TestProofs.sol +++ b/contracts/TestProofs.sol @@ -14,12 +14,21 @@ contract TestProofs is Proofs { return _timeout(id); } + function end(bytes32 id) public view returns (uint) { + return _end(id); + } + function missed(bytes32 id) public view returns (uint) { return _missed(id); } - function expectProofs(bytes32 id, uint _period, uint _timeout) public { - _expectProofs(id, _period, _timeout); + function expectProofs( + bytes32 id, + uint _period, + uint _timeout, + uint _duration + ) public { + _expectProofs(id, _period, _timeout, _duration); } function isProofRequired( diff --git a/test/Proofs.test.js b/test/Proofs.test.js index 1dcd350..d507e7f 100644 --- a/test/Proofs.test.js +++ b/test/Proofs.test.js @@ -6,6 +6,7 @@ describe("Proofs", function () { const id = ethers.utils.randomBytes(32) const period = 10 const timeout = 5 + const duration = 100 let proofs @@ -14,40 +15,47 @@ describe("Proofs", function () { proofs = await Proofs.deploy() }) + async function mineBlock() { + await ethers.provider.send("evm_mine") + } + + async function minedBlockNumber() { + return await ethers.provider.getBlockNumber() + } + it("indicates that proofs are required", async function() { - await proofs.expectProofs(id, period, timeout) + await proofs.expectProofs(id, period, timeout, duration) expect(await proofs.period(id)).to.equal(period) expect(await proofs.timeout(id)).to.equal(timeout) }) + it("calculates an endtime based on duration and timeout", async function() { + await proofs.expectProofs(id, period, timeout, duration) + let start = await minedBlockNumber() + let end = start + duration + 2 * timeout + expect(await proofs.end(id)).to.equal(end) + }) + it("does not allow ids to be reused", async function() { - await proofs.expectProofs(id, period, timeout) + await proofs.expectProofs(id, period, timeout, duration) await expect( - proofs.expectProofs(id, period, timeout) + proofs.expectProofs(id, period, timeout, duration) ).to.be.revertedWith("Proof id already in use") }) it("does not allow a proof timeout that is too large", async function () { let invalidTimeout = 129 // max proof timeout is 128 blocks await expect( - proofs.expectProofs(id, period, invalidTimeout) + proofs.expectProofs(id, period, invalidTimeout, duration) ).to.be.revertedWith("Invalid proof timeout") }) describe("when proofs are required", async function () { beforeEach(async function () { - await proofs.expectProofs(id, period, timeout) + await proofs.expectProofs(id, period, timeout, duration) }) - async function mineBlock() { - await ethers.provider.send("evm_mine") - } - - async function minedBlockNumber() { - return await ethers.provider.getBlockNumber() - } - async function mineUntilProofIsRequired(id) { while (!await proofs.isProofRequired(id, await minedBlockNumber())) { mineBlock()