Skip to content

Commit

Permalink
Move block context to blob (#649)
Browse files Browse the repository at this point in the history
Co-authored-by: chengwenxi <[email protected]>
Co-authored-by: FletcherMan <[email protected]>
Co-authored-by: curryxbo <[email protected]>
Co-authored-by: kukoomomo <[email protected]>
Co-authored-by: Kathy <[email protected]>
  • Loading branch information
6 people authored Feb 14, 2025
1 parent 1f705d5 commit a1c6c5f
Show file tree
Hide file tree
Showing 107 changed files with 1,825 additions and 1,181 deletions.
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[submodule "go-ethereum"]
path = go-ethereum
url = https://github.com/morph-l2/go-ethereum.git
branch = main
branch = feature/block_context
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
################## update dependencies ####################

ETHEREUM_TARGET_VERSION := v1.10.14-0.20241224100051-1582a364edc0
TENDERMINT_TARGET_VERSION := v0.3.1
ETHEREUM_TARGET_VERSION := v1.10.14-0.20241226065029-3b9465a03a8c
TENDERMINT_TARGET_VERSION := v0.3.2-0.20250115141431-c84dfe5c8533

ETHEREUM_MODULE_NAME := github.com/morph-l2/go-ethereum
TENDERMINT_MODULE_NAME := github.com/morph-l2/tendermint
Expand Down
2 changes: 1 addition & 1 deletion bindings/bin/l2staking_deployed.hex

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion bindings/bin/rollup_deployed.hex

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion bindings/bindings/l2staking.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion bindings/bindings/l2staking_more.go

Large diffs are not rendered by default.

19 changes: 10 additions & 9 deletions bindings/bindings/rollup.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion bindings/bindings/rollup_more.go

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions bindings/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ module morph-l2/bindings

go 1.22

replace github.com/tendermint/tendermint => github.com/morph-l2/tendermint v0.3.1
replace github.com/tendermint/tendermint => github.com/morph-l2/tendermint v0.3.2-0.20250115141431-c84dfe5c8533

require github.com/morph-l2/go-ethereum v1.10.14-0.20241224100051-1582a364edc0
require github.com/morph-l2/go-ethereum v1.10.14-0.20241226065029-3b9465a03a8c

require (
github.com/VictoriaMetrics/fastcache v1.12.2 // indirect
Expand Down
4 changes: 2 additions & 2 deletions bindings/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqky
github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/morph-l2/go-ethereum v1.10.14-0.20241224100051-1582a364edc0 h1:w0RXAFr/x9fWNgQkcrmSnZseYCNkbBFDWgEIfSqhCeY=
github.com/morph-l2/go-ethereum v1.10.14-0.20241224100051-1582a364edc0/go.mod h1:sMJCfHOBzVRDkM2yF/Hy+oUk2rgC0CQZHTLs0cyzhhk=
github.com/morph-l2/go-ethereum v1.10.14-0.20241226065029-3b9465a03a8c h1:We0UnGcfs8wOSegGa97NjUE/6dZHE4ASuIWDuYBa+u8=
github.com/morph-l2/go-ethereum v1.10.14-0.20241226065029-3b9465a03a8c/go.mod h1:sMJCfHOBzVRDkM2yF/Hy+oUk2rgC0CQZHTLs0cyzhhk=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
Expand Down
2 changes: 1 addition & 1 deletion contracts/contracts/l1/rollup/IL1MessageQueue.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.16;
pragma solidity =0.8.24;

interface IL1MessageQueue {
/**********
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.16;
pragma solidity =0.8.24;

interface IL1MessageQueueWithGasPriceOracle {
/**********
Expand Down
6 changes: 4 additions & 2 deletions contracts/contracts/l1/rollup/IRollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ interface IRollup {

/// @param version The version of current batch.
/// @param parentBatchHeader The header of parent batch, see the comments of `BatchHeaderV0Codec`.
/// @param blockContexts The block contexts of current batch.
/// @param lastBlockNumber The last block number in this batch
/// @param numL1Messages The number of L1 messages in this batch
/// @param prevStateRoot The state root of parent batch.
/// @param postStateRoot The state root of current batch.
/// @param withdrawalRoot The withdraw trie root of current batch.
struct BatchDataInput {
uint8 version;
bytes parentBatchHeader;
bytes blockContexts;
uint64 lastBlockNumber;
uint16 numL1Messages;
bytes32 prevStateRoot;
bytes32 postStateRoot;
bytes32 withdrawalRoot;
Expand Down
136 changes: 51 additions & 85 deletions contracts/contracts/l1/rollup/Rollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity =0.8.24;
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import {BatchHeaderCodecV0} from "../../libraries/codec/BatchHeaderCodecV0.sol";
import {BatchCodecV0} from "../../libraries/codec/BatchCodecV0.sol";
import {BatchHeaderCodecV1} from "../../libraries/codec/BatchHeaderCodecV1.sol";
import {IRollupVerifier} from "../../libraries/verifier/IRollupVerifier.sol";
import {IL1MessageQueue} from "./IL1MessageQueue.sol";
import {IRollup} from "./IRollup.sol";
Expand Down Expand Up @@ -220,10 +220,7 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {
BatchDataInput calldata batchDataInput,
BatchSignatureInput calldata batchSignatureInput
) external payable override onlyActiveStaker nonReqRevert whenNotPaused {
require(batchDataInput.version == 0, "invalid version");
// check whether the batch is empty
uint256 _blockContextsLength = batchDataInput.blockContexts.length;
require(_blockContextsLength > 0, "batch is empty");
require(batchDataInput.version == 0 || batchDataInput.version == 1, "invalid version");
require(batchDataInput.prevStateRoot != bytes32(0), "previous state root is zero");
require(batchDataInput.postStateRoot != bytes32(0), "new state root is zero");

Expand All @@ -248,41 +245,46 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {

uint256 _totalL1MessagesPoppedOverall = BatchHeaderCodecV0.getTotalL1MessagePopped(_batchPtr);
// compute the data hash for batch
uint256 _totalL1MessagesPoppedInBatch;
uint256 _totalNumL1Messages;
bytes32 dataHash;
(dataHash, _totalNumL1Messages) = _commitBatch(
batchDataInput.blockContexts,
_totalL1MessagesPoppedInBatch,
bytes32 dataHash = _commitBatch(
batchDataInput.lastBlockNumber,
batchDataInput.numL1Messages,
_totalL1MessagesPoppedOverall
);

unchecked {
_totalL1MessagesPoppedInBatch += _totalNumL1Messages;
_totalL1MessagesPoppedOverall += _totalNumL1Messages;
_totalL1MessagesPoppedOverall += batchDataInput.numL1Messages;
}
assembly {
_batchIndex := add(_batchIndex, 1) // increase batch index
}
bytes32 _blobVersionedHash = (blobhash(0) == bytes32(0)) ? ZERO_VERSIONED_HASH : blobhash(0);

{
{
uint256 _headerLength = BatchHeaderCodecV0.BATCH_HEADER_LENGTH;
if (batchDataInput.version == 1) {
_headerLength = BatchHeaderCodecV1.BATCH_HEADER_LENGTH;
}
assembly {
_batchPtr := mload(0x40)
mstore(0x40, add(_batchPtr, mul(_headerLength, 32)))
mstore(0x40, add(_batchPtr, _headerLength))
}

// store entries, the order matters
BatchHeaderCodecV0.storeVersion(_batchPtr, batchDataInput.version);
BatchHeaderCodecV0.storeBatchIndex(_batchPtr, _batchIndex);
BatchHeaderCodecV0.storeL1MessagePopped(_batchPtr, _totalL1MessagesPoppedInBatch);
BatchHeaderCodecV0.storeL1MessagePopped(_batchPtr, batchDataInput.numL1Messages);
BatchHeaderCodecV0.storeTotalL1MessagePopped(_batchPtr, _totalL1MessagesPoppedOverall);
BatchHeaderCodecV0.storeDataHash(_batchPtr, dataHash);
BatchHeaderCodecV0.storeBlobVersionedHash(_batchPtr, _blobVersionedHash);
BatchHeaderCodecV0.storePrevStateHash(_batchPtr, batchDataInput.prevStateRoot);
BatchHeaderCodecV0.storePostStateHash(_batchPtr, batchDataInput.postStateRoot);
BatchHeaderCodecV0.storeWithdrawRootHash(_batchPtr, batchDataInput.withdrawalRoot);
BatchHeaderCodecV0.storeSequencerSetVerifyHash(_batchPtr, keccak256(batchSignatureInput.sequencerSets));
BatchHeaderCodecV0.storeParentBatchHash(_batchPtr, _parentBatchHash);
BatchHeaderCodecV0.storeBlobVersionedHash(_batchPtr, _blobVersionedHash);
// store last block number if version >= 1
if (batchDataInput.version >= 1) {
BatchHeaderCodecV1.storeLastBlockNumber(_batchPtr, batchDataInput.lastBlockNumber);
}
committedBatches[_batchIndex] = BatchHeaderCodecV0.computeBatchHash(_batchPtr, _headerLength);
committedStateRoots[_batchIndex] = batchDataInput.postStateRoot;
uint256 proveRemainingTime = 0;
Expand All @@ -294,7 +296,7 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {
batchDataStore[_batchIndex] = BatchData(
block.timestamp,
block.timestamp + finalizationPeriodSeconds + proveRemainingTime,
_loadL2BlockNumber(batchDataInput.blockContexts),
batchDataInput.lastBlockNumber,
// Before BLS is implemented, the accuracy of the sequencer set uploaded by rollup cannot be guaranteed.
// Therefore, if the batch is successfully challenged, only the submitter will be punished.
IL1Staking(l1StakingContract).getStakerBitmap(_msgSender()) // => batchSignature.signedSequencersBitmap
Expand Down Expand Up @@ -475,7 +477,7 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {
*****************************/

/// @dev proveState proves a batch by submitting a proof.
function proveState(bytes calldata _batchHeader, bytes calldata _batchProof) external nonReqRevert whenNotPaused {
function proveState(bytes calldata _batchHeader, bytes calldata _batchProof) external nonReqRevert whenNotPaused onlyActiveStaker{
// get batch data from batch header
(uint256 memPtr, bytes32 _batchHash) = _loadBatchHeader(_batchHeader);
// check batch hash
Expand Down Expand Up @@ -705,96 +707,64 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {
}
}

/// @notice Extract the version number from a batch header
/// @param batchHeader The encoded batch header bytes
/// @return version The version of the batch header
function _getBatchVersion(bytes calldata batchHeader) internal pure returns (uint8 version) {
require(batchHeader.length > 0, "Empty batch header");
version = uint8(batchHeader[0]); // Safe extraction of the first byte
}

/// @dev Internal function to load batch header from calldata to memory.
/// @param _batchHeader The batch header in calldata.
/// @return _memPtr The start memory offset of loaded batch header.
/// @return _batchHash The hash of the loaded batch header.
function _loadBatchHeader(bytes calldata _batchHeader) internal pure returns (uint256 _memPtr, bytes32 _batchHash) {
uint8 _version = _getBatchVersion(_batchHeader);

// load to memory
uint256 _length;
(_memPtr, _length) = BatchHeaderCodecV0.loadAndValidate(_batchHeader);
if (_version == 0) {
(_memPtr, _length) = BatchHeaderCodecV0.loadAndValidate(_batchHeader);
} else if (_version == 1) {
(_memPtr, _length) = BatchHeaderCodecV1.loadAndValidate(_batchHeader);
} else {
revert("Unsupported batch version");
}

// compute batch hash
// all the versions use the same way to compute batch hash
_batchHash = BatchHeaderCodecV0.computeBatchHash(_memPtr, _length);
}

/// @dev Internal function to load the latestL2BlockNumber.
/// @param _blockContexts The batch block contexts in memory.
function _loadL2BlockNumber(bytes memory _blockContexts) internal pure returns (uint256) {
uint256 blockPtr;
uint256 batchPtr;
assembly {
batchPtr := add(_blockContexts, 0x20)
blockPtr := add(batchPtr, 2)
}
uint256 _numBlocks = BatchCodecV0.validateBatchLength(batchPtr, _blockContexts.length);
for (uint256 i = 0; i < _numBlocks - 1; i++) {
unchecked {
blockPtr += BatchCodecV0.BLOCK_CONTEXT_LENGTH;
}
}
uint256 l2BlockNumber = BatchCodecV0.getBlockNumber(blockPtr);
return l2BlockNumber;
}

/// @dev Internal function to commit a batch with version 0.
/// @param _blockContexts The encoded block contexts to commit.
/// @param _totalL1MessagesPoppedInBatch The total number of L1 messages popped in current batch.
/// @param _lastBlockNumber The last block number in this batch.
/// @param _numL1Messages The number of L1 messages in this batch
/// @param _totalL1MessagesPoppedOverall The total number of L1 messages popped in all batches including current batch.
/// @return _dataHash The computed data hash for this batch.
/// @return _totalNumL1MessagesInBatch The total number of L1 message popped in current batch
function _commitBatch(
bytes memory _blockContexts,
uint256 _totalL1MessagesPoppedInBatch,
uint64 _lastBlockNumber,
uint16 _numL1Messages,
uint256 _totalL1MessagesPoppedOverall
) internal view returns (bytes32 _dataHash, uint256 _totalNumL1MessagesInBatch) {
uint256 batchPtr;
) internal view returns (bytes32 _dataHash) {
uint256 startDataPtr;
uint256 dataPtr;

assembly {
dataPtr := mload(0x40)
startDataPtr := dataPtr
batchPtr := add(_blockContexts, 0x20) // skip batchContexts.length
}

uint256 _numBlocks = BatchCodecV0.validateBatchLength(batchPtr, _blockContexts.length);
assembly {
batchPtr := add(batchPtr, 2) // skip numBlocks
}
// concatenate block contexts, use scope to avoid stack too deep
for (uint256 i = 0; i < _numBlocks; i++) {
dataPtr = BatchCodecV0.copyBlockContext(batchPtr, dataPtr, i);
uint256 blockPtr = batchPtr + i * BatchCodecV0.BLOCK_CONTEXT_LENGTH;
uint256 _numL1MessagesInBlock = BatchCodecV0.getNumL1Messages(blockPtr);
unchecked {
_totalNumL1MessagesInBatch += _numL1MessagesInBlock;
}
}
assembly {
mstore(0x40, add(dataPtr, mul(_totalNumL1MessagesInBatch, 0x20))) // reserve memory for l1 message hashes
mstore(dataPtr, shl(192, _lastBlockNumber)) // store lastBlockNumber
dataPtr := add(dataPtr, 8)
mstore(dataPtr, shl(240, _numL1Messages)) // store numL1Messages
dataPtr := add(dataPtr, 2)
mstore(0x40, add(dataPtr, mul(_numL1Messages, 0x20))) // reserve memory for l1 message hashes
}

// concatenate tx hashes
while (_numBlocks > 0) {
// concatenate l1 message hashes
uint256 _numL1MessagesInBlock = BatchCodecV0.getNumL1Messages(batchPtr);
dataPtr = _loadL1MessageHashes(
dataPtr,
_numL1MessagesInBlock,
_totalL1MessagesPoppedInBatch,
_totalL1MessagesPoppedOverall
);
uint256 _numTransactionsInBlock = BatchCodecV0.getNumTransactions(batchPtr);
require(_numTransactionsInBlock >= _numL1MessagesInBlock, "num txs less than num L1 msgs");
unchecked {
_totalL1MessagesPoppedInBatch += _numL1MessagesInBlock;
_totalL1MessagesPoppedOverall += _numL1MessagesInBlock;

_numBlocks -= 1;
batchPtr += BatchCodecV0.BLOCK_CONTEXT_LENGTH;
}
}
// concatenate l1 message hashes
dataPtr = _loadL1MessageHashes(dataPtr, _numL1Messages, _totalL1MessagesPoppedOverall);

// compute data hash and store to memory
assembly {
Expand All @@ -805,13 +775,11 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {
/// @dev Internal function to load L1 message hashes from the message queue.
/// @param _ptr The memory offset to store the transaction hash.
/// @param _numL1Messages The number of L1 messages to load.
/// @param _totalL1MessagesPoppedInBatch The total number of L1 messages popped in current batch.
/// @param _totalL1MessagesPoppedOverall The total number of L1 messages popped in all batches including current batch.
/// @return uint256 The new memory offset after loading.
function _loadL1MessageHashes(
uint256 _ptr,
uint256 _numL1Messages,
uint256 _totalL1MessagesPoppedInBatch,
uint256 _totalL1MessagesPoppedOverall
) internal view returns (uint256) {
if (_numL1Messages == 0) {
Expand All @@ -826,8 +794,6 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {
mstore(_ptr, _hash)
_ptr := add(_ptr, 0x20)
}

_totalL1MessagesPoppedInBatch += 1;
_totalL1MessagesPoppedOverall += 1;
}
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/contracts/l2/staking/IDistribute.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;
pragma solidity =0.8.24;

import {EnumerableSetUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol";

Expand Down
2 changes: 1 addition & 1 deletion contracts/contracts/l2/system/IMorphToken.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;
pragma solidity =0.8.24;

import {IERC20MetadataUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol";

Expand Down
2 changes: 1 addition & 1 deletion contracts/contracts/l2/system/MorphToken.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;
pragma solidity =0.8.24;

import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

Expand Down
2 changes: 1 addition & 1 deletion contracts/contracts/l2/system/WrappedEther.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;
pragma solidity =0.8.24;

import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {ERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";
Expand Down
2 changes: 1 addition & 1 deletion contracts/contracts/libraries/ICrossDomainMessenger.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.9;
pragma solidity =0.8.24;

interface ICrossDomainMessenger {
/***********
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.9;
pragma solidity =0.8.24;

interface IERC677Receiver {
function onTokenTransfer(address sender, uint256 value, bytes memory data) external;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.9;
pragma solidity =0.8.24;

interface IGatewayCallback {
function onGatewayCallback(bytes memory data) external;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.9;
pragma solidity =0.8.24;

interface IMessageDropCallback {
function onDropMessage(bytes memory message) external payable;
Expand Down
Loading

0 comments on commit a1c6c5f

Please sign in to comment.