Skip to content

Commit

Permalink
Throw on non-empty storage (#7194)
Browse files Browse the repository at this point in the history
  • Loading branch information
flcl42 authored Jun 25, 2024
1 parent fe97a9a commit 28ce1fe
Show file tree
Hide file tree
Showing 16 changed files with 70 additions and 154 deletions.
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

0 comments on commit 28ce1fe

Please sign in to comment.