proofs: use Timestamp instead of uint64

This commit is contained in:
Mark Spanbroek 2025-03-06 15:14:15 +01:00
parent 468bc2e833
commit 52cf22789c
4 changed files with 30 additions and 19 deletions

View File

@ -5,7 +5,7 @@ using ERC20A as Token;
methods {
function Token.balanceOf(address) external returns (uint256) envfree;
function Token.totalSupply() external returns (uint256) envfree;
function publicPeriodEnd(Periods.Period) external returns (uint64) envfree;
function publicPeriodEnd(Periods.Period) external returns (Marketplace.Timestamp) envfree;
function generateSlotId(Marketplace.RequestId, uint64) external returns (Marketplace.SlotId) envfree;
}

View File

@ -20,8 +20,8 @@ struct CollateralConfig {
}
struct ProofConfig {
uint64 period; // proofs requirements are calculated per period (in seconds)
uint64 timeout; // mark proofs as missing before the timeout (in seconds)
Duration period; // proofs requirements are calculated per period (in seconds)
Duration timeout; // mark proofs as missing before the timeout (in seconds)
uint8 downtime; // ignore this much recent blocks for proof requirements
// Ensures the pointer does not remain in downtime for many consecutive
// periods. For each period increase, move the pointer `pointerProduct`

View File

@ -1,37 +1,45 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import "./Timestamps.sol";
contract Periods {
error Periods_InvalidSecondsPerPeriod();
type Period is uint64;
type Period is uint40;
uint64 internal immutable _secondsPerPeriod;
Duration internal immutable _secondsPerPeriod;
constructor(uint64 secondsPerPeriod) {
if (secondsPerPeriod == 0) {
constructor(Duration secondsPerPeriod) {
if (secondsPerPeriod == Duration.wrap(0)) {
revert Periods_InvalidSecondsPerPeriod();
}
_secondsPerPeriod = secondsPerPeriod;
}
function _periodOf(uint64 timestamp) internal view returns (Period) {
return Period.wrap(timestamp / _secondsPerPeriod);
function _periodOf(Timestamp timestamp) internal view returns (Period) {
return
Period.wrap(
Timestamp.unwrap(timestamp) / Duration.unwrap(_secondsPerPeriod)
);
}
function _blockPeriod() internal view returns (Period) {
return _periodOf(uint64(block.timestamp));
return _periodOf(Timestamps.currentTime());
}
function _nextPeriod(Period period) internal pure returns (Period) {
return Period.wrap(Period.unwrap(period) + 1);
}
function _periodStart(Period period) internal view returns (uint64) {
return Period.unwrap(period) * _secondsPerPeriod;
function _periodStart(Period period) internal view returns (Timestamp) {
return
Timestamp.wrap(
Period.unwrap(period) * Duration.unwrap(_secondsPerPeriod)
);
}
function _periodEnd(Period period) internal view returns (uint64) {
function _periodEnd(Period period) internal view returns (Timestamp) {
return _periodStart(_nextPeriod(period));
}

View File

@ -3,6 +3,7 @@ pragma solidity 0.8.28;
import "./Configuration.sol";
import "./Requests.sol";
import "./Timestamps.sol";
import "./Periods.sol";
import "./Groth16.sol";
@ -11,6 +12,8 @@ import "./Groth16.sol";
* @notice Abstract contract that handles proofs tracking, validation and reporting functionality
*/
abstract contract Proofs is Periods {
using Timestamps for Timestamp;
error Proofs_InsufficientBlockHeight();
error Proofs_InvalidProof();
error Proofs_ProofAlreadySubmitted();
@ -39,7 +42,7 @@ abstract contract Proofs is Periods {
_verifier = verifier;
}
mapping(SlotId => uint64) private _slotStarts;
mapping(SlotId => Timestamp) private _slotStarts;
mapping(SlotId => uint64) private _missed;
mapping(SlotId => mapping(Period => bool)) private _received;
mapping(SlotId => mapping(Period => bool)) private _missing;
@ -73,7 +76,7 @@ abstract contract Proofs is Periods {
* and saves the required probability.
*/
function _startRequiringProofs(SlotId id) internal {
_slotStarts[id] = uint64(block.timestamp);
_slotStarts[id] = Timestamps.currentTime();
}
/**
@ -234,10 +237,10 @@ abstract contract Proofs is Periods {
SlotId id,
Period missedPeriod
) internal view {
uint256 end = _periodEnd(missedPeriod);
if (end >= block.timestamp) revert Proofs_PeriodNotEnded();
if (block.timestamp >= end + _config.timeout)
revert Proofs_ValidationTimedOut();
Timestamp end = _periodEnd(missedPeriod);
Timestamp current = Timestamps.currentTime();
if (current <= end) revert Proofs_PeriodNotEnded();
if (end.add(_config.timeout) <= current) revert Proofs_ValidationTimedOut();
if (_received[id][missedPeriod]) revert Proofs_ProofNotMissing();
if (!_isProofRequired(id, missedPeriod)) revert Proofs_ProofNotRequired();
if (_missing[id][missedPeriod]) revert Proofs_ProofAlreadyMarkedMissing();