Commit 9ce2a4c7 authored by clabby's avatar clabby

Remove timestamp estimation

parent 76b23d3a
......@@ -16,7 +16,7 @@ AssetReceiverTest:test_withdrawETHwithAmount_unauthorized_reverts() (gas: 10738)
AttestationStationTest:test_attest_bulk_succeeds() (gas: 703740)
AttestationStationTest:test_attest_individual_succeeds() (gas: 632078)
AttestationStationTest:test_attest_single_succeeds() (gas: 651316)
BlockOracle_Test:test_checkpointAndLoad_succeeds() (gas: 51618)
BlockOracle_Test:test_checkpointAndLoad_succeeds() (gas: 51477)
BlockOracle_Test:test_load_noBlockHash_reverts() (gas: 12805)
Bytes_slice_Test:test_slice_acrossMultipleWords_works() (gas: 9413)
Bytes_slice_Test:test_slice_acrossWords_works() (gas: 1430)
......@@ -103,7 +103,7 @@ FaultDisputeGame_Test:test_gameStart_succeeds() (gas: 10410)
FaultDisputeGame_Test:test_gameType_succeeds() (gas: 8266)
FaultDisputeGame_Test:test_initialize_correctData_succeeds() (gas: 58226)
FaultDisputeGame_Test:test_initialize_firstOutput_reverts() (gas: 210532)
FaultDisputeGame_Test:test_initialize_l1HeadTooOld_reverts() (gas: 228360)
FaultDisputeGame_Test:test_initialize_l1HeadTooOld_reverts() (gas: 228357)
FaultDisputeGame_Test:test_move_clockCorrectness_succeeds() (gas: 415921)
FaultDisputeGame_Test:test_move_clockTimeExceeded_reverts() (gas: 26428)
FaultDisputeGame_Test:test_move_defendRoot_reverts() (gas: 13322)
......
......@@ -7,10 +7,10 @@ import "src/libraries/DisputeErrors.sol";
/// @title BlockOracle
/// @notice Stores a map of block numbers => block hashes for use in dispute resolution
contract BlockOracle {
/// @notice The BlockInfo struct contains a block's hash and estimated timestamp.
/// @notice The BlockInfo struct contains a block's hash and child timestamp.
struct BlockInfo {
Hash hash;
Timestamp timestamp;
Timestamp childTimestamp;
}
/// @notice Maps block numbers to block hashes and timestamps
......@@ -25,22 +25,16 @@ contract BlockOracle {
if (Hash.unwrap(blockInfo_.hash) == 0) revert BlockHashNotPresent();
}
/// @notice Stores a block hash for the previous block number, assuming that the block number
/// is within the acceptable range of [tip - 256, tip].
/// @notice Stores a block hash for the previous block number.
/// @return blockNumber_ The block number that was checkpointed, which is always
/// `block.number - 1`.
function checkpoint() external returns (uint256 blockNumber_) {
// Fetch the block hash for the given block number and revert if it is out of
// the `BLOCKHASH` opcode's range.
// SAFETY: This block hash will always be accessible by the `BLOCKHASH` opcode,
// and in the case of `block.number = 0`, we'll underflow.
bytes32 blockHash = blockhash(blockNumber_ = block.number - 1);
// Estimate the timestamp of the block assuming an average block time of 13 seconds.
Timestamp estimatedTimestamp = Timestamp.wrap(uint64(block.timestamp - 13));
// Persist the block information.
blocks[blockNumber_] = BlockInfo({
hash: Hash.wrap(blockHash),
timestamp: estimatedTimestamp
hash: Hash.wrap(blockhash(blockNumber_ = block.number - 1)),
childTimestamp: Timestamp.wrap(uint64(block.timestamp))
});
}
}
......@@ -477,12 +477,20 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, Semver {
// INVARIANT: The L1 head must contain the disputed output root. If it does not,
// the game cannot be played.
// TODO(clabby): The block timestamp in the oracle is an estimate that assumes a 13
// second block time. Should we add a buffer here to ensure that the
// estimation has room for error? This invariant cannot break. We could
// add the L1 block number to the `Types.OutputProposal` type as well,
// which would remove the need for estimation.
if (Timestamp.unwrap(blockInfo.timestamp) < disputed.timestamp) revert L1HeadTooOld();
// SAFETY: The block timestamp in the oracle records the timestamp of the
// block *after* the hash stored. This means that the timestamp
// is off by 1 block. This is known, and covered as follows:
// - The timestamp will always be less than the disputed timestamp
// if the checkpoint was made before the proposal. We must revert here.
// - The timestamp will be equal to the disputed timestamp if the
// checkpoint was made in the same block as the proposal, and the
// hash will be the parent block, which does not contain the proposal.
// We must revert here.
// - The timestamp will always be greater than the disputed timestamp
// if the checkpoint was made any block after the proposal. This is
// the only case where we can continue, since we must have the L1
// head contain the disputed output root to play the game.
if (Timestamp.unwrap(blockInfo.childTimestamp) <= disputed.timestamp) revert L1HeadTooOld();
// Persist the output proposals fetched from the oracle. These outputs will be referenced
// for loading local data into the preimage oracle as well as to authenticate the game's
......
......@@ -23,7 +23,7 @@ contract BlockOracle_Test is Test {
BlockOracle.BlockInfo memory res = oracle.load(blockNumber);
assertEq(Hash.unwrap(res.hash), blockhash(blockNumber));
assertEq(Timestamp.unwrap(res.timestamp), block.timestamp - 13);
assertEq(Timestamp.unwrap(res.childTimestamp), block.timestamp);
}
/// @notice Tests that the `load` function reverts if the block hash for the given block
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment