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(EVM): Simplify returngas from constructor #1037

Merged
Show file tree
Hide file tree
Changes from all 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
36 changes: 18 additions & 18 deletions system-contracts/SystemContractsHashes.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,49 @@
"contractName": "AccountCodeStorage",
"bytecodePath": "artifacts-zk/contracts-preprocessed/AccountCodeStorage.sol/AccountCodeStorage.json",
"sourceCodePath": "contracts-preprocessed/AccountCodeStorage.sol",
"bytecodeHash": "0x0100007717dc02746f2cb709926f52fd61d96cb46101936b1185de956b574682",
"bytecodeHash": "0x0100007757f0a993c2b61e4b7b980eac7c16f9461d56b872befad11edf1791ef",
"sourceCodeHash": "0xfdac12f45b5cfd4abd12923206f2d6f253d11a6624783e079b55e975d573ceb6"
},
{
"contractName": "BootloaderUtilities",
"bytecodePath": "artifacts-zk/contracts-preprocessed/BootloaderUtilities.sol/BootloaderUtilities.json",
"sourceCodePath": "contracts-preprocessed/BootloaderUtilities.sol",
"bytecodeHash": "0x010006f13cbea31bcb77c670158b426d21e8f580951a7fc4ef9b2212ab67a30f",
"bytecodeHash": "0x010006f1164848f2e7669df28198a273458ba1fdf1ed0a04321289821d624ad4",
"sourceCodeHash": "0xed45097b2eaa4e47cd83f6feb3671d44adb49bac64c267844e76b3444605be19"
},
{
"contractName": "ComplexUpgrader",
"bytecodePath": "artifacts-zk/contracts-preprocessed/ComplexUpgrader.sol/ComplexUpgrader.json",
"sourceCodePath": "contracts-preprocessed/ComplexUpgrader.sol",
"bytecodeHash": "0x010000470f54c0e5cc35e659aefce4a345fde4a905a3396e08e6e08e9502c4a2",
"bytecodeHash": "0x0100004772c49529c6ccb5f6b3b1ea23d7498a172b59f3aa8797443ab7ec423a",
"sourceCodeHash": "0x796046a914fb676ba2bbd337b2924311ee2177ce54571c18a2c3945755c83614"
},
{
"contractName": "Compressor",
"bytecodePath": "artifacts-zk/contracts-preprocessed/Compressor.sol/Compressor.json",
"sourceCodePath": "contracts-preprocessed/Compressor.sol",
"bytecodeHash": "0x0100013fc97f375809db1ce6fb6e5951a6a2e52361002d148a1768eaf6bad9e7",
"bytecodeHash": "0x0100013f346ef598ecf8a5ba86e2fa4b306816a89a5a96af611047f3508faf03",
"sourceCodeHash": "0xc6f7cd8b21aae52ed3dd5083c09b438a7af142a4ecda6067c586770e8be745a5"
},
{
"contractName": "ContractDeployer",
"bytecodePath": "artifacts-zk/contracts-preprocessed/ContractDeployer.sol/ContractDeployer.json",
"sourceCodePath": "contracts-preprocessed/ContractDeployer.sol",
"bytecodeHash": "0x01000699eff3447b6d51bb1eaf32037bd4aafbbb1baa9a70f76125830ee97937",
"sourceCodeHash": "0x9ad8797aa39ae899362ed936542fe13160ef2a2ed95d67c2d66ac62077e61059"
"bytecodeHash": "0x010006975c637c78ca0e91e71c84b324c6e95c733fc041a0390a02656caa03c6",
"sourceCodeHash": "0x763a3e674b2900206bded35a5d390136da61cb043c86f2f4e0633d666313be25"
},
{
"contractName": "Create2Factory",
"bytecodePath": "artifacts-zk/contracts-preprocessed/Create2Factory.sol/Create2Factory.json",
"sourceCodePath": "contracts-preprocessed/Create2Factory.sol",
"bytecodeHash": "0x0100003f8b2f60eb000b89fd840c27aec320d8df5e2c860b6d3bd0f6010762ec",
"bytecodeHash": "0x0100003fc7635b13ed69e2a8e85908317afa68eee660998372981c7ca9991aaa",
"sourceCodeHash": "0x114d9322a9ca654989f3e0b3b21f1311dbc4db84f443d054cd414f6414d84de3"
},
{
"contractName": "DefaultAccount",
"bytecodePath": "artifacts-zk/contracts-preprocessed/DefaultAccount.sol/DefaultAccount.json",
"sourceCodePath": "contracts-preprocessed/DefaultAccount.sol",
"bytecodeHash": "0x01000509cce015327bf1a00b6007b69a884240bd559faa2fa2f45bfa9e9abd96",
"bytecodeHash": "0x010005096489d3a6c7c9d18750a4bda0f78c7a7f71ec540cb9b0fb8f2970922b",
"sourceCodeHash": "0xef448fac6b6f1c217b6495ee134a3553e02dfb920fd46bc71de33672e64d9ab8"
},
{
Expand All @@ -59,56 +59,56 @@
"contractName": "ImmutableSimulator",
"bytecodePath": "artifacts-zk/contracts-preprocessed/ImmutableSimulator.sol/ImmutableSimulator.json",
"sourceCodePath": "contracts-preprocessed/ImmutableSimulator.sol",
"bytecodeHash": "0x01000033536138bb4d3541b826f736392db784f4d1f419b8f98edbdf9ec99b05",
"bytecodeHash": "0x010000333575bcc1f34a79d1b43bb8f69813d35463b602e8e1fb88d85806aee1",
"sourceCodeHash": "0x9659e69f7db09e8f60a8bb95314b1ed26afcc689851665cf27f5408122f60c98"
},
{
"contractName": "KnownCodesStorage",
"bytecodePath": "artifacts-zk/contracts-preprocessed/KnownCodesStorage.sol/KnownCodesStorage.json",
"sourceCodePath": "contracts-preprocessed/KnownCodesStorage.sol",
"bytecodeHash": "0x010000cd5b164d338301040c3f5a2c73c775b2e0f7b7c5049dc2198d912e8d95",
"bytecodeHash": "0x010000cdc5734c8109be1afdc5ad40c84157d9f19bc1967d8a128444bcce0360",
"sourceCodeHash": "0x851fb5e170dfde39f1f9bc74654ec0b8f8f1d4c2fb20c06c77844c1e3ee0659a"
},
{
"contractName": "L1Messenger",
"bytecodePath": "artifacts-zk/contracts-preprocessed/L1Messenger.sol/L1Messenger.json",
"sourceCodePath": "contracts-preprocessed/L1Messenger.sol",
"bytecodeHash": "0x01000265b0203371672d9ba8d5f4ae92635606bf9c77b550c387917bddb9acdf",
"bytecodeHash": "0x01000265966dd95109bdd779e6deeb4f531d0cd983fb053ed77fbb982f94607b",
"sourceCodeHash": "0xa8768fdaac6d8804782f14e2a51bbe2b6be31dee9103b6d02d149ea8dc46eb6a"
},
{
"contractName": "L2BaseToken",
"bytecodePath": "artifacts-zk/contracts-preprocessed/L2BaseToken.sol/L2BaseToken.json",
"sourceCodePath": "contracts-preprocessed/L2BaseToken.sol",
"bytecodeHash": "0x010000f36487ed4282e33a1f8a323586e769a33409c55ddccb1d839117bfbe9c",
"bytecodeHash": "0x010000f33e4c891018536ca207056f7536854b030d847fdd7f21eb5576b30ed4",
"sourceCodeHash": "0x8bdd2b4d0b53dba84c9f0af250bbaa2aad10b3de6747bba957f0bd3721090dfa"
},
{
"contractName": "MsgValueSimulator",
"bytecodePath": "artifacts-zk/contracts-preprocessed/MsgValueSimulator.sol/MsgValueSimulator.json",
"sourceCodePath": "contracts-preprocessed/MsgValueSimulator.sol",
"bytecodeHash": "0x0100005946d91043ea599c05aa4d735d401d7aa6600b5b12f967c6ec8c983fb7",
"bytecodeHash": "0x01000059700408fe641af24437be3a197adfa4798b943594dc83f10a70bae855",
"sourceCodeHash": "0x082f3dcbc2fe4d93706c86aae85faa683387097d1b676e7ebd00f71ee0f13b71"
},
{
"contractName": "NonceHolder",
"bytecodePath": "artifacts-zk/contracts-preprocessed/NonceHolder.sol/NonceHolder.json",
"sourceCodePath": "contracts-preprocessed/NonceHolder.sol",
"bytecodeHash": "0x010000cf9366b12f1aed3bf74174fbca6eb1a6ab841830659a527408c11d3a32",
"bytecodeHash": "0x010000cffce37e7325318c746f5af8bd8d5f22236eabe2c5c78fc2acca5b418d",
"sourceCodeHash": "0xcd0c0366effebf2c98c58cf96322cc242a2d1c675620ef5514b7ed1f0a869edc"
},
{
"contractName": "PubdataChunkPublisher",
"bytecodePath": "artifacts-zk/contracts-preprocessed/PubdataChunkPublisher.sol/PubdataChunkPublisher.json",
"sourceCodePath": "contracts-preprocessed/PubdataChunkPublisher.sol",
"bytecodeHash": "0x01000041d59901297fd33c6a872493d201611711ab0e5a44ba4c24f4671756b2",
"bytecodeHash": "0x01000041a25a3ab6180cb1d752e742d9e39c8637b6c9e1e64a52d002f761b32d",
"sourceCodeHash": "0xd7161e2c8092cf57b43c6220bc605c0e7e540bddcde1af24e2d90f75633b098e"
},
{
"contractName": "SystemContext",
"bytecodePath": "artifacts-zk/contracts-preprocessed/SystemContext.sol/SystemContext.json",
"sourceCodePath": "contracts-preprocessed/SystemContext.sol",
"bytecodeHash": "0x010001c5238dcdd879430a91bf5ce05aa4f2d57ef5044b5e460a45bb426267fd",
"bytecodeHash": "0x010001c56a15564c7f07cc0dc68099436b1b40110f2d011b957860e324f948d7",
"sourceCodeHash": "0xe2f6eb015d260aafe9405b28ef3ec27921add4de7f329b7ef61e0aa6c9365e29"
},
{
Expand All @@ -122,8 +122,8 @@
"contractName": "EvmEmulator",
"bytecodePath": "contracts-preprocessed/artifacts/EvmEmulator.yul/EvmEmulator.yul.zbin",
"sourceCodePath": "contracts-preprocessed/EvmEmulator.yul",
"bytecodeHash": "0x01000c17f157cd87a1e8d9d8c0e9fb8a1b3ecd0409e68769365f5014e4b053ff",
"sourceCodeHash": "0xd17982c310a48c4edc2c5351b2a4372a0c161719f09c73de8aa8a960a2eae1a5"
"bytecodeHash": "0x01000c11e73a6952799a1f6104b39b411edda95ec98ea3023b45b019170d1dca",
"sourceCodeHash": "0x8e2f59560e10ece459fbde4ad7355df59a330055a4bbdb8b2d4500e4f35c1efe"
},
{
"contractName": "EvmGasManager",
Expand Down
34 changes: 11 additions & 23 deletions system-contracts/contracts/ContractDeployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
mapping(address => AccountInfo) internal accountInfo;

uint256 private constant EVM_HASHES_PREFIX = 1 << 254;
uint256 private constant CONSTRUCTOR_RETURN_GAS_TSLOT = 1;
uint256 private constant ALLOWED_BYTECODE_TYPES_MODE_SLOT = 2;

modifier onlySelf() {
Expand All @@ -46,12 +45,6 @@
mode = _getAllowedBytecodeTypesMode();
}

function constructorReturnGas() external view returns (uint256 returnGas) {
assembly {
returnGas := tload(CONSTRUCTOR_RETURN_GAS_TSLOT)
}
}

/// @notice Returns information about a certain account.
function getAccountInfo(address _address) external view returns (AccountInfo memory info) {
return accountInfo[_address];
Expand Down Expand Up @@ -179,7 +172,7 @@
function createEVM(bytes calldata _initCode) external payable override onlySystemCall returns (address) {
uint256 senderNonce;
// If the account is an EOA, use the min nonce. If it's a contract, use deployment nonce
if (msg.sender == tx.origin) {

Check warning on line 175 in system-contracts/contracts/ContractDeployer.sol

View workflow job for this annotation

GitHub Actions / lint

Avoid to use tx.origin

Check warning on line 175 in system-contracts/contracts/ContractDeployer.sol

View workflow job for this annotation

GitHub Actions / lint

Avoid to use tx.origin

Check warning on line 175 in system-contracts/contracts/ContractDeployer.sol

View workflow job for this annotation

GitHub Actions / lint

Avoid to use tx.origin
// Subtract 1 for EOA since the nonce has already been incremented for this transaction
senderNonce = NONCE_HOLDER_SYSTEM_CONTRACT.getMinNonce(msg.sender) - 1;
} else {
Expand Down Expand Up @@ -238,8 +231,8 @@

// Unfortunately we can not provide revert reason as it would break EVM compatibility
// we should not increase nonce in case of collision
require(NONCE_HOLDER_SYSTEM_CONTRACT.getRawNonce(newAddress) == 0x0);

Check failure on line 234 in system-contracts/contracts/ContractDeployer.sol

View workflow job for this annotation

GitHub Actions / lint

Provide an error message for require

Check failure on line 234 in system-contracts/contracts/ContractDeployer.sol

View workflow job for this annotation

GitHub Actions / lint

GC: Use Custom Errors instead of require statements

Check failure on line 234 in system-contracts/contracts/ContractDeployer.sol

View workflow job for this annotation

GitHub Actions / lint

Provide an error message for require

Check failure on line 234 in system-contracts/contracts/ContractDeployer.sol

View workflow job for this annotation

GitHub Actions / lint

GC: Use Custom Errors instead of require statements

Check failure on line 234 in system-contracts/contracts/ContractDeployer.sol

View workflow job for this annotation

GitHub Actions / lint

Provide an error message for require

Check failure on line 234 in system-contracts/contracts/ContractDeployer.sol

View workflow job for this annotation

GitHub Actions / lint

GC: Use Custom Errors instead of require statements
require(ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.getCodeHash(uint256(uint160(newAddress))) == 0x0);

Check failure on line 235 in system-contracts/contracts/ContractDeployer.sol

View workflow job for this annotation

GitHub Actions / lint

Provide an error message for require

Check failure on line 235 in system-contracts/contracts/ContractDeployer.sol

View workflow job for this annotation

GitHub Actions / lint

Provide an error message for require

Check failure on line 235 in system-contracts/contracts/ContractDeployer.sol

View workflow job for this annotation

GitHub Actions / lint

Provide an error message for require

return newAddress;
}
Expand All @@ -248,7 +241,7 @@
function createEvmFromEmulator(
address newAddress,
bytes calldata _initCode
) external payable onlySystemCallFromEvmEmulator returns (address) {
) external payable onlySystemCallFromEvmEmulator returns (uint256, address) {
uint32 providedErgs;
uint32 stipend = EVM_GAS_STIPEND;
assembly {
Expand All @@ -257,8 +250,8 @@
providedErgs := sub(_gas, stipend)
}
}
_evmDeployOnAddress(providedErgs, msg.sender, newAddress, _initCode);
return newAddress;
uint256 constructorReturnEvmGas = _evmDeployOnAddress(providedErgs, msg.sender, newAddress, _initCode);
return (constructorReturnEvmGas, newAddress);
}

/// @notice Deploys a contract account with similar address derivation rules to the EVM's `CREATE2` opcode.
Expand Down Expand Up @@ -423,15 +416,15 @@
address _sender,
address _newAddress,
bytes calldata _initCode
) internal {
) internal returns (uint256 constructorReturnEvmGas) {
if (_getAllowedBytecodeTypesMode() != AllowedBytecodeTypes.EraVmAndEVM) {
revert EVMEmulationNotSupported();
}

// Unfortunately we can not provide revert reason as it would break EVM compatibility
require(NONCE_HOLDER_SYSTEM_CONTRACT.getRawNonce(_newAddress) == 0x0);
require(ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.getCodeHash(uint256(uint160(_newAddress))) == 0x0);
_performDeployOnAddressEVM(_gasToPass, _sender, _newAddress, AccountAbstractionVersion.None, _initCode);
return _performDeployOnAddressEVM(_gasToPass, _sender, _newAddress, AccountAbstractionVersion.None, _initCode);
}

/// @notice Deploy a certain bytecode on the address.
Expand Down Expand Up @@ -476,7 +469,7 @@
address _newAddress,
AccountAbstractionVersion _aaVersion,
bytes calldata _input
) internal {
) internal returns (uint256 constructorReturnEvmGas) {
AccountInfo memory newAccountInfo;
newAccountInfo.supportedAAVersion = _aaVersion;
// Accounts have sequential nonces by default.
Expand All @@ -486,8 +479,8 @@
// Note, that for contracts the "nonce" is set as deployment nonce.
NONCE_HOLDER_SYSTEM_CONTRACT.incrementDeploymentNonce(_newAddress);

// When constructing they just get the intrepeter bytecode hash in consutrcting mode
_constructEVMContract(_gasToPass, _sender, _newAddress, _input);
// We will store dummy constructing bytecode hash to trigger EVM emulator in constructor call
return _constructEVMContract(_gasToPass, _sender, _newAddress, _input);
}

/// @notice Check that bytecode hash is marked as known on the `KnownCodeStorage` system contracts
Expand Down Expand Up @@ -564,7 +557,7 @@
address _sender,
address _newAddress,
bytes calldata _input
) internal {
) internal returns (uint256 constructorReturnEvmGas) {
uint256 value = msg.value;
// 1. Transfer the balance to the new address on the constructor call.
if (value > 0) {
Expand Down Expand Up @@ -594,10 +587,9 @@
_isSystem: false
});

uint256 constructorReturnGas;
assembly {
let dataLen := mload(paddedBytecode)
constructorReturnGas := mload(add(paddedBytecode, dataLen))
constructorReturnEvmGas := mload(add(paddedBytecode, dataLen))
mstore(paddedBytecode, sub(dataLen, 0x20))
}

Expand All @@ -612,11 +604,7 @@

_setEvmCodeHash(_newAddress, evmBytecodeHash);

assembly {
tstore(CONSTRUCTOR_RETURN_GAS_TSLOT, constructorReturnGas)
}

emit ContractDeployed(_sender, evmBytecodeHash, _newAddress);
emit ContractDeployed(_sender, versionedCodeHash, _newAddress);
}

function _setEvmCodeHash(address _address, bytes32 _hash) internal {
Expand Down
38 changes: 26 additions & 12 deletions system-contracts/contracts/EvmEmulator.yul
Original file line number Diff line number Diff line change
Expand Up @@ -1109,9 +1109,7 @@ object "EvmEmulator" {
gasLeft := _saveReturndataAfterEVMCall(0, 0)
}
default {
returndatacopy(0, 0, 32)
addr := mload(0)
gasLeft := _fetchConstructorReturnGas()
gasLeft, addr := _saveConstructorReturnGas()
}

let gasUsed := sub(gasForTheCall, gasLeft)
Expand All @@ -1138,9 +1136,18 @@ object "EvmEmulator" {
}
}

function _fetchConstructorReturnGas() -> gasLeft {
mstore(0, 0x24E5AB4A00000000000000000000000000000000000000000000000000000000)
gasLeft := fetchFromSystemContract(DEPLOYER_SYSTEM_CONTRACT(), 4)
function _saveConstructorReturnGas() -> gasLeft, addr {
loadReturndataIntoActivePtr()

if gt(returndatasize(), 63) { // >= 64
// ContractDeployer returns (uint256 gasLeft, address createdContract)
returndatacopy(0, 0, 64)
gasLeft := mload(0)
addr := mload(32)
}
// else: unexpected return data after constructor succeeded, should never happen.

_eraseReturndataPointer()
}

////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -4103,9 +4110,7 @@ object "EvmEmulator" {
gasLeft := _saveReturndataAfterEVMCall(0, 0)
}
default {
returndatacopy(0, 0, 32)
addr := mload(0)
gasLeft := _fetchConstructorReturnGas()
gasLeft, addr := _saveConstructorReturnGas()
}

let gasUsed := sub(gasForTheCall, gasLeft)
Expand All @@ -4132,9 +4137,18 @@ object "EvmEmulator" {
}
}

function _fetchConstructorReturnGas() -> gasLeft {
mstore(0, 0x24E5AB4A00000000000000000000000000000000000000000000000000000000)
gasLeft := fetchFromSystemContract(DEPLOYER_SYSTEM_CONTRACT(), 4)
function _saveConstructorReturnGas() -> gasLeft, addr {
loadReturndataIntoActivePtr()

if gt(returndatasize(), 63) { // >= 64
// ContractDeployer returns (uint256 gasLeft, address createdContract)
returndatacopy(0, 0, 64)
gasLeft := mload(0)
addr := mload(32)
}
// else: unexpected return data after constructor succeeded, should never happen.

_eraseReturndataPointer()
}

////////////////////////////////////////////////////////////////
Expand Down
2 changes: 0 additions & 2 deletions system-contracts/contracts/interfaces/IContractDeployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,6 @@ interface IContractDeployer {

function evmCodeHash(address) external view returns (bytes32);

function constructorReturnGas() external view returns (uint256);

/// @notice Changes what types of bytecodes are allowed to be deployed on the chain. Can be used only during upgrades.
/// @param newAllowedBytecodeTypes The new allowed bytecode types mode.
function setAllowedBytecodeTypesToDeploy(uint256 newAllowedBytecodeTypes) external;
Expand Down
19 changes: 13 additions & 6 deletions system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul
Original file line number Diff line number Diff line change
Expand Up @@ -1047,9 +1047,7 @@ function _executeCreate(offset, size, value, evmGasLeftOld, isCreate2, salt) ->
gasLeft := _saveReturndataAfterEVMCall(0, 0)
}
default {
returndatacopy(0, 0, 32)
addr := mload(0)
gasLeft := _fetchConstructorReturnGas()
gasLeft, addr := _saveConstructorReturnGas()
}

let gasUsed := sub(gasForTheCall, gasLeft)
Expand All @@ -1076,9 +1074,18 @@ function performSystemCallForCreate(value, bytecodeStart, bytecodeLen) -> succes
}
}

function _fetchConstructorReturnGas() -> gasLeft {
mstore(0, 0x24E5AB4A00000000000000000000000000000000000000000000000000000000)
gasLeft := fetchFromSystemContract(DEPLOYER_SYSTEM_CONTRACT(), 4)
function _saveConstructorReturnGas() -> gasLeft, addr {
loadReturndataIntoActivePtr()

if gt(returndatasize(), 63) { // >= 64
// ContractDeployer returns (uint256 gasLeft, address createdContract)
returndatacopy(0, 0, 64)
gasLeft := mload(0)
addr := mload(32)
}
// else: unexpected return data after constructor succeeded, should never happen.

_eraseReturndataPointer()
}

////////////////////////////////////////////////////////////////
Expand Down
Loading