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 @@ -29,7 +29,7 @@ public void Setup()
[Benchmark]
public bool Current()
{
return _codeInfo.ValidateJump(0, false);
return _codeInfo.ValidateJump(0);
}
}
}
7 changes: 0 additions & 7 deletions src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,6 @@ public interface IReleaseSpec : IEip1559Spec, IReceiptSpec
/// </summary>
bool IsEip2200Enabled { get; }

/// <summary>
/// Berlin subroutines -> https://github.com/ethereum/EIPs/issues/2315
/// </summary>
bool IsEip2315Enabled { get; }

/// <summary>
/// Berlin BLS crypto precompiles
/// </summary>
Expand Down Expand Up @@ -336,8 +331,6 @@ public interface IReleaseSpec : IEip1559Spec, IReceiptSpec

public bool ShiftOpcodesEnabled => IsEip145Enabled;

public bool SubroutinesEnabled => IsEip2315Enabled;

public bool RevertOpcodeEnabled => IsEip140Enabled;

public bool ExtCodeHashOpcodeEnabled => IsEip1052Enabled;
Expand Down
58 changes: 13 additions & 45 deletions src/Nethermind/Nethermind.Evm.Test/CodeAnalysis/CodeInfoTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,7 @@ public void Validates_when_only_jump_dest_present(int destination, bool isValid)

CodeInfo codeInfo = new(code);

codeInfo.ValidateJump(destination, false).Should().Be(isValid);
}

[TestCase(-1, false)]
[TestCase(0, true)]
[TestCase(1, false)]
public void Validates_when_only_begin_sub_present(int destination, bool isValid)
{
byte[] code =
{
(byte)Instruction.BEGINSUB
};

CodeInfo codeInfo = new(code);


codeInfo.ValidateJump(destination, true).Should().Be(isValid);
codeInfo.ValidateJump(destination).Should().Be(isValid);
}

[Test]
Expand All @@ -58,23 +42,7 @@ public void Validates_when_push_with_data_like_jump_dest()

CodeInfo codeInfo = new(code);

codeInfo.ValidateJump(1, true).Should().BeFalse();
codeInfo.ValidateJump(1, false).Should().BeFalse();
}

[Test]
public void Validates_when_push_with_data_like_begin_sub()
{
byte[] code =
{
(byte)Instruction.PUSH1,
(byte)Instruction.BEGINSUB
};

CodeInfo codeInfo = new(code);

codeInfo.ValidateJump(1, true).Should().BeFalse();
codeInfo.ValidateJump(1, false).Should().BeFalse();
codeInfo.ValidateJump(1).Should().BeFalse();
}

[Test]
Expand All @@ -89,7 +57,7 @@ public void Validate_CodeBitmap_With_Push10()

CodeInfo codeInfo = new(code);

codeInfo.ValidateJump(11, false).Should().BeTrue();
codeInfo.ValidateJump(11).Should().BeTrue();
}

[Test]
Expand All @@ -104,7 +72,7 @@ public void Validate_CodeBitmap_With_Push30()

CodeInfo codeInfo = new(code);

codeInfo.ValidateJump(31, false).Should().BeTrue();
codeInfo.ValidateJump(31).Should().BeTrue();
}

[Test]
Expand All @@ -117,7 +85,7 @@ public void Small_Jumpdest()

CodeInfo codeInfo = new(code);

codeInfo.ValidateJump(10, false).Should().BeTrue();
codeInfo.ValidateJump(10).Should().BeTrue();
}

[Test]
Expand All @@ -130,7 +98,7 @@ public void Small_Push1()

CodeInfo codeInfo = new(code);

codeInfo.ValidateJump(10, false).Should().BeFalse();
codeInfo.ValidateJump(10).Should().BeFalse();
}

[Test]
Expand All @@ -140,7 +108,7 @@ public void Jumpdest_Over10k()

CodeInfo codeInfo = new(code);

codeInfo.ValidateJump(10, false).Should().BeTrue();
codeInfo.ValidateJump(10).Should().BeTrue();
}

[Test]
Expand All @@ -150,7 +118,7 @@ public void Push1_Over10k()

CodeInfo codeInfo = new(code);

codeInfo.ValidateJump(10, false).Should().BeFalse();
codeInfo.ValidateJump(10).Should().BeFalse();
}

[Test]
Expand All @@ -164,8 +132,8 @@ public void Push1Jumpdest_Over10k()

CodeInfo codeInfo = new(code);

codeInfo.ValidateJump(10, false).Should().BeFalse();
codeInfo.ValidateJump(11, false).Should().BeFalse(); // 0x5b but not JUMPDEST but data
codeInfo.ValidateJump(10).Should().BeFalse();
codeInfo.ValidateJump(11).Should().BeFalse(); // 0x5b but not JUMPDEST but data
}

[TestCase(1)]
Expand Down Expand Up @@ -231,15 +199,15 @@ public void PushNJumpdest_Over10k(int n)

for (i = 0; i < Vector256<byte>.Count * 2 + Vector128<byte>.Count; i++)
{
codeInfo.ValidateJump(i, false).Should().BeTrue();
codeInfo.ValidateJump(i).Should().BeTrue();
}
for (; i < Vector256<byte>.Count * 3; i++)
{
codeInfo.ValidateJump(i, false).Should().BeFalse();
codeInfo.ValidateJump(i).Should().BeFalse();
}
for (; i < code.Length; i++)
{
codeInfo.ValidateJump(i, false).Should().BeFalse(); // Are 0x5b but not JUMPDEST but data
codeInfo.ValidateJump(i).Should().BeFalse(); // Are 0x5b but not JUMPDEST but data
}
}
}
Expand Down
37 changes: 0 additions & 37 deletions src/Nethermind/Nethermind.Evm.Test/InstructionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,42 +20,5 @@ public void Return_prevrandao_name_for_prevrandao_opcode_for_post_merge()
{
Instruction.PREVRANDAO.GetName(true, Cancun.Instance).Should().Be("PREVRANDAO");
}

[Test]
public void Return_tload_name_for_beginsub_opcode_for_eip1153()
{
Instruction.BEGINSUB.GetName(true, Cancun.Instance).Should().Be("TLOAD");
}

[Test]
public void Return_beginsub_name_for_beginsub_opcode_for_eip1153()
{
Instruction.BEGINSUB.GetName(true, Shanghai.Instance).Should().Be("BEGINSUB");
}

[Test]
public void Return_returnsub_name_for_returnsub_opcode_for_eip1153()
{
Instruction.RETURNSUB.GetName(true, Shanghai.Instance).Should().Be("RETURNSUB");
}

[Test]
public void Return_tstore_name_for_returnsub_opcode_for_eip1153()
{
Instruction.RETURNSUB.GetName(true, Cancun.Instance).Should().Be("TSTORE");
}


[Test]
public void Return_mcopy_name_for_mcopy_opcode_post_eip_5656()
{
Instruction.MCOPY.GetName(true, Cancun.Instance).Should().Be("MCOPY");
}

[Test]
public void Return_jumpsub_name_for_mcopy_opcode_pre_eip_5656()
{
Instruction.MCOPY.GetName(true, Shanghai.Instance).Should().Be("JUMPSUB");
}
}
}
7 changes: 0 additions & 7 deletions src/Nethermind/Nethermind.Evm/ByteCodeBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,6 @@ public static Prepare SWAPx(this Prepare @this, byte i)
=> @this.Op(Instruction.SWAP1 + i - 1);
public static Prepare DUPx(this Prepare @this, byte i)
=> @this.Op(Instruction.DUP1 + i - 1);
public static Prepare BEGINSUB(this Prepare @this)
=> @this.Op(Instruction.BEGINSUB);
public static Prepare RETURNSUB(this Prepare @this)
=> @this.Op(Instruction.RETURNSUB);
public static Prepare INVALID(this Prepare @this)
=> @this.Op(Instruction.INVALID);
#endregion
Expand All @@ -116,9 +112,6 @@ public static Prepare SELFDESTRUCT(this Prepare @this, Address? address = null)
public static Prepare EXTCODEHASH(this Prepare @this, Address? address = null)
=> @this.PushSingle(address)
.Op(Instruction.EXTCODEHASH);
public static Prepare JUMPSUB(this Prepare @this, UInt256? pos = null)
=> @this.PushSingle(pos)
.Op(Instruction.JUMPSUB);
public static Prepare PUSHx(this Prepare @this, byte[] args)
=> @this.PushData(args);
public static Prepare MLOAD(this Prepare @this, UInt256? pos = null)
Expand Down
4 changes: 2 additions & 2 deletions src/Nethermind/Nethermind.Evm/CodeAnalysis/CodeInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ public CodeInfo(IPrecompile precompile)
_analyzer = _emptyAnalyzer;
}

public bool ValidateJump(int destination, bool isSubroutine)
public bool ValidateJump(int destination)
{
return _analyzer.ValidateJump(destination, isSubroutine);
return _analyzer.ValidateJump(destination);
}

void IThreadPoolWorkItem.Execute()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,25 @@ namespace Nethermind.Evm.CodeAnalysis
{
public sealed class JumpDestinationAnalyzer(ReadOnlyMemory<byte> code)
{
private const int PUSH1 = 0x60;
private const int PUSH1 = (int)Instruction.PUSH1;
private const int PUSHx = PUSH1 - 1;
private const int JUMPDEST = 0x5b;
private const int BEGINSUB = 0x5c;
private const int JUMPDEST = (int)Instruction.JUMPDEST;
private const int BitShiftPerInt64 = 6;

private static readonly long[]? _emptyJumpDestinationBitmap = new long[1];
private long[]? _jumpDestinationBitmap = code.Length == 0 ? _emptyJumpDestinationBitmap : null;

private ReadOnlyMemory<byte> MachineCode { get; } = code;

public bool ValidateJump(int destination, bool isSubroutine)
public bool ValidateJump(int destination)
{
ReadOnlySpan<byte> machineCode = MachineCode.Span;
_jumpDestinationBitmap ??= CreateJumpDestinationBitmap(machineCode);

var result = false;
// Cast to uint to change negative numbers to very int high numbers
// Then do length check, this both reduces check by 1 and eliminates the bounds
// check from accessing the span.
if ((uint)destination < (uint)machineCode.Length && IsJumpDestination(_jumpDestinationBitmap, destination))
{
// Store byte to int, as less expensive operations at word size
int codeByte = machineCode[destination];
result = isSubroutine ? codeByte == BEGINSUB : codeByte == JUMPDEST;
}

return result;
return (uint)destination < (uint)machineCode.Length && IsJumpDestination(_jumpDestinationBitmap, destination);
}

/// <summary>
Expand Down Expand Up @@ -90,12 +81,8 @@ private static long[] CreateJumpDestinationBitmap(ReadOnlySpan<byte> code)
{
// Check the bytes for any JUMPDESTs.
Vector128<sbyte> dest = Sse2.CompareEqual(data, Vector128.Create((sbyte)JUMPDEST));
// Check the bytes for any BEGINSUBs.
Vector128<sbyte> sub = Sse2.CompareEqual(data, Vector128.Create((sbyte)BEGINSUB));
// Merge the two results.
Vector128<sbyte> combined = Sse2.Or(dest, sub);
// Extract the checks as a set of int flags.
int flags = Sse2.MoveMask(combined);
int flags = Sse2.MoveMask(dest);
// Shift up flags by depending which side of long we are on, and merge to current set.
currentFlags |= (long)flags << (programCounter & (32 + 16));
// Forward programCounter by Vector128 stride.
Expand All @@ -110,7 +97,7 @@ private static long[] CreateJumpDestinationBitmap(ReadOnlySpan<byte> code)
// access here.
int op = Unsafe.Add(ref MemoryMarshal.GetReference(code), programCounter);

if ((uint)op - JUMPDEST <= BEGINSUB - JUMPDEST)
if (op == JUMPDEST)
{
// Accumulate Jump Destinations to register, shift will wrap and single bit
// so can shift by the whole programCounter.
Expand Down
6 changes: 0 additions & 6 deletions src/Nethermind/Nethermind.Evm/Instruction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,6 @@ public enum Instruction : byte
MSIZE = 0x59,
GAS = 0x5a,
JUMPDEST = 0x5b,
BEGINSUB = 0x5c,
RETURNSUB = 0x5d,
JUMPSUB = 0x5e,
MCOPY = 0x5e,

PUSH0 = 0x5f, // EIP-3855
Expand Down Expand Up @@ -182,9 +179,6 @@ public static class InstructionExtensions
instruction switch
{
Instruction.PREVRANDAO when !isPostMerge => "DIFFICULTY",
Instruction.TLOAD or Instruction.BEGINSUB => spec?.TransientStorageEnabled == true ? "TLOAD" : "BEGINSUB",
Instruction.TSTORE or Instruction.RETURNSUB => spec?.TransientStorageEnabled == true ? "TSTORE" : "RETURNSUB",
Instruction.JUMPSUB or Instruction.MCOPY => spec?.IsEip5656Enabled == true ? "MCOPY" : "JUMPSUB",
_ => FastEnum.IsDefined(instruction) ? FastEnum.GetName(instruction) : null
};
}
Expand Down
Loading