Skip to content

Commit

Permalink
Merge branch 'boojum-integration' into bh-EVM-216-move-l1-tests-to-fo…
Browse files Browse the repository at this point in the history
…undry

# Conflicts:
#	ethereum/test/unit_tests/executor_test.spec.ts
  • Loading branch information
benceharomi committed Sep 27, 2023
2 parents fc3cc60 + c2dc75a commit 008b905
Show file tree
Hide file tree
Showing 35 changed files with 2,429 additions and 1,105 deletions.
8 changes: 4 additions & 4 deletions SystemConfig.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"L2_TX_MAX_GAS_LIMIT": 80000000,
"MAX_PUBDATA_PER_BLOCK": 110000,
"MAX_PUBDATA_PER_BATCH": 110000,
"PRIORITY_TX_MAX_PUBDATA": 99000,
"FAIR_L2_GAS_PRICE": 500000000,
"L1_GAS_PER_PUBDATA_BYTE": 17,
"BLOCK_OVERHEAD_L2_GAS": 1200000,
"BLOCK_OVERHEAD_L1_GAS": 1000000,
"MAX_TRANSACTIONS_IN_BLOCK": 1024,
"BATCH_OVERHEAD_L2_GAS": 1200000,
"BATCH_OVERHEAD_L1_GAS": 1000000,
"MAX_TRANSACTIONS_IN_BATCH": 1024,
"BOOTLOADER_TX_ENCODING_SPACE": 485225,
"L1_TX_INTRINSIC_L2_GAS": 167157,
"L1_TX_INTRINSIC_PUBDATA": 88,
Expand Down
25 changes: 13 additions & 12 deletions docs/Overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ See the [documentation](https://era.zksync.io/docs/dev/fundamentals/rollups.html
- **Governor** - a privileged address that controls the upgradability of the network and sets other privileged
addresses.
- **Security council** - an address of the Gnosis multisig with the trusted owners that can decrease upgrade timelock.
- **Validator/Operator** - a privileged address that can commit/verify/execute L2 blocks.
- **Validator/Operator** - a privileged address that can commit/verify/execute L2 batches.
- **L2 batch (or just batch)** - An aggregation of multiple L2 blocks. Note, that while the API operates on L2 blocks, the prove system operates on batches, which represent a single proved VM execution, which typically contains multiple L2 blocks.
- **Facet** - implementation contract. The word comes from the EIP-2535.
- **Gas** - a unit that measures the amount of computational effort required to execute specific operations on the
zkSync Era network.
Expand Down Expand Up @@ -143,11 +144,11 @@ burn the funds on L2, allowing the user to reclaim them through the `finalizeEth
L2 -> L1 communication, in contrast to L1 -> L2 communication, is based only on transferring the information, and not on
the transaction execution on L1.

From the L2 side, there is a special zkEVM opcode that saves `l2ToL1Log` in the L2 block. A validator will send all
`l2ToL1Logs` when sending an L2 block to the L1 (see `ExecutorFacet`). Later on, users will be able to both read their
From the L2 side, there is a special zkEVM opcode that saves `l2ToL1Log` in the L2 batch. A validator will send all
`l2ToL1Logs` when sending an L2 batch to the L1 (see `ExecutorFacet`). Later on, users will be able to both read their
`l2ToL1logs` on L1 and _prove_ that they sent it.

From the L1 side, for each L2 block, a Merkle root with such logs in leaves is calculated. Thus, a user can provide
From the L1 side, for each L2 batch, a Merkle root with such logs in leaves is calculated. Thus, a user can provide
Merkle proof for each `l2ToL1Logs`.

_NOTE_: For each executed L1 -> L2 transaction, the system program necessarily sends an L2 -> L1 log. To verify the
Expand All @@ -164,18 +165,18 @@ this trick:

#### ExecutorFacet

A contract that accepts L2 blocks, enforces data availability and checks the validity of zk-proofs.
A contract that accepts L2 batches, enforces data availability and checks the validity of zk-proofs.

The state transition is divided into three stages:

- `commitBlocks` - check L2 block timestamp, process the L2 logs, save data for a block, and prepare data for zk-proof.
- `proveBlocks` - validate zk-proof.
- `executeBlocks` - finalize the state, marking L1 -> L2 communication processing, and saving Merkle tree with L2 logs.
- `commitBatches` - check L2 batch timestamp, process the L2 logs, save data for a batch, and prepare data for zk-proof.
- `proveBatches` - validate zk-proof.
- `executeBatches` - finalize the state, marking L1 -> L2 communication processing, and saving Merkle tree with L2 logs.

When a block is committed, we process L2 -> L1 logs. Here are the invariants that are expected there:
When a batch is committed, we process L2 -> L1 logs. Here are the invariants that are expected there:

- The only L2 -> L1 log from the `L2_SYSTEM_CONTEXT_ADDRESS`, with the `key == l2BlockTimestamp` and
`value == l2BlockHash`.
- The only L2 -> L1 log from the `L2_SYSTEM_CONTEXT_ADDRESS`, with the `key == l2BatchTimestamp` and
`value == l2BatchHash`.
- Several (or none) logs from the `L2_KNOWN_CODE_STORAGE_ADDRESS` with the `key == bytecodeHash`, where bytecode is
marked as a known factory dependency.
- Several (or none) logs from the `L2_BOOTLOADER_ADDRESS` with the `key == canonicalTxHash` where `canonicalTxHash` is a
Expand Down Expand Up @@ -230,7 +231,7 @@ the L1 recipient.
#### ValidatorTimelock

An intermediate smart contract between the validator EOA account and the zkSync smart contract. Its primary purpose is
to provide a trustless means of delaying block execution without modifying the main zkSync contract. zkSync actively
to provide a trustless means of delaying batch execution without modifying the main zkSync contract. zkSync actively
monitors the chain activity and reacts to any suspicious activity by freezing the chain. This allows time for
investigation and mitigation before resuming normal operations.

Expand Down
30 changes: 15 additions & 15 deletions ethereum/contracts/bridge/L1ERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, AllowListed, ReentrancyGua
/// @dev zkSync smart contract that is used to operate with L2 via asynchronous L2 <-> L1 communication
IZkSync internal immutable zkSync;

/// @dev A mapping L2 block number => message number => flag
/// @dev A mapping L2 batch number => message number => flag
/// @dev Used to indicate that zkSync L2 -> L1 message was already processed
mapping(uint256 => mapping(uint256 => bool)) public isWithdrawalFinalized;

Expand Down Expand Up @@ -247,24 +247,24 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, AllowListed, ReentrancyGua
/// @param _depositSender The address of the deposit initiator
/// @param _l1Token The address of the deposited L1 ERC20 token
/// @param _l2TxHash The L2 transaction hash of the failed deposit finalization
/// @param _l2BlockNumber The L2 block number where the deposit finalization was processed
/// @param _l2BatchNumber The L2 batch number where the deposit finalization was processed
/// @param _l2MessageIndex The position in the L2 logs Merkle tree of the l2Log that was sent with the message
/// @param _l2TxNumberInBlock The L2 transaction number in a block, in which the log was sent
/// @param _l2TxNumberInBatch The L2 transaction number in a batch, in which the log was sent
/// @param _merkleProof The Merkle proof of the processing L1 -> L2 transaction with deposit finalization
function claimFailedDeposit(
address _depositSender,
address _l1Token,
bytes32 _l2TxHash,
uint256 _l2BlockNumber,
uint256 _l2BatchNumber,
uint256 _l2MessageIndex,
uint16 _l2TxNumberInBlock,
uint16 _l2TxNumberInBatch,
bytes32[] calldata _merkleProof
) external nonReentrant senderCanCallFunction(allowList) {
bool proofValid = zkSync.proveL1ToL2TransactionStatus(
_l2TxHash,
_l2BlockNumber,
_l2BatchNumber,
_l2MessageIndex,
_l2TxNumberInBlock,
_l2TxNumberInBatch,
_merkleProof,
TxStatus.Failure
);
Expand All @@ -284,34 +284,34 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, AllowListed, ReentrancyGua
}

/// @notice Finalize the withdrawal and release funds
/// @param _l2BlockNumber The L2 block number where the withdrawal was processed
/// @param _l2BatchNumber The L2 batch number where the withdrawal was processed
/// @param _l2MessageIndex The position in the L2 logs Merkle tree of the l2Log that was sent with the message
/// @param _l2TxNumberInBlock The L2 transaction number in a block, in which the log was sent
/// @param _l2TxNumberInBatch The L2 transaction number in the batch, in which the log was sent
/// @param _message The L2 withdraw data, stored in an L2 -> L1 message
/// @param _merkleProof The Merkle proof of the inclusion L2 -> L1 message about withdrawal initialization
function finalizeWithdrawal(
uint256 _l2BlockNumber,
uint256 _l2BatchNumber,
uint256 _l2MessageIndex,
uint16 _l2TxNumberInBlock,
uint16 _l2TxNumberInBatch,
bytes calldata _message,
bytes32[] calldata _merkleProof
) external nonReentrant senderCanCallFunction(allowList) {
require(!isWithdrawalFinalized[_l2BlockNumber][_l2MessageIndex], "pw");
require(!isWithdrawalFinalized[_l2BatchNumber][_l2MessageIndex], "pw");

L2Message memory l2ToL1Message = L2Message({
txNumberInBlock: _l2TxNumberInBlock,
txNumberInBatch: _l2TxNumberInBatch,
sender: l2Bridge,
data: _message
});

(address l1Receiver, address l1Token, uint256 amount) = _parseL2WithdrawalMessage(l2ToL1Message.data);
// Preventing the stack too deep error
{
bool success = zkSync.proveL2MessageInclusion(_l2BlockNumber, _l2MessageIndex, l2ToL1Message, _merkleProof);
bool success = zkSync.proveL2MessageInclusion(_l2BatchNumber, _l2MessageIndex, l2ToL1Message, _merkleProof);
require(success, "nq");
}

isWithdrawalFinalized[_l2BlockNumber][_l2MessageIndex] = true;
isWithdrawalFinalized[_l2BatchNumber][_l2MessageIndex] = true;
// Withdraw funds
IERC20(l1Token).safeTransfer(l1Receiver, amount);

Expand Down
26 changes: 13 additions & 13 deletions ethereum/contracts/bridge/L1WethBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ contract L1WethBridge is IL1Bridge, AllowListed, ReentrancyGuard {
/// @dev The address of the WETH on L2
address public l2WethAddress;

/// @dev A mapping L2 block number => message number => flag
/// @dev A mapping L2 batch number => message number => flag
/// @dev Used to indicate that zkSync L2 -> L1 WETH message was already processed
mapping(uint256 => mapping(uint256 => bool)) public isWithdrawalFinalized;

Expand Down Expand Up @@ -214,54 +214,54 @@ contract L1WethBridge is IL1Bridge, AllowListed, ReentrancyGuard {
address, // _depositSender,
address, // _l1Token,
bytes32, // _l2TxHash
uint256, // _l2BlockNumber,
uint256, // _l2BatchNumber,
uint256, // _l2MessageIndex,
uint16, // _l2TxNumberInBlock,
uint16, // _l2TxNumberInBatch,
bytes32[] calldata // _merkleProof
) external pure {
revert("Method not supported. Failed deposit funds are sent to the L2 refund recipient address.");
}

/// @notice Finalize the withdrawal and release funds
/// @param _l2BlockNumber The L2 block number where the ETH (WETH) withdrawal was processed
/// @param _l2BatchNumber The L2 batch number where the ETH (WETH) withdrawal was processed
/// @param _l2MessageIndex The position in the L2 logs Merkle tree of the l2Log that was sent with the ETH
/// withdrawal message containing additional data about WETH withdrawal
/// @param _l2TxNumberInBlock The L2 transaction number in a block, in which the ETH withdrawal log was sent
/// @param _l2TxNumberInBatch The L2 transaction number in the batch, in which the ETH withdrawal log was sent
/// @param _message The L2 withdraw data, stored in an L2 -> L1 message
/// @param _merkleProof The Merkle proof of the inclusion L2 -> L1 message about withdrawal initialization
function finalizeWithdrawal(
uint256 _l2BlockNumber,
uint256 _l2BatchNumber,
uint256 _l2MessageIndex,
uint16 _l2TxNumberInBlock,
uint16 _l2TxNumberInBatch,
bytes calldata _message,
bytes32[] calldata _merkleProof
) external nonReentrant senderCanCallFunction(allowList) {
require(!isWithdrawalFinalized[_l2BlockNumber][_l2MessageIndex], "Withdrawal is already finalized");
require(!isWithdrawalFinalized[_l2BatchNumber][_l2MessageIndex], "Withdrawal is already finalized");

(address l1WethWithdrawReceiver, uint256 amount) = _parseL2EthWithdrawalMessage(_message);

// Check if the withdrawal has already been finalized on L2.
bool alreadyFinalised = zkSync.isEthWithdrawalFinalized(_l2MessageIndex, _l2TxNumberInBlock);
bool alreadyFinalised = zkSync.isEthWithdrawalFinalized(_l2MessageIndex, _l2TxNumberInBatch);
if (alreadyFinalised) {
// Check that the specified message was actually sent while withdrawing eth from L2.
L2Message memory l2ToL1Message = L2Message({
txNumberInBlock: _l2TxNumberInBlock,
txNumberInBatch: _l2TxNumberInBatch,
sender: L2_ETH_TOKEN_SYSTEM_CONTRACT_ADDR,
data: _message
});
bool success = zkSync.proveL2MessageInclusion(_l2BlockNumber, _l2MessageIndex, l2ToL1Message, _merkleProof);
bool success = zkSync.proveL2MessageInclusion(_l2BatchNumber, _l2MessageIndex, l2ToL1Message, _merkleProof);
require(success, "vq");
} else {
// Finalize the withdrawal if it is not yet done.
zkSync.finalizeEthWithdrawal(_l2BlockNumber, _l2MessageIndex, _l2TxNumberInBlock, _message, _merkleProof);
zkSync.finalizeEthWithdrawal(_l2BatchNumber, _l2MessageIndex, _l2TxNumberInBatch, _message, _merkleProof);
}

// Wrap ETH to WETH tokens (smart contract address receives the equivalent amount of WETH)
IWETH9(l1WethAddress).deposit{value: amount}();
// Transfer WETH tokens from the smart contract address to the withdrawal receiver
IERC20(l1WethAddress).safeTransfer(l1WethWithdrawReceiver, amount);

isWithdrawalFinalized[_l2BlockNumber][_l2MessageIndex] = true;
isWithdrawalFinalized[_l2BatchNumber][_l2MessageIndex] = true;

emit WithdrawalFinalized(l1WethWithdrawReceiver, l1WethAddress, amount);
}
Expand Down
10 changes: 5 additions & 5 deletions ethereum/contracts/bridge/interfaces/IL1Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ interface IL1Bridge {

event ClaimedFailedDeposit(address indexed to, address indexed l1Token, uint256 amount);

function isWithdrawalFinalized(uint256 _l2BlockNumber, uint256 _l2MessageIndex) external view returns (bool);
function isWithdrawalFinalized(uint256 _l2BatchNumber, uint256 _l2MessageIndex) external view returns (bool);

function deposit(
address _l2Receiver,
Expand All @@ -31,16 +31,16 @@ interface IL1Bridge {
address _depositSender,
address _l1Token,
bytes32 _l2TxHash,
uint256 _l2BlockNumber,
uint256 _l2BatchNumber,
uint256 _l2MessageIndex,
uint16 _l2TxNumberInBlock,
uint16 _l2TxNumberInBatch,
bytes32[] calldata _merkleProof
) external;

function finalizeWithdrawal(
uint256 _l2BlockNumber,
uint256 _l2BatchNumber,
uint256 _l2MessageIndex,
uint16 _l2TxNumberInBlock,
uint16 _l2TxNumberInBatch,
bytes calldata _message,
bytes32[] calldata _merkleProof
) external;
Expand Down
3 changes: 3 additions & 0 deletions ethereum/contracts/common/L2ContractAddresses.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@ address constant L2_KNOWN_CODE_STORAGE_SYSTEM_CONTRACT_ADDR = address(0x8004);

/// @dev The address of the context system contract
address constant L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR = address(0x800b);

/// @dev The address of the bytecode compressor system contract
address constant L2_BYTECODE_COMPRESSOR_SYSTEM_CONTRACT_ADDR = address(0x800e);
Loading

0 comments on commit 008b905

Please sign in to comment.