From 89245adabca554747502e4294c838639468ef1f5 Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Wed, 28 Aug 2024 17:01:37 +0200 Subject: [PATCH 1/2] Simplify _fetchDeployedCodeLen --- .../EvmInterpreterFunctions.template.yul | 23 ++++------ .../contracts/EvmInterpreterPreprocessed.yul | 46 +++++++------------ 2 files changed, 24 insertions(+), 45 deletions(-) diff --git a/system-contracts/contracts/EvmInterpreterFunctions.template.yul b/system-contracts/contracts/EvmInterpreterFunctions.template.yul index c6f7d0b2f..387885695 100644 --- a/system-contracts/contracts/EvmInterpreterFunctions.template.yul +++ b/system-contracts/contracts/EvmInterpreterFunctions.template.yul @@ -264,24 +264,17 @@ function _fetchDeployedCodeWithDest(addr, _offset, _len, dest) -> codeLen { function _fetchDeployedCodeLen(addr) -> codeLen { let codeHash := _getRawCodeHash(addr) - mstore(0, codeHash) - - let success := staticcall(gas(), CODE_ORACLE_SYSTEM_CONTRACT(), 0, 32, 0, 0) - - switch iszero(success) + switch shr(248, codeHash) case 1 { - // The code oracle call can only fail in the case where the contract - // we are querying is the current one executing and it has not yet been - // deployed, i.e., if someone calls codesize (or extcodesize(address())) - // inside the constructor. In that case, code length is zero. - codeLen := 0 + // EraVM + let codeLengthInWords := and(shr(224, codeHash), 0xffff) + codeLen := shl(5, codeLengthInWords) // codeLengthInWords * 32 } - default { - // The first word is the true length of the bytecode - returndatacopy(0, 0, 32) - codeLen := mload(0) + case 2 { + // EVM + let codeLengthInBytes := and(shr(224, codeHash), 0xffff) + codeLen := codeLengthInBytes } - } function getDeployedBytecode() { diff --git a/system-contracts/contracts/EvmInterpreterPreprocessed.yul b/system-contracts/contracts/EvmInterpreterPreprocessed.yul index 6d1fe6fe9..6caa979c2 100644 --- a/system-contracts/contracts/EvmInterpreterPreprocessed.yul +++ b/system-contracts/contracts/EvmInterpreterPreprocessed.yul @@ -333,24 +333,17 @@ object "EVMInterpreter" { function _fetchDeployedCodeLen(addr) -> codeLen { let codeHash := _getRawCodeHash(addr) - mstore(0, codeHash) - - let success := staticcall(gas(), CODE_ORACLE_SYSTEM_CONTRACT(), 0, 32, 0, 0) - - switch iszero(success) + switch shr(248, codeHash) case 1 { - // The code oracle call can only fail in the case where the contract - // we are querying is the current one executing and it has not yet been - // deployed, i.e., if someone calls codesize (or extcodesize(address())) - // inside the constructor. In that case, code length is zero. - codeLen := 0 + // EraVM + let codeLengthInWords := and(shr(224, codeHash), 0xffff) + codeLen := shl(5, codeLengthInWords) // codeLengthInWords * 32 } - default { - // The first word is the true length of the bytecode - returndatacopy(0, 0, 32) - codeLen := mload(0) + case 2 { + // EVM + let codeLengthInBytes := and(shr(224, codeHash), 0xffff) + codeLen := codeLengthInBytes } - } function getDeployedBytecode() { @@ -3299,24 +3292,17 @@ object "EVMInterpreter" { function _fetchDeployedCodeLen(addr) -> codeLen { let codeHash := _getRawCodeHash(addr) - mstore(0, codeHash) - - let success := staticcall(gas(), CODE_ORACLE_SYSTEM_CONTRACT(), 0, 32, 0, 0) - - switch iszero(success) + switch shr(248, codeHash) case 1 { - // The code oracle call can only fail in the case where the contract - // we are querying is the current one executing and it has not yet been - // deployed, i.e., if someone calls codesize (or extcodesize(address())) - // inside the constructor. In that case, code length is zero. - codeLen := 0 + // EraVM + let codeLengthInWords := and(shr(224, codeHash), 0xffff) + codeLen := shl(5, codeLengthInWords) // codeLengthInWords * 32 } - default { - // The first word is the true length of the bytecode - returndatacopy(0, 0, 32) - codeLen := mload(0) + case 2 { + // EVM + let codeLengthInBytes := and(shr(224, codeHash), 0xffff) + codeLen := codeLengthInBytes } - } function getDeployedBytecode() { From 448bc978c4f59558baf99538e508e035335fc93e Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Wed, 28 Aug 2024 17:09:29 +0200 Subject: [PATCH 2/2] Use _fetchDeployedCodeLen for both code types --- .../contracts/EvmInterpreterLoop.template.yul | 4 +--- system-contracts/contracts/EvmInterpreterPreprocessed.yul | 8 ++------ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/system-contracts/contracts/EvmInterpreterLoop.template.yul b/system-contracts/contracts/EvmInterpreterLoop.template.yul index dc3346988..5880cd1f4 100644 --- a/system-contracts/contracts/EvmInterpreterLoop.template.yul +++ b/system-contracts/contracts/EvmInterpreterLoop.template.yul @@ -480,9 +480,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 2500) } - switch _isEVM(addr) - case 0 { sp := pushStackItemWithoutCheck(sp, extcodesize(addr)) } - default { sp := pushStackItemWithoutCheck(sp, _fetchDeployedCodeLen(addr)) } + sp := pushStackItemWithoutCheck(sp, _fetchDeployedCodeLen(addr)) ip := add(ip, 1) } case 0x3C { // OP_EXTCODECOPY diff --git a/system-contracts/contracts/EvmInterpreterPreprocessed.yul b/system-contracts/contracts/EvmInterpreterPreprocessed.yul index 6caa979c2..654007bc3 100644 --- a/system-contracts/contracts/EvmInterpreterPreprocessed.yul +++ b/system-contracts/contracts/EvmInterpreterPreprocessed.yul @@ -2010,9 +2010,7 @@ object "EVMInterpreter" { evmGasLeft := chargeGas(evmGasLeft, 2500) } - switch _isEVM(addr) - case 0 { sp := pushStackItemWithoutCheck(sp, extcodesize(addr)) } - default { sp := pushStackItemWithoutCheck(sp, _fetchDeployedCodeLen(addr)) } + sp := pushStackItemWithoutCheck(sp, _fetchDeployedCodeLen(addr)) ip := add(ip, 1) } case 0x3C { // OP_EXTCODECOPY @@ -4969,9 +4967,7 @@ object "EVMInterpreter" { evmGasLeft := chargeGas(evmGasLeft, 2500) } - switch _isEVM(addr) - case 0 { sp := pushStackItemWithoutCheck(sp, extcodesize(addr)) } - default { sp := pushStackItemWithoutCheck(sp, _fetchDeployedCodeLen(addr)) } + sp := pushStackItemWithoutCheck(sp, _fetchDeployedCodeLen(addr)) ip := add(ip, 1) } case 0x3C { // OP_EXTCODECOPY