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

feat: adapting Era test node to the new VM (and updating system contracts) #111

Merged
merged 22 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from 12 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
96 changes: 41 additions & 55 deletions Cargo.lock

Large diffs are not rendered by default.

31 changes: 22 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,28 @@ categories = ["cryptography"]
publish = false # We don't want to publish our binaries.

[dependencies]
zksync_basic_types = { git = "https://github.com/matter-labs/zksync-era.git", rev = "a98e454221da7d6ecad9b317cf44b0786e819659" }
zksync_core = { git = "https://github.com/matter-labs/zksync-era.git", rev = "a98e454221da7d6ecad9b317cf44b0786e819659" }
vm = { git = "https://github.com/matter-labs/zksync-era.git", rev = "a98e454221da7d6ecad9b317cf44b0786e819659" }
vlog = { git = "https://github.com/matter-labs/zksync-era.git", rev = "a98e454221da7d6ecad9b317cf44b0786e819659" }
zksync_contracts = { git = "https://github.com/matter-labs/zksync-era.git", rev = "a98e454221da7d6ecad9b317cf44b0786e819659" }
zksync_types = { git = "https://github.com/matter-labs/zksync-era.git", rev = "a98e454221da7d6ecad9b317cf44b0786e819659" }
zksync_utils = { git = "https://github.com/matter-labs/zksync-era.git", rev = "a98e454221da7d6ecad9b317cf44b0786e819659" }
zksync_state = { git = "https://github.com/matter-labs/zksync-era.git", rev = "a98e454221da7d6ecad9b317cf44b0786e819659" }
zksync_web3_decl = { git = "https://github.com/matter-labs/zksync-era.git", rev = "a98e454221da7d6ecad9b317cf44b0786e819659" }
#zksync_basic_types = { git = "https://github.com/matter-labs/zksync-era.git", rev = "a98e454221da7d6ecad9b317cf44b0786e819659" }
#zksync_core = { git = "https://github.com/matter-labs/zksync-era.git", rev = "a98e454221da7d6ecad9b317cf44b0786e819659" }
#vm = { git = "https://github.com/matter-labs/zksync-era.git", rev = "a98e454221da7d6ecad9b317cf44b0786e819659" }
#vlog = { git = "https://github.com/matter-labs/zksync-era.git", rev = "a98e454221da7d6ecad9b317cf44b0786e819659" }
#zksync_contracts = { git = "https://github.com/matter-labs/zksync-era.git", rev = "a98e454221da7d6ecad9b317cf44b0786e819659" }
#zksync_types = { git = "https://github.com/matter-labs/zksync-era.git", rev = "a98e454221da7d6ecad9b317cf44b0786e819659" }
#zksync_utils = { git = "https://github.com/matter-labs/zksync-era.git", rev = "a98e454221da7d6ecad9b317cf44b0786e819659" }
#zksync_state = { git = "https://github.com/matter-labs/zksync-era.git", rev = "a98e454221da7d6ecad9b317cf44b0786e819659" }
#zksync_web3_decl = { git = "https://github.com/matter-labs/zksync-era.git", rev = "a98e454221da7d6ecad9b317cf44b0786e819659" }


zksync_basic_types = { path = "../../matter/zksync-2-dev/core/lib/basic_types" }
zksync_core = { path = "../../matter/zksync-2-dev/core/bin/zksync_core" }
vm = { path = "../../matter/zksync-2-dev/core/lib/vm" }
vlog = { path = "../../matter/zksync-2-dev/core/lib/vlog" }
zksync_contracts = { path = "../../matter/zksync-2-dev/core/lib/contracts" }
zksync_types = { path = "../../matter/zksync-2-dev/core/lib/types" }
zksync_utils = { path = "../../matter/zksync-2-dev/core/lib/utils" }
zksync_state = { path = "../../matter/zksync-2-dev/core/lib/state" }
zksync_web3_decl = { path = "../../matter/zksync-2-dev/core/lib/web3_decl" }


openssl-sys = { version = "0.9", features = ["vendored"] }

anyhow = "1.0"
Expand Down
10 changes: 5 additions & 5 deletions etc/system-contracts/SystemConfig.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"GUARANTEED_PUBDATA_BYTES": 4000,
"MAX_PUBDATA_PER_BLOCK": 110000,
"MAX_TRANSACTIONS_IN_BLOCK": 1024,
"BLOCK_OVERHEAD_L2_GAS": 1200000,
"BLOCK_OVERHEAD_L1_GAS": 1000000,
"MAX_PUBDATA_PER_BATCH": 110000,
"MAX_TRANSACTIONS_IN_BATCH": 1024,
"BATCH_OVERHEAD_L2_GAS": 1200000,
"BATCH_OVERHEAD_L1_GAS": 1000000,
"L2_TX_INTRINSIC_GAS": 14070,
"L2_TX_INTRINSIC_PUBDATA": 0,
"L1_TX_INTRINSIC_L2_GAS": 167157,
Expand All @@ -14,4 +14,4 @@
"KECCAK_ROUND_COST_GAS": 40,
"SHA256_ROUND_COST_GAS": 7,
"ECRECOVER_COST_GAS": 1112
}
}
563 changes: 412 additions & 151 deletions etc/system-contracts/bootloader/bootloader.yul

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion etc/system-contracts/contracts/BytecodeCompressor.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

Expand Down
34 changes: 34 additions & 0 deletions etc/system-contracts/contracts/ComplexUpgrader.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./interfaces/IComplexUpgrader.sol";
import {FORCE_DEPLOYER} from "./Constants.sol";

/**
* @author Matter Labs
* @notice Upgrader which should be used to perform complex multistep upgrades on L2. In case some custom logic for an upgrade is needed
* this logic should be deployed into the user space and then this contract will delegatecall to the deployed contract.
*/
contract ComplexUpgrader is IComplexUpgrader {
/// @notice Executes an upgrade process by delegating calls to another contract.
/// @dev This function allows only the `FORCE_DEPLOYER` to initiate the upgrade.
/// If the delegate call fails, the function will revert the transaction, returning the error message
/// provided by the delegated contract.
/// @param _delegateTo the address of the contract to which the calls will be delegated
/// @param _calldata the calldata to be delegate called in the `_delegateTo` contract
function upgrade(
address _delegateTo,
bytes calldata _calldata
) external payable {
require(msg.sender == FORCE_DEPLOYER, "Can only be called by FORCE_DEPLOYER");

require(_delegateTo.code.length > 0, "Delegatee is an EOA");
(bool success, bytes memory returnData) = _delegateTo.delegatecall(_calldata);
assembly {
if iszero(success) {
revert(add(returnData, 0x20), mload(returnData))
}
}
}
}
5 changes: 5 additions & 0 deletions etc/system-contracts/contracts/Constants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import "./interfaces/IEthToken.sol";
import "./interfaces/IL1Messenger.sol";
import "./interfaces/ISystemContext.sol";
import "./interfaces/IBytecodeCompressor.sol";
import "./interfaces/IComplexUpgrader.sol";
import "./BootloaderUtilities.sol";

/// @dev All the system contracts introduced by zkSync have their addresses
Expand Down Expand Up @@ -62,6 +63,10 @@ IBytecodeCompressor constant BYTECODE_COMPRESSOR_CONTRACT = IBytecodeCompressor(
address(SYSTEM_CONTRACTS_OFFSET + 0x0e)
);

IComplexUpgrader constant COMPLEX_UPGRADER_CONTRACT = IComplexUpgrader(
address(SYSTEM_CONTRACTS_OFFSET + 0x0f)
);

/// @dev If the bitwise AND of the extraAbi[2] param when calling the MSG_VALUE_SIMULATOR
/// is non-zero, the call will be assumed to be a system one.
uint256 constant MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT = 1;
Expand Down
24 changes: 14 additions & 10 deletions etc/system-contracts/contracts/ContractDeployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ pragma solidity ^0.8.0;

import {ImmutableData} from "./interfaces/IImmutableSimulator.sol";
import "./interfaces/IContractDeployer.sol";
import {CREATE2_PREFIX, CREATE_PREFIX, NONCE_HOLDER_SYSTEM_CONTRACT, ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT, FORCE_DEPLOYER, MAX_SYSTEM_CONTRACT_ADDRESS, KNOWN_CODE_STORAGE_CONTRACT, ETH_TOKEN_SYSTEM_CONTRACT, IMMUTABLE_SIMULATOR_SYSTEM_CONTRACT} from "./Constants.sol";
import {CREATE2_PREFIX, CREATE_PREFIX, NONCE_HOLDER_SYSTEM_CONTRACT, ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT, FORCE_DEPLOYER, MAX_SYSTEM_CONTRACT_ADDRESS, KNOWN_CODE_STORAGE_CONTRACT, ETH_TOKEN_SYSTEM_CONTRACT, IMMUTABLE_SIMULATOR_SYSTEM_CONTRACT, COMPLEX_UPGRADER_CONTRACT} from "./Constants.sol";

import "./libraries/Utils.sol";
import "./libraries/EfficientCall.sol";
import {SystemContractHelper, ISystemContract} from "./libraries/SystemContractHelper.sol";
import {SystemContractHelper} from "./libraries/SystemContractHelper.sol";
import "./interfaces/ISystemContract.sol";

/**
* @author Matter Labs
Expand All @@ -21,7 +22,7 @@ import {SystemContractHelper, ISystemContract} from "./libraries/SystemContractH
contract ContractDeployer is IContractDeployer, ISystemContract {
/// @notice Information about an account contract.
/// @dev For EOA and simple contracts (i.e. not accounts) this value is 0.
mapping(address => AccountInfo) internal _accountInfo;
mapping(address => AccountInfo) internal accountInfo;

modifier onlySelf() {
require(msg.sender == address(this), "Callable only by self");
Expand All @@ -30,13 +31,13 @@ contract ContractDeployer is IContractDeployer, ISystemContract {

/// @notice Returns information about a certain account.
function getAccountInfo(address _address) external view returns (AccountInfo memory info) {
return _accountInfo[_address];
return accountInfo[_address];
}

/// @notice Returns the account abstraction version if `_address` is a deployed contract.
/// Returns the latest supported account abstraction version if `_address` is an EOA.
function extendedAccountVersion(address _address) public view returns (AccountAbstractionVersion) {
AccountInfo memory info = _accountInfo[_address];
AccountInfo memory info = accountInfo[_address];
if (info.supportedAAVersion != AccountAbstractionVersion.None) {
return info.supportedAAVersion;
}
Expand All @@ -51,14 +52,14 @@ contract ContractDeployer is IContractDeployer, ISystemContract {

/// @notice Stores the new account information
function _storeAccountInfo(address _address, AccountInfo memory _newInfo) internal {
_accountInfo[_address] = _newInfo;
accountInfo[_address] = _newInfo;
}

/// @notice Update the used version of the account.
/// @param _version The new version of the AA protocol to use.
/// @dev Note that it allows changes from account to non-account and vice versa.
function updateAccountVersion(AccountAbstractionVersion _version) external onlySystemCall {
_accountInfo[msg.sender].supportedAAVersion = _version;
accountInfo[msg.sender].supportedAAVersion = _version;

emit AccountVersionUpdated(msg.sender, _version);
}
Expand All @@ -67,7 +68,7 @@ contract ContractDeployer is IContractDeployer, ISystemContract {
/// it only allows changes from sequential to arbitrary ordering.
/// @param _nonceOrdering The new nonce ordering to use.
function updateNonceOrdering(AccountNonceOrdering _nonceOrdering) external onlySystemCall {
AccountInfo memory currentInfo = _accountInfo[msg.sender];
AccountInfo memory currentInfo = accountInfo[msg.sender];

require(
_nonceOrdering == AccountNonceOrdering.Arbitrary &&
Expand Down Expand Up @@ -234,7 +235,10 @@ contract ContractDeployer is IContractDeployer, ISystemContract {
/// @dev We do not require `onlySystemCall` here, since the method is accessible only
/// by `FORCE_DEPLOYER`.
function forceDeployOnAddresses(ForceDeployment[] calldata _deployments) external payable {
require(msg.sender == FORCE_DEPLOYER, "Can only be called by FORCE_DEPLOYER_CONTRACT");
require(
msg.sender == FORCE_DEPLOYER || msg.sender == address(COMPLEX_UPGRADER_CONTRACT),
"Can only be called by FORCE_DEPLOYER or COMPLEX_UPGRADER_CONTRACT"
);

uint256 deploymentsLength = _deployments.length;
// We need to ensure that the `value` provided by the call is enough to provide `value`
Expand All @@ -256,7 +260,7 @@ contract ContractDeployer is IContractDeployer, ISystemContract {
AccountAbstractionVersion _aaVersion,
bytes calldata _input
) internal {
require(_bytecodeHash != bytes32(0x0), "BytecodeHash can not be zero");
require(_bytecodeHash != bytes32(0x0), "BytecodeHash cannot be zero");
require(uint160(_newAddress) > MAX_SYSTEM_CONTRACT_ADDRESS, "Can not deploy contracts in kernel space");

// We do not allow deploying twice on the same address.
Expand Down
4 changes: 2 additions & 2 deletions etc/system-contracts/contracts/EventWriter.yul
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ object "EventWriter" {
/// @param initializer The event initializing value
/// @param value1 The first topic or data chunk.
function eventInitialize(initializer, value1) {
pop(verbatim_2i_0o("event_initialize", initializer, value1))
verbatim_2i_0o("event_initialize", initializer, value1)
}

/// @notice Continue writing the previously initialized event.
/// @param value1 The first topic or data chunk.
/// @param value2 The second topic or data chunk.
function eventWrite(value1, value2) {
pop(verbatim_2i_0o("event_write", value1, value2))
verbatim_2i_0o("event_write", value1, value2)
}

// @dev Write 1-th topic and first data chunk
Expand Down
5 changes: 4 additions & 1 deletion etc/system-contracts/contracts/L1Messenger.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import "./libraries/EfficientCall.sol";
* it requires that the preimage of `value` be provided.
*/
contract L1Messenger is IL1Messenger {
/// @notice Sends an arbitrary length message to L1.
/// @param _message The variable length message to be sent to L1.
/// @return hash The keccak256 hashed value of the message.
function sendToL1(bytes calldata _message) external override returns (bytes32 hash) {
hash = EfficientCall.keccak(_message);

Expand All @@ -44,7 +47,7 @@ contract L1Messenger is IL1Messenger {
precompileParams,
Utils.safeCastToU32(gasToPay)
);
require(precompileCallSuccess);
require(precompileCallSuccess, "Failed to burn gas");

SystemContractHelper.toL1(true, bytes32(uint256(uint160(msg.sender))), hash);

Expand Down
48 changes: 38 additions & 10 deletions etc/system-contracts/contracts/L2EthToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,35 @@ contract L2EthToken is IEthToken {

/// @notice Initiate the ETH withdrawal, funds will be available to claim on L1 `finalizeEthWithdrawal` method.
/// @param _l1Receiver The address on L1 to receive the funds.
/// @dev The function accepts the `msg.value`. Since this contract holds the mapping of all ether
/// balances of the system, the sent `msg.value` is added to the `this` balance before the call.
/// So the balance of `address(this)` is always bigger or equal to the `msg.value`!
function withdraw(address _l1Receiver) external payable override {
uint256 amount = msg.value;
uint256 amount = _burnMsgValue();

// Send the L2 log, a user could use it as proof of the withdrawal
bytes memory message = _getL1WithdrawMessage(_l1Receiver, amount);
L1_MESSENGER_CONTRACT.sendToL1(message);

emit Withdrawal(msg.sender, _l1Receiver, amount);
}

/// @notice Initiate the ETH withdrawal, with the sent message. The funds will be available to claim on L1 `finalizeEthWithdrawal` method.
/// @param _l1Receiver The address on L1 to receive the funds.
/// @param _additionalData Additional data to be sent to L1 with the withdrawal.
function withdrawWithMessage(address _l1Receiver, bytes memory _additionalData) external payable override {
uint256 amount = _burnMsgValue();

// Send the L2 log, a user could use it as proof of the withdrawal
bytes memory message = _getExtendedWithdrawMessage(_l1Receiver, amount, msg.sender, _additionalData);
L1_MESSENGER_CONTRACT.sendToL1(message);

emit WithdrawalWithMessage(msg.sender, _l1Receiver, amount, _additionalData);
}

/// @dev The function burn the sent `msg.value`.
/// NOTE: Since this contract holds the mapping of all ether balances of the system,
/// the sent `msg.value` is added to the `this` balance before the call.
/// So the balance of `address(this)` is always bigger or equal to the `msg.value`!
function _burnMsgValue() internal returns (uint256 amount) {
amount = msg.value;

// Silent burning of the ether
unchecked {
Expand All @@ -86,19 +110,23 @@ contract L2EthToken is IEthToken {
balance[address(this)] -= amount;
totalSupply -= amount;
}

// Send the L2 log, a user could use it as proof of the withdrawal
bytes memory message = _getL1WithdrawMessage(_l1Receiver, amount);
L1_MESSENGER_CONTRACT.sendToL1(message);

emit Withdrawal(msg.sender, _l1Receiver, amount);
}

/// @dev Get the message to be sent to L1 to initiate a withdrawal.
function _getL1WithdrawMessage(address _to, uint256 _amount) internal pure returns (bytes memory) {
return abi.encodePacked(IMailbox.finalizeEthWithdrawal.selector, _to, _amount);
}

/// @dev Get the message to be sent to L1 to initiate a withdrawal.
function _getExtendedWithdrawMessage(
address _to,
uint256 _amount,
address _sender,
bytes memory _additionalData
) internal pure returns (bytes memory) {
return abi.encodePacked(IMailbox.finalizeEthWithdrawal.selector, _to, _amount, _sender, _additionalData);
}

/// @dev This method has not been stabilized and might be
/// removed later on.
function name() external pure override returns (string memory) {
Expand Down
7 changes: 4 additions & 3 deletions etc/system-contracts/contracts/MsgValueSimulator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ pragma solidity ^0.8.0;

import "./libraries/Utils.sol";
import "./libraries/EfficientCall.sol";
import {SystemContractHelper, ISystemContract} from "./libraries/SystemContractHelper.sol";
import {MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT, ETH_TOKEN_SYSTEM_CONTRACT, MAX_MSG_VALUE} from "./Constants.sol";
import "./interfaces/ISystemContract.sol";
import {SystemContractHelper} from "./libraries/SystemContractHelper.sol";
import {MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT, ETH_TOKEN_SYSTEM_CONTRACT} from "./Constants.sol";

/**
* @author Matter Labs
Expand All @@ -30,7 +31,7 @@ contract MsgValueSimulator is ISystemContract {
to = address(uint160(addressAsUint));
}

fallback(bytes calldata _data) external payable onlySystemCall returns (bytes memory) {
fallback(bytes calldata _data) external onlySystemCall returns (bytes memory) {
(uint256 value, bool isSystemCall, address to) = _getAbiParams();

// Prevent mimic call to the MsgValueSimulator to prevent an unexpected change of callee.
Expand Down
4 changes: 2 additions & 2 deletions etc/system-contracts/contracts/NonceHolder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity ^0.8.0;

import "./interfaces/INonceHolder.sol";
import "./interfaces/IContractDeployer.sol";
import {ISystemContract} from "./libraries/SystemContractHelper.sol";
import {ISystemContract} from "./interfaces/ISystemContract.sol";
import {DEPLOYER_SYSTEM_CONTRACT} from "./Constants.sol";

/**
Expand Down Expand Up @@ -81,7 +81,7 @@ contract NonceHolder is INonceHolder, ISystemContract {
function setValueUnderNonce(uint256 _key, uint256 _value) public onlySystemCall {
IContractDeployer.AccountInfo memory accountInfo = DEPLOYER_SYSTEM_CONTRACT.getAccountInfo(msg.sender);

require(_value != 0, "Nonce value can not be set to 0");
require(_value != 0, "Nonce value cannot be set to 0");
// If an account has sequential nonce ordering, we enforce that the previous
// nonce has already been used.
if (accountInfo.nonceOrdering == IContractDeployer.AccountNonceOrdering.Sequential && _key != 0) {
Expand Down
Loading
Loading