Skip to content
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

Throw on non-empty storage #7194

Merged
merged 9 commits into from
Jun 25, 2024
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
24 changes: 0 additions & 24 deletions src/Nethermind/Ethereum.Blockchain.Block.Test/Pyspecs/EipTests.cs

This file was deleted.

24 changes: 0 additions & 24 deletions src/Nethermind/Ethereum.Blockchain.Block.Test/Pyspecs/VMTests.cs

This file was deleted.

This file was deleted.

42 changes: 21 additions & 21 deletions src/Nethermind/Ethereum.Blockchain.Test/Eip2537Tests.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

// using System.Collections.Generic;
// using Ethereum.Test.Base;
// using NUnit.Framework;
using System.Collections.Generic;
using Ethereum.Test.Base;
using NUnit.Framework;

// namespace Ethereum.Blockchain.Test
// {
// [TestFixture]
// [Parallelizable(ParallelScope.All)]
// public class Eip2537Tests : GeneralStateTestBase
// {
// [TestCaseSource(nameof(LoadTests))]
// public void Test(GeneralStateTest test)
// {
// Assert.True(RunTest(test).Pass);
// }
namespace Ethereum.Blockchain.Test
{
[TestFixture]
[Parallelizable(ParallelScope.All)]
public class Eip2537Tests : GeneralStateTestBase
{
[TestCaseSource(nameof(LoadTests))]
public void Test(GeneralStateTest test)
{
Assert.True(RunTest(test).Pass);
}

// public static IEnumerable<GeneralStateTest> LoadTests()
// {
// var loader = new TestsSourceLoader(new LoadGeneralStateTestsStrategy(), "../EIPTests/StateTests/stEIP2537");
// return (IEnumerable<GeneralStateTest>)loader.LoadTests();
// }
// }
// }
public static IEnumerable<GeneralStateTest> LoadTests()
{
var loader = new TestsSourceLoader(new LoadGeneralStateTestsStrategy(), "../EIPTests/StateTests/stEIP2537");
return (IEnumerable<GeneralStateTest>)loader.LoadTests();
}
}
}
22 changes: 14 additions & 8 deletions src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,26 @@
using Nethermind.State;
using Nethermind.Trie.Pruning;
using NUnit.Framework;
using System.Threading.Tasks;

namespace Ethereum.Test.Base
{
public abstract class GeneralStateTestBase
{
private static ILogger _logger = new(new ConsoleAsyncLogger(LogLevel.Info));
private static ILogManager _logManager = LimboLogs.Instance;
private static UInt256 _defaultBaseFeeForStateTest = 0xA;
private static readonly UInt256 _defaultBaseFeeForStateTest = 0xA;
private readonly TxValidator _txValidator = new(MainnetSpecProvider.Instance.ChainId);

[SetUp]
public void Setup()
{
}

protected void Setup(ILogManager logManager)
[OneTimeSetUp]
public Task OneTimeSetUp() => KzgPolynomialCommitments.InitializeAsync();

protected static void Setup(ILogManager logManager)
{
_logManager = logManager ?? LimboLogs.Instance;
_logger = _logManager.GetClassLogger();
Expand Down Expand Up @@ -95,7 +99,7 @@ protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer)
test.CurrentNumber,
test.CurrentGasLimit,
test.CurrentTimestamp,
Array.Empty<byte>());
[]);
header.BaseFeePerGas = test.Fork.IsEip1559Enabled ? test.CurrentBaseFee ?? _defaultBaseFeeForStateTest : UInt256.Zero;
header.StateRoot = test.PostHash;
header.Hash = header.CalculateHash();
Expand All @@ -109,8 +113,6 @@ protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer)
Stopwatch stopwatch = Stopwatch.StartNew();
IReleaseSpec? spec = specProvider.GetSpec((ForkActivation)test.CurrentNumber);

if (spec is Cancun) KzgPolynomialCommitments.InitializeAsync();

if (test.Transaction.ChainId is null)
test.Transaction.ChainId = MainnetSpecProvider.Instance.ChainId;
if (test.ParentBlobGasUsed is not null && test.ParentExcessBlobGas is not null)
Expand All @@ -123,7 +125,7 @@ protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer)
number: test.CurrentNumber - 1,
gasLimit: test.CurrentGasLimit,
timestamp: test.CurrentTimestamp,
extraData: Array.Empty<byte>()
extraData: []
)
{
BlobGasUsed = (ulong)test.ParentBlobGasUsed,
Expand All @@ -137,17 +139,21 @@ protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer)
bool isValid = _txValidator.IsWellFormed(test.Transaction, spec) && IsValidBlock(block, specProvider);

if (isValid)
{
transactionProcessor.Execute(test.Transaction, new BlockExecutionContext(header), txTracer);
}

stopwatch.Stop();

stateProvider.Commit(specProvider.GenesisSpec);
stateProvider.Commit(specProvider.GetSpec((ForkActivation)1));
stateProvider.CommitTree(1);

// '@winsvega added a 0-wei reward to the miner , so we had to add that into the state test execution phase. He needed it for retesteth.'
if (!stateProvider.AccountExists(test.CurrentCoinbase))
{
stateProvider.CreateAccount(test.CurrentCoinbase, 0);
}

stateProvider.Commit(specProvider.GetSpec((ForkActivation)1));

stateProvider.RecalculateStateRoot();
Expand Down Expand Up @@ -199,7 +205,7 @@ private bool IsValidBlock(Block block, ISpecProvider specProvider)

private List<string> RunAssertions(GeneralStateTest test, IWorldState stateProvider)
{
List<string> differences = new();
List<string> differences = [];
if (test.PostHash != stateProvider.StateRoot)
{
differences.Add($"STATE ROOT exp: {test.PostHash}, actual: {stateProvider.StateRoot}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ private string GetBlockchainTestsDirectory()
char pathSeparator = Path.AltDirectorySeparatorChar;
string currentDirectory = AppDomain.CurrentDomain.BaseDirectory;

return currentDirectory.Remove(currentDirectory.LastIndexOf("src")) + $"src{pathSeparator}tests{pathSeparator}BlockchainTests";
return Path.Combine(currentDirectory.Remove(currentDirectory.LastIndexOf("src")), "src", "tests", "BlockchainTests");
}

private IEnumerable<BlockchainTest> LoadTestsFromDirectory(string testDir, string wildcard)
Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Ethereum.Test.Base/LoadEipTestsStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ private string GetGeneralStateTestsDirectory()
char pathSeparator = Path.AltDirectorySeparatorChar;
string currentDirectory = AppDomain.CurrentDomain.BaseDirectory;

return currentDirectory.Remove(currentDirectory.LastIndexOf("src")) + $"src{pathSeparator}tests{pathSeparator}EIPTests{pathSeparator}StateTests";
return Path.Combine(currentDirectory.Remove(currentDirectory.LastIndexOf("src")), "src", "tests", "EIPTests", "StateTests");
}

private IEnumerable<GeneralStateTest> LoadTestsFromDirectory(string testDir, string wildcard)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ private string GetGeneralStateTestsDirectory()
char pathSeparator = Path.AltDirectorySeparatorChar;
string currentDirectory = AppDomain.CurrentDomain.BaseDirectory;

return currentDirectory.Remove(currentDirectory.LastIndexOf("src")) + $"src{pathSeparator}tests{pathSeparator}GeneralStateTests";
return Path.Combine(currentDirectory.Remove(currentDirectory.LastIndexOf("src")), "src", "tests", "GeneralStateTests");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,9 @@ public IEnumerable<IEthereumTest> Load(string testsDirectoryName, string wildcar

private string GetGeneralStateTestsDirectory()
{
char pathSeparator = Path.AltDirectorySeparatorChar;
string currentDirectory = AppDomain.CurrentDomain.BaseDirectory;

return currentDirectory.Remove(currentDirectory.LastIndexOf("src")) + $"src{pathSeparator}tests{pathSeparator}GeneralStateTests";
return Path.Combine(currentDirectory.Remove(currentDirectory.LastIndexOf("src")), "src", "tests", "GeneralStateTests");
}

private IEnumerable<GeneralStateTest> LoadTestsFromDirectory(string testDir, string wildcard)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ private string GetLegacyBlockchainTestsDirectory()
char pathSeparator = Path.AltDirectorySeparatorChar;
string currentDirectory = AppDomain.CurrentDomain.BaseDirectory;

return currentDirectory.Remove(currentDirectory.LastIndexOf("src")) + $"src{pathSeparator}tests{pathSeparator}LegacyTests{pathSeparator}Constantinople{pathSeparator}BlockchainTests";
return Path.Combine(currentDirectory.Remove(currentDirectory.LastIndexOf("src")), "src", "tests", "LegacyTests", "Constantinople", "BlockchainTests");
}

private IEnumerable<BlockchainTest> LoadTestsFromDirectory(string testDir, string wildcard)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,9 @@ public IEnumerable<IEthereumTest> Load(string testsDirectoryName, string wildcar

private string GetLegacyGeneralStateTestsDirectory()
{
char pathSeparator = Path.AltDirectorySeparatorChar;
string currentDirectory = AppDomain.CurrentDomain.BaseDirectory;

return currentDirectory.Remove(currentDirectory.LastIndexOf("src")) + $"src{pathSeparator}tests{pathSeparator}LegacyTests{pathSeparator}Constantinople{pathSeparator}GeneralStateTests";
return Path.Combine(currentDirectory.Remove(currentDirectory.LastIndexOf("src")), "src", "tests", "LegacyTests", "Constantinople", "GeneralStateTests");
}

private IEnumerable<GeneralStateTest> LoadTestsFromDirectory(string testDir, string wildcard)
Expand Down
10 changes: 10 additions & 0 deletions src/Nethermind/Nethermind.Evm/AddressExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
using System;
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Core.Specs;
using Nethermind.Int256;
using Nethermind.Serialization.Rlp;
using Nethermind.State;

namespace Nethermind.Evm
{
Expand Down Expand Up @@ -36,5 +38,13 @@ public static Address From(Address deployingAddress, ReadOnlySpan<byte> salt, Re
ValueHash256 contractAddressKeccak = ValueKeccak.Compute(bytes);
return new Address(in contractAddressKeccak);
}

// See https://eips.ethereum.org/EIPS/eip-7610
public static bool IsNonZeroAccount(this Address contractAddress, IReleaseSpec spec, ICodeInfoRepository codeInfoRepository, IWorldState state)
{
return codeInfoRepository.GetCachedCodeInfo(state, contractAddress, spec).MachineCode.Length != 0 ||
state.GetNonce(contractAddress) != 0 ||
state.GetStorageRoot(contractAddress) != Keccak.EmptyTreeHash;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,10 @@ protected virtual TransactionResult Execute(Transaction tx, in BlockExecutionCon

private static void UpdateMetrics(ExecutionOptions opts, UInt256 effectiveGasPrice)
{
if (opts is ExecutionOptions.Commit or ExecutionOptions.None)
if (opts is ExecutionOptions.Commit or ExecutionOptions.None && (effectiveGasPrice[2] | effectiveGasPrice[3]) == 0)
{
float gasPrice = (float)((double)effectiveGasPrice / 1_000_000_000.0);

Metrics.MinGasPrice = Math.Min(gasPrice, Metrics.MinGasPrice);
Metrics.MaxGasPrice = Math.Max(gasPrice, Metrics.MaxGasPrice);

Expand Down Expand Up @@ -580,26 +581,11 @@ protected virtual void PayFees(Transaction tx, BlockHeader header, IReleaseSpec

protected void PrepareAccountForContractDeployment(Address contractAddress, IReleaseSpec spec)
{
if (WorldState.AccountExists(contractAddress))
if (WorldState.AccountExists(contractAddress) && contractAddress.IsNonZeroAccount(spec, _codeInfoRepository, WorldState))
{
CodeInfo codeInfo = _codeInfoRepository.GetCachedCodeInfo(WorldState, contractAddress, spec);
bool codeIsNotEmpty = codeInfo.MachineCode.Length != 0;
bool accountNonceIsNotZero = WorldState.GetNonce(contractAddress) != 0;

// TODO: verify what should happen if code info is a precompile
// (but this would generally be a hash collision)
if (codeIsNotEmpty || accountNonceIsNotZero)
{
if (Logger.IsTrace)
{
Logger.Trace($"Contract collision at {contractAddress}");
}

ThrowTransactionCollisionException();
}
if (Logger.IsTrace) Logger.Trace($"Contract collision at {contractAddress}");

// we clean any existing storage (in case of a previously called self destruct)
WorldState.UpdateStorageRoot(contractAddress, Keccak.EmptyTreeHash);
ThrowTransactionCollisionException();
}
}

Expand Down
Loading