Skip to content

Commit

Permalink
fix(EVM): Implement resetEVMFrame function (#1051)
Browse files Browse the repository at this point in the history
  • Loading branch information
0xVolosnikov authored Oct 30, 2024
1 parent df1c554 commit cf476b1
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 0 deletions.
30 changes: 30 additions & 0 deletions system-contracts/contracts/EvmEmulator.yul
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,14 @@ object "EvmEmulator" {
}
}

function resetEvmFrame() {
// function resetEvmFrame()
// non-standard selector 0x05
mstore(0, 0x0500000000000000000000000000000000000000000000000000000000000000)

performSystemCall(EVM_GAS_MANAGER_CONTRACT(), 1)
}

////////////////////////////////////////////////////////////////
// CALLS FUNCTIONALITY
////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -772,6 +780,9 @@ object "EvmEmulator" {
)

let frameGasLeft := _saveReturndataAfterEVMCall(add(MEM_OFFSET(), retOffset), retSize)
if iszero(success) {
resetEvmFrame()
}

newGasLeft := add(evmGasLeft, frameGasLeft)
stackHead := success
Expand Down Expand Up @@ -802,6 +813,9 @@ object "EvmEmulator" {
}
success := call(ergsToPass, addr, value, argsOffset, argsSize, 0, 0)
frameGasLeft := _saveReturndataAfterEVMCall(retOffset, retSize)
if iszero(success) {
resetEvmFrame()
}
}
}

Expand Down Expand Up @@ -1103,6 +1117,7 @@ object "EvmEmulator" {
case 0 {
addr := 0
gasLeft := _saveReturndataAfterEVMCall(0, 0)
resetEvmFrame()
}
default {
gasLeft, addr := _saveConstructorReturnGas()
Expand Down Expand Up @@ -3616,6 +3631,14 @@ object "EvmEmulator" {
}
}

function resetEvmFrame() {
// function resetEvmFrame()
// non-standard selector 0x05
mstore(0, 0x0500000000000000000000000000000000000000000000000000000000000000)

performSystemCall(EVM_GAS_MANAGER_CONTRACT(), 1)
}

////////////////////////////////////////////////////////////////
// CALLS FUNCTIONALITY
////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -3769,6 +3792,9 @@ object "EvmEmulator" {
)

let frameGasLeft := _saveReturndataAfterEVMCall(add(MEM_OFFSET(), retOffset), retSize)
if iszero(success) {
resetEvmFrame()
}

newGasLeft := add(evmGasLeft, frameGasLeft)
stackHead := success
Expand Down Expand Up @@ -3799,6 +3825,9 @@ object "EvmEmulator" {
}
success := call(ergsToPass, addr, value, argsOffset, argsSize, 0, 0)
frameGasLeft := _saveReturndataAfterEVMCall(retOffset, retSize)
if iszero(success) {
resetEvmFrame()
}
}
}

Expand Down Expand Up @@ -4100,6 +4129,7 @@ object "EvmEmulator" {
case 0 {
addr := 0
gasLeft := _saveReturndataAfterEVMCall(0, 0)
resetEvmFrame()
}
default {
gasLeft, addr := _saveConstructorReturnGas()
Expand Down
7 changes: 7 additions & 0 deletions system-contracts/contracts/EvmGasManager.yul
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,13 @@ object "EvmGasManager" {
warmAccount(coinbase()) // and the coinbase too
return(0x0, 0x0)
}
case 5 { // function resetEVMFrame()
// Reset EVM frame context data
// This method is used by EvmEmulator to clean frame data after failed EVM call.
$llvm_AlwaysInline_llvm$_onlyEvmSystemCall()

tstore(EVM_AUX_DATA_SLOT(), 0) // mark as consumed (clean it)
}
default {
revert(0, 0)
}
Expand Down
15 changes: 15 additions & 0 deletions system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,14 @@ function consumeEvmFrame() -> passGas, isStatic, callerEVM {
}
}

function resetEvmFrame() {
// function resetEvmFrame()
// non-standard selector 0x05
mstore(0, 0x0500000000000000000000000000000000000000000000000000000000000000)

performSystemCall(EVM_GAS_MANAGER_CONTRACT(), 1)
}

////////////////////////////////////////////////////////////////
// CALLS FUNCTIONALITY
////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -710,6 +718,9 @@ function performDelegateCall(oldSp, evmGasLeft, isStatic, oldStackHead) -> newGa
)

let frameGasLeft := _saveReturndataAfterEVMCall(add(MEM_OFFSET(), retOffset), retSize)
if iszero(success) {
resetEvmFrame()
}

newGasLeft := add(evmGasLeft, frameGasLeft)
stackHead := success
Expand Down Expand Up @@ -740,6 +751,9 @@ function _genericCall(addr, gasToPass, value, argsOffset, argsSize, retOffset, r
}
success := call(ergsToPass, addr, value, argsOffset, argsSize, 0, 0)
frameGasLeft := _saveReturndataAfterEVMCall(retOffset, retSize)
if iszero(success) {
resetEvmFrame()
}
}
}

Expand Down Expand Up @@ -1041,6 +1055,7 @@ function _executeCreate(offset, size, value, evmGasLeftOld, isCreate2, salt) ->
case 0 {
addr := 0
gasLeft := _saveReturndataAfterEVMCall(0, 0)
resetEvmFrame()
}
default {
gasLeft, addr := _saveConstructorReturnGas()
Expand Down

0 comments on commit cf476b1

Please sign in to comment.