From 286a4dc8fc803cada6e6d41e2974918e14f591dd Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Mon, 9 Dec 2024 12:41:38 +0100 Subject: [PATCH] fix(EVM): Fix logs implementation (2) (#1137) --- system-contracts/contracts/EvmEmulator.yul | 250 ++++++------------ .../EvmEmulatorFunctions.template.yul | 29 ++ .../evm-emulator/EvmEmulatorLoop.template.yul | 96 +------ 3 files changed, 117 insertions(+), 258 deletions(-) diff --git a/system-contracts/contracts/EvmEmulator.yul b/system-contracts/contracts/EvmEmulator.yul index 367aa87c9..ea8b65d34 100644 --- a/system-contracts/contracts/EvmEmulator.yul +++ b/system-contracts/contracts/EvmEmulator.yul @@ -1301,6 +1301,35 @@ object "EvmEmulator" { $llvm_AlwaysInline_llvm$_copyRest(dest_end, 0, rest_len) } } + + //////////////////////////////////////////////////////////////// + // LOGS FUNCTIONALITY + //////////////////////////////////////////////////////////////// + + function _genericLog(sp, stackHead, evmGasLeft, topicCount, isStatic) -> newEvmGasLeft, offset, size, newSp, newStackHead { + newEvmGasLeft := chargeGas(evmGasLeft, 375) + + if isStatic { + panic() + } + + let rawOffset + popStackCheck(sp, add(2, topicCount)) + rawOffset, newSp, newStackHead := popStackItemWithoutCheck(sp, stackHead) + size, newSp, newStackHead := popStackItemWithoutCheck(newSp, newStackHead) + + checkMemIsAccessible(rawOffset, size) + + // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost + let dynamicGas := add(shl(3, size), expandMemory(rawOffset, size)) + dynamicGas := add(dynamicGas, mul(375, topicCount)) + + newEvmGasLeft := chargeGas(newEvmGasLeft, dynamicGas) + + if size { + offset := add(rawOffset, MEM_OFFSET()) + } + } function simulate( isCallerEVM, @@ -2641,125 +2670,49 @@ object "EvmEmulator" { ip := add(ip, 1) } case 0xA0 { // OP_LOG0 - evmGasLeft := chargeGas(evmGasLeft, 375) - - if isStatic { - panic() - } - let offset, size - popStackCheck(sp, 2) - offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - - checkMemIsAccessible(offset, size) - - // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost - let dynamicGas := add(shl(3, size), expandMemory(offset, size)) - evmGasLeft := chargeGas(evmGasLeft, dynamicGas) - - log0(add(offset, MEM_OFFSET()), size) + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 0, isStatic) + log0(offset, size) ip := add(ip, 1) } case 0xA1 { // OP_LOG1 - evmGasLeft := chargeGas(evmGasLeft, 375) - - if isStatic { - panic() - } - let offset, size - popStackCheck(sp, 3) - offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - - checkMemIsAccessible(offset, size) - - // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost - let dynamicGas := add(shl(3, size), expandMemory(offset, size)) - dynamicGas := add(dynamicGas, 375) - evmGasLeft := chargeGas(evmGasLeft, dynamicGas) - + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 1, isStatic) { let topic1 topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - log1(add(offset, MEM_OFFSET()), size, topic1) + log1(offset, size, topic1) } ip := add(ip, 1) } case 0xA2 { // OP_LOG2 - evmGasLeft := chargeGas(evmGasLeft, 375) - - if isStatic { - panic() - } - let offset, size - popStackCheck(sp, 4) - offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - - checkMemIsAccessible(offset, size) - - // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost - let dynamicGas := add(shl(3, size), expandMemory(offset, size)) - dynamicGas := add(dynamicGas, 750) - evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 2, isStatic) { let topic1, topic2 topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) topic2, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - log2(add(offset, MEM_OFFSET()), size, topic1, topic2) + log2(offset, size, topic1, topic2) } ip := add(ip, 1) } case 0xA3 { // OP_LOG3 - evmGasLeft := chargeGas(evmGasLeft, 375) - - if isStatic { - panic() - } - let offset, size - popStackCheck(sp, 5) - offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - - checkMemIsAccessible(offset, size) - - // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost - let dynamicGas := add(shl(3, size), expandMemory(offset, size)) - dynamicGas := add(dynamicGas, 1125) - evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 3, isStatic) { let topic1, topic2, topic3 topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) topic2, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) topic3, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - log3(add(offset, MEM_OFFSET()), size, topic1, topic2, topic3) + log3(offset, size, topic1, topic2, topic3) } ip := add(ip, 1) } case 0xA4 { // OP_LOG4 - evmGasLeft := chargeGas(evmGasLeft, 375) - - if isStatic { - panic() - } - let offset, size - popStackCheck(sp, 6) - offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - - checkMemIsAccessible(offset, size) - - // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost - let dynamicGas := add(shl(3, size), expandMemory(offset, size)) - dynamicGas := add(dynamicGas, 1500) - evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 4, isStatic) { let topic1, topic2, topic3, topic4 @@ -2767,7 +2720,7 @@ object "EvmEmulator" { topic2, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) topic3, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) topic4, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - log4(add(offset, MEM_OFFSET()), size, topic1, topic2, topic3, topic4) + log4(offset, size, topic1, topic2, topic3, topic4) } ip := add(ip, 1) } @@ -4488,6 +4441,35 @@ object "EvmEmulator" { $llvm_AlwaysInline_llvm$_copyRest(dest_end, 0, rest_len) } } + + //////////////////////////////////////////////////////////////// + // LOGS FUNCTIONALITY + //////////////////////////////////////////////////////////////// + + function _genericLog(sp, stackHead, evmGasLeft, topicCount, isStatic) -> newEvmGasLeft, offset, size, newSp, newStackHead { + newEvmGasLeft := chargeGas(evmGasLeft, 375) + + if isStatic { + panic() + } + + let rawOffset + popStackCheck(sp, add(2, topicCount)) + rawOffset, newSp, newStackHead := popStackItemWithoutCheck(sp, stackHead) + size, newSp, newStackHead := popStackItemWithoutCheck(newSp, newStackHead) + + checkMemIsAccessible(rawOffset, size) + + // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost + let dynamicGas := add(shl(3, size), expandMemory(rawOffset, size)) + dynamicGas := add(dynamicGas, mul(375, topicCount)) + + newEvmGasLeft := chargeGas(newEvmGasLeft, dynamicGas) + + if size { + offset := add(rawOffset, MEM_OFFSET()) + } + } function $llvm_NoInline_llvm$_simulate( isCallerEVM, @@ -5828,125 +5810,49 @@ object "EvmEmulator" { ip := add(ip, 1) } case 0xA0 { // OP_LOG0 - evmGasLeft := chargeGas(evmGasLeft, 375) - - if isStatic { - panic() - } - let offset, size - popStackCheck(sp, 2) - offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - - checkMemIsAccessible(offset, size) - - // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost - let dynamicGas := add(shl(3, size), expandMemory(offset, size)) - evmGasLeft := chargeGas(evmGasLeft, dynamicGas) - - log0(add(offset, MEM_OFFSET()), size) + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 0, isStatic) + log0(offset, size) ip := add(ip, 1) } case 0xA1 { // OP_LOG1 - evmGasLeft := chargeGas(evmGasLeft, 375) - - if isStatic { - panic() - } - let offset, size - popStackCheck(sp, 3) - offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - - checkMemIsAccessible(offset, size) - - // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost - let dynamicGas := add(shl(3, size), expandMemory(offset, size)) - dynamicGas := add(dynamicGas, 375) - evmGasLeft := chargeGas(evmGasLeft, dynamicGas) - + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 1, isStatic) { let topic1 topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - log1(add(offset, MEM_OFFSET()), size, topic1) + log1(offset, size, topic1) } ip := add(ip, 1) } case 0xA2 { // OP_LOG2 - evmGasLeft := chargeGas(evmGasLeft, 375) - - if isStatic { - panic() - } - let offset, size - popStackCheck(sp, 4) - offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - - checkMemIsAccessible(offset, size) - - // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost - let dynamicGas := add(shl(3, size), expandMemory(offset, size)) - dynamicGas := add(dynamicGas, 750) - evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 2, isStatic) { let topic1, topic2 topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) topic2, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - log2(add(offset, MEM_OFFSET()), size, topic1, topic2) + log2(offset, size, topic1, topic2) } ip := add(ip, 1) } case 0xA3 { // OP_LOG3 - evmGasLeft := chargeGas(evmGasLeft, 375) - - if isStatic { - panic() - } - let offset, size - popStackCheck(sp, 5) - offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - - checkMemIsAccessible(offset, size) - - // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost - let dynamicGas := add(shl(3, size), expandMemory(offset, size)) - dynamicGas := add(dynamicGas, 1125) - evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 3, isStatic) { let topic1, topic2, topic3 topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) topic2, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) topic3, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - log3(add(offset, MEM_OFFSET()), size, topic1, topic2, topic3) + log3(offset, size, topic1, topic2, topic3) } ip := add(ip, 1) } case 0xA4 { // OP_LOG4 - evmGasLeft := chargeGas(evmGasLeft, 375) - - if isStatic { - panic() - } - let offset, size - popStackCheck(sp, 6) - offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - - checkMemIsAccessible(offset, size) - - // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost - let dynamicGas := add(shl(3, size), expandMemory(offset, size)) - dynamicGas := add(dynamicGas, 1500) - evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 4, isStatic) { let topic1, topic2, topic3, topic4 @@ -5954,7 +5860,7 @@ object "EvmEmulator" { topic2, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) topic3, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) topic4, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - log4(add(offset, MEM_OFFSET()), size, topic1, topic2, topic3, topic4) + log4(offset, size, topic1, topic2, topic3, topic4) } ip := add(ip, 1) } diff --git a/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul b/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul index 00d579de5..50089c79d 100644 --- a/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul +++ b/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul @@ -1238,4 +1238,33 @@ function $llvm_AlwaysInline_llvm$_memsetToZero(dest,len) { if rest_len { $llvm_AlwaysInline_llvm$_copyRest(dest_end, 0, rest_len) } +} + +//////////////////////////////////////////////////////////////// +// LOGS FUNCTIONALITY +//////////////////////////////////////////////////////////////// + +function _genericLog(sp, stackHead, evmGasLeft, topicCount, isStatic) -> newEvmGasLeft, offset, size, newSp, newStackHead { + newEvmGasLeft := chargeGas(evmGasLeft, 375) + + if isStatic { + panic() + } + + let rawOffset + popStackCheck(sp, add(2, topicCount)) + rawOffset, newSp, newStackHead := popStackItemWithoutCheck(sp, stackHead) + size, newSp, newStackHead := popStackItemWithoutCheck(newSp, newStackHead) + + checkMemIsAccessible(rawOffset, size) + + // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost + let dynamicGas := add(shl(3, size), expandMemory(rawOffset, size)) + dynamicGas := add(dynamicGas, mul(375, topicCount)) + + newEvmGasLeft := chargeGas(newEvmGasLeft, dynamicGas) + + if size { + offset := add(rawOffset, MEM_OFFSET()) + } } \ No newline at end of file diff --git a/system-contracts/evm-emulator/EvmEmulatorLoop.template.yul b/system-contracts/evm-emulator/EvmEmulatorLoop.template.yul index e1eeae682..b5d956b44 100644 --- a/system-contracts/evm-emulator/EvmEmulatorLoop.template.yul +++ b/system-contracts/evm-emulator/EvmEmulatorLoop.template.yul @@ -1328,125 +1328,49 @@ for { } true { } { ip := add(ip, 1) } case 0xA0 { // OP_LOG0 - evmGasLeft := chargeGas(evmGasLeft, 375) - - if isStatic { - panic() - } - let offset, size - popStackCheck(sp, 2) - offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - - checkMemIsAccessible(offset, size) - - // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost - let dynamicGas := add(shl(3, size), expandMemory(offset, size)) - evmGasLeft := chargeGas(evmGasLeft, dynamicGas) - - log0(add(offset, MEM_OFFSET()), size) + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 0, isStatic) + log0(offset, size) ip := add(ip, 1) } case 0xA1 { // OP_LOG1 - evmGasLeft := chargeGas(evmGasLeft, 375) - - if isStatic { - panic() - } - let offset, size - popStackCheck(sp, 3) - offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - - checkMemIsAccessible(offset, size) - - // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost - let dynamicGas := add(shl(3, size), expandMemory(offset, size)) - dynamicGas := add(dynamicGas, 375) - evmGasLeft := chargeGas(evmGasLeft, dynamicGas) - + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 1, isStatic) { let topic1 topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - log1(add(offset, MEM_OFFSET()), size, topic1) + log1(offset, size, topic1) } ip := add(ip, 1) } case 0xA2 { // OP_LOG2 - evmGasLeft := chargeGas(evmGasLeft, 375) - - if isStatic { - panic() - } - let offset, size - popStackCheck(sp, 4) - offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - - checkMemIsAccessible(offset, size) - - // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost - let dynamicGas := add(shl(3, size), expandMemory(offset, size)) - dynamicGas := add(dynamicGas, 750) - evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 2, isStatic) { let topic1, topic2 topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) topic2, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - log2(add(offset, MEM_OFFSET()), size, topic1, topic2) + log2(offset, size, topic1, topic2) } ip := add(ip, 1) } case 0xA3 { // OP_LOG3 - evmGasLeft := chargeGas(evmGasLeft, 375) - - if isStatic { - panic() - } - let offset, size - popStackCheck(sp, 5) - offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - - checkMemIsAccessible(offset, size) - - // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost - let dynamicGas := add(shl(3, size), expandMemory(offset, size)) - dynamicGas := add(dynamicGas, 1125) - evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 3, isStatic) { let topic1, topic2, topic3 topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) topic2, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) topic3, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - log3(add(offset, MEM_OFFSET()), size, topic1, topic2, topic3) + log3(offset, size, topic1, topic2, topic3) } ip := add(ip, 1) } case 0xA4 { // OP_LOG4 - evmGasLeft := chargeGas(evmGasLeft, 375) - - if isStatic { - panic() - } - let offset, size - popStackCheck(sp, 6) - offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - - checkMemIsAccessible(offset, size) - - // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost - let dynamicGas := add(shl(3, size), expandMemory(offset, size)) - dynamicGas := add(dynamicGas, 1500) - evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 4, isStatic) { let topic1, topic2, topic3, topic4 @@ -1454,7 +1378,7 @@ for { } true { } { topic2, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) topic3, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) topic4, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) - log4(add(offset, MEM_OFFSET()), size, topic1, topic2, topic3, topic4) + log4(offset, size, topic1, topic2, topic3, topic4) } ip := add(ip, 1) }