Skip to content

Commit

Permalink
Merge branch 'main' into fix-claim-all
Browse files Browse the repository at this point in the history
  • Loading branch information
SegueII authored Nov 14, 2024
2 parents 55f2252 + 65b99be commit 4dca79f
Show file tree
Hide file tree
Showing 72 changed files with 1,372 additions and 887 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 = release/2.0.x
branch = main
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
################## update dependencies ####################

ETHEREUM_TARGET_VERSION := morph-v2.0.1
ETHEREUM_TARGET_VERSION := v1.10.14-0.20241105040223-5c7f1bb7073e
TENDERMINT_TARGET_VERSION := v0.3.1

ETHEREUM_MODULE_NAME := github.com/morph-l2/go-ethereum
Expand Down
2 changes: 1 addition & 1 deletion bindings/bin/l1messagequeuewithgaspriceoracle_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.

78 changes: 23 additions & 55 deletions bindings/bindings/l1messagequeuewithgaspriceoracle.go

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions bindings/bindings/l1messagequeuewithgaspriceoracle_more.go

Large diffs are not rendered by default.

29 changes: 14 additions & 15 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.

2 changes: 1 addition & 1 deletion bindings/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.22

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

require github.com/morph-l2/go-ethereum v1.10.14-0.20241021080617-0ff2a10a9625
require github.com/morph-l2/go-ethereum v1.10.14-0.20241105040223-5c7f1bb7073e

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.20241021080617-0ff2a10a9625 h1:4+cbRSS4lacSIC81RXxvA04UHhGVC4SHVn+bKeqhPSM=
github.com/morph-l2/go-ethereum v1.10.14-0.20241021080617-0ff2a10a9625/go.mod h1:sMJCfHOBzVRDkM2yF/Hy+oUk2rgC0CQZHTLs0cyzhhk=
github.com/morph-l2/go-ethereum v1.10.14-0.20241105040223-5c7f1bb7073e h1:pV7z8mnNQr+JJO2CGUzwAlzjrPnZ0YlO92izBaq00Zs=
github.com/morph-l2/go-ethereum v1.10.14-0.20241105040223-5c7f1bb7073e/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
10 changes: 2 additions & 8 deletions contracts/contracts/l1/rollup/IL1MessageQueue.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ interface IL1MessageQueue {
/// @notice Emitted when some L1 => L2 transactions are included in L1.
/// @param startIndex The start index of messages popped.
/// @param count The number of messages popped.
/// @param skippedBitmap A bitmap indicates whether a message is skipped.
event DequeueTransaction(uint256 startIndex, uint256 count, uint256 skippedBitmap);
event DequeueTransaction(uint256 startIndex, uint256 count);

/// @notice Emitted when a message is dropped from L1.
/// @param index The index of message dropped.
Expand Down Expand Up @@ -96,10 +95,6 @@ interface IL1MessageQueue {
bytes calldata data
) external view returns (bytes32);

/// @notice Return whether the message is skipped.
/// @param queueIndex The queue index of the message to check.
function isMessageSkipped(uint256 queueIndex) external view returns (bool);

/// @notice Return whether the message is dropped.
/// @param queueIndex The queue index of the message to check.
function isMessageDropped(uint256 queueIndex) external view returns (bool);
Expand Down Expand Up @@ -136,8 +131,7 @@ interface IL1MessageQueue {
///
/// @param startIndex The start index to pop.
/// @param count The number of messages to pop.
/// @param skippedBitmap A bitmap indicates whether a message is skipped.
function popCrossDomainMessage(uint256 startIndex, uint256 count, uint256 skippedBitmap) external;
function popCrossDomainMessage(uint256 startIndex, uint256 count) external;

/// @notice Drop a skipped message from the queue.
function dropCrossDomainMessage(uint256 index) external;
Expand Down
2 changes: 0 additions & 2 deletions contracts/contracts/l1/rollup/IRollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@ 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 skippedL1MessageBitmap The bitmap indicates whether each L1 message is skipped or not.
/// @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;
bytes skippedL1MessageBitmap;
bytes32 prevStateRoot;
bytes32 postStateRoot;
bytes32 withdrawalRoot;
Expand Down
37 changes: 5 additions & 32 deletions contracts/contracts/l1/rollup/L1MessageQueueWithGasPriceOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ contract L1MessageQueueWithGasPriceOracle is OwnableUpgradeable, IL1MessageQueue
/// @dev The bitmap for dropped messages, where `droppedMessageBitmap[i]` keeps the bits from `[i*256, (i+1)*256)`.
BitMapsUpgradeable.BitMap private droppedMessageBitmap;

/// @dev The bitmap for skipped messages, where `skippedMessageBitmap[i]` keeps the bits from `[i*256, (i+1)*256)`.
mapping(uint256 => uint256) private skippedMessageBitmap;
/// @dev The bitmap for skipped messages, where `skippedMessageBitmap[i]` keeps the bits from `[i*256, (i+1)*256)`. Deprecated.
mapping(uint256 => uint256) private __skippedMessageBitmap;

/// @inheritdoc IL1MessageQueueWithGasPriceOracle
address public whitelistChecker;
Expand Down Expand Up @@ -260,17 +260,9 @@ contract L1MessageQueueWithGasPriceOracle is OwnableUpgradeable, IL1MessageQueue
return hash;
}

/// @inheritdoc IL1MessageQueue
function isMessageSkipped(uint256 _queueIndex) external view returns (bool) {
if (_queueIndex >= pendingQueueIndex) return false;

return _isMessageSkipped(_queueIndex);
}

/// @inheritdoc IL1MessageQueue
function isMessageDropped(uint256 _queueIndex) external view returns (bool) {
// it should be a skipped message first.
return _isMessageSkipped(_queueIndex) && droppedMessageBitmap.get(_queueIndex);
return droppedMessageBitmap.get(_queueIndex);
}

/*****************************
Expand Down Expand Up @@ -320,35 +312,23 @@ contract L1MessageQueueWithGasPriceOracle is OwnableUpgradeable, IL1MessageQueue
}

/// @inheritdoc IL1MessageQueue
function popCrossDomainMessage(uint256 _startIndex, uint256 _count, uint256 _skippedBitmap) external {
function popCrossDomainMessage(uint256 _startIndex, uint256 _count) external {
require(_msgSender() == ROLLUP_CONTRACT, "Only callable by the rollup");

require(_count <= 256, "pop too many messages");
require(pendingQueueIndex == _startIndex, "start index mismatch");

unchecked {
// clear extra bits in `_skippedBitmap`, and if _count = 256, it's designed to overflow.
uint256 mask = (1 << _count) - 1;
_skippedBitmap &= mask;

uint256 bucket = _startIndex >> 8;
uint256 offset = _startIndex & 0xff;
skippedMessageBitmap[bucket] |= _skippedBitmap << offset;
if (offset + _count > 256) {
skippedMessageBitmap[bucket + 1] = _skippedBitmap >> (256 - offset);
}

pendingQueueIndex = _startIndex + _count;
}

emit DequeueTransaction(_startIndex, _count, _skippedBitmap);
emit DequeueTransaction(_startIndex, _count);
}

/// @inheritdoc IL1MessageQueue
function dropCrossDomainMessage(uint256 _index) external onlyMessenger {
require(_index < pendingQueueIndex, "cannot drop pending message");

require(_isMessageSkipped(_index), "drop non-skipped message");
require(!droppedMessageBitmap.get(_index), "message already dropped");
droppedMessageBitmap.set(_index);

Expand Down Expand Up @@ -409,11 +389,4 @@ contract L1MessageQueueWithGasPriceOracle is OwnableUpgradeable, IL1MessageQueue
uint256 intrinsicGas = calculateIntrinsicGasFee(_calldata);
require(_gasLimit >= intrinsicGas, "Insufficient gas limit, must be above intrinsic gas");
}

/// @dev Returns whether the bit at `index` is set.
function _isMessageSkipped(uint256 index) internal view returns (bool) {
uint256 bucket = index >> 8;
uint256 mask = 1 << (index & 0xff);
return skippedMessageBitmap[bucket] & mask != 0;
}
}
62 changes: 11 additions & 51 deletions contracts/contracts/l1/rollup/Rollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -243,28 +243,19 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {
(dataHash, _totalNumL1Messages) = _commitBatch(
batchDataInput.blockContexts,
_totalL1MessagesPoppedInBatch,
_totalL1MessagesPoppedOverall,
batchDataInput.skippedL1MessageBitmap
_totalL1MessagesPoppedOverall
);
unchecked {
_totalL1MessagesPoppedInBatch += _totalNumL1Messages;
_totalL1MessagesPoppedOverall += _totalNumL1Messages;
}
// check the length of bitmap
unchecked {
require(
((_totalL1MessagesPoppedInBatch + 255) / 256) * 32 == batchDataInput.skippedL1MessageBitmap.length,
"wrong bitmap length"
);
}
assembly {
_batchIndex := add(_batchIndex, 1) // increase batch index
}
bytes32 _blobVersionedHash = (blobhash(0) == bytes32(0)) ? ZERO_VERSIONED_HASH : blobhash(0);

{
uint256 _headerLength = BatchHeaderCodecV0.BATCH_HEADER_FIXED_LENGTH +
batchDataInput.skippedL1MessageBitmap.length;
uint256 _headerLength = BatchHeaderCodecV0.BATCH_HEADER_LENGTH;
assembly {
_batchPtr := mload(0x40)
mstore(0x40, add(_batchPtr, mul(_headerLength, 32)))
Expand All @@ -280,7 +271,6 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {
BatchHeaderCodecV0.storeWithdrawRootHash(_batchPtr, batchDataInput.withdrawalRoot);
BatchHeaderCodecV0.storeSequencerSetVerifyHash(_batchPtr, keccak256(batchSignatureInput.sequencerSets));
BatchHeaderCodecV0.storeParentBatchHash(_batchPtr, _parentBatchHash);
BatchHeaderCodecV0.storeSkippedBitmap(_batchPtr, batchDataInput.skippedL1MessageBitmap);
BatchHeaderCodecV0.storeBlobVersionedHash(_batchPtr, _blobVersionedHash);
committedBatches[_batchIndex] = BatchHeaderCodecV0.computeBatchHash(_batchPtr, _headerLength);
committedStateRoots[_batchIndex] = batchDataInput.postStateRoot;
Expand Down Expand Up @@ -529,7 +519,6 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {

// Pop finalized and non-skipped message from L1MessageQueue.
_popL1Messages(
BatchHeaderCodecV0.getSkippedBitmapPtr(memPtr),
BatchHeaderCodecV0.getTotalL1MessagePopped(memPtr),
BatchHeaderCodecV0.getL1MessagePopped(memPtr)
);
Expand Down Expand Up @@ -594,25 +583,19 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {
**********************/

/// @dev Internal function to pop finalized l1 messages.
/// @param bitmapPtr The memory offset of `skippedL1MessageBitmap`.
/// @param totalL1MessagePopped The total number of L1 messages popped in all batches including current batch.
/// @param l1MessagePopped The number of L1 messages popped in current batch.
function _popL1Messages(uint256 bitmapPtr, uint256 totalL1MessagePopped, uint256 l1MessagePopped) internal {
function _popL1Messages(uint256 totalL1MessagePopped, uint256 l1MessagePopped) internal {
if (l1MessagePopped == 0) return;
unchecked {
uint256 startIndex = totalL1MessagePopped - l1MessagePopped;
uint256 bitmap;

for (uint256 i = 0; i < l1MessagePopped; i += 256) {
uint256 _count = 256;
if (l1MessagePopped - i < _count) {
_count = l1MessagePopped - i;
}
assembly {
bitmap := mload(bitmapPtr)
bitmapPtr := add(bitmapPtr, 0x20)
}
IL1MessageQueue(messageQueue).popCrossDomainMessage(startIndex, _count, bitmap);
IL1MessageQueue(messageQueue).popCrossDomainMessage(startIndex, _count);
startIndex += 256;
}
}
Expand Down Expand Up @@ -747,14 +730,12 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {
/// @param _blockContexts The encoded block contexts to commit.
/// @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.
/// @param _skippedL1MessageBitmap The bitmap indicates whether each L1 message is skipped or not.
/// @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,
uint256 _totalL1MessagesPoppedOverall,
bytes calldata _skippedL1MessageBitmap
uint256 _totalL1MessagesPoppedOverall
) internal view returns (bytes32 _dataHash, uint256 _totalNumL1MessagesInBatch) {
uint256 batchPtr;
uint256 startDataPtr;
Expand Down Expand Up @@ -791,8 +772,7 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {
dataPtr,
_numL1MessagesInBlock,
_totalL1MessagesPoppedInBatch,
_totalL1MessagesPoppedOverall,
_skippedL1MessageBitmap
_totalL1MessagesPoppedOverall
);
uint256 _numTransactionsInBlock = BatchCodecV0.getNumTransactions(batchPtr);
require(_numTransactionsInBlock >= _numL1MessagesInBlock, "num txs less than num L1 msgs");
Expand All @@ -816,49 +796,29 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {
/// @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.
/// @param _skippedL1MessageBitmap The bitmap indicates whether each L1 message is skipped or not.
/// @return uint256 The new memory offset after loading.
function _loadL1MessageHashes(
uint256 _ptr,
uint256 _numL1Messages,
uint256 _totalL1MessagesPoppedInBatch,
uint256 _totalL1MessagesPoppedOverall,
bytes calldata _skippedL1MessageBitmap
uint256 _totalL1MessagesPoppedOverall
) internal view returns (uint256) {
if (_numL1Messages == 0) {
return _ptr;
}
IL1MessageQueue _messageQueue = IL1MessageQueue(messageQueue);

unchecked {
uint256 _bitmap;
uint256 rem;
for (uint256 i = 0; i < _numL1Messages; i++) {
uint256 quo = _totalL1MessagesPoppedInBatch >> 8;
rem = _totalL1MessagesPoppedInBatch & 0xff;

// load bitmap every 256 bits
if (i == 0 || rem == 0) {
assembly {
_bitmap := calldataload(add(_skippedL1MessageBitmap.offset, mul(0x20, quo)))
}
}
if (((_bitmap >> rem) & 1) == 0) {
// message not skipped
bytes32 _hash = _messageQueue.getCrossDomainMessage(_totalL1MessagesPoppedOverall);
assembly {
mstore(_ptr, _hash)
_ptr := add(_ptr, 0x20)
}
bytes32 _hash = _messageQueue.getCrossDomainMessage(_totalL1MessagesPoppedOverall);
assembly {
mstore(_ptr, _hash)
_ptr := add(_ptr, 0x20)
}

_totalL1MessagesPoppedInBatch += 1;
_totalL1MessagesPoppedOverall += 1;
}

// check last L1 message is not skipped, _totalL1MessagesPoppedInBatch must > 0
rem = (_totalL1MessagesPoppedInBatch - 1) & 0xff;
require(((_bitmap >> rem) & 1) == 0, "cannot skip last L1 message");
}

return _ptr;
Expand Down
45 changes: 2 additions & 43 deletions contracts/contracts/libraries/codec/BatchHeaderCodecV0.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,24 @@ pragma solidity ^0.8.24;
/// * withdrawRootHash 32 bytes32 153 L2 withdrawal tree root hash
/// * sequencerSetVerifyHash 32 bytes32 185 L2 sequencers set verify hash
/// * parentBatchHash 32 bytes32 217 The parent batch hash
/// * skippedL1MessageBitmap dynamic uint256[] 249 A bitmap to indicate which L1 messages are skipped in the batch
/// ```
library BatchHeaderCodecV0 {
/// @dev The length of fixed parts of the batch header.
uint256 internal constant BATCH_HEADER_FIXED_LENGTH = 249;
uint256 internal constant BATCH_HEADER_LENGTH = 249;

/// @notice Load batch header in calldata to memory.
/// @param _batchHeader The encoded batch header bytes in calldata.
/// @return batchPtr The start memory offset of the batch header in memory.
/// @return length The length in bytes of the batch header.
function loadAndValidate(bytes calldata _batchHeader) internal pure returns (uint256 batchPtr, uint256 length) {
length = _batchHeader.length;
require(length >= BATCH_HEADER_FIXED_LENGTH, "batch header length too small");
require(length == BATCH_HEADER_LENGTH, "batch header length must be 249");
// copy batch header to memory.
assembly {
batchPtr := mload(0x40)
calldatacopy(batchPtr, _batchHeader.offset, length)
mstore(0x40, add(batchPtr, length))
}

// check batch header length
uint256 _l1MessagePopped = getL1MessagePopped(batchPtr);

unchecked {
require(length == BATCH_HEADER_FIXED_LENGTH + ((_l1MessagePopped + 255) / 256) * 32, "wrong bitmap length");
}
}

/// @notice Get the version of the batch header.
Expand Down Expand Up @@ -133,26 +125,6 @@ library BatchHeaderCodecV0 {
}
}

/// @notice Get the start memory offset for skipped L1 messages bitmap.
/// @param batchPtr The start memory offset of the batch header in memory.
/// @return _bitmapPtr the start memory offset for skipped L1 messages bitmap.
function getSkippedBitmapPtr(uint256 batchPtr) internal pure returns (uint256 _bitmapPtr) {
assembly {
_bitmapPtr := add(batchPtr, BATCH_HEADER_FIXED_LENGTH)
}
}

/// @notice Get the skipped L1 messages bitmap.
/// @param batchPtr The start memory offset of the batch header in memory.
/// @param index The index of bitmap to load.
/// @return _bitmap The bitmap from bits `index * 256` to `index * 256 + 255`.
function getSkippedBitmap(uint256 batchPtr, uint256 index) internal pure returns (uint256 _bitmap) {
assembly {
batchPtr := add(batchPtr, BATCH_HEADER_FIXED_LENGTH)
_bitmap := mload(add(batchPtr, mul(index, 32)))
}
}

/// @notice Store the version of batch header.
/// @param batchPtr The start memory offset of the batch header in memory.
/// @param _version The version of batch header.
Expand Down Expand Up @@ -258,19 +230,6 @@ library BatchHeaderCodecV0 {
}
}

/// @notice Store the skipped L1 message bitmap of batch header.
/// @param batchPtr The start memory offset of the batch header in memory.
/// @param _skippedL1MessageBitmap The skipped L1 message bitmap.
function storeSkippedBitmap(uint256 batchPtr, bytes calldata _skippedL1MessageBitmap) internal pure {
assembly {
calldatacopy(
add(batchPtr, BATCH_HEADER_FIXED_LENGTH),
_skippedL1MessageBitmap.offset,
_skippedL1MessageBitmap.length
)
}
}

/// @notice Compute the batch hash.
/// @dev Caller should make sure that the encoded batch header is correct.
///
Expand Down
Loading

0 comments on commit 4dca79f

Please sign in to comment.