-
Notifications
You must be signed in to change notification settings - Fork 512
eip-7883 implementation #8489
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
yerke26
wants to merge
22
commits into
master
Choose a base branch
from
test/precompile500wx2up
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
eip-7883 implementation #8489
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
3a0be32
bump pricing
marcindsobczak dd05498
disable precompile cache
marcindsobczak 6a5e345
min gas at 300
marcindsobczak 8e2aa66
400 is the new min
marcindsobczak 7de750b
divide by 2
marcindsobczak 4188e8c
min gas 500
marcindsobczak 1fa07d5
min gas 600
marcindsobczak 4da7700
divide by 2
marcindsobczak fed68e9
min gas 500
marcindsobczak 04dd929
increase words cost if >32 bytes
marcindsobczak 843de06
Merge remote-tracking branch 'origin/master' into test/precompile500wx2
marcindsobczak 685a0cb
Merge remote-tracking branch 'origin/master' into test/precompile500w…
marcindsobczak e9f1a72
add eip activation
yerke26 8492ae8
fix whitespace
yerke26 9ddf52e
add tests
yerke26 dc91923
Merge branch 'master' into test/precompile500wx2up
yerke26 6fad146
add more tests
yerke26 c108ece
Merge branch 'master' into test/precompile500wx2up
yerke26 9950f82
fix whitespaces
yerke26 7249c9a
Merge remote-tracking branch 'origin/test/precompile500wx2up' into te…
yerke26 3bed928
minor refactoring
yerke26 8988740
Merge branch 'master' into test/precompile500wx2up
yerke26 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited | ||
// SPDX-License-Identifier: LGPL-3.0-only | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using FluentAssertions; | ||
using Nethermind.Core.Specs; | ||
using Nethermind.Evm.Precompiles; | ||
using Nethermind.Int256; | ||
using Nethermind.Specs; | ||
using NUnit.Framework; | ||
|
||
namespace Nethermind.Evm.Test; | ||
|
||
public class Eip7883Tests | ||
{ | ||
[Test] | ||
public void DataGasCost([ValueSource(nameof(Eip7883TestCases))] Eip7883TestCase test) | ||
{ | ||
var inputData = PrepareInput(test.BaseLength, test.ExpLength, test.ModulusLength); | ||
|
||
long gas = ModExpPrecompile.Instance.DataGasCost(inputData, test.Spec); | ||
gas.Should().Be(test.Result); | ||
} | ||
|
||
public class Eip7883TestCase | ||
{ | ||
public IReleaseSpec Spec { get; set; } | ||
public UInt256 BaseLength { get; set; } | ||
public UInt256 ExpLength { get; set; } | ||
public UInt256 ModulusLength { get; set; } | ||
public long Result { get; set; } | ||
} | ||
|
||
private static readonly IReleaseSpec SpecEipEnabled = new ReleaseSpec | ||
{ | ||
IsEip7883Enabled = true, | ||
IsEip2565Enabled = true, | ||
}; | ||
|
||
private static readonly IReleaseSpec SpecEipDisabled = new ReleaseSpec | ||
{ | ||
IsEip7883Enabled = false, | ||
IsEip2565Enabled = true, | ||
}; | ||
|
||
private static IEnumerable<Eip7883TestCase> Eip7883TestCases() | ||
{ | ||
// eip enabled test cases | ||
yield return new Eip7883TestCase | ||
{ Spec = SpecEipEnabled, BaseLength = 32, ExpLength = 32, ModulusLength = 32, Result = 500L }; | ||
yield return new Eip7883TestCase | ||
{ Spec = SpecEipEnabled, BaseLength = 32, ExpLength = 32, ModulusLength = 10000, Result = 1041666L }; | ||
yield return new Eip7883TestCase | ||
{ Spec = SpecEipEnabled, BaseLength = 32, ExpLength = 10000, ModulusLength = 32, Result = 850602L }; | ||
yield return new Eip7883TestCase | ||
{ Spec = SpecEipEnabled, BaseLength = 10000, ExpLength = 32, ModulusLength = 32, Result = 1041666L }; | ||
yield return new Eip7883TestCase | ||
{ Spec = SpecEipEnabled, BaseLength = 32, ExpLength = 10000, ModulusLength = 10000, Result = 166133333333L }; | ||
yield return new Eip7883TestCase | ||
{ Spec = SpecEipEnabled, BaseLength = 10000, ExpLength = 10000, ModulusLength = 32, Result = 166133333333L }; | ||
yield return new Eip7883TestCase | ||
{ Spec = SpecEipEnabled, BaseLength = 10000, ExpLength = 32, ModulusLength = 10000, Result = 1041666L }; | ||
yield return new Eip7883TestCase | ||
{ Spec = SpecEipEnabled, BaseLength = 10000, ExpLength = 10000, ModulusLength = 10000, Result = 166133333333L }; | ||
|
||
// eip disabled test cases | ||
yield return new Eip7883TestCase | ||
{ Spec = SpecEipDisabled, BaseLength = 32, ExpLength = 32, ModulusLength = 32, Result = 200L }; | ||
yield return new Eip7883TestCase | ||
{ Spec = SpecEipDisabled, BaseLength = 32, ExpLength = 32, ModulusLength = 10000, Result = 520833L }; | ||
yield return new Eip7883TestCase | ||
{ Spec = SpecEipDisabled, BaseLength = 32, ExpLength = 10000, ModulusLength = 32, Result = 425301L }; | ||
yield return new Eip7883TestCase | ||
{ Spec = SpecEipDisabled, BaseLength = 10000, ExpLength = 32, ModulusLength = 32, Result = 520833L }; | ||
yield return new Eip7883TestCase | ||
{ Spec = SpecEipDisabled, BaseLength = 32, ExpLength = 10000, ModulusLength = 10000, Result = 41533333333L }; | ||
yield return new Eip7883TestCase | ||
{ Spec = SpecEipDisabled, BaseLength = 10000, ExpLength = 10000, ModulusLength = 32, Result = 41533333333L }; | ||
yield return new Eip7883TestCase | ||
{ Spec = SpecEipDisabled, BaseLength = 10000, ExpLength = 32, ModulusLength = 10000, Result = 520833L }; | ||
yield return new Eip7883TestCase | ||
{ Spec = SpecEipDisabled, BaseLength = 10000, ExpLength = 10000, ModulusLength = 10000, Result = 41533333333L }; | ||
} | ||
|
||
private static ReadOnlyMemory<byte> PrepareInput(UInt256 baseLength, UInt256 expLength, UInt256 modulusLength) | ||
{ | ||
var inputBytes = new byte[96]; | ||
|
||
Array.Copy(baseLength.ToBigEndian(), 0, inputBytes, 0, 32); | ||
Array.Copy(expLength.ToBigEndian(), 0, inputBytes, 32, 32); | ||
Array.Copy(modulusLength.ToBigEndian(), 0, inputBytes, 64, 32); | ||
|
||
return new ReadOnlyMemory<byte>(inputBytes); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,15 +59,15 @@ public long DataGasCost(ReadOnlyMemory<byte> inputData, IReleaseSpec releaseSpec | |
UInt256 expLength = new(extendedInput.Slice(32, 32), true); | ||
UInt256 modulusLength = new(extendedInput.Slice(64, 32), true); | ||
|
||
UInt256 complexity = MultComplexity(baseLength, modulusLength); | ||
UInt256 complexity = MultComplexity(baseLength, modulusLength, releaseSpec.IsEip7883Enabled); | ||
|
||
UInt256 expLengthUpTo32 = UInt256.Min(32, expLength); | ||
UInt256 startIndex = 96 + baseLength; //+ expLength - expLengthUpTo32; // Geth takes head here, why? | ||
UInt256 exp = new(inputData.Span.SliceWithZeroPaddingEmptyOnError((int)startIndex, (int)expLengthUpTo32), true); | ||
UInt256 iterationCount = CalculateIterationCount(expLength, exp); | ||
UInt256 iterationCount = CalculateIterationCount(expLength, exp, releaseSpec.IsEip7883Enabled); | ||
bool overflow = UInt256.MultiplyOverflow(complexity, iterationCount, out UInt256 result); | ||
result /= 3; | ||
return result > long.MaxValue || overflow ? long.MaxValue : Math.Max(200L, (long)result); | ||
return result > long.MaxValue || overflow ? long.MaxValue : Math.Max(releaseSpec.IsEip7883Enabled ? 500L : 200L, (long)result); | ||
} | ||
catch (OverflowException) | ||
{ | ||
|
@@ -173,12 +173,12 @@ public static (byte[], bool) OldRun(byte[] inputData) | |
/// return words**2 | ||
/// </summary> | ||
/// <returns></returns> | ||
private static UInt256 MultComplexity(in UInt256 baseLength, in UInt256 modulusLength) | ||
private static UInt256 MultComplexity(in UInt256 baseLength, in UInt256 modulusLength, bool isEip7883Enabled) | ||
{ | ||
UInt256 maxLength = UInt256.Max(baseLength, modulusLength); | ||
UInt256.Mod(maxLength, 8, out UInt256 mod8); | ||
UInt256 words = (maxLength / 8) + ((mod8.IsZero) ? UInt256.Zero : UInt256.One); | ||
return words * words; | ||
return maxLength > 32 && isEip7883Enabled ? 2 * words * words : words * words; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we create constants in GasCostOf for these values? (the 2x multiplier) |
||
} | ||
|
||
/// <summary> | ||
|
@@ -191,8 +191,9 @@ private static UInt256 MultComplexity(in UInt256 baseLength, in UInt256 modulusL | |
/// </summary> | ||
/// <param name="exponentLength"></param> | ||
/// <param name="exponent"></param> | ||
/// <param name="isEip7883Enabled"></param> | ||
/// <returns></returns> | ||
private static UInt256 CalculateIterationCount(UInt256 exponentLength, UInt256 exponent) | ||
private static UInt256 CalculateIterationCount(UInt256 exponentLength, UInt256 exponent, bool isEip7883Enabled) | ||
{ | ||
try | ||
{ | ||
|
@@ -209,7 +210,8 @@ private static UInt256 CalculateIterationCount(UInt256 exponentLength, UInt256 e | |
bitLength--; | ||
} | ||
|
||
bool overflow = UInt256.MultiplyOverflow((exponentLength - 32), 8, out UInt256 multiplicationResult); | ||
var multiplier = (UInt256)(isEip7883Enabled ? 16 : 8); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we create constants in GasCostOf for these values? |
||
bool overflow = UInt256.MultiplyOverflow(exponentLength - 32, multiplier, out UInt256 multiplicationResult); | ||
overflow |= UInt256.AddOverflow(multiplicationResult, (UInt256)bitLength, out iterationCount); | ||
if (overflow) | ||
{ | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we create constants in GasCostOf for these values?