diff --git a/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs b/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs
index f7e8519de72..f9a087f223d 100644
--- a/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs
+++ b/src/Nethermind/Nethermind.Core/Specs/IReleaseSpec.cs
@@ -278,6 +278,11 @@ public interface IReleaseSpec : IEip1559Spec, IReceiptSpec
///
bool IsEip6780Enabled { get; }
+ ///
+ /// Raise gas costs of hash functions
+ ///
+ bool IsEip7667Enabled { get; }
+
///
/// Should transactions be validated against chainId.
///
diff --git a/src/Nethermind/Nethermind.Evm.Test/Eip7667Tests.cs b/src/Nethermind/Nethermind.Evm.Test/Eip7667Tests.cs
new file mode 100644
index 00000000000..dfb7b2d061f
--- /dev/null
+++ b/src/Nethermind/Nethermind.Evm.Test/Eip7667Tests.cs
@@ -0,0 +1,223 @@
+using FluentAssertions;
+using Nethermind.Evm.Precompiles;
+using Nethermind.Int256;
+using Nethermind.Specs;
+using NUnit.Framework;
+
+namespace Nethermind.Evm.Test;
+
+public class Eip7667Tests : VirtualMachineTestsBase
+{
+ protected override long BlockNumber => MainnetSpecProvider.ParisBlockNumber;
+ protected override ulong Timestamp => MainnetSpecProvider.PragueBlockTimestamp;
+
+ [Test]
+ public void Sha3_cost_before_eip_7667()
+ {
+ var spec = SpecProvider.GetSpec((BlockNumber, Timestamp - 1));
+ Assert.That(spec.GetSha3Cost(), Is.EqualTo(30));
+ }
+
+ [Test]
+ public void Sha3_cost_after_eip_7667()
+ {
+ Assert.That(Spec.GetSha3Cost(), Is.EqualTo(300));
+ }
+
+ [Test]
+ public void Sha3_word_cost_before_eip_7667()
+ {
+ var spec = SpecProvider.GetSpec((BlockNumber, Timestamp - 1));
+ Assert.That(spec.GetSha3WordCost(), Is.EqualTo(6));
+ }
+
+ [Test]
+ public void Sha3_word_cost_after_eip_7667()
+ {
+ Assert.That(Spec.GetSha3WordCost(), Is.EqualTo(60));
+ }
+
+ [Test]
+ public void Log_data_cost_before_eip_7667()
+ {
+ var spec = SpecProvider.GetSpec((BlockNumber, Timestamp - 1));
+ Assert.That(spec.GetLogDataCost(), Is.EqualTo(8));
+ }
+
+ [Test]
+ public void Log_data_cost_after_eip_7667()
+ {
+ Assert.That(Spec.GetLogDataCost(), Is.EqualTo(10));
+ }
+
+ [Test]
+ public void Keccak256_op_before_eip_7667()
+ {
+ byte[] code = Prepare.EvmCode
+ .PushData(32)
+ .PushData(0)
+ .Op(Instruction.KECCAK256)
+ .STOP()
+ .Done;
+
+ TestAllTracerWithOutput result = Execute((BlockNumber, Timestamp - 1), code);
+
+ long gasSpent = GasCostOf.Transaction + GasCostOf.VeryLow * 2 // for push
+ + GasCostOf.VeryLow // memory gas cost
+ + GasCostOf.Sha3 + GasCostOf.Sha3Word; // Keccak256
+
+ result.StatusCode.Should().Be(1);
+ Assert.That(result.GasSpent, Is.EqualTo(gasSpent));
+ }
+
+ [Test]
+ public void Keccak256_op_after_eip_7667()
+ {
+ byte[] code = Prepare.EvmCode
+ .PushData(32)
+ .PushData(0)
+ .Op(Instruction.KECCAK256)
+ .STOP()
+ .Done;
+
+ TestAllTracerWithOutput result = Execute(code);
+
+ long gasSpent = GasCostOf.Transaction + GasCostOf.VeryLow * 2 // for push
+ + GasCostOf.VeryLow // memory gas cost
+ + GasCostOf.Sha3Eip7667 + GasCostOf.Sha3WordEip7667; // Keccak256
+
+ result.StatusCode.Should().Be(1);
+ Assert.That(result.GasSpent, Is.EqualTo(gasSpent));
+ }
+
+ [Test]
+ public void Create_op_before_eip_7667()
+ {
+ byte[] salt = [4, 5, 6];
+ byte[] deployedCode = [1, 2, 3];
+ byte[] initCode = Prepare.EvmCode.ForInitOf(deployedCode).Done;
+ byte[] createCode = Prepare.EvmCode.Create2(initCode, salt, 0).STOP().Done;
+
+ TestAllTracerWithOutput result = Execute((BlockNumber, Timestamp - 1), createCode);
+
+ long gasSpent = GasCostOf.Sha3Word * EvmPooledMemory.Div32Ceiling((UInt256)initCode.Length) + 53658;
+
+ Assert.That(result.GasSpent, Is.EqualTo(gasSpent));
+ }
+
+ [Test]
+ public void Create_op_after_eip_7667()
+ {
+ byte[] salt = [4, 5, 6];
+ byte[] deployedCode = [1, 2, 3];
+ byte[] initCode = Prepare.EvmCode.ForInitOf(deployedCode).Done;
+ byte[] createCode = Prepare.EvmCode.Create2(initCode, salt, 0).STOP().Done;
+
+ TestAllTracerWithOutput result = Execute(createCode);
+
+ long gasSpent = GasCostOf.Sha3WordEip7667 * EvmPooledMemory.Div32Ceiling((UInt256)initCode.Length) + 53658;
+
+ Assert.That(result.GasSpent, Is.EqualTo(gasSpent));
+ }
+
+ [Test]
+ public void Log_op_before_eip7667()
+ {
+ const int length = 32;
+ byte[] createCode = Prepare.EvmCode
+ .PushData(length)
+ .PushData(0)
+ .Op(Instruction.LOG0)
+ .STOP()
+ .Done;
+
+ TestAllTracerWithOutput result = Execute((BlockNumber, Timestamp - 1), createCode);
+
+ long gasSpent = GasCostOf.LogData * length + 21384;
+
+ Assert.That(result.GasSpent, Is.EqualTo(gasSpent));
+ }
+
+ [Test]
+ public void Log_op_after_eip7667()
+ {
+ const int length = 32;
+ byte[] createCode = Prepare.EvmCode
+ .PushData(length)
+ .PushData(0)
+ .Op(Instruction.LOG0)
+ .STOP()
+ .Done;
+
+ TestAllTracerWithOutput result = Execute(createCode);
+
+ long gasSpent = GasCostOf.LogDataEip7667 * length + 21384;
+
+ Assert.That(result.GasSpent, Is.EqualTo(gasSpent));
+ }
+
+ [Test]
+ public void Sha256_precompile_base_cost_before_eip_7667()
+ {
+ var sha256Precompile = Sha256Precompile.Instance;
+ var spec = SpecProvider.GetSpec((BlockNumber, Timestamp - 1));
+
+ Assert.That(sha256Precompile.BaseGasCost(spec), Is.EqualTo(GasCostOf.Sha256PrecompileBaseCost));
+ Assert.That(GasCostOf.Sha256PrecompileBaseCost, Is.EqualTo(60));
+ }
+
+ [Test]
+ public void Sha256_precompile_base_cost_after_eip_7667()
+ {
+ var sha256Precompile = Sha256Precompile.Instance;
+
+ Assert.That(sha256Precompile.BaseGasCost(Spec), Is.EqualTo(GasCostOf.Sha256PrecompileBaseCostEip7667));
+ Assert.That(GasCostOf.Sha256PrecompileBaseCostEip7667, Is.EqualTo(300));
+ }
+
+ [Test]
+ public void Sha256_precompile_data_cost_before_eip_7667()
+ {
+ var sha256Precompile = Sha256Precompile.Instance;
+ var bytes = new byte[1];
+ var spec = SpecProvider.GetSpec((BlockNumber, Timestamp - 1));
+ var dataCost = GasCostOf.Sha256PrecompileWordCost * EvmPooledMemory.Div32Ceiling((ulong)bytes.Length);
+
+ Assert.That(sha256Precompile.DataGasCost(bytes, spec), Is.EqualTo(dataCost));
+ Assert.That(GasCostOf.Sha256PrecompileWordCost, Is.EqualTo(12));
+ }
+
+ [Test]
+ public void Sha256_precompile_data_cost_after_eip_7667()
+ {
+ var sha256Precompile = Sha256Precompile.Instance;
+ var bytes = new byte[1];
+ var dataCost = GasCostOf.Sha256PrecompileWordCostEip7667 * EvmPooledMemory.Div32Ceiling((ulong)bytes.Length);
+
+ Assert.That(sha256Precompile.DataGasCost(bytes, Spec), Is.EqualTo(dataCost));
+ Assert.That(GasCostOf.Sha256PrecompileWordCostEip7667, Is.EqualTo(60));
+ }
+
+ [Test]
+ public void Blake2F_precompile_data_cost_before_eip_7667()
+ {
+ var blake2FPrecompile = Blake2FPrecompile.Instance;
+ var spec = SpecProvider.GetSpec((BlockNumber, Timestamp - 1));
+ var bytes = new byte[213];
+ bytes[3] = 1;
+
+ Assert.That(blake2FPrecompile.DataGasCost(bytes, spec), Is.EqualTo(GasCostOf.Blake2GFRound));
+ Assert.That(GasCostOf.Blake2GFRound, Is.EqualTo(1));
+ }
+
+ [Test]
+ public void Blake2F_precompile_data_cost_after_eip_7667()
+ {
+ var blake2FPrecompile = Blake2FPrecompile.Instance;
+ var bytes = new byte[213];
+ bytes[3] = 1;
+
+ Assert.That(blake2FPrecompile.DataGasCost(bytes, Spec), Is.EqualTo(GasCostOf.Blake2GFRoundEip7667));
+ Assert.That(GasCostOf.Blake2GFRoundEip7667, Is.EqualTo(10));
+ }
+}
diff --git a/src/Nethermind/Nethermind.Evm/GasCostOf.cs b/src/Nethermind/Nethermind.Evm/GasCostOf.cs
index 68dc8cae654..a648cae4135 100644
--- a/src/Nethermind/Nethermind.Evm/GasCostOf.cs
+++ b/src/Nethermind/Nethermind.Evm/GasCostOf.cs
@@ -43,8 +43,11 @@ public static class GasCostOf
public const long Log = 375;
public const long LogTopic = 375;
public const long LogData = 8;
+ public const long LogDataEip7667 = 10;
public const long Sha3 = 30;
+ public const long Sha3Eip7667 = 300;
public const long Sha3Word = 6;
+ public const long Sha3WordEip7667 = 60;
public const long BlockHash = 20;
public const long SelfDestruct = 0;
public const long SelfDestructEip150 = 5000;
@@ -62,5 +65,14 @@ public static class GasCostOf
public const long AccessStorageListEntry = 1900; // eip-2930
public const long TLoad = WarmStateRead; // eip-1153
public const long TStore = WarmStateRead; // eip-1153
+
+ public const long Blake2GFRoundEip7667 = 10;
+ public const long Blake2GFRound = 1;
+
+ public const long Sha256PrecompileBaseCostEip7667 = 300L;
+ public const long Sha256PrecompileBaseCost = 60L;
+
+ public const long Sha256PrecompileWordCostEip7667 = 60L;
+ public const long Sha256PrecompileWordCost = 12L;
}
}
diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Blake2FPrecompile.cs b/src/Nethermind/Nethermind.Evm/Precompiles/Blake2FPrecompile.cs
index 14534399d3f..0329dc26b96 100644
--- a/src/Nethermind/Nethermind.Evm/Precompiles/Blake2FPrecompile.cs
+++ b/src/Nethermind/Nethermind.Evm/Precompiles/Blake2FPrecompile.cs
@@ -36,7 +36,7 @@ public long DataGasCost(in ReadOnlyMemory inputData, IReleaseSpec releaseS
uint rounds = inputData[..4].Span.ReadEthUInt32();
- return rounds;
+ return rounds * releaseSpec.GetBlake2GFRoundDataCost();
}
public (ReadOnlyMemory, bool) Run(in ReadOnlyMemory inputData, IReleaseSpec releaseSpec)
diff --git a/src/Nethermind/Nethermind.Evm/Precompiles/Sha256Precompile.cs b/src/Nethermind/Nethermind.Evm/Precompiles/Sha256Precompile.cs
index 4aa42639104..ffc8662924e 100644
--- a/src/Nethermind/Nethermind.Evm/Precompiles/Sha256Precompile.cs
+++ b/src/Nethermind/Nethermind.Evm/Precompiles/Sha256Precompile.cs
@@ -34,12 +34,12 @@ private static void InitIfNeeded()
public long BaseGasCost(IReleaseSpec releaseSpec)
{
- return 60L;
+ return releaseSpec.GetSha256PrecompileBaseCost();
}
public long DataGasCost(in ReadOnlyMemory inputData, IReleaseSpec releaseSpec)
{
- return 12L * EvmPooledMemory.Div32Ceiling((ulong)inputData.Length);
+ return releaseSpec.GetSha256PrecompileWordCost() * EvmPooledMemory.Div32Ceiling((ulong)inputData.Length);
}
public (ReadOnlyMemory, bool) Run(in ReadOnlyMemory inputData, IReleaseSpec releaseSpec)
diff --git a/src/Nethermind/Nethermind.Evm/ReleaseSpecExtensions.cs b/src/Nethermind/Nethermind.Evm/ReleaseSpecExtensions.cs
index ec553bcca02..bed5ef83978 100644
--- a/src/Nethermind/Nethermind.Evm/ReleaseSpecExtensions.cs
+++ b/src/Nethermind/Nethermind.Evm/ReleaseSpecExtensions.cs
@@ -83,5 +83,35 @@ public static class ReleaseSpecExtensions
spec.UseExpDDosProtection
? GasCostOf.ExpByteEip160
: GasCostOf.ExpByte;
+
+ public static long GetSha3Cost(this IReleaseSpec spec) =>
+ spec.IsEip7667Enabled
+ ? GasCostOf.Sha3Eip7667
+ : GasCostOf.Sha3;
+
+ public static long GetSha3WordCost(this IReleaseSpec spec) =>
+ spec.IsEip7667Enabled
+ ? GasCostOf.Sha3WordEip7667
+ : GasCostOf.Sha3Word;
+
+ public static long GetLogDataCost(this IReleaseSpec spec) =>
+ spec.IsEip7667Enabled
+ ? GasCostOf.LogDataEip7667
+ : GasCostOf.LogData;
+
+ public static long GetSha256PrecompileBaseCost(this IReleaseSpec spec) =>
+ spec.IsEip7667Enabled
+ ? GasCostOf.Sha256PrecompileBaseCostEip7667
+ : GasCostOf.Sha256PrecompileBaseCost;
+
+ public static long GetSha256PrecompileWordCost(this IReleaseSpec spec) =>
+ spec.IsEip7667Enabled
+ ? GasCostOf.Sha256PrecompileWordCostEip7667
+ : GasCostOf.Sha256PrecompileWordCost;
+
+ public static long GetBlake2GFRoundDataCost(this IReleaseSpec spec) =>
+ spec.IsEip7667Enabled
+ ? GasCostOf.Blake2GFRoundEip7667
+ : GasCostOf.Blake2GFRound;
}
}
diff --git a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs
index 64a9c11ea86..19ea3e5a244 100644
--- a/src/Nethermind/Nethermind.Evm/VirtualMachine.cs
+++ b/src/Nethermind/Nethermind.Evm/VirtualMachine.cs
@@ -1225,7 +1225,7 @@ private CallResult ExecuteCall(EvmState vmState, ReadOnlyM
{
if (!stack.PopUInt256(out a)) goto StackUnderflow;
if (!stack.PopUInt256(out b)) goto StackUnderflow;
- gasAvailable -= GasCostOf.Sha3 + GasCostOf.Sha3Word * EvmPooledMemory.Div32Ceiling(in b);
+ gasAvailable -= spec.GetSha3Cost() + spec.GetSha3WordCost() * EvmPooledMemory.Div32Ceiling(in b);
if (!UpdateMemoryCost(vmState, ref gasAvailable, in a, b)) goto OutOfGas;
@@ -1824,7 +1824,7 @@ private CallResult ExecuteCall(EvmState vmState, ReadOnlyM
{
if (vmState.IsStatic) goto StaticCallViolation;
- exceptionType = InstructionLog(vmState, ref stack, ref gasAvailable, instruction);
+ exceptionType = InstructionLog(vmState, ref stack, ref gasAvailable, instruction, spec);
if (exceptionType != EvmExceptionType.None) goto ReturnFailure;
break;
}
@@ -2449,7 +2449,7 @@ private EvmExceptionType InstructionSelfDestruct(EvmState vmState, ref
long gasCost = GasCostOf.Create +
(spec.IsEip3860Enabled ? GasCostOf.InitCodeWord * EvmPooledMemory.Div32Ceiling(initCodeLength) : 0) +
(instruction == Instruction.CREATE2
- ? GasCostOf.Sha3Word * EvmPooledMemory.Div32Ceiling(initCodeLength)
+ ? spec.GetSha3WordCost() * EvmPooledMemory.Div32Ceiling(initCodeLength)
: 0);
if (!UpdateGas(gasCost, ref gasAvailable)) return (EvmExceptionType.OutOfGas, null);
@@ -2560,7 +2560,7 @@ private EvmExceptionType InstructionSelfDestruct(EvmState vmState, ref
}
[SkipLocalsInit]
- private static EvmExceptionType InstructionLog(EvmState vmState, ref EvmStack stack, ref long gasAvailable, Instruction instruction)
+ private static EvmExceptionType InstructionLog(EvmState vmState, ref EvmStack stack, ref long gasAvailable, Instruction instruction, IReleaseSpec spec)
where TTracing : struct, IIsTracing
{
if (!stack.PopUInt256(out UInt256 position)) return EvmExceptionType.StackUnderflow;
@@ -2569,7 +2569,7 @@ private static EvmExceptionType InstructionLog(EvmState vmState, ref E
if (!UpdateMemoryCost(vmState, ref gasAvailable, in position, length)) return EvmExceptionType.OutOfGas;
if (!UpdateGas(
GasCostOf.Log + topicsCount * GasCostOf.LogTopic +
- (long)length * GasCostOf.LogData, ref gasAvailable)) return EvmExceptionType.OutOfGas;
+ (long)length * spec.GetLogDataCost(), ref gasAvailable)) return EvmExceptionType.OutOfGas;
ReadOnlyMemory data = vmState.Memory.Load(in position, length);
Hash256[] topics = new Hash256[topicsCount];
diff --git a/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs b/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs
index b36a57071d0..26c1587c4f8 100644
--- a/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs
+++ b/src/Nethermind/Nethermind.Specs.Test/OverridableReleaseSpec.cs
@@ -115,6 +115,8 @@ public OverridableReleaseSpec(IReleaseSpec spec)
public bool IsEip4844Enabled => _spec.IsEip4844Enabled;
public bool IsEip3607Enabled { get; set; }
+ public bool IsEip7667Enabled { get; set; }
+
public bool IsEip158IgnoredAccount(Address address)
{
return _spec.IsEip158IgnoredAccount(address);
diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs
index 817250bc01e..9d6c5831e58 100644
--- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs
+++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainParameters.cs
@@ -117,6 +117,7 @@ public class ChainParameters
public ulong? Eip6780TransitionTimestamp { get; set; }
public ulong? Eip4788TransitionTimestamp { get; set; }
public Address Eip4788ContractAddress { get; set; }
+ public ulong? Eip7667TransitionTimestamp { get; set; }
#region EIP-4844 parameters
///
diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs
index 7aad4bac04f..c9ccd86888e 100644
--- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs
+++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs
@@ -251,6 +251,7 @@ private static ReleaseSpec CreateReleaseSpec(ChainSpec chainSpec, long releaseSt
releaseSpec.IsEip6780Enabled = (chainSpec.Parameters.Eip6780TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp;
releaseSpec.IsEip4788Enabled = (chainSpec.Parameters.Eip4788TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp;
releaseSpec.Eip4788ContractAddress = chainSpec.Parameters.Eip4788ContractAddress;
+ releaseSpec.IsEip7667Enabled = (chainSpec.Parameters.Eip7667TransitionTimestamp ?? ulong.MaxValue) <= releaseStartTimestamp;
return releaseSpec;
}
diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs
index db4155117c8..d07bc2c5fa0 100644
--- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs
+++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/ChainSpecLoader.cs
@@ -142,6 +142,7 @@ private void LoadParameters(ChainSpecJson chainSpecJson, ChainSpec chainSpec)
Eip5656TransitionTimestamp = chainSpecJson.Params.Eip5656TransitionTimestamp,
Eip6780TransitionTimestamp = chainSpecJson.Params.Eip6780TransitionTimestamp,
Eip4788TransitionTimestamp = chainSpecJson.Params.Eip4788TransitionTimestamp,
+ Eip7667TransitionTimestamp = chainSpecJson.Params.Eip7667TransitionTimestamp,
Eip4788ContractAddress = chainSpecJson.Params.Eip4788ContractAddress ?? Eip4788Constants.BeaconRootsAddress,
TransactionPermissionContract = chainSpecJson.Params.TransactionPermissionContract,
TransactionPermissionContractTransition = chainSpecJson.Params.TransactionPermissionContractTransition,
diff --git a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs
index 5f22e8e6a85..662752846ac 100644
--- a/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs
+++ b/src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/ChainSpecParamsJson.cs
@@ -140,6 +140,7 @@ internal class ChainSpecParamsJson
public ulong? Eip5656TransitionTimestamp { get; set; }
public ulong? Eip6780TransitionTimestamp { get; set; }
public ulong? Eip4788TransitionTimestamp { get; set; }
+ public ulong? Eip7667TransitionTimestamp { get; set; }
public Address Eip4788ContractAddress { get; set; }
public UInt256? Eip4844BlobGasPriceUpdateFraction { get; set; }
public ulong? Eip4844MaxBlobGasPerBlock { get; set; }
diff --git a/src/Nethermind/Nethermind.Specs/Forks/18_Prague.cs b/src/Nethermind/Nethermind.Specs/Forks/18_Prague.cs
new file mode 100644
index 00000000000..14ae3d673d8
--- /dev/null
+++ b/src/Nethermind/Nethermind.Specs/Forks/18_Prague.cs
@@ -0,0 +1,18 @@
+using System.Threading;
+using Nethermind.Core.Specs;
+using Nethermind.Specs.Forks;
+
+namespace Nethermind.Evm.Test;
+
+public class Prague : Cancun
+{
+ private static IReleaseSpec _instance;
+
+ protected Prague()
+ {
+ Name = "Eip7667Spec";
+ IsEip7667Enabled = true;
+ }
+
+ public new static IReleaseSpec Instance => LazyInitializer.EnsureInitialized(ref _instance, () => new Prague());
+}
diff --git a/src/Nethermind/Nethermind.Specs/MainnetSpecProvider.cs b/src/Nethermind/Nethermind.Specs/MainnetSpecProvider.cs
index 4108dffe7b8..e0efb2f84ff 100644
--- a/src/Nethermind/Nethermind.Specs/MainnetSpecProvider.cs
+++ b/src/Nethermind/Nethermind.Specs/MainnetSpecProvider.cs
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LGPL-3.0-only
using Nethermind.Core.Specs;
+using Nethermind.Evm.Test;
using Nethermind.Int256;
using Nethermind.Specs.Forks;
@@ -47,7 +48,8 @@ public class MainnetSpecProvider : ISpecProvider
{ BlockNumber: < ParisBlockNumber } => GrayGlacier.Instance,
{ Timestamp: null } or { Timestamp: < ShanghaiBlockTimestamp } => Paris.Instance,
{ Timestamp: < CancunBlockTimestamp } => Shanghai.Instance,
- _ => Cancun.Instance
+ { Timestamp: < PragueBlockTimestamp } => Cancun.Instance,
+ _ => Prague.Instance
};
public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalDifficulty = null)
@@ -86,7 +88,7 @@ public void UpdateMergeTransitionInfo(long? blockNumber, UInt256? terminalTotalD
(ForkActivation)GrayGlacierBlockNumber,
ShanghaiActivation,
CancunActivation,
- //PragueActivation,
+ // PragueActivation,
//OsakaActivation
};
diff --git a/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs b/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs
index 5de83c8356b..cbea42bbafe 100644
--- a/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs
+++ b/src/Nethermind/Nethermind.Specs/ReleaseSpec.cs
@@ -84,6 +84,7 @@ public ReleaseSpec Clone()
public bool IsEip5656Enabled { get; set; }
public bool IsEip6780Enabled { get; set; }
public bool IsEip4788Enabled { get; set; }
+ public bool IsEip7667Enabled { get; set; }
private Address _eip4788ContractAddress;
public Address Eip4788ContractAddress
diff --git a/src/Nethermind/Nethermind.Specs/SystemTransactionReleaseSpec.cs b/src/Nethermind/Nethermind.Specs/SystemTransactionReleaseSpec.cs
index 8774d7a03ae..2c44a2f7f8c 100644
--- a/src/Nethermind/Nethermind.Specs/SystemTransactionReleaseSpec.cs
+++ b/src/Nethermind/Nethermind.Specs/SystemTransactionReleaseSpec.cs
@@ -110,6 +110,8 @@ public SystemTransactionReleaseSpec(IReleaseSpec spec)
public bool IsEip3541Enabled => _spec.IsEip3541Enabled;
public bool IsEip3607Enabled => _spec.IsEip3607Enabled;
+ public bool IsEip7667Enabled => _spec.IsEip7667Enabled;
+
public bool IsEip158IgnoredAccount(Address address)
{
return _spec.IsEip158IgnoredAccount(address);