Skip to content

Commit

Permalink
Merge 72552a5 into cb42ae4
Browse files Browse the repository at this point in the history
  • Loading branch information
vladbochok authored Sep 9, 2024
2 parents cb42ae4 + 72552a5 commit c5f4248
Show file tree
Hide file tree
Showing 32 changed files with 915 additions and 818 deletions.
21 changes: 19 additions & 2 deletions l1-contracts/contracts/common/L1ContractErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -327,9 +327,26 @@ error ZeroAddress();
error ZeroBalance();
// 0xc84885d4
error ZeroChainId();

// 0x520aa59c
error PubdataIsEmpty();
// 0x99d8fec9
error EmptyData();
// 0xc99a8360
error UnsupportedCommitBatchEncoding(uint8 version);
// 0xe167e4a6
error UnsupportedProofBatchEncoding(uint8 version);
// 0xe8e3f6f4
error UnsupportedExecuteBatchEncoding(uint8 version);
// 0xd7d93e1f
error IncorrectBatchBounds(
uint256 processFromExpected,
uint256 processToExpected,
uint256 processFromProvided,
uint256 processToProvided
);
// 0x04a0b7e9
error AssetIdNotSupported(bytes32 assetId);

// 0x64107968
error AssetHandlerNotRegistered(bytes32 assetId);

enum SharedBridgeKey {
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

0 comments on commit c5f4248

Please sign in to comment.