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

Change Executor.sol interface #780

Merged
merged 7 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
17 changes: 17 additions & 0 deletions l1-contracts/contracts/common/L1ContractErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,23 @@ error ZeroBalance();
// 0xc84885d4
error ZeroChainId();

error PubdataIsEmpty();
vladbochok marked this conversation as resolved.
Show resolved Hide resolved

error EmptyData();

error UnsupportedCommitBatchEncoding(uint8 version);

error UnsupportedProofBatchEncoding(uint8 version);

error UnsupportedExecuteBatchEncoding(uint8 version);

error IncorrectBatchBounds(
uint256 processFromExpected,
uint256 processToExpected,
uint256 processFromProvided,
uint256 processToProvided
);

error AssetIdNotSupported(bytes32 assetId);

error AssetHandlerNotRegistered(bytes32 assetId);
Expand Down
6 changes: 3 additions & 3 deletions l1-contracts/contracts/common/libraries/Merkle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ library Merkle {
/// @param _itemHashes Hashes of the elements in the range
/// @return The Merkle root
function calculateRootPaths(
bytes32[] calldata _startPath,
bytes32[] calldata _endPath,
bytes32[] memory _startPath,
bytes32[] memory _endPath,
uint256 _startIndex,
bytes32[] calldata _itemHashes
bytes32[] memory _itemHashes
) internal pure returns (bytes32) {
uint256 pathLength = _startPath.length;
require(pathLength == _endPath.length, "Merkle: path length mismatch");
Expand Down
7 changes: 7 additions & 0 deletions l1-contracts/contracts/common/libraries/UnsafeBytes.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ library UnsafeBytes {
}
}

function readUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128 result, uint256 offset) {
assembly {
offset := add(_start, 16)
result := mload(add(_bytes, offset))
}
}

function readUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256 result, uint256 offset) {
assembly {
offset := add(_start, 32)
Expand Down
143 changes: 0 additions & 143 deletions l1-contracts/contracts/dev-contracts/test/DummyExecutor.sol

This file was deleted.

8 changes: 2 additions & 6 deletions l1-contracts/contracts/state-transition/TestnetVerifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,13 @@ contract TestnetVerifier is Verifier {

/// @dev Verifies a zk-SNARK proof, skipping the verification if the proof is empty.
/// @inheritdoc IVerifier
function verify(
uint256[] calldata _publicInputs,
uint256[] calldata _proof,
uint256[] calldata _recursiveAggregationInput
) public view override returns (bool) {
function verify(uint256[] calldata _publicInputs, uint256[] calldata _proof) public view override returns (bool) {
// We allow skipping the zkp verification for the test(net) environment
// If the proof is not empty, verify it, otherwise, skip the verification
if (_proof.length == 0) {
return true;
}

return super.verify(_publicInputs, _proof, _recursiveAggregationInput);
return super.verify(_publicInputs, _proof);
}
}
46 changes: 18 additions & 28 deletions l1-contracts/contracts/state-transition/ValidatorTimelock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {Ownable2Step} from "@openzeppelin/contracts-v4/access/Ownable2Step.sol";
import {LibMap} from "./libraries/LibMap.sol";
import {IExecutor} from "./chain-interfaces/IExecutor.sol";
import {IChainTypeManager} from "./IChainTypeManager.sol";
import {PriorityOpsBatchInfo} from "./libraries/PriorityTree.sol";
import {Unauthorized, TimeNotReached, ZeroAddress} from "../common/L1ContractErrors.sol";

/// @author Matter Labs
Expand Down Expand Up @@ -119,63 +118,54 @@ contract ValidatorTimelock is IExecutor, Ownable2Step {
/// a call to the zkChain diamond contract with the same calldata.
function commitBatchesSharedBridge(
uint256 _chainId,
StoredBatchInfo calldata,
CommitBatchInfo[] calldata _newBatchesData
uint256 _processBatchFrom,
uint256 _processBatchTo,
bytes calldata
) external onlyValidator(_chainId) {
_commitBatchesInner(_chainId, _newBatchesData);
}

function _commitBatchesInner(uint256 _chainId, CommitBatchInfo[] calldata _newBatchesData) internal {
unchecked {
// This contract is only a temporary solution, that hopefully will be disabled until 2106 year, so...
// It is safe to cast.
uint32 timestamp = uint32(block.timestamp);
// We disable this check because calldata array length is cheap.
// solhint-disable-next-line gas-length-in-loops
for (uint256 i = 0; i < _newBatchesData.length; ++i) {
committedBatchTimestamp[_chainId].set(_newBatchesData[i].batchNumber, timestamp);
for (uint256 i = _processBatchFrom; i <= _processBatchTo; ++i) {
committedBatchTimestamp[_chainId].set(i, timestamp);
}
}

_propagateToZkSyncZKChain(_chainId);
_propagateToZKChain(_chainId);
}

/// @dev Make a call to the zkChain diamond contract with the same calldata.
/// Note: If the batch is reverted, it needs to be committed first before the execution.
/// So it's safe to not override the committed batches.
function revertBatchesSharedBridge(uint256 _chainId, uint256) external onlyValidator(_chainId) {
_propagateToZkSyncZKChain(_chainId);
_propagateToZKChain(_chainId);
}

/// @dev Make a call to the zkChain diamond contract with the same calldata.
/// Note: We don't track the time when batches are proven, since all information about
/// the batch is known on the commit stage and the proved is not finalized (may be reverted).
function proveBatchesSharedBridge(
uint256 _chainId,
StoredBatchInfo calldata,
StoredBatchInfo[] calldata,
ProofInput calldata
uint256, // _processBatchFrom
uint256, // _processBatchTo
bytes calldata
) external onlyValidator(_chainId) {
_propagateToZkSyncZKChain(_chainId);
_propagateToZKChain(_chainId);
}

/// @dev Check that batches were committed at least X time ago and
/// make a call to the zkChain diamond contract with the same calldata.
function executeBatchesSharedBridge(
uint256 _chainId,
StoredBatchInfo[] calldata _newBatchesData,
PriorityOpsBatchInfo[] calldata
uint256 _processBatchFrom,
uint256 _processBatchTo,
bytes calldata
) external onlyValidator(_chainId) {
_executeBatchesInner(_chainId, _newBatchesData);
}

function _executeBatchesInner(uint256 _chainId, StoredBatchInfo[] calldata _newBatchesData) internal {
uint256 delay = executionDelay; // uint32
unchecked {
// We disable this check because calldata array length is cheap.
// solhint-disable-next-line gas-length-in-loops
for (uint256 i = 0; i < _newBatchesData.length; ++i) {
uint256 commitBatchTimestamp = committedBatchTimestamp[_chainId].get(_newBatchesData[i].batchNumber);
for (uint256 i = _processBatchFrom; i <= _processBatchTo; ++i) {
uint256 commitBatchTimestamp = committedBatchTimestamp[_chainId].get(i);

// Note: if the `commitBatchTimestamp` is zero, that means either:
// * The batch was committed, but not through this contract.
Expand All @@ -187,12 +177,12 @@ contract ValidatorTimelock is IExecutor, Ownable2Step {
}
}
}
_propagateToZkSyncZKChain(_chainId);
_propagateToZKChain(_chainId);
}

/// @dev Call the zkChain diamond contract with the same calldata as this contract was called.
/// Note: it is called the zkChain diamond contract, not delegatecalled!
function _propagateToZkSyncZKChain(uint256 _chainId) internal {
function _propagateToZKChain(uint256 _chainId) internal {
address contractAddress = chainTypeManager.getZKChain(_chainId);
assembly {
// Copy function signature and arguments from calldata at zero position into memory at pointer position
Expand Down
35 changes: 18 additions & 17 deletions l1-contracts/contracts/state-transition/Verifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,7 @@ contract Verifier is IVerifier {
/// @inheritdoc IVerifier
function verify(
uint256[] calldata, // _publicInputs
uint256[] calldata, // _proof
uint256[] calldata // _recursiveAggregationInput
uint256[] calldata // _proof
) public view virtual returns (bool) {
// No memory was accessed yet, so keys can be loaded into the right place and not corrupt any other memory.
_loadVerificationKey();
Expand Down Expand Up @@ -523,7 +522,17 @@ contract Verifier is IVerifier {
// 2. Load the proof (except for the recursive part)
offset := calldataload(0x24)
let proofLengthInWords := calldataload(add(offset, 0x04))
isValid := and(eq(proofLengthInWords, 44), isValid)

// Check the proof length depending on whether the recursive part is present
let expectedProofLength
switch mload(VK_RECURSIVE_FLAG_SLOT)
case 0 {
expectedProofLength := 44
}
default {
expectedProofLength := 48
}
isValid := and(eq(proofLengthInWords, expectedProofLength), isValid)

// PROOF_STATE_POLYS_0
{
Expand Down Expand Up @@ -670,30 +679,22 @@ contract Verifier is IVerifier {
}

// 3. Load the recursive part of the proof
offset := calldataload(0x44)
let recursiveProofLengthInWords := calldataload(add(offset, 0x04))

switch mload(VK_RECURSIVE_FLAG_SLOT)
case 0 {
// recursive part should be empty
isValid := and(iszero(recursiveProofLengthInWords), isValid)
}
default {
if mload(VK_RECURSIVE_FLAG_SLOT) {
// recursive part should be consist of 2 points
isValid := and(eq(recursiveProofLengthInWords, 4), isValid)

// PROOF_RECURSIVE_PART_P1
{
let x := mod(calldataload(add(offset, 0x024)), Q_MOD)
let y := mod(calldataload(add(offset, 0x044)), Q_MOD)
let x := mod(calldataload(add(offset, 0x5a4)), Q_MOD)
let y := mod(calldataload(add(offset, 0x5c4)), Q_MOD)
let xx := mulmod(x, x, Q_MOD)
isValid := and(eq(mulmod(y, y, Q_MOD), addmod(mulmod(x, xx, Q_MOD), 3, Q_MOD)), isValid)
mstore(PROOF_RECURSIVE_PART_P1_X_SLOT, x)
mstore(PROOF_RECURSIVE_PART_P1_Y_SLOT, y)
}
// PROOF_RECURSIVE_PART_P2
{
let x := mod(calldataload(add(offset, 0x064)), Q_MOD)
let y := mod(calldataload(add(offset, 0x084)), Q_MOD)
let x := mod(calldataload(add(offset, 0x5e4)), Q_MOD)
let y := mod(calldataload(add(offset, 0x604)), Q_MOD)
let xx := mulmod(x, x, Q_MOD)
isValid := and(eq(mulmod(y, y, Q_MOD), addmod(mulmod(x, xx, Q_MOD), 3, Q_MOD)), isValid)
mstore(PROOF_RECURSIVE_PART_P2_X_SLOT, x)
Expand Down
Loading
Loading