From 20ea287e32c7f6657f9c0ca38e583ed48b8dc890 Mon Sep 17 00:00:00 2001 From: Xi Lin Date: Mon, 6 Nov 2023 00:04:53 -0600 Subject: [PATCH] feat(contracts): remove proof verification on `finalizeBatchWithProof` (#1003) --- contracts/docs/apis/ScrollChain.md | 19 ++++++++ contracts/src/L1/rollup/IScrollChain.sol | 12 +++++ contracts/src/L1/rollup/ScrollChain.sol | 57 ++++++++++++++++++++++++ 3 files changed, 88 insertions(+) diff --git a/contracts/docs/apis/ScrollChain.md b/contracts/docs/apis/ScrollChain.md index 1a4fe5a55d..67a418da8a 100644 --- a/contracts/docs/apis/ScrollChain.md +++ b/contracts/docs/apis/ScrollChain.md @@ -83,6 +83,25 @@ Return the batch hash of a committed batch. |---|---|---| | _0 | bytes32 | undefined | +### finalizeBatch + +```solidity +function finalizeBatch(bytes _batchHeader, bytes32 _prevStateRoot, bytes32 _postStateRoot, bytes32 _withdrawRoot) external nonpayable +``` + + + + + +#### Parameters + +| Name | Type | Description | +|---|---|---| +| _batchHeader | bytes | undefined | +| _prevStateRoot | bytes32 | undefined | +| _postStateRoot | bytes32 | undefined | +| _withdrawRoot | bytes32 | undefined | + ### finalizeBatchWithProof ```solidity diff --git a/contracts/src/L1/rollup/IScrollChain.sol b/contracts/src/L1/rollup/IScrollChain.sol index 9f86c2046e..7f2f4ca6a3 100644 --- a/contracts/src/L1/rollup/IScrollChain.sol +++ b/contracts/src/L1/rollup/IScrollChain.sol @@ -83,4 +83,16 @@ interface IScrollChain { bytes32 withdrawRoot, bytes calldata aggrProof ) external; + + /// @notice Finalize a committed batch on layer 1 without providing proof. + /// @param batchHeader The header of current batch, see the encoding in comments of `commitBatch. + /// @param prevStateRoot The state root of parent batch. + /// @param postStateRoot The state root of current batch. + /// @param withdrawRoot The withdraw trie root of current batch. + function finalizeBatch( + bytes calldata batchHeader, + bytes32 prevStateRoot, + bytes32 postStateRoot, + bytes32 withdrawRoot + ) external; } diff --git a/contracts/src/L1/rollup/ScrollChain.sol b/contracts/src/L1/rollup/ScrollChain.sol index b254304f01..65f8a4d4af 100644 --- a/contracts/src/L1/rollup/ScrollChain.sol +++ b/contracts/src/L1/rollup/ScrollChain.sol @@ -353,6 +353,63 @@ contract ScrollChain is OwnableUpgradeable, PausableUpgradeable, IScrollChain { emit FinalizeBatch(_batchIndex, _batchHash, _postStateRoot, _withdrawRoot); } + /// @inheritdoc IScrollChain + function finalizeBatch( + bytes calldata _batchHeader, + bytes32 _prevStateRoot, + bytes32 _postStateRoot, + bytes32 _withdrawRoot + ) external override OnlyProver whenNotPaused { + require(_prevStateRoot != bytes32(0), "previous state root is zero"); + require(_postStateRoot != bytes32(0), "new state root is zero"); + + // compute batch hash and verify + (uint256 memPtr, bytes32 _batchHash) = _loadBatchHeader(_batchHeader); + + uint256 _batchIndex = BatchHeaderV0Codec.batchIndex(memPtr); + require(committedBatches[_batchIndex] == _batchHash, "incorrect batch hash"); + + // verify previous state root. + require(finalizedStateRoots[_batchIndex - 1] == _prevStateRoot, "incorrect previous state root"); + + // avoid duplicated verification + require(finalizedStateRoots[_batchIndex] == bytes32(0), "batch already verified"); + + // check and update lastFinalizedBatchIndex + unchecked { + require(lastFinalizedBatchIndex + 1 == _batchIndex, "incorrect batch index"); + lastFinalizedBatchIndex = _batchIndex; + } + + // record state root and withdraw root + finalizedStateRoots[_batchIndex] = _postStateRoot; + withdrawRoots[_batchIndex] = _withdrawRoot; + + // Pop finalized and non-skipped message from L1MessageQueue. + uint256 _l1MessagePopped = BatchHeaderV0Codec.l1MessagePopped(memPtr); + if (_l1MessagePopped > 0) { + IL1MessageQueue _queue = IL1MessageQueue(messageQueue); + + unchecked { + uint256 _startIndex = BatchHeaderV0Codec.totalL1MessagePopped(memPtr) - _l1MessagePopped; + + for (uint256 i = 0; i < _l1MessagePopped; i += 256) { + uint256 _count = 256; + if (_l1MessagePopped - i < _count) { + _count = _l1MessagePopped - i; + } + uint256 _skippedBitmap = BatchHeaderV0Codec.skippedBitmap(memPtr, i / 256); + + _queue.popCrossDomainMessage(_startIndex, _count, _skippedBitmap); + + _startIndex += 256; + } + } + } + + emit FinalizeBatch(_batchIndex, _batchHash, _postStateRoot, _withdrawRoot); + } + /************************ * Restricted Functions * ************************/