Skip to content

Commit

Permalink
HeaderLib
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan committed Jan 17, 2024
1 parent ddc35fa commit 8eb5a77
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 44 deletions.
37 changes: 4 additions & 33 deletions l1-contracts/src/core/Rollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {IOutbox} from "./interfaces/messagebridge/IOutbox.sol";
import {IRegistry} from "./interfaces/messagebridge/IRegistry.sol";

// Libraries
import {HeaderDecoder} from "./libraries/decoders/HeaderDecoder.sol";
import {HeaderLib} from "./libraries/HeaderLib.sol";
import {MessagesDecoder} from "./libraries/decoders/MessagesDecoder.sol";
import {Hash} from "./libraries/Hash.sol";
import {Errors} from "./libraries/Errors.sol";
Expand Down Expand Up @@ -56,9 +56,9 @@ contract Rollup is IRollup {
bytes calldata _body, // TODO(#3944): this will be replaced with _txsHash once the separation is finished.
bytes memory _proof
) external override(IRollup) {
HeaderDecoder.Header memory header = HeaderDecoder.decode(_header);

_validateHeader(header);
// Decode and validate header
HeaderLib.Header memory header = HeaderLib.decode(_header);
HeaderLib.validate(header, VERSION, lastBlockTs, archive);

// Check if the data is available using availability oracle (change availability oracle if you want a different DA layer)
bytes32 txsHash;
Expand Down Expand Up @@ -99,35 +99,6 @@ contract Rollup is IRollup {
emit L2BlockProcessed(header.globalVariables.blockNumber);
}

function _validateHeader(HeaderDecoder.Header memory header) internal view {
if (block.chainid != header.globalVariables.chainId) {
revert Errors.Rollup__InvalidChainId(header.globalVariables.chainId, block.chainid);
}

if (header.globalVariables.version != VERSION) {
revert Errors.Rollup__InvalidVersion(header.globalVariables.version, VERSION);
}

// block number already constrained by archive root check

if (header.globalVariables.timestamp > block.timestamp) {
revert Errors.Rollup__TimestampInFuture();
}

// @todo @LHerskind consider if this is too strict
// This will make multiple l2 blocks in the same l1 block impractical.
// e.g., the first block will update timestamp which will make the second fail.
// Could possibly allow multiple blocks if in same l1 block
if (header.globalVariables.timestamp < lastBlockTs) {
revert Errors.Rollup__TimestampTooOld();
}

// @todo @LHerskind Proper genesis state. If the state is empty, we allow anything for now.
if (archive != bytes32(0) && archive != header.lastArchive.root) {
revert Errors.Rollup__InvalidArchive(archive, header.lastArchive.root);
}
}

function _computePublicInputHash(bytes calldata _header, bytes32 _txsHash, bytes32 _inHash)
internal
pure
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
pragma solidity >=0.8.18;

// Libraries
import {Constants} from "../ConstantsGen.sol";
import {Hash} from "../Hash.sol";
import {Errors} from "./Errors.sol";
import {Constants} from "./ConstantsGen.sol";
import {Hash} from "./Hash.sol";

/**
* @title Header Decoder Library
* @title Header Library
* @author Aztec Labs
* @notice Decoding a L2 header
* @notice Decoding and validating an L2 block header
* Concerned with readability and velocity of development not giving a damn about gas costs.
*
* -------------------
Expand Down Expand Up @@ -47,7 +48,7 @@ import {Hash} from "../Hash.sol";
* | | | }
* | --- | --- | ---
*/
library HeaderDecoder {
library HeaderLib {
struct AppendOnlyTreeSnapshot {
bytes32 root;
uint32 nextAvailableLeafIndex;
Expand Down Expand Up @@ -82,7 +83,8 @@ library HeaderDecoder {

/**
* @notice Decodes the header
* @param _header - The header calldata.
* @param _header - The header calldata
* @return The decoded header
*/
function decode(bytes calldata _header) internal pure returns (Header memory) {
require(_header.length == 376, "Invalid header length");
Expand Down Expand Up @@ -110,4 +112,43 @@ library HeaderDecoder {

return header;
}

/**
* @notice Validates the header
* @param _header - The decoded header
* @param _version - The expected version
* @param _lastBlockTs - The timestamp of the last block
* @param _archive - The expected archive root
*/
function validate(Header memory _header, uint256 _version, uint256 _lastBlockTs, bytes32 _archive)
internal
view
{
if (block.chainid != _header.globalVariables.chainId) {
revert Errors.Rollup__InvalidChainId(_header.globalVariables.chainId, block.chainid);
}

if (_header.globalVariables.version != _version) {
revert Errors.Rollup__InvalidVersion(_header.globalVariables.version, _version);
}

// block number already constrained by archive root check

if (_header.globalVariables.timestamp > block.timestamp) {
revert Errors.Rollup__TimestampInFuture();
}

// @todo @LHerskind consider if this is too strict
// This will make multiple l2 blocks in the same l1 block impractical.
// e.g., the first block will update timestamp which will make the second fail.
// Could possibly allow multiple blocks if in same l1 block
if (_header.globalVariables.timestamp < _lastBlockTs) {
revert Errors.Rollup__TimestampTooOld();
}

// @todo @LHerskind Proper genesis state. If the state is empty, we allow anything for now.
if (_archive != bytes32(0) && _archive != _header.lastArchive.root) {
revert Errors.Rollup__InvalidArchive(_archive, _header.lastArchive.root);
}
}
}
4 changes: 2 additions & 2 deletions l1-contracts/test/decoders/Decoder.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import {DecoderHelper} from "./helpers/DecoderHelper.sol";
import {HeaderDecoderHelper} from "./helpers/HeaderDecoderHelper.sol";
import {MessagesDecoderHelper} from "./helpers/MessagesDecoderHelper.sol";
import {TxsDecoderHelper} from "./helpers/TxsDecoderHelper.sol";
import {HeaderLib} from "../../src/core/libraries/HeaderLib.sol";

import {Decoder} from "../../src/core/libraries/decoders/Decoder.sol";
import {HeaderDecoder} from "../../src/core/libraries/decoders/HeaderDecoder.sol";
import {MessagesDecoder} from "../../src/core/libraries/decoders/MessagesDecoder.sol";
import {TxsDecoder} from "../../src/core/libraries/decoders/TxsDecoder.sol";

Expand Down Expand Up @@ -59,7 +59,7 @@ contract DecoderTest is DecoderBase {
// Header
{
DecoderBase.DecodedHeader memory referenceHeader = data.block.decodedHeader;
HeaderDecoder.Header memory header = headerHelper.decode(data.block.header);
HeaderLib.Header memory header = headerHelper.decode(data.block.header);

// GlobalVariables
{
Expand Down
6 changes: 3 additions & 3 deletions l1-contracts/test/decoders/helpers/HeaderDecoderHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
// Copyright 2023 Aztec Labs.
pragma solidity >=0.8.18;

import {HeaderDecoder} from "../../../src/core/libraries/decoders/HeaderDecoder.sol";
import {HeaderLib} from "../../../src/core/libraries/HeaderLib.sol";

contract HeaderDecoderHelper {
// A wrapper used such that we get "calldata" and not memory
function decode(bytes calldata _header) public pure returns (HeaderDecoder.Header memory) {
return HeaderDecoder.decode(_header);
function decode(bytes calldata _header) public pure returns (HeaderLib.Header memory) {
return HeaderLib.decode(_header);
}
}

0 comments on commit 8eb5a77

Please sign in to comment.