Skip to content

Commit

Permalink
Merge pull request #752 from matter-labs/vv-evm-simplify-fetchDeploye…
Browse files Browse the repository at this point in the history
…dCodeLen

[EVM-Equivalence-YUL] Simplify EXTCODESIZE
  • Loading branch information
jrchatruc authored Aug 29, 2024
2 parents 253d370 + 448bc97 commit 2fe0652
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 54 deletions.
23 changes: 8 additions & 15 deletions system-contracts/contracts/EvmInterpreterFunctions.template.yul
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
4 changes: 1 addition & 3 deletions system-contracts/contracts/EvmInterpreterLoop.template.yul
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
54 changes: 18 additions & 36 deletions system-contracts/contracts/EvmInterpreterPreprocessed.yul
Original file line number Diff line number Diff line change
Expand Up @@ -346,24 +346,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() {
Expand Down Expand Up @@ -2048,9 +2041,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
Expand Down Expand Up @@ -3330,24 +3321,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() {
Expand Down Expand Up @@ -5032,9 +5016,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
Expand Down

0 comments on commit 2fe0652

Please sign in to comment.