diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Call.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Call.cs index 70f7caa6b16..fd4e4fd96db 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Call.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.Call.cs @@ -89,7 +89,7 @@ public struct OpStaticCall : IOpCall /// An value indicating success or the type of error encountered. /// [SkipLocalsInit] - public static EvmExceptionType InstructionCall(VirtualMachine vm, + public static EvmExceptionType InstructionCall(VirtualMachine vm, ref EvmStack stack, ref TGasPolicy gas, ref int programCounter) @@ -97,6 +97,7 @@ public static EvmExceptionType InstructionCall(StatusCode.SuccessBytes.Span); TGasPolicy.UpdateGasUp(ref gas, gasLimitUl); - vm.AddTransferLog(caller, target, transferValue); + vm.AddTransferLog(caller, target, transferValue); return FastCall(vm, spec, in transferValue, target); } diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.ControlFlow.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.ControlFlow.cs index 52ff8facd25..74fce6e08b0 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.ControlFlow.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.ControlFlow.cs @@ -202,9 +202,10 @@ public static EvmExceptionType InstructionRevert(VirtualMachine [SkipLocalsInit] - private static EvmExceptionType InstructionSelfDestruct(VirtualMachine vm, ref EvmStack stack, ref TGasPolicy gas, ref int programCounter) + private static EvmExceptionType InstructionSelfDestruct(VirtualMachine vm, ref EvmStack stack, ref TGasPolicy gas, ref int programCounter) where TGasPolicy : struct, IGasPolicy where TEip8037 : struct, IFlag + where TEip7708 : struct, IFlag { // Increment metrics for self-destruct operations. Metrics.IncrementSelfDestructs(); @@ -243,17 +244,7 @@ private static EvmExceptionType InstructionSelfDestruct(Vi // Retrieve the current balance for transfer. UInt256 result = state.GetBalance(executingAccount); - if (executingAccount == inheritor) - { - if (TEip8037.IsActive) - vm.AddBurnLog(executingAccount, result); - else - vm.AddSelfDestructLog(executingAccount, result); - } - else - { - vm.AddTransferLog(executingAccount, inheritor, result); - } + vm.AddSelfDestructLog(executingAccount, inheritor, result); if (vm.TxTracer.IsTracingActions) vm.TxTracer.ReportSelfDestruct(executingAccount, result, inheritor); diff --git a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.cs b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.cs index f2a652ce3dd..493961309ec 100644 --- a/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.cs +++ b/src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.cs @@ -295,18 +295,30 @@ internal static unsafe partial class EvmInstructions lookup[(int)Instruction.CREATE] = spec.IsEip8037Enabled ? &InstructionCreate : &InstructionCreate; - lookup[(int)Instruction.CALL] = spec.IsEip8037Enabled - ? &InstructionCall - : &InstructionCall; - lookup[(int)Instruction.CALLCODE] = spec.IsEip8037Enabled - ? &InstructionCall - : &InstructionCall; + lookup[(int)Instruction.CALL] = (spec.IsEip8037Enabled, spec.IsEip7708Enabled) switch + { + (true, true) => &InstructionCall, + (true, false) => &InstructionCall, + (false, true) => &InstructionCall, + (false, false) => &InstructionCall, + }; + lookup[(int)Instruction.CALLCODE] = (spec.IsEip8037Enabled, spec.IsEip7708Enabled) switch + { + (true, true) => &InstructionCall, + (true, false) => &InstructionCall, + (false, true) => &InstructionCall, + (false, false) => &InstructionCall, + }; lookup[(int)Instruction.RETURN] = &InstructionReturn; if (spec.DelegateCallEnabled) { - lookup[(int)Instruction.DELEGATECALL] = spec.IsEip8037Enabled - ? &InstructionCall - : &InstructionCall; + lookup[(int)Instruction.DELEGATECALL] = (spec.IsEip8037Enabled, spec.IsEip7708Enabled) switch + { + (true, true) => &InstructionCall, + (true, false) => &InstructionCall, + (false, true) => &InstructionCall, + (false, false) => &InstructionCall, + }; } if (spec.Create2OpcodeEnabled) { @@ -318,9 +330,13 @@ internal static unsafe partial class EvmInstructions lookup[(int)Instruction.RETURNDATALOAD] = &InstructionReturnDataLoad; if (spec.StaticCallEnabled) { - lookup[(int)Instruction.STATICCALL] = spec.IsEip8037Enabled - ? &InstructionCall - : &InstructionCall; + lookup[(int)Instruction.STATICCALL] = (spec.IsEip8037Enabled, spec.IsEip7708Enabled) switch + { + (true, true) => &InstructionCall, + (true, false) => &InstructionCall, + (false, true) => &InstructionCall, + (false, false) => &InstructionCall, + }; } // Extended call opcodes in EO mode. @@ -350,9 +366,13 @@ internal static unsafe partial class EvmInstructions // Final opcodes. lookup[(int)Instruction.INVALID] = &InstructionInvalid; - lookup[(int)Instruction.SELFDESTRUCT] = spec.IsEip8037Enabled - ? &InstructionSelfDestruct - : &InstructionSelfDestruct; + lookup[(int)Instruction.SELFDESTRUCT] = (spec.IsEip8037Enabled, spec.IsEip7708Enabled) switch + { + (true, true) => &InstructionSelfDestruct, + (true, false) => &InstructionSelfDestruct, + (false, true) => &InstructionSelfDestruct, + (false, false) => &InstructionSelfDestruct, + }; return lookup; } diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs index 0ee3a3dcd1b..093dc259991 100644 --- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs +++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs @@ -1454,32 +1454,36 @@ private void AddTransferLog(VmState currentState) // CALLCODE: value is transferred from ExecutingAccount to ExecutingAccount (self-transfer), so no log if (currentState.ExecutionType is not (ExecutionType.DELEGATECALL or ExecutionType.CALLCODE)) { - AddTransferLog(currentState.From, currentState.To, currentState.Env.Value); + // Runtime check acceptable here — called once per frame entry, not per instruction. + if (Spec.IsEip7708Enabled && !currentState.Env.Value.IsZero && currentState.From != currentState.To) + AddLog(TransferLog.CreateTransfer(currentState.From, currentState.To, currentState.Env.Value)); } } - internal void AddTransferLog(Address from, Address to, in UInt256 value) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void AddTransferLog(Address from, Address to, in UInt256 value) + where TEip7708 : struct, IFlag { - // Self-transfers don't change balances, so don't log them - if (Spec.IsEip7708Enabled && !value.IsZero && from != to) - { + if (TEip7708.IsActive && !value.IsZero && from != to) AddLog(TransferLog.CreateTransfer(from, to, value)); - } } - internal void AddBurnLog(Address account, in UInt256 value) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void AddSelfDestructLog(Address executingAccount, Address inheritor, in UInt256 value) + where TEip8037 : struct, IFlag + where TEip7708 : struct, IFlag { - if (Spec.IsEip7708Enabled && !value.IsZero) + if (!TEip7708.IsActive || value.IsZero) return; + + if (executingAccount == inheritor) { - AddLog(TransferLog.CreateBurn(account, value)); + AddLog(TEip8037.IsActive + ? TransferLog.CreateBurn(executingAccount, value) + : TransferLog.CreateSelfDestruct(executingAccount, value)); } - } - - internal void AddSelfDestructLog(Address contract, in UInt256 value) - { - if (Spec.IsEip7708Enabled && !value.IsZero) + else { - AddLog(TransferLog.CreateSelfDestruct(contract, value)); + AddLog(TransferLog.CreateTransfer(executingAccount, inheritor, value)); } } }