Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,15 @@ public struct OpStaticCall : IOpCall
/// An <see cref="EvmExceptionType"/> value indicating success or the type of error encountered.
/// </returns>
[SkipLocalsInit]
public static EvmExceptionType InstructionCall<TGasPolicy, TOpCall, TTracingInst, TEip8037>(VirtualMachine<TGasPolicy> vm,
public static EvmExceptionType InstructionCall<TGasPolicy, TOpCall, TTracingInst, TEip8037, TEip7708>(VirtualMachine<TGasPolicy> vm,
ref EvmStack stack,
ref TGasPolicy gas,
ref int programCounter)
where TGasPolicy : struct, IGasPolicy<TGasPolicy>
where TOpCall : struct, IOpCall
where TTracingInst : struct, IFlag
where TEip8037 : struct, IFlag
where TEip7708 : struct, IFlag
{
// Increment global call metrics.
Metrics.IncrementCalls();
Expand Down Expand Up @@ -269,7 +270,7 @@ public static EvmExceptionType InstructionCall<TGasPolicy, TOpCall, TTracingInst
vm.ReturnDataBuffer = default;
stack.PushBytes<TTracingInst>(StatusCode.SuccessBytes.Span);
TGasPolicy.UpdateGasUp(ref gas, gasLimitUl);
vm.AddTransferLog(caller, target, transferValue);
vm.AddTransferLog<TEip7708>(caller, target, transferValue);
return FastCall(vm, spec, in transferValue, target);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,10 @@ public static EvmExceptionType InstructionRevert<TGasPolicy>(VirtualMachine<TGas
/// and marks the executing account for destruction.
/// </summary>
[SkipLocalsInit]
private static EvmExceptionType InstructionSelfDestruct<TGasPolicy, TEip8037>(VirtualMachine<TGasPolicy> vm, ref EvmStack stack, ref TGasPolicy gas, ref int programCounter)
private static EvmExceptionType InstructionSelfDestruct<TGasPolicy, TEip8037, TEip7708>(VirtualMachine<TGasPolicy> vm, ref EvmStack stack, ref TGasPolicy gas, ref int programCounter)
where TGasPolicy : struct, IGasPolicy<TGasPolicy>
where TEip8037 : struct, IFlag
where TEip7708 : struct, IFlag
{
// Increment metrics for self-destruct operations.
Metrics.IncrementSelfDestructs();
Expand Down Expand Up @@ -243,17 +244,7 @@ private static EvmExceptionType InstructionSelfDestruct<TGasPolicy, TEip8037>(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<TEip8037, TEip7708>(executingAccount, inheritor, result);

if (vm.TxTracer.IsTracingActions)
vm.TxTracer.ReportSelfDestruct(executingAccount, result, inheritor);
Expand Down
50 changes: 35 additions & 15 deletions src/Nethermind/Nethermind.Evm/Instructions/EvmInstructions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -295,18 +295,30 @@ internal static unsafe partial class EvmInstructions
lookup[(int)Instruction.CREATE] = spec.IsEip8037Enabled
? &InstructionCreate<TGasPolicy, OpCreate, TTracingInst, OnFlag>
: &InstructionCreate<TGasPolicy, OpCreate, TTracingInst, OffFlag>;
lookup[(int)Instruction.CALL] = spec.IsEip8037Enabled
? &InstructionCall<TGasPolicy, OpCall, TTracingInst, OnFlag>
: &InstructionCall<TGasPolicy, OpCall, TTracingInst, OffFlag>;
lookup[(int)Instruction.CALLCODE] = spec.IsEip8037Enabled
? &InstructionCall<TGasPolicy, OpCallCode, TTracingInst, OnFlag>
: &InstructionCall<TGasPolicy, OpCallCode, TTracingInst, OffFlag>;
lookup[(int)Instruction.CALL] = (spec.IsEip8037Enabled, spec.IsEip7708Enabled) switch
{
(true, true) => &InstructionCall<TGasPolicy, OpCall, TTracingInst, OnFlag, OnFlag>,
(true, false) => &InstructionCall<TGasPolicy, OpCall, TTracingInst, OnFlag, OffFlag>,
(false, true) => &InstructionCall<TGasPolicy, OpCall, TTracingInst, OffFlag, OnFlag>,
(false, false) => &InstructionCall<TGasPolicy, OpCall, TTracingInst, OffFlag, OffFlag>,
};
lookup[(int)Instruction.CALLCODE] = (spec.IsEip8037Enabled, spec.IsEip7708Enabled) switch
{
(true, true) => &InstructionCall<TGasPolicy, OpCallCode, TTracingInst, OnFlag, OnFlag>,
(true, false) => &InstructionCall<TGasPolicy, OpCallCode, TTracingInst, OnFlag, OffFlag>,
(false, true) => &InstructionCall<TGasPolicy, OpCallCode, TTracingInst, OffFlag, OnFlag>,
(false, false) => &InstructionCall<TGasPolicy, OpCallCode, TTracingInst, OffFlag, OffFlag>,
};
lookup[(int)Instruction.RETURN] = &InstructionReturn;
if (spec.DelegateCallEnabled)
{
lookup[(int)Instruction.DELEGATECALL] = spec.IsEip8037Enabled
? &InstructionCall<TGasPolicy, OpDelegateCall, TTracingInst, OnFlag>
: &InstructionCall<TGasPolicy, OpDelegateCall, TTracingInst, OffFlag>;
lookup[(int)Instruction.DELEGATECALL] = (spec.IsEip8037Enabled, spec.IsEip7708Enabled) switch
{
(true, true) => &InstructionCall<TGasPolicy, OpDelegateCall, TTracingInst, OnFlag, OnFlag>,
(true, false) => &InstructionCall<TGasPolicy, OpDelegateCall, TTracingInst, OnFlag, OffFlag>,
(false, true) => &InstructionCall<TGasPolicy, OpDelegateCall, TTracingInst, OffFlag, OnFlag>,
(false, false) => &InstructionCall<TGasPolicy, OpDelegateCall, TTracingInst, OffFlag, OffFlag>,
};
}
if (spec.Create2OpcodeEnabled)
{
Expand All @@ -318,9 +330,13 @@ internal static unsafe partial class EvmInstructions
lookup[(int)Instruction.RETURNDATALOAD] = &InstructionReturnDataLoad<TGasPolicy, TTracingInst>;
if (spec.StaticCallEnabled)
{
lookup[(int)Instruction.STATICCALL] = spec.IsEip8037Enabled
? &InstructionCall<TGasPolicy, OpStaticCall, TTracingInst, OnFlag>
: &InstructionCall<TGasPolicy, OpStaticCall, TTracingInst, OffFlag>;
lookup[(int)Instruction.STATICCALL] = (spec.IsEip8037Enabled, spec.IsEip7708Enabled) switch
{
(true, true) => &InstructionCall<TGasPolicy, OpStaticCall, TTracingInst, OnFlag, OnFlag>,
(true, false) => &InstructionCall<TGasPolicy, OpStaticCall, TTracingInst, OnFlag, OffFlag>,
(false, true) => &InstructionCall<TGasPolicy, OpStaticCall, TTracingInst, OffFlag, OnFlag>,
(false, false) => &InstructionCall<TGasPolicy, OpStaticCall, TTracingInst, OffFlag, OffFlag>,
};
}

// Extended call opcodes in EO mode.
Expand Down Expand Up @@ -350,9 +366,13 @@ internal static unsafe partial class EvmInstructions

// Final opcodes.
lookup[(int)Instruction.INVALID] = &InstructionInvalid;
lookup[(int)Instruction.SELFDESTRUCT] = spec.IsEip8037Enabled
? &InstructionSelfDestruct<TGasPolicy, OnFlag>
: &InstructionSelfDestruct<TGasPolicy, OffFlag>;
lookup[(int)Instruction.SELFDESTRUCT] = (spec.IsEip8037Enabled, spec.IsEip7708Enabled) switch
{
(true, true) => &InstructionSelfDestruct<TGasPolicy, OnFlag, OnFlag>,
(true, false) => &InstructionSelfDestruct<TGasPolicy, OnFlag, OffFlag>,
(false, true) => &InstructionSelfDestruct<TGasPolicy, OffFlag, OnFlag>,
(false, false) => &InstructionSelfDestruct<TGasPolicy, OffFlag, OffFlag>,
};

return lookup;
}
Expand Down
34 changes: 19 additions & 15 deletions src/Nethermind/Nethermind.Evm/VirtualMachine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1454,32 +1454,36 @@ private void AddTransferLog(VmState<TGasPolicy> 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<TEip7708>(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<TEip8037, TEip7708>(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));
}
}
}
Expand Down
Loading