Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan committed Jan 13, 2024
1 parent 8777e4c commit 29d7999
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 46 deletions.
52 changes: 23 additions & 29 deletions l1-contracts/src/core/Rollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ contract Rollup is IRollup {
uint256 public immutable VERSION;
AvailabilityOracle public immutable AVAILABILITY_ORACLE;

bytes32 public rollupStateHash;
bytes32 public archive; // Root of the archive tree
uint256 public lastBlockTs;
// Tracks the last time time was warped on L2 ("warp" is the testing cheatcode).
// See https://github.com/AztecProtocol/aztec-packages/issues/1614
Expand All @@ -47,29 +47,26 @@ contract Rollup is IRollup {
* @notice Process an incoming L2 block and progress the state
* @param _header - The L2 block header.
* @param _archive - A snapshot (root and next available leaf index) of the archive tree after the L2 block is applied
* @param _l1_to_l2_msgs - The L1 to L2 messages processed in this block
* @param _l2_to_l1_msgs - The L2 to L1 messages processed in this block
* @param _body - The L2 block body.
* @param _proof - The proof of correct execution.
*/
function process(
bytes calldata _header,
bytes calldata _archive,
bytes calldata _l1_to_l2_msgs,
bytes calldata _l2_to_l1_msgs,
bytes calldata _body, // Note: this will be replaced with _txsHash once the separation is finished.
bytes memory _proof
) external override(IRollup) {
_validateHeader(_header);
// TODO: @benejsan Should we represent this values from header as a nice struct?
HeaderDecoder.Header memory header = HeaderDecoder.decode(_header);

// Decode the header
(uint256 l2BlockNumber, bytes32 oldStateHash, bytes32 newStateHash) =
HeaderDecoder.decode(_l2Block[:HeaderDecoder.BLOCK_HEADER_SIZE]);
_validateHeader(header);

// Check if the data is available using availability oracle (change availability oracle if you want a different DA layer)
bytes32 txsHash;
{
// @todo @LHerskind Hack such that the node is unchanged for now.
// should be removed when we have a proper block publication.
txsHash = AVAILABILITY_ORACLE.publish(_l2Block[HeaderDecoder.BLOCK_HEADER_SIZE:]);
txsHash = AVAILABILITY_ORACLE.publish(_body);
}

if (!AVAILABILITY_ORACLE.isAvailable(txsHash)) {
Expand All @@ -79,10 +76,7 @@ contract Rollup is IRollup {

// Decode the cross-chain messages
(bytes32 inHash,, bytes32[] memory l1ToL2Msgs, bytes32[] memory l2ToL1Msgs) =
MessagesDecoder.decode(_l2Block[HeaderDecoder.BLOCK_HEADER_SIZE:]);

bytes32 publicInputHash =
_computePublicInputHash(_l2Block[:HeaderDecoder.BLOCK_HEADER_SIZE], txsHash, inHash);
MessagesDecoder.decode(_body);

// @todo @LHerskind Proper genesis state. If the state is empty, we allow anything for now.
// TODO(#3936): Temporarily disabling this because L2Block encoding has not yet been updated.
Expand All @@ -91,13 +85,14 @@ contract Rollup is IRollup {
// }

bytes32[] memory publicInputs = new bytes32[](1);
publicInputs[0] = publicInputHash;
publicInputs[0] = _computePublicInputHash(_header, txsHash, inHash);

if (!VERIFIER.verify(_proof, publicInputs)) {
revert Errors.Rollup__InvalidProof();
}

rollupStateHash = newStateHash;
// TODO: @benejsan Manually extracting the root here is ugly. TODO: Re-think how to represent archive snap.
archive = bytes32(_header[:0x20]);
lastBlockTs = block.timestamp;

// @todo (issue #605) handle fee collector
Expand All @@ -107,34 +102,33 @@ contract Rollup is IRollup {
IOutbox outbox = REGISTRY.getOutbox();
outbox.sendL1Messages(l2ToL1Msgs);

emit L2BlockProcessed(l2BlockNumber);
emit L2BlockProcessed(header.blockNumber);
}

function _validateHeader(bytes calldata _header) internal view {
uint256 chainId = uint256(bytes32(_header[:0x20]));
uint256 version = uint256(bytes32(_header[0x20:0x40]));
uint256 ts = uint256(bytes32(_header[0x60:0x80]));
// block number already constrained by start state hash

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

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

if (ts > block.timestamp) {
if (header.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 (ts < lastBlockTs) {
if (header.timestamp < lastBlockTs) {
revert Errors.Rollup__TimestampTooOld();
}

if (archive != header.lastArchive) {
revert Errors.Rollup__InvalidArchive(archive, header.lastArchive);
}
}

function _computePublicInputHash(bytes calldata _header, bytes32 _txsHash, bytes32 _inHash)
Expand Down
9 changes: 7 additions & 2 deletions l1-contracts/src/core/interfaces/IRollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
pragma solidity >=0.8.18;

interface IRollup {
event L2BlockProcessed(uint256 indexed blockNum);
event L2BlockProcessed(uint256 indexed blockNumber);

function process(bytes memory _proof, bytes calldata _l2Block) external;
function process(
bytes calldata _header,
bytes calldata _archive,
bytes calldata _body,
bytes memory _proof
) external;
}
2 changes: 1 addition & 1 deletion l1-contracts/src/core/libraries/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ library Errors {
); // 0x5e789f34

// Rollup
error Rollup__InvalidStateHash(bytes32 expected, bytes32 actual); // 0xa3cfaab3
error Rollup__InvalidArchive(bytes32 expected, bytes32 actual); // 0xb682a40e
error Rollup__InvalidProof(); // 0xa5b2ba17
error Rollup__InvalidChainId(uint256 expected, uint256 actual); // 0x37b5bc12
error Rollup__InvalidVersion(uint256 expected, uint256 actual); // 0x9ef30794
Expand Down
37 changes: 23 additions & 14 deletions l1-contracts/src/core/libraries/decoders/HeaderDecoder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ import {Hash} from "../Hash.sol";
* | --- | --- | ---
*/
library HeaderDecoder {
// TODO: This is only partial
struct Header {
uint256 chainId;
uint256 version;
uint256 blockNumber;
uint256 timestamp;
bytes32 lastArchive;
}

// DECODING OFFSET CONSTANTS
// Where the start of trees metadata begins in the block
uint256 private constant START_TREES_BLOCK_HEADER_OFFSET = 0x80;
Expand All @@ -65,21 +74,21 @@ library HeaderDecoder {

/**
* @notice Decodes the header
* @param _header - The L2 block calldata.
* @return l2BlockNumber - The L2 block number
* @return startStateHash - The start state hash
* @return endStateHash - The end state hash
* @param _header - The header calldata.
*/
function decode(bytes calldata _header)
internal
pure
returns (uint256 l2BlockNumber, bytes32 startStateHash, bytes32 endStateHash)
{
l2BlockNumber = uint256(bytes32(_header[0x40:0x60]));
// Note, for startStateHash to match the storage, the l2 block number must be new - 1.
// Only jumping 1 block at a time.
startStateHash = computeStateHash(l2BlockNumber - 1, START_TREES_BLOCK_HEADER_OFFSET, _header);
endStateHash = computeStateHash(l2BlockNumber, END_TREES_BLOCK_HEADER_OFFSET, _header);
function decode(bytes calldata _header) internal pure returns (Header memory) {
Header memory header;

header.chainId = uint256(bytes32(_header[:0x20]));
header.version = uint256(bytes32(_header[0x20:0x40]));
header.blockNumber = uint256(bytes32(_header[0x40:0x60]));
header.timestamp = uint256(bytes32(_header[0x60:0x80]));

// The rest is needed only by verifier and hence not decoded here.

header.lastArchive = bytes32(_header[0x134:0x154]);

return header;
}

/**
Expand Down

0 comments on commit 29d7999

Please sign in to comment.