Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Remove skipMap from batch #658

Open
wants to merge 2 commits into
base: release/0.4.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
16 changes: 16 additions & 0 deletions MakefileEc2.mk
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,19 @@ build-bk-prod-morph-prod-mainnet-to-morph-tx-submitter:
cp tx-submitter/tx-submitter dist/
tar -czvf tx-submitter.tar.gz dist
aws s3 cp tx-submitter.tar.gz s3://morph-0582-morph-technical-department-mainnet-data/morph-setup/tx-submitter.tar.gz

# build for holesky
build-bk-prod-morph-prod-testnet-to-morph-node-holesky:
if [ ! -d dist ]; then mkdir -p dist; fi
cd $(PWD)/node && make build
cp node/build/bin/morphnode dist/
cp node/build/bin/tendermint dist/
tar -czvf morph-node.tar.gz dist
aws s3 cp morph-node.tar.gz s3://morph-0582-morph-technical-department-testnet-data/testnet/holesky/morph-setup/morph-node.tar.gz

build-bk-prod-morph-prod-testnet-to-morph-tx-submitter-holesky:
if [ ! -d dist ]; then mkdir -p dist; fi
env GO111MODULE=on CGO_LDFLAGS="-ldl" CGO_ENABLED=1 go build -v $(LDFLAGS) -o tx-submitter/tx-submitter ./tx-submitter/cmd
cp tx-submitter/tx-submitter dist/
tar -czvf tx-submitter.tar.gz dist
aws s3 cp tx-submitter.tar.gz s3://morph-0582-morph-technical-department-testnet-data/testnet/holesky/morph-setup/tx-submitter.tar.gz

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
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 @@ -254,28 +254,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 @@ -291,7 +282,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 @@ -540,7 +530,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 @@ -605,25 +594,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 @@ -758,14 +741,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 @@ -802,8 +783,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 @@ -827,49 +807,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
Loading
Loading