From 434f72dbd362f68bda90677a40a449aba1417c41 Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Mon, 26 Aug 2024 16:12:39 +0200 Subject: [PATCH 1/2] Use transient storage for evm frames in EvmGasManager --- system-contracts/contracts/EvmGasManager.sol | 44 +++++++++++++------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/system-contracts/contracts/EvmGasManager.sol b/system-contracts/contracts/EvmGasManager.sol index 57623e39e..cab0c2150 100644 --- a/system-contracts/contracts/EvmGasManager.sol +++ b/system-contracts/contracts/EvmGasManager.sol @@ -10,7 +10,7 @@ uint160 constant PRECOMPILES_END = 0xffff; // Denotes that passGas has been consumed uint256 constant INF_PASS_GAS = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; - +uint256 constant EVM_STACK_SLOT = 2; contract EvmGasManager { // We need strust to use `storage` pointers struct WarmAccountInfo { @@ -123,25 +123,39 @@ contract EvmGasManager { */ - function pushEVMFrame(uint256 _passGas, bool _isStatic) external { - EVMStackFrameInfo memory frame = EVMStackFrameInfo({passGas: _passGas, isStatic: _isStatic}); - - evmStackFrames.push(frame); + function pushEVMFrame(uint256 passGas, bool isStatic) external { + assembly { + let stackDepth := add(tload(EVM_STACK_SLOT), 1) + tstore(EVM_STACK_SLOT, stackDepth) + let stackPointer := add(EVM_STACK_SLOT, mul(2, stackDepth)) + tstore(stackPointer, passGas) + tstore(add(stackPointer, 1), isStatic) + } } function consumeEvmFrame() external returns (uint256 passGas, bool isStatic) { - if (evmStackFrames.length == 0) return (INF_PASS_GAS, false); - - EVMStackFrameInfo memory frameInfo = evmStackFrames[evmStackFrames.length - 1]; - - passGas = frameInfo.passGas; - isStatic = frameInfo.isStatic; - - // Mark as used - evmStackFrames[evmStackFrames.length - 1].passGas = INF_PASS_GAS; + uint256 stackDepth; + assembly { + stackDepth := tload(EVM_STACK_SLOT) + } + if (stackDepth == 0) return (INF_PASS_GAS, false); + + assembly { + let stackPointer := add(EVM_STACK_SLOT, mul(2, stackDepth)) + passGas := tload(stackPointer) + isStatic := tload(add(stackPointer, 1)) + tstore(stackPointer, INF_PASS_GAS) // Mark as used + } } function popEVMFrame() external { - evmStackFrames.pop(); + uint256 stackDepth; + assembly { + stackDepth := tload(EVM_STACK_SLOT) + } + require(stackDepth != 0); + assembly { + tstore(EVM_STACK_SLOT, sub(stackDepth, 1)) + } } } From 6eea51f0dc4b725f921d19e6ae2b447bce11eb7f Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Mon, 26 Aug 2024 16:24:07 +0200 Subject: [PATCH 2/2] Run prettier --- system-contracts/contracts/EvmGasManager.sol | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/system-contracts/contracts/EvmGasManager.sol b/system-contracts/contracts/EvmGasManager.sol index cab0c2150..17bc3a68f 100644 --- a/system-contracts/contracts/EvmGasManager.sol +++ b/system-contracts/contracts/EvmGasManager.sol @@ -11,6 +11,7 @@ uint160 constant PRECOMPILES_END = 0xffff; // Denotes that passGas has been consumed uint256 constant INF_PASS_GAS = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; uint256 constant EVM_STACK_SLOT = 2; + contract EvmGasManager { // We need strust to use `storage` pointers struct WarmAccountInfo { @@ -139,7 +140,7 @@ contract EvmGasManager { stackDepth := tload(EVM_STACK_SLOT) } if (stackDepth == 0) return (INF_PASS_GAS, false); - + assembly { let stackPointer := add(EVM_STACK_SLOT, mul(2, stackDepth)) passGas := tload(stackPointer) @@ -156,6 +157,6 @@ contract EvmGasManager { require(stackDepth != 0); assembly { tstore(EVM_STACK_SLOT, sub(stackDepth, 1)) - } + } } }