Skip to content

Commit

Permalink
Revert parts of changes #7106
Browse files Browse the repository at this point in the history
  • Loading branch information
LukaszRozmej committed Jun 18, 2024
1 parent 45209c4 commit 4456064
Show file tree
Hide file tree
Showing 16 changed files with 63 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
using Nethermind.Blockchain.Contracts.Json;
using Nethermind.Consensus;
using Nethermind.Core;
using Nethermind.Core.Collections;
using Nethermind.Core.Crypto;
using Nethermind.Core.Extensions;
using Nethermind.Core.Test.Builders;
Expand Down Expand Up @@ -97,10 +96,9 @@ public Address GetAccountAddress(TestRpcBlockchain chain, Address entryPointAddr
.SignedAndResolved(TestItem.PrivateKeyA)
.TestObject;

using ArrayPoolList<byte> data = Bytes.FromHexString(chain.EthRpcModule.eth_call(new TransactionForRpc(getAccountAddressTransaction)).Data)
.SliceWithZeroPaddingEmptyOnError(12, 20);
Address accountAddress = new(Bytes.FromHexString(chain.EthRpcModule.eth_call(new TransactionForRpc(getAccountAddressTransaction)).Data).SliceWithZeroPaddingEmptyOnError(12, 20));

return new(data.ToArray());
return accountAddress;
}

public byte[] GetWalletConstructor(Address entryPointAddress)
Expand Down
19 changes: 11 additions & 8 deletions src/Nethermind/Nethermind.Core/Extensions/ByteArrayExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,30 +43,33 @@ public static byte[] Slice(this byte[] bytes, int startIndex, int length)
return slice;
}

public static ArrayPoolList<byte> SliceWithZeroPaddingEmptyOnError(this byte[] bytes, int startIndex, int length)
public static byte[] SliceWithZeroPaddingEmptyOnError(this byte[] bytes, int startIndex, int length)
{
int copiedFragmentLength = Math.Min(bytes.Length - startIndex, length);
if (copiedFragmentLength <= 0)
{
return ArrayPoolList<byte>.Empty();
return Array.Empty<byte>();
}

ArrayPoolList<byte> slice = new(length, length);
bytes.Slice(startIndex, copiedFragmentLength).CopyTo(slice.AsSpan().Slice(0, copiedFragmentLength));
byte[] slice = new byte[length];

Buffer.BlockCopy(bytes, startIndex, slice, 0, copiedFragmentLength);
return slice;
}

public static ArrayPoolList<byte> SliceWithZeroPaddingEmptyOnError(this ReadOnlySpan<byte> bytes, int startIndex, int length)
public static byte[] SliceWithZeroPaddingEmptyOnError(this ReadOnlySpan<byte> bytes, int startIndex, int length)
{
int copiedFragmentLength = Math.Min(bytes.Length - startIndex, length);
if (copiedFragmentLength <= 0)
{
return ArrayPoolList<byte>.Empty();
return Array.Empty<byte>();
}

ArrayPoolList<byte> slice = new(length, length);
bytes.Slice(startIndex, copiedFragmentLength).CopyTo(slice.AsSpan().Slice(0, copiedFragmentLength));
byte[] slice = new byte[length];

bytes.Slice(startIndex, copiedFragmentLength).CopyTo(slice.AsSpan(0, copiedFragmentLength));
return slice;
}

}
}
6 changes: 0 additions & 6 deletions src/Nethermind/Nethermind.Core/Extensions/Bytes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,6 @@ public static int LeadingZerosCount(this Span<byte> bytes, int startIndex = 0)
return nonZeroIndex < 0 ? bytes.Length - startIndex : nonZeroIndex;
}

public static int LeadingZerosCount(this ReadOnlySpan<byte> bytes, int startIndex = 0)
{
int nonZeroIndex = bytes[startIndex..].IndexOfAnyExcept((byte)0);
return nonZeroIndex < 0 ? bytes.Length - startIndex : nonZeroIndex;
}

public static int TrailingZerosCount(this byte[] bytes)
{
int lastIndex = bytes.AsSpan().LastIndexOfAnyExcept((byte)0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ private G1MulPrecompile()

public long DataGasCost(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec) => 0L;

[SkipLocalsInit]
public (ReadOnlyMemory<byte>, bool) Run(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec)
{
const int expectedInputLength = 2 * BlsParams.LenFp + BlsParams.LenFr;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ public long DataGasCost(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseS

private const int ItemSize = 160;

[SkipLocalsInit]
public (ReadOnlyMemory<byte>, bool) Run(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec)
{
if (inputData.Length % ItemSize > 0 || inputData.Length == 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ private G2AddPrecompile()

public long DataGasCost(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec) => 0L;

[SkipLocalsInit]
public (ReadOnlyMemory<byte>, bool) Run(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec)
{
const int expectedInputLength = 8 * BlsParams.LenFp;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ private G2MulPrecompile()

public long DataGasCost(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec) => 0L;

[SkipLocalsInit]
public (ReadOnlyMemory<byte>, bool) Run(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec)
{
const int expectedInputLength = 4 * BlsParams.LenFp + BlsParams.LenFr;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ public long DataGasCost(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseS

private const int ItemSize = 288;

[SkipLocalsInit]
public (ReadOnlyMemory<byte>, bool) Run(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec)
{
if (inputData.Length % ItemSize > 0 || inputData.Length == 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ private MapToG1Precompile()

public long DataGasCost(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec) => 0L;

[SkipLocalsInit]
public (ReadOnlyMemory<byte>, bool) Run(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec)
{
const int expectedInputLength = 64;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ private MapToG2Precompile()

public long DataGasCost(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec) => 0L;

[SkipLocalsInit]
public (ReadOnlyMemory<byte>, bool) Run(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec)
{
const int expectedInputLength = 2 * BlsParams.LenFp;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ private PairingPrecompile() { }

public long DataGasCost(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec) => 43000L * (inputData.Length / PairSize);

[SkipLocalsInit]
public (ReadOnlyMemory<byte>, bool) Run(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec)
{
if (inputData.Length % PairSize > 0 || inputData.Length == 0)
Expand Down
51 changes: 20 additions & 31 deletions src/Nethermind/Nethermind.Evm/Precompiles/ModExpPrecompile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@

using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Nethermind.Core;
using Nethermind.Core.Extensions;
using Nethermind.Core.Specs;
using Nethermind.Int256;
using MathGmp.Native;
using Nethermind.Core.Collections;

namespace Nethermind.Evm.Precompiles
{
Expand All @@ -27,7 +25,10 @@ private ModExpPrecompile()

public static Address Address { get; } = Address.FromNumber(5);

public long BaseGasCost(IReleaseSpec releaseSpec) => 0L;
public long BaseGasCost(IReleaseSpec releaseSpec)
{
return 0L;
}

/// <summary>
/// https://github.com/ethereum/EIPs/pull/2892
Expand Down Expand Up @@ -62,8 +63,7 @@ public long DataGasCost(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseS

UInt256 expLengthUpTo32 = UInt256.Min(32, expLength);
UInt256 startIndex = 96 + baseLength; //+ expLength - expLengthUpTo32; // Geth takes head here, why?
using ArrayPoolList<byte> expSpan = inputData.Span.SliceWithZeroPaddingEmptyOnError((int)startIndex, (int)expLengthUpTo32);
UInt256 exp = new(expSpan.AsSpan(), true);
UInt256 exp = new(inputData.Span.SliceWithZeroPaddingEmptyOnError((int)startIndex, (int)expLengthUpTo32), true);
UInt256 iterationCount = CalculateIterationCount(expLength, exp);
bool overflow = UInt256.MultiplyOverflow(complexity, iterationCount, out UInt256 result);
result /= 3;
Expand All @@ -75,21 +75,14 @@ public long DataGasCost(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseS
}
}

private static mpz_t ImportDataToGmp(ReadOnlyMemory<byte> inputData, int startIndex, int length)
{
using ArrayPoolList<byte> baseData = inputData.Span.SliceWithZeroPaddingEmptyOnError(startIndex, length);
return ImportDataToGmp(baseData.AsSpan());
}

private static unsafe mpz_t ImportDataToGmp(ReadOnlySpan<byte> data)
private static mpz_t ImportDataToGmp(byte[] data)
{
mpz_t result = new();
gmp_lib.mpz_init(result);
ulong memorySize = (ulong)data.Length;
using void_ptr memoryChunk = gmp_lib.allocate(memorySize);

Span<byte> spanUnmanagedBuffer = new(memoryChunk.ToIntPtr().ToPointer(), data.Length);
data.CopyTo(spanUnmanagedBuffer);
Marshal.Copy(data, 0, memoryChunk.ToIntPtr(), data.Length);
gmp_lib.mpz_import(result, memorySize, 1, 1, 1, 0, memoryChunk);

return result;
Expand Down Expand Up @@ -121,15 +114,19 @@ private static (int, int, int) GetInputLengths(in ReadOnlyMemory<byte> inputData
return (Bytes.Empty, true);
}

using mpz_t modulusInt = ImportDataToGmp(inputData, 96 + baseLength + expLength, modulusLength);
byte[] modulusData = inputData.Span.SliceWithZeroPaddingEmptyOnError(96 + baseLength + expLength, modulusLength);
using mpz_t modulusInt = ImportDataToGmp(modulusData);

if (gmp_lib.mpz_sgn(modulusInt) == 0)
{
return (new byte[modulusLength], true);
}

using mpz_t baseInt = ImportDataToGmp(inputData, 96, baseLength);
using mpz_t expInt = ImportDataToGmp(inputData, 96 + baseLength, expLength);
byte[] baseData = inputData.Span.SliceWithZeroPaddingEmptyOnError(96, baseLength);
using mpz_t baseInt = ImportDataToGmp(baseData);

byte[] expData = inputData.Span.SliceWithZeroPaddingEmptyOnError(96 + baseLength, expLength);
using mpz_t expInt = ImportDataToGmp(expData);

using mpz_t powmResult = new();
gmp_lib.mpz_init(powmResult);
Expand All @@ -149,31 +146,24 @@ private static (int, int, int) GetInputLengths(in ReadOnlyMemory<byte> inputData
}

[Obsolete("This is a previous implementation using BigInteger instead of GMP")]
[SkipLocalsInit]
public static (ReadOnlyMemory<byte>, bool) OldRun(byte[] inputData)
{
Metrics.ModExpPrecompile++;

(int baseLength, int expLength, int modulusLength) = GetInputLengths(inputData);

ReadOnlySpan<byte> inputDataSpan = inputData.AsSpan();

BigInteger modulusInt = ExtractBigInteger(inputDataSpan, 96 + baseLength + expLength, modulusLength);
BigInteger modulusInt = inputData
.SliceWithZeroPaddingEmptyOnError(96 + baseLength + expLength, modulusLength).ToUnsignedBigInteger();

if (modulusInt.IsZero)
{
return (new byte[modulusLength], true);
}

BigInteger baseInt = ExtractBigInteger(inputDataSpan, 96, baseLength);
BigInteger expInt = ExtractBigInteger(inputDataSpan, 96 + baseLength, expLength);
BigInteger baseInt = inputData.SliceWithZeroPaddingEmptyOnError(96, baseLength).ToUnsignedBigInteger();
BigInteger expInt = inputData.SliceWithZeroPaddingEmptyOnError(96 + baseLength, expLength)
.ToUnsignedBigInteger();
return (BigInteger.ModPow(baseInt, expInt, modulusInt).ToBigEndianByteArray(modulusLength), true);

BigInteger ExtractBigInteger(ReadOnlySpan<byte> span, int startIndex, int length)
{
using ArrayPoolList<byte> arrayPoolList = span.SliceWithZeroPaddingEmptyOnError(startIndex, length);
return arrayPoolList.AsSpan().ToUnsignedBigInteger();
}
}

/// <summary>
Expand All @@ -183,7 +173,6 @@ BigInteger ExtractBigInteger(ReadOnlySpan<byte> span, int startIndex, int length
/// return words**2
/// </summary>
/// <returns></returns>
[SkipLocalsInit]
private static UInt256 MultComplexity(in UInt256 baseLength, in UInt256 modulusLength)
{
UInt256 maxLength = UInt256.Max(baseLength, modulusLength);
Expand Down Expand Up @@ -220,7 +209,7 @@ private static UInt256 CalculateIterationCount(UInt256 exponentLength, UInt256 e
bitLength--;
}

bool overflow = UInt256.MultiplyOverflow(exponentLength - 32, 8, out UInt256 multiplicationResult);
bool overflow = UInt256.MultiplyOverflow((exponentLength - 32), 8, out UInt256 multiplicationResult);
overflow |= UInt256.AddOverflow(multiplicationResult, (UInt256)bitLength, out iterationCount);
if (overflow)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@

using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using Nethermind.Core;
using Nethermind.Core.Collections;
using Nethermind.Core.Extensions;
using Nethermind.Core.Specs;
using Nethermind.Int256;
Expand All @@ -26,7 +24,10 @@ private ModExpPrecompilePreEip2565()

public static Address Address { get; } = Address.FromNumber(5);

public long BaseGasCost(IReleaseSpec releaseSpec) => 0L;
public long BaseGasCost(IReleaseSpec releaseSpec)
{
return 0L;
}

public long DataGasCost(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec)
{
Expand All @@ -42,10 +43,10 @@ public long DataGasCost(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseS

UInt256 complexity = MultComplexity(UInt256.Max(baseLength, modulusLength));

using ArrayPoolList<byte> expSignificantBytes = inputData.Span.SliceWithZeroPaddingEmptyOnError(96 + (int)baseLength, (int)UInt256.Min(expLength, 32));
byte[] expSignificantBytes = inputData.Span.SliceWithZeroPaddingEmptyOnError(96 + (int)baseLength, (int)UInt256.Min(expLength, 32));

UInt256 lengthOver32 = expLength <= 32 ? 0 : expLength - 32;
UInt256 adjusted = AdjustedExponentLength(lengthOver32, expSignificantBytes.AsSpan());
UInt256 adjusted = AdjustedExponentLength(lengthOver32, expSignificantBytes);
UInt256 gas = complexity * UInt256.Max(adjusted, UInt256.One) / 20;
return gas > long.MaxValue ? long.MaxValue : (long)gas;
}
Expand All @@ -55,49 +56,49 @@ public long DataGasCost(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseS
}
}

[SkipLocalsInit]
public (ReadOnlyMemory<byte>, bool) Run(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec)
{
Metrics.ModExpPrecompile++;

ReadOnlySpan<byte> inputDataSpan = inputData.Span;
int baseLength = (int)ExtractBigInteger(inputDataSpan, 0, 32);
BigInteger expLengthBig = ExtractBigInteger(inputDataSpan, 32, 32);
int baseLength = (int)inputData.Span.SliceWithZeroPaddingEmptyOnError(0, 32).ToUnsignedBigInteger();
BigInteger expLengthBig = inputData.Span.SliceWithZeroPaddingEmptyOnError(32, 32).ToUnsignedBigInteger();
int expLength = expLengthBig > int.MaxValue ? int.MaxValue : (int)expLengthBig;
int modulusLength = (int)ExtractBigInteger(inputDataSpan, 64, 32);
int modulusLength = (int)inputData.Span.SliceWithZeroPaddingEmptyOnError(64, 32).ToUnsignedBigInteger();

BigInteger modulusInt = ExtractBigInteger(inputDataSpan, 96 + baseLength + expLength, modulusLength);
BigInteger modulusInt = inputData.Span.SliceWithZeroPaddingEmptyOnError(96 + baseLength + expLength, modulusLength).ToUnsignedBigInteger();

if (modulusInt.IsZero)
{
return (new byte[modulusLength], true);
}

BigInteger baseInt = ExtractBigInteger(inputDataSpan, 96, baseLength);
BigInteger expInt = ExtractBigInteger(inputDataSpan, 96 + baseLength, expLength);
BigInteger baseInt = inputData.Span.SliceWithZeroPaddingEmptyOnError(96, baseLength).ToUnsignedBigInteger();
BigInteger expInt = inputData.Span.SliceWithZeroPaddingEmptyOnError(96 + baseLength, expLength).ToUnsignedBigInteger();
return (BigInteger.ModPow(baseInt, expInt, modulusInt).ToBigEndianByteArray(modulusLength), true);
}

BigInteger ExtractBigInteger(ReadOnlySpan<byte> span, int startIndex, int length)
private UInt256 MultComplexity(in UInt256 adjustedExponentLength)
{
if (adjustedExponentLength <= 64)
{
using ArrayPoolList<byte> arrayPoolList = span.SliceWithZeroPaddingEmptyOnError(startIndex, length);
return arrayPoolList.AsSpan().ToUnsignedBigInteger();
return adjustedExponentLength * adjustedExponentLength;
}
}

private UInt256 MultComplexity(in UInt256 adjustedExponentLength) =>
adjustedExponentLength <= 64
? adjustedExponentLength * adjustedExponentLength
: adjustedExponentLength <= 1024
? adjustedExponentLength * adjustedExponentLength / 4 + 96 * adjustedExponentLength - 3072
: adjustedExponentLength * adjustedExponentLength / 16 + 480 * adjustedExponentLength - 199680;
if (adjustedExponentLength <= 1024)
{
return adjustedExponentLength * adjustedExponentLength / 4 + 96 * adjustedExponentLength - 3072;
}

return adjustedExponentLength * adjustedExponentLength / 16 + 480 * adjustedExponentLength - 199680;
}

private static UInt256 AdjustedExponentLength(in UInt256 lengthOver32, ReadOnlySpan<byte> exponent)
private static UInt256 AdjustedExponentLength(in UInt256 lengthOver32, byte[] exponent)
{
bool overflow = false;
bool underflow = false;
UInt256 result;

int leadingZeros = exponent.LeadingZerosCount();
int leadingZeros = exponent.AsSpan().LeadingZerosCount();
if (leadingZeros == exponent.Length)
{
overflow |= UInt256.MultiplyOverflow(lengthOver32, 8, out result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ public class Bn254PairingPrecompile : IPrecompile<Bn254PairingPrecompile>

public long DataGasCost(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec) => (releaseSpec.IsEip1108Enabled ? 34000L : 80000L) * (inputData.Length / PairSize);

[SkipLocalsInit]
public (ReadOnlyMemory<byte>, bool) Run(in ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec)
{
Metrics.Bn254PairingPrecompile++;
Expand Down
Loading

0 comments on commit 4456064

Please sign in to comment.