mirror of
https://github.com/logos-storage/logos-storage-contracts-eth.git
synced 2026-01-08 00:03:07 +00:00
[Proofs] Remove ProofId and EndId, use SlotId and RequestId
Rationale: in practice, a ProofId was always a slot id, and an EndId was always a request id. Now that the definitons of SlotId and RequestId are separated from the Marketplace, we can import and use them.
This commit is contained in:
parent
27ccb1e2bc
commit
d5d99515fc
@ -62,7 +62,7 @@ contract Marketplace is Collateral, Proofs {
|
||||
RequestContext storage context = _context(id);
|
||||
// set contract end time to `duration` from now (time request was created)
|
||||
context.endsAt = block.timestamp + request.ask.duration;
|
||||
_setProofEnd(_toEndId(id), context.endsAt);
|
||||
_setProofEnd(id, context.endsAt);
|
||||
|
||||
requestsPerClient[request.client].add(RequestId.unwrap(id));
|
||||
|
||||
@ -88,9 +88,8 @@ contract Marketplace is Collateral, Proofs {
|
||||
|
||||
require(balanceOf(msg.sender) >= collateral, "Insufficient collateral");
|
||||
|
||||
ProofId proofId = _toProofId(slotId);
|
||||
_expectProofs(proofId, _toEndId(requestId), request.ask.proofProbability);
|
||||
_submitProof(proofId, proof);
|
||||
_expectProofs(slotId, requestId, request.ask.proofProbability);
|
||||
_submitProof(slotId, proof);
|
||||
|
||||
slot.host = msg.sender;
|
||||
slot.requestId = requestId;
|
||||
@ -135,7 +134,7 @@ contract Marketplace is Collateral, Proofs {
|
||||
// Slot collateral is not yet implemented as the design decision was
|
||||
// not finalised.
|
||||
|
||||
_unexpectProofs(_toProofId(slotId));
|
||||
_unexpectProofs(slotId);
|
||||
|
||||
slotsPerHost[slot.host].remove(SlotId.unwrap(slotId));
|
||||
|
||||
@ -151,7 +150,7 @@ contract Marketplace is Collateral, Proofs {
|
||||
context.state == RequestState.Started
|
||||
) {
|
||||
context.state = RequestState.Failed;
|
||||
_setProofEnd(_toEndId(requestId), block.timestamp - 1);
|
||||
_setProofEnd(requestId, block.timestamp - 1);
|
||||
context.endsAt = block.timestamp - 1;
|
||||
emit RequestFailed(requestId);
|
||||
|
||||
@ -311,7 +310,7 @@ contract Marketplace is Collateral, Proofs {
|
||||
}
|
||||
|
||||
function requestEnd(RequestId requestId) public view returns (uint256) {
|
||||
uint256 end = _end(_toEndId(requestId));
|
||||
uint256 end = _end(requestId);
|
||||
if (_requestAcceptsProofs(requestId)) {
|
||||
return end;
|
||||
} else {
|
||||
@ -419,14 +418,6 @@ contract Marketplace is Collateral, Proofs {
|
||||
return SlotId.wrap(keccak256(abi.encode(requestId, slotIndex)));
|
||||
}
|
||||
|
||||
function _toProofId(SlotId slotId) internal pure returns (ProofId) {
|
||||
return ProofId.wrap(SlotId.unwrap(slotId));
|
||||
}
|
||||
|
||||
function _toEndId(RequestId requestId) internal pure returns (EndId) {
|
||||
return EndId.wrap(RequestId.unwrap(requestId));
|
||||
}
|
||||
|
||||
function _notEqual(RequestId a, uint256 b) internal pure returns (bool) {
|
||||
return RequestId.unwrap(a) != bytes32(b);
|
||||
}
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.8;
|
||||
|
||||
contract Proofs {
|
||||
type ProofId is bytes32;
|
||||
type EndId is bytes32;
|
||||
import "./Requests.sol";
|
||||
|
||||
contract Proofs {
|
||||
uint256 private immutable period;
|
||||
uint256 private immutable timeout;
|
||||
uint8 private immutable downtime;
|
||||
@ -20,15 +19,15 @@ contract Proofs {
|
||||
downtime = __downtime;
|
||||
}
|
||||
|
||||
mapping(ProofId => bool) private ids;
|
||||
mapping(ProofId => uint256) private starts;
|
||||
mapping(EndId => uint256) private ends;
|
||||
mapping(ProofId => EndId) private idEnds;
|
||||
mapping(ProofId => uint256) private probabilities;
|
||||
mapping(ProofId => uint256) private markers;
|
||||
mapping(ProofId => uint256) private missed;
|
||||
mapping(ProofId => mapping(uint256 => bool)) private received;
|
||||
mapping(ProofId => mapping(uint256 => bool)) private missing;
|
||||
mapping(SlotId => bool) private ids;
|
||||
mapping(SlotId => uint256) private starts;
|
||||
mapping(RequestId => uint256) private ends;
|
||||
mapping(SlotId => RequestId) private requestIds;
|
||||
mapping(SlotId => uint256) private probabilities;
|
||||
mapping(SlotId => uint256) private markers;
|
||||
mapping(SlotId => uint256) private missed;
|
||||
mapping(SlotId => mapping(uint256 => bool)) private received;
|
||||
mapping(SlotId => mapping(uint256 => bool)) private missing;
|
||||
|
||||
function _period() internal view returns (uint256) {
|
||||
return period;
|
||||
@ -38,24 +37,23 @@ contract Proofs {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
function _end(EndId endId) internal view returns (uint256) {
|
||||
uint256 end = ends[endId];
|
||||
function _end(RequestId request) internal view returns (uint256) {
|
||||
uint256 end = ends[request];
|
||||
require(end > 0, "Proof ending doesn't exist");
|
||||
return ends[endId];
|
||||
return end;
|
||||
}
|
||||
|
||||
function _endId(ProofId id) internal view returns (EndId) {
|
||||
EndId endId = idEnds[id];
|
||||
require(EndId.unwrap(endId) > 0, "endId for given id doesn't exist");
|
||||
return endId;
|
||||
function _requestId(SlotId id) internal view returns (RequestId) {
|
||||
RequestId requestId = requestIds[id];
|
||||
require(RequestId.unwrap(requestId) > 0, "request for slot doesn't exist");
|
||||
return requestId;
|
||||
}
|
||||
|
||||
function _endFromId(ProofId id) internal view returns (uint256) {
|
||||
EndId endId = _endId(id);
|
||||
return _end(endId);
|
||||
function _end(SlotId id) internal view returns (uint256) {
|
||||
return _end(_requestId(id));
|
||||
}
|
||||
|
||||
function _missed(ProofId id) internal view returns (uint256) {
|
||||
function _missed(SlotId id) internal view returns (uint256) {
|
||||
return missed[id];
|
||||
}
|
||||
|
||||
@ -70,41 +68,38 @@ contract Proofs {
|
||||
/// @notice Informs the contract that proofs should be expected for id
|
||||
/// @dev Requires that the id is not already in use
|
||||
/// @param id identifies the proof expectation, typically a slot id
|
||||
/// @param endId Identifies the id of the proof expectation ending. Typically a request id. Different from id because the proof ending is shared amongst many ids.
|
||||
/// @param probability The probability that a proof should be expected
|
||||
function _expectProofs(
|
||||
ProofId id, // typically slot id
|
||||
EndId endId, // typically request id, used so that the ending is global for all slots
|
||||
SlotId id, // typically slot id
|
||||
RequestId request, // typically request id, used so that the ending is global for all slots
|
||||
uint256 probability
|
||||
) internal {
|
||||
require(!ids[id], "Proof id already in use");
|
||||
require(!ids[id], "Slot id already in use");
|
||||
ids[id] = true;
|
||||
starts[id] = block.timestamp;
|
||||
probabilities[id] = probability;
|
||||
markers[id] = uint256(blockhash(block.number - 1)) % period;
|
||||
idEnds[id] = endId;
|
||||
requestIds[id] = request;
|
||||
}
|
||||
|
||||
function _unexpectProofs(
|
||||
ProofId id
|
||||
) internal {
|
||||
function _unexpectProofs(SlotId id) internal {
|
||||
require(ids[id], "Proof id not in use");
|
||||
ids[id] = false;
|
||||
}
|
||||
|
||||
function _getPointer(ProofId id, uint256 proofPeriod)
|
||||
function _getPointer(SlotId id, uint256 proofPeriod)
|
||||
internal
|
||||
view
|
||||
returns (uint8)
|
||||
{
|
||||
uint256 blockNumber = block.number % 256;
|
||||
uint256 periodNumber = proofPeriod % 256;
|
||||
uint256 idOffset = uint256(ProofId.unwrap(id)) % 256;
|
||||
uint256 idOffset = uint256(SlotId.unwrap(id)) % 256;
|
||||
uint256 pointer = (blockNumber + periodNumber + idOffset) % 256;
|
||||
return uint8(pointer);
|
||||
}
|
||||
|
||||
function _getPointer(ProofId id) internal view returns (uint8) {
|
||||
function _getPointer(SlotId id) internal view returns (uint8) {
|
||||
return _getPointer(id, currentPeriod());
|
||||
}
|
||||
|
||||
@ -114,7 +109,7 @@ contract Proofs {
|
||||
return keccak256(abi.encode(hash));
|
||||
}
|
||||
|
||||
function _getChallenge(ProofId id, uint256 proofPeriod)
|
||||
function _getChallenge(SlotId id, uint256 proofPeriod)
|
||||
internal
|
||||
view
|
||||
returns (bytes32)
|
||||
@ -122,11 +117,11 @@ contract Proofs {
|
||||
return _getChallenge(_getPointer(id, proofPeriod));
|
||||
}
|
||||
|
||||
function _getChallenge(ProofId id) internal view returns (bytes32) {
|
||||
function _getChallenge(SlotId id) internal view returns (bytes32) {
|
||||
return _getChallenge(id, currentPeriod());
|
||||
}
|
||||
|
||||
function _getProofRequirement(ProofId id, uint256 proofPeriod)
|
||||
function _getProofRequirement(SlotId id, uint256 proofPeriod)
|
||||
internal
|
||||
view
|
||||
returns (bool isRequired, uint8 pointer)
|
||||
@ -134,7 +129,7 @@ contract Proofs {
|
||||
if (proofPeriod <= periodOf(starts[id])) {
|
||||
return (false, 0);
|
||||
}
|
||||
uint256 end = _endFromId(id);
|
||||
uint256 end = _end(id);
|
||||
if (proofPeriod >= periodOf(end)) {
|
||||
return (false, 0);
|
||||
}
|
||||
@ -144,7 +139,7 @@ contract Proofs {
|
||||
isRequired = ids[id] && uint256(challenge) % probability == 0;
|
||||
}
|
||||
|
||||
function _isProofRequired(ProofId id, uint256 proofPeriod)
|
||||
function _isProofRequired(SlotId id, uint256 proofPeriod)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
@ -155,25 +150,25 @@ contract Proofs {
|
||||
return isRequired && pointer >= downtime;
|
||||
}
|
||||
|
||||
function _isProofRequired(ProofId id) internal view returns (bool) {
|
||||
function _isProofRequired(SlotId id) internal view returns (bool) {
|
||||
return _isProofRequired(id, currentPeriod());
|
||||
}
|
||||
|
||||
function _willProofBeRequired(ProofId id) internal view returns (bool) {
|
||||
function _willProofBeRequired(SlotId id) internal view returns (bool) {
|
||||
bool isRequired;
|
||||
uint8 pointer;
|
||||
(isRequired, pointer) = _getProofRequirement(id, currentPeriod());
|
||||
return isRequired && pointer < downtime;
|
||||
}
|
||||
|
||||
function _submitProof(ProofId id, bytes calldata proof) internal {
|
||||
function _submitProof(SlotId id, bytes calldata proof) internal {
|
||||
require(proof.length > 0, "Invalid proof"); // TODO: replace by actual check
|
||||
require(!received[id][currentPeriod()], "Proof already submitted");
|
||||
received[id][currentPeriod()] = true;
|
||||
emit ProofSubmitted(id, proof);
|
||||
}
|
||||
|
||||
function _markProofAsMissing(ProofId id, uint256 missedPeriod) internal {
|
||||
function _markProofAsMissing(SlotId id, uint256 missedPeriod) internal {
|
||||
uint256 periodEnd = (missedPeriod + 1) * period;
|
||||
require(periodEnd < block.timestamp, "Period has not ended yet");
|
||||
require(block.timestamp < periodEnd + timeout, "Validation timed out");
|
||||
@ -186,14 +181,14 @@ contract Proofs {
|
||||
|
||||
/// @notice Sets the proof end time
|
||||
/// @dev Can only be set once
|
||||
/// @param endId the endId of the proofs to extend (typically a request id).
|
||||
/// @param ending the new end time (in seconds)
|
||||
function _setProofEnd(EndId endId, uint256 ending) internal {
|
||||
// TODO: create type aliases for id and endId so that _end() can return
|
||||
// EndId storage and we don't need to replicate the below require here
|
||||
require (ends[endId] == 0 || ending < block.timestamp, "End exists or must be past");
|
||||
ends[endId] = ending;
|
||||
function _setProofEnd(RequestId request, uint256 ending) internal {
|
||||
require(
|
||||
ends[request] == 0 || ending < block.timestamp,
|
||||
"End exists or must be past"
|
||||
);
|
||||
ends[request] = ending;
|
||||
}
|
||||
|
||||
event ProofSubmitted(ProofId id, bytes proof);
|
||||
event ProofSubmitted(SlotId id, bytes proof);
|
||||
}
|
||||
|
||||
@ -36,46 +36,45 @@ contract Storage is Marketplace {
|
||||
}
|
||||
|
||||
function missingProofs(SlotId slotId) public view returns (uint256) {
|
||||
return _missed(_toProofId(slotId));
|
||||
return _missed(slotId);
|
||||
}
|
||||
|
||||
function isProofRequired(SlotId slotId) public view returns (bool) {
|
||||
if (!_slotAcceptsProofs(slotId)) {
|
||||
return false;
|
||||
}
|
||||
return _isProofRequired(_toProofId(slotId));
|
||||
return _isProofRequired(slotId);
|
||||
}
|
||||
|
||||
function willProofBeRequired(SlotId slotId) public view returns (bool) {
|
||||
if (!_slotAcceptsProofs(slotId)) {
|
||||
return false;
|
||||
}
|
||||
return _willProofBeRequired(_toProofId(slotId));
|
||||
return _willProofBeRequired(slotId);
|
||||
}
|
||||
|
||||
function getChallenge(SlotId slotId) public view returns (bytes32) {
|
||||
if (!_slotAcceptsProofs(slotId)) {
|
||||
return bytes32(0);
|
||||
}
|
||||
return _getChallenge(_toProofId(slotId));
|
||||
return _getChallenge(slotId);
|
||||
}
|
||||
|
||||
function getPointer(SlotId slotId) public view returns (uint8) {
|
||||
return _getPointer(_toProofId(slotId));
|
||||
return _getPointer(slotId);
|
||||
}
|
||||
|
||||
function submitProof(SlotId slotId, bytes calldata proof) public {
|
||||
_submitProof(_toProofId(slotId), proof);
|
||||
_submitProof(slotId, proof);
|
||||
}
|
||||
|
||||
function markProofAsMissing(SlotId slotId, uint256 period)
|
||||
public
|
||||
slotMustAcceptProofs(slotId)
|
||||
{
|
||||
ProofId proofId = _toProofId(slotId);
|
||||
_markProofAsMissing(proofId, period);
|
||||
_markProofAsMissing(slotId, period);
|
||||
address host = _host(slotId);
|
||||
if (_missed(_toProofId(slotId)) % slashMisses == 0) {
|
||||
if (_missed(slotId) % slashMisses == 0) {
|
||||
_slash(host, slashPercentage);
|
||||
|
||||
if (balanceOf(host) < minCollateralThreshold) {
|
||||
|
||||
@ -24,51 +24,51 @@ contract TestProofs is Proofs {
|
||||
return _timeout();
|
||||
}
|
||||
|
||||
function end(EndId id) public view returns (uint256) {
|
||||
function end(RequestId id) public view returns (uint256) {
|
||||
return _end(id);
|
||||
}
|
||||
|
||||
function missed(ProofId id) public view returns (uint256) {
|
||||
function missed(SlotId id) public view returns (uint256) {
|
||||
return _missed(id);
|
||||
}
|
||||
|
||||
function expectProofs(
|
||||
ProofId id,
|
||||
EndId endId,
|
||||
SlotId slot,
|
||||
RequestId request,
|
||||
uint256 _probability
|
||||
) public {
|
||||
_expectProofs(id, endId, _probability);
|
||||
_expectProofs(slot, request, _probability);
|
||||
}
|
||||
|
||||
function unexpectProofs(ProofId id) public {
|
||||
function unexpectProofs(SlotId id) public {
|
||||
_unexpectProofs(id);
|
||||
}
|
||||
|
||||
function isProofRequired(ProofId id) public view returns (bool) {
|
||||
function isProofRequired(SlotId id) public view returns (bool) {
|
||||
return _isProofRequired(id);
|
||||
}
|
||||
|
||||
function willProofBeRequired(ProofId id) public view returns (bool) {
|
||||
function willProofBeRequired(SlotId id) public view returns (bool) {
|
||||
return _willProofBeRequired(id);
|
||||
}
|
||||
|
||||
function getChallenge(ProofId id) public view returns (bytes32) {
|
||||
function getChallenge(SlotId id) public view returns (bytes32) {
|
||||
return _getChallenge(id);
|
||||
}
|
||||
|
||||
function getPointer(ProofId id) public view returns (uint8) {
|
||||
function getPointer(SlotId id) public view returns (uint8) {
|
||||
return _getPointer(id);
|
||||
}
|
||||
|
||||
function submitProof(ProofId id, bytes calldata proof) public {
|
||||
function submitProof(SlotId id, bytes calldata proof) public {
|
||||
_submitProof(id, proof);
|
||||
}
|
||||
|
||||
function markProofAsMissing(ProofId id, uint256 _period) public {
|
||||
function markProofAsMissing(SlotId id, uint256 _period) public {
|
||||
_markProofAsMissing(id, _period);
|
||||
}
|
||||
|
||||
function setProofEnd(EndId id, uint256 ending) public {
|
||||
function setProofEnd(RequestId id, uint256 ending) public {
|
||||
_setProofEnd(id, ending);
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,8 +13,8 @@ const {
|
||||
const { periodic, hours, minutes } = require("./time")
|
||||
|
||||
describe("Proofs", function () {
|
||||
const id = hexlify(randomBytes(32))
|
||||
const endId = hexlify(randomBytes(32))
|
||||
const slotId = hexlify(randomBytes(32))
|
||||
const requestId = hexlify(randomBytes(32))
|
||||
const period = 30 * 60
|
||||
const timeout = 5
|
||||
const downtime = 64
|
||||
@ -37,21 +37,21 @@ describe("Proofs", function () {
|
||||
|
||||
describe("general", function () {
|
||||
beforeEach(async function () {
|
||||
await proofs.setProofEnd(endId, (await currentTime()) + duration)
|
||||
await proofs.setProofEnd(requestId, (await currentTime()) + duration)
|
||||
})
|
||||
|
||||
it("does not allow ids to be reused", async function () {
|
||||
await proofs.expectProofs(id, endId, probability)
|
||||
await proofs.expectProofs(slotId, requestId, probability)
|
||||
await expect(
|
||||
proofs.expectProofs(id, endId, probability)
|
||||
).to.be.revertedWith("Proof id already in use")
|
||||
proofs.expectProofs(slotId, requestId, probability)
|
||||
).to.be.revertedWith("Slot id already in use")
|
||||
})
|
||||
|
||||
it("requires proofs with an agreed upon probability", async function () {
|
||||
await proofs.expectProofs(id, endId, probability)
|
||||
await proofs.expectProofs(slotId, requestId, probability)
|
||||
let amount = 0
|
||||
for (let i = 0; i < 100; i++) {
|
||||
if (await proofs.isProofRequired(id)) {
|
||||
if (await proofs.isProofRequired(slotId)) {
|
||||
amount += 1
|
||||
}
|
||||
await advanceTime(period)
|
||||
@ -63,33 +63,33 @@ describe("Proofs", function () {
|
||||
it("requires no proofs in the start period", async function () {
|
||||
const startPeriod = Math.floor((await currentTime()) / period)
|
||||
const probability = 1
|
||||
await proofs.expectProofs(id, endId, probability)
|
||||
await proofs.expectProofs(slotId, requestId, probability)
|
||||
while (Math.floor((await currentTime()) / period) == startPeriod) {
|
||||
expect(await proofs.isProofRequired(id)).to.be.false
|
||||
expect(await proofs.isProofRequired(slotId)).to.be.false
|
||||
await advanceTime(Math.floor(period / 10))
|
||||
}
|
||||
})
|
||||
|
||||
it("requires no proofs in the end period", async function () {
|
||||
const probability = 1
|
||||
await proofs.expectProofs(id, endId, probability)
|
||||
await proofs.expectProofs(slotId, requestId, probability)
|
||||
await advanceTime(duration)
|
||||
expect(await proofs.isProofRequired(id)).to.be.false
|
||||
expect(await proofs.isProofRequired(slotId)).to.be.false
|
||||
})
|
||||
|
||||
it("requires no proofs after the end time", async function () {
|
||||
const probability = 1
|
||||
await proofs.expectProofs(id, endId, probability)
|
||||
await proofs.expectProofs(slotId, requestId, probability)
|
||||
await advanceTime(duration + timeout)
|
||||
expect(await proofs.isProofRequired(id)).to.be.false
|
||||
expect(await proofs.isProofRequired(slotId)).to.be.false
|
||||
})
|
||||
|
||||
it("requires proofs for different ids at different times", async function () {
|
||||
let id1 = hexlify(randomBytes(32))
|
||||
let id2 = hexlify(randomBytes(32))
|
||||
let id3 = hexlify(randomBytes(32))
|
||||
for (let id of [id1, id2, id3]) {
|
||||
await proofs.expectProofs(id, endId, probability)
|
||||
for (let slotId of [id1, id2, id3]) {
|
||||
await proofs.expectProofs(slotId, requestId, probability)
|
||||
}
|
||||
let req1, req2, req3
|
||||
while (req1 === req2 && req2 === req3) {
|
||||
@ -103,9 +103,9 @@ describe("Proofs", function () {
|
||||
it("moves pointer one block at a time", async function () {
|
||||
await advanceTimeTo(periodEnd(periodOf(await currentTime())))
|
||||
for (let i = 0; i < 256; i++) {
|
||||
let previous = await proofs.getPointer(id)
|
||||
let previous = await proofs.getPointer(slotId)
|
||||
await mine()
|
||||
let current = await proofs.getPointer(id)
|
||||
let current = await proofs.getPointer(slotId)
|
||||
expect(current).to.equal((previous + 1) % 256)
|
||||
}
|
||||
})
|
||||
@ -113,39 +113,39 @@ describe("Proofs", function () {
|
||||
|
||||
describe("when proof requirement is upcoming", function () {
|
||||
async function waitUntilProofWillBeRequired() {
|
||||
while (!(await proofs.willProofBeRequired(id))) {
|
||||
while (!(await proofs.willProofBeRequired(slotId))) {
|
||||
await mine()
|
||||
}
|
||||
}
|
||||
|
||||
beforeEach(async function () {
|
||||
await proofs.setProofEnd(endId, (await currentTime()) + duration)
|
||||
await proofs.expectProofs(id, endId, probability)
|
||||
await proofs.setProofEnd(requestId, (await currentTime()) + duration)
|
||||
await proofs.expectProofs(slotId, requestId, probability)
|
||||
await advanceTimeTo(periodEnd(periodOf(await currentTime())))
|
||||
await waitUntilProofWillBeRequired()
|
||||
})
|
||||
|
||||
it("means the pointer is in downtime", async function () {
|
||||
expect(await proofs.getPointer(id)).to.be.lt(downtime)
|
||||
while ((await proofs.getPointer(id)) < downtime) {
|
||||
expect(await proofs.willProofBeRequired(id)).to.be.true
|
||||
expect(await proofs.getPointer(slotId)).to.be.lt(downtime)
|
||||
while ((await proofs.getPointer(slotId)) < downtime) {
|
||||
expect(await proofs.willProofBeRequired(slotId)).to.be.true
|
||||
await mine()
|
||||
}
|
||||
})
|
||||
|
||||
it("means that a proof is required after downtime", async function () {
|
||||
while ((await proofs.getPointer(id)) < downtime) {
|
||||
while ((await proofs.getPointer(slotId)) < downtime) {
|
||||
await mine()
|
||||
}
|
||||
expect(await proofs.willProofBeRequired(id)).to.be.false
|
||||
expect(await proofs.isProofRequired(id)).to.be.true
|
||||
expect(await proofs.willProofBeRequired(slotId)).to.be.false
|
||||
expect(await proofs.isProofRequired(slotId)).to.be.true
|
||||
})
|
||||
|
||||
it("will not require proofs when no longer expected", async function () {
|
||||
expect(await proofs.getPointer(id)).to.be.lt(downtime)
|
||||
expect(await proofs.willProofBeRequired(id)).to.be.true
|
||||
await proofs.unexpectProofs(id)
|
||||
expect(await proofs.willProofBeRequired(id)).to.be.false
|
||||
expect(await proofs.getPointer(slotId)).to.be.lt(downtime)
|
||||
expect(await proofs.willProofBeRequired(slotId)).to.be.true
|
||||
await proofs.unexpectProofs(slotId)
|
||||
expect(await proofs.willProofBeRequired(slotId)).to.be.false
|
||||
})
|
||||
})
|
||||
|
||||
@ -153,16 +153,16 @@ describe("Proofs", function () {
|
||||
const proof = hexlify(randomBytes(42))
|
||||
|
||||
beforeEach(async function () {
|
||||
await proofs.setProofEnd(endId, (await currentTime()) + duration)
|
||||
await proofs.expectProofs(id, endId, probability)
|
||||
await proofs.setProofEnd(requestId, (await currentTime()) + duration)
|
||||
await proofs.expectProofs(slotId, requestId, probability)
|
||||
})
|
||||
|
||||
async function waitUntilProofIsRequired(id) {
|
||||
async function waitUntilProofIsRequired(slotId) {
|
||||
await advanceTimeTo(periodEnd(periodOf(await currentTime())))
|
||||
while (
|
||||
!(
|
||||
(await proofs.isProofRequired(id)) &&
|
||||
(await proofs.getPointer(id)) < 250
|
||||
(await proofs.isProofRequired(slotId)) &&
|
||||
(await proofs.getPointer(slotId)) < 250
|
||||
)
|
||||
) {
|
||||
await advanceTime(period)
|
||||
@ -170,107 +170,107 @@ describe("Proofs", function () {
|
||||
}
|
||||
|
||||
it("provides different challenges per period", async function () {
|
||||
await waitUntilProofIsRequired(id)
|
||||
const challenge1 = await proofs.getChallenge(id)
|
||||
await waitUntilProofIsRequired(id)
|
||||
const challenge2 = await proofs.getChallenge(id)
|
||||
await waitUntilProofIsRequired(slotId)
|
||||
const challenge1 = await proofs.getChallenge(slotId)
|
||||
await waitUntilProofIsRequired(slotId)
|
||||
const challenge2 = await proofs.getChallenge(slotId)
|
||||
expect(challenge2).not.to.equal(challenge1)
|
||||
})
|
||||
|
||||
it("provides different challenges per id", async function () {
|
||||
it("provides different challenges per slotId", async function () {
|
||||
const id2 = hexlify(randomBytes(32))
|
||||
const id3 = hexlify(randomBytes(32))
|
||||
const challenge1 = await proofs.getChallenge(id)
|
||||
const challenge1 = await proofs.getChallenge(slotId)
|
||||
const challenge2 = await proofs.getChallenge(id2)
|
||||
const challenge3 = await proofs.getChallenge(id3)
|
||||
expect(challenge1 === challenge2 && challenge2 === challenge3).to.be.false
|
||||
})
|
||||
|
||||
it("submits a correct proof", async function () {
|
||||
await proofs.submitProof(id, proof)
|
||||
await proofs.submitProof(slotId, proof)
|
||||
})
|
||||
|
||||
it("fails proof submission when proof is incorrect", async function () {
|
||||
await expect(proofs.submitProof(id, [])).to.be.revertedWith(
|
||||
await expect(proofs.submitProof(slotId, [])).to.be.revertedWith(
|
||||
"Invalid proof"
|
||||
)
|
||||
})
|
||||
|
||||
it("emits an event when proof was submitted", async function () {
|
||||
await expect(proofs.submitProof(id, proof))
|
||||
await expect(proofs.submitProof(slotId, proof))
|
||||
.to.emit(proofs, "ProofSubmitted")
|
||||
.withArgs(id, proof)
|
||||
.withArgs(slotId, proof)
|
||||
})
|
||||
|
||||
it("fails proof submission when already submitted", async function () {
|
||||
await advanceTimeTo(periodEnd(periodOf(await currentTime())))
|
||||
await proofs.submitProof(id, proof)
|
||||
await expect(proofs.submitProof(id, proof)).to.be.revertedWith(
|
||||
await proofs.submitProof(slotId, proof)
|
||||
await expect(proofs.submitProof(slotId, proof)).to.be.revertedWith(
|
||||
"Proof already submitted"
|
||||
)
|
||||
})
|
||||
|
||||
it("marks a proof as missing", async function () {
|
||||
expect(await proofs.missed(id)).to.equal(0)
|
||||
await waitUntilProofIsRequired(id)
|
||||
expect(await proofs.missed(slotId)).to.equal(0)
|
||||
await waitUntilProofIsRequired(slotId)
|
||||
let missedPeriod = periodOf(await currentTime())
|
||||
await advanceTimeTo(periodEnd(missedPeriod))
|
||||
await proofs.markProofAsMissing(id, missedPeriod)
|
||||
expect(await proofs.missed(id)).to.equal(1)
|
||||
await proofs.markProofAsMissing(slotId, missedPeriod)
|
||||
expect(await proofs.missed(slotId)).to.equal(1)
|
||||
})
|
||||
|
||||
it("does not mark a proof as missing before period end", async function () {
|
||||
await waitUntilProofIsRequired(id)
|
||||
await waitUntilProofIsRequired(slotId)
|
||||
let currentPeriod = periodOf(await currentTime())
|
||||
await expect(
|
||||
proofs.markProofAsMissing(id, currentPeriod)
|
||||
proofs.markProofAsMissing(slotId, currentPeriod)
|
||||
).to.be.revertedWith("Period has not ended yet")
|
||||
})
|
||||
|
||||
it("does not mark a proof as missing after timeout", async function () {
|
||||
await waitUntilProofIsRequired(id)
|
||||
await waitUntilProofIsRequired(slotId)
|
||||
let currentPeriod = periodOf(await currentTime())
|
||||
await advanceTimeTo(periodEnd(currentPeriod) + timeout)
|
||||
await expect(
|
||||
proofs.markProofAsMissing(id, currentPeriod)
|
||||
proofs.markProofAsMissing(slotId, currentPeriod)
|
||||
).to.be.revertedWith("Validation timed out")
|
||||
})
|
||||
|
||||
it("does not mark a submitted proof as missing", async function () {
|
||||
await waitUntilProofIsRequired(id)
|
||||
await waitUntilProofIsRequired(slotId)
|
||||
let submittedPeriod = periodOf(await currentTime())
|
||||
await proofs.submitProof(id, proof)
|
||||
await proofs.submitProof(slotId, proof)
|
||||
await advanceTimeTo(periodEnd(submittedPeriod))
|
||||
await expect(
|
||||
proofs.markProofAsMissing(id, submittedPeriod)
|
||||
proofs.markProofAsMissing(slotId, submittedPeriod)
|
||||
).to.be.revertedWith("Proof was submitted, not missing")
|
||||
})
|
||||
|
||||
it("does not mark proof as missing when not required", async function () {
|
||||
while (await proofs.isProofRequired(id)) {
|
||||
while (await proofs.isProofRequired(slotId)) {
|
||||
await advanceTime(period)
|
||||
}
|
||||
let currentPeriod = periodOf(await currentTime())
|
||||
await advanceTimeTo(periodEnd(currentPeriod))
|
||||
await expect(
|
||||
proofs.markProofAsMissing(id, currentPeriod)
|
||||
proofs.markProofAsMissing(slotId, currentPeriod)
|
||||
).to.be.revertedWith("Proof was not required")
|
||||
})
|
||||
|
||||
it("does not mark proof as missing twice", async function () {
|
||||
await waitUntilProofIsRequired(id)
|
||||
await waitUntilProofIsRequired(slotId)
|
||||
let missedPeriod = periodOf(await currentTime())
|
||||
await advanceTimeTo(periodEnd(missedPeriod))
|
||||
await proofs.markProofAsMissing(id, missedPeriod)
|
||||
await proofs.markProofAsMissing(slotId, missedPeriod)
|
||||
await expect(
|
||||
proofs.markProofAsMissing(id, missedPeriod)
|
||||
proofs.markProofAsMissing(slotId, missedPeriod)
|
||||
).to.be.revertedWith("Proof already marked as missing")
|
||||
})
|
||||
|
||||
it("requires no proofs when no longer expected", async function () {
|
||||
await waitUntilProofIsRequired(id)
|
||||
await proofs.unexpectProofs(id)
|
||||
await expect(await proofs.isProofRequired(id)).to.be.false
|
||||
await waitUntilProofIsRequired(slotId)
|
||||
await proofs.unexpectProofs(slotId)
|
||||
await expect(await proofs.isProofRequired(slotId)).to.be.false
|
||||
})
|
||||
})
|
||||
|
||||
@ -278,28 +278,28 @@ describe("Proofs", function () {
|
||||
const proof = hexlify(randomBytes(42))
|
||||
|
||||
it("fails to get proof end when proof ending doesn't exist", async function () {
|
||||
await expect(proofs.end(endId)).to.be.revertedWith(
|
||||
await expect(proofs.end(requestId)).to.be.revertedWith(
|
||||
"Proof ending doesn't exist"
|
||||
)
|
||||
})
|
||||
|
||||
it("sets proof end when proof ending doesn't already exist", async function () {
|
||||
let ending = (await currentTime()) + duration
|
||||
await expect(proofs.setProofEnd(endId, ending)).not.to.be.reverted
|
||||
await expect(await proofs.end(endId)).to.equal(ending)
|
||||
await expect(proofs.setProofEnd(requestId, ending)).not.to.be.reverted
|
||||
await expect(await proofs.end(requestId)).to.equal(ending)
|
||||
})
|
||||
|
||||
it("sets proof end when proof ending exists and ending set to past", async function () {
|
||||
// let ending = (await currentTime()) + duration
|
||||
// await proofs.setProofEnd(endId, ending)
|
||||
// await proofs.setProofEnd(requestId, ending)
|
||||
let past = (await currentTime()) - 1
|
||||
await expect(proofs.setProofEnd(endId, past)).not.to.be.reverted
|
||||
await expect(proofs.setProofEnd(requestId, past)).not.to.be.reverted
|
||||
})
|
||||
|
||||
it("fails when proof ending already exists and ending set to future", async function () {
|
||||
let ending = (await currentTime()) + duration
|
||||
await proofs.setProofEnd(endId, ending)
|
||||
await expect(proofs.setProofEnd(endId, ending)).to.be.revertedWith(
|
||||
await proofs.setProofEnd(requestId, ending)
|
||||
await expect(proofs.setProofEnd(requestId, ending)).to.be.revertedWith(
|
||||
"End exists or must be past"
|
||||
)
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user