Skip to content
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 bindings/bin/rollup_deployed.hex

Large diffs are not rendered by default.

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

Large diffs are not rendered by default.

85 changes: 83 additions & 2 deletions bindings/bindings/rollup.go

Large diffs are not rendered by default.

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

Large diffs are not rendered by default.

35 changes: 33 additions & 2 deletions bindings/bindings/zkevmverifierv1.go

Large diffs are not rendered by default.

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

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions contracts/contracts/l1/rollup/IRollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,13 @@ interface IRollup {
BatchSignatureInput calldata batchSignatureInput
) external payable;

/// @notice Commit batch state when blob hash is already stored (recommit after revert without blob).
/// @dev Requires batchBlobVersionedHashes[nextBatchIndex] != 0.
function commitState(
BatchDataInput calldata batchDataInput,
BatchSignatureInput calldata batchSignatureInput
) external;

/// @notice Commit a batch with ZKP proof for permissionless submission.
/// @dev This function allows anyone to submit batches when the sequencer is offline or censoring.
///
Expand Down
62 changes: 54 additions & 8 deletions contracts/contracts/l1/rollup/Rollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {IL1Staking} from "../staking/IL1Staking.sol";

/// @title Rollup
/// @notice This contract maintains data for the Morph rollup.
/// +----------------------+--------+---------+--------+--------------------------------------------------+
contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {
/*************
* Constants *
Expand Down Expand Up @@ -104,6 +105,10 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {
/// @dev After this period, anyone can submit batches if sequencers are offline or censoring.
uint256 public rollupDelayPeriod;

/// @notice Store blob versioned hash per batch index. Preserved across revertBatch so recommit can reuse.
/// @dev Placed after rollupDelayPeriod for upgrade-safe storage layout (forward compatibility).
mapping(uint256 batchIndex => bytes32 blobVersionedHash) public batchBlobVersionedHashes;

/**********************
* Function Modifiers *
**********************/
Expand All @@ -116,13 +121,13 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {

/// @notice Only challenger allowed.
modifier onlyChallenger() {
require(isChallenger[_msgSender()], "caller challenger allowed");
require(isChallenger[_msgSender()], "only challenger allowed");
_;
}

/// @notice Modifier to ensure that there is no pending revert request.
modifier nonReqRevert() {
require(revertReqIndex == 0, "need revert");
require(revertReqIndex == 0, "pending revert request");
_;
}

Expand Down Expand Up @@ -217,6 +222,7 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {

committedBatches[_batchIndex] = _batchHash;
batchDataStore[_batchIndex] = BatchData(block.timestamp, block.timestamp, 0, 0);
batchBlobVersionedHashes[_batchIndex] = BatchHeaderCodecV0.getBlobVersionedHash(memPtr);

committedStateRoots[_batchIndex] = _postStateRoot;
finalizedStateRoots[_batchIndex] = _postStateRoot;
Expand All @@ -232,20 +238,49 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {
BatchDataInput calldata batchDataInput,
BatchSignatureInput calldata batchSignatureInput
) external payable override onlyActiveStaker nonReqRevert whenNotPaused {
// check l1msg delay - sequencer must process L1 messages when delayed
// check if the next batch has a stored blob hash
(uint256 _batchPtr, ) = _loadBatchHeader(batchDataInput.parentBatchHeader);
uint256 _nextBatchIndex = BatchHeaderCodecV0.getBatchIndex(_batchPtr) + 1;
require(batchBlobVersionedHashes[_nextBatchIndex] == bytes32(0), "commitBatch requires no stored blob hash");
if (
IL1MessageQueue(messageQueue).getFirstUnfinalizedMessageEnqueueTime() + rollupDelayPeriod < block.timestamp
) {
require(batchDataInput.numL1Messages > 0, "l1msg delay");
}
uint256 submitterBitmap = IL1Staking(l1StakingContract).getStakerBitmap(_msgSender());
bytes32 _blobVersionedHash = (blobhash(0) == bytes32(0)) ? ZERO_VERSIONED_HASH : blobhash(0);
_commitBatchWithBatchData(batchDataInput, batchSignatureInput, submitterBitmap, _blobVersionedHash);
}

/// @inheritdoc IRollup
/// @notice Commit batch state when blob hash is already stored (recommit after revert without blob).
function commitState(
BatchDataInput calldata batchDataInput,
BatchSignatureInput calldata batchSignatureInput
) external override onlyActiveStaker nonReqRevert whenNotPaused {
require(blobhash(0) == bytes32(0), "commitState must not carry blob");
(uint256 _batchPtr, ) = _loadBatchHeader(batchDataInput.parentBatchHeader);
uint256 _nextBatchIndex = BatchHeaderCodecV0.getBatchIndex(_batchPtr) + 1;
require(batchBlobVersionedHashes[_nextBatchIndex] != bytes32(0), "no stored blob hash for this batch");
if (
IL1MessageQueue(messageQueue).getFirstUnfinalizedMessageEnqueueTime() + rollupDelayPeriod < block.timestamp
) {
require(batchDataInput.numL1Messages > 0, "l1msg delay");
}
uint256 submitterBitmap = IL1Staking(l1StakingContract).getStakerBitmap(_msgSender());
_commitBatchWithBatchData(batchDataInput, batchSignatureInput, submitterBitmap);
_commitBatchWithBatchData(
batchDataInput,
batchSignatureInput,
submitterBitmap,
batchBlobVersionedHashes[_nextBatchIndex]
);
}

function _commitBatchWithBatchData(
BatchDataInput calldata batchDataInput,
BatchSignatureInput calldata batchSignatureInput,
uint256 submitterBitmap
uint256 submitterBitmap,
bytes32 blobVersionedHash
) internal {
require(batchDataInput.version == 0 || batchDataInput.version == 1, "invalid version");
require(batchDataInput.prevStateRoot != bytes32(0), "previous state root is zero");
Expand Down Expand Up @@ -284,7 +319,7 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {
assembly {
_batchIndex := add(_batchIndex, 1) // increase batch index
}
bytes32 _blobVersionedHash = (blobhash(0) == bytes32(0)) ? ZERO_VERSIONED_HASH : blobhash(0);
bytes32 _blobVersionedHash = blobVersionedHash;

{
uint256 _headerLength = BatchHeaderCodecV0.BATCH_HEADER_LENGTH;
Expand Down Expand Up @@ -314,6 +349,7 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {
}
committedBatches[_batchIndex] = BatchHeaderCodecV0.computeBatchHash(_batchPtr, _headerLength);
committedStateRoots[_batchIndex] = batchDataInput.postStateRoot;
batchBlobVersionedHashes[_batchIndex] = _blobVersionedHash;
uint256 proveRemainingTime = 0;
if (inChallenge) {
// Make the batch finalize time longer than the time required for the current challenge
Expand Down Expand Up @@ -368,8 +404,17 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {
require(batchDataInput.numL1Messages > 0, "l1msg delay");
}
require(rollupDelay || l1MsgQueueDelayed, "invalid timing");

_commitBatchWithBatchData(batchDataInput, batchSignatureInput,0);
// check if the next batch has a stored blob hash
(uint256 _batchPtr, ) = _loadBatchHeader(batchDataInput.parentBatchHeader);
uint256 _nextBatchIndex = BatchHeaderCodecV0.getBatchIndex(_batchPtr) + 1;
bytes32 _blobVersionedHash = bytes32(0);
if (batchBlobVersionedHashes[_nextBatchIndex] != bytes32(0)) {
require(blobhash(0) == bytes32(0), "must not carry blob when using stored blob hash");
_blobVersionedHash = batchBlobVersionedHashes[_nextBatchIndex];
} else {
_blobVersionedHash = (blobhash(0) == bytes32(0)) ? ZERO_VERSIONED_HASH : blobhash(0);
}
_commitBatchWithBatchData(batchDataInput, batchSignatureInput, 0, _blobVersionedHash);

// get batch data from batch header
(uint256 memPtr, bytes32 _batchHash) = _loadBatchHeader(_batchHeader);
Expand Down Expand Up @@ -617,6 +662,7 @@ contract Rollup is IRollup, OwnableUpgradeable, PausableUpgradeable {

delete batchDataStore[_batchIndex - 1];
delete committedStateRoots[_batchIndex - 1];
delete batchBlobVersionedHashes[_batchIndex - 1];
delete challenges[_batchIndex - 1];

emit FinalizeBatch(
Expand Down
Loading
Loading