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

t8n test #7744

Draft
wants to merge 29 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
9b032c3
create Evm.Test project
yerke26 Nov 8, 2024
d7404d0
refactoring for testing
yerke26 Nov 10, 2024
540c028
added t8nTests
yerke26 Nov 10, 2024
d1cc5f3
fix tests
yerke26 Nov 10, 2024
0ddc8f9
add testdata
yerke26 Nov 11, 2024
d461649
add testdata folder copyToOutput
yerke26 Nov 11, 2024
ea7a26c
move Evm.Test to Evm solution
yerke26 Nov 11, 2024
10cb77e
remove Evm.Test solution
yerke26 Nov 11, 2024
c59ae28
testdata folder CopyToOutputDirectory
yerke26 Nov 11, 2024
ef9e26a
refactoring
yerke26 Nov 11, 2024
3c823d3
fix tests
yerke26 Nov 11, 2024
573b05f
remove unnecessary files
yerke26 Nov 11, 2024
d8e092d
Merge branch 'master' into feature/t8n-test
yerke26 Nov 11, 2024
e260d9b
fix test
yerke26 Nov 11, 2024
f43d2eb
Use Custom ReceiptJsonConverter
yerke26 Nov 11, 2024
43f5b61
fix cmd options
yerke26 Nov 12, 2024
600c4b2
fix t8n
yerke26 Nov 12, 2024
38715b6
Merge branch 'master' into feature/t8n-test
yerke26 Dec 3, 2024
85a5592
change to dotnet 9.0
yerke26 Dec 3, 2024
1ca749a
Merge branch 'master' into feature/t8n-test
yerke26 Dec 23, 2024
1ed0e03
Merge branch 'master' into feature/t8n-test
yerke26 Jan 15, 2025
4fd1761
add evm version command
yerke26 Jan 20, 2025
cb28a1f
fix transaction reading
yerke26 Jan 20, 2025
2521cc7
fix package downgrades
yerke26 Jan 20, 2025
97fb29e
revert ReceiptForRpc changes
yerke26 Jan 20, 2025
197a587
revert ReceiptForRpc changes
yerke26 Jan 20, 2025
b619820
fix t8n tests
yerke26 Jan 20, 2025
152a3d2
revert TxReceiptConverter
yerke26 Jan 20, 2025
ed8ca28
Merge branch 'master' into feature/t8n-test
yerke26 Jan 22, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,10 @@
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using System.Globalization;
using Nethermind.Core;
using Nethermind.JsonRpc.Data;
using System.Text.Json;
using System.Text.Json.Serialization;
using Nethermind.Core.Crypto;
using Nethermind.Int256;
using Nethermind.Serialization.Json;

namespace Nethermind.JsonRpc.Converters;

Expand All @@ -22,39 +18,6 @@ public class TxReceiptConverter : JsonConverter<TxReceipt>

public override void Write(Utf8JsonWriter writer, TxReceipt value, JsonSerializerOptions options)
{
writer.WriteStartObject();
var receipt = new ReceiptForRpc(value.TxHash!, value, default);
if (receipt.Type != TxType.Legacy)
{
writer.WritePropertyName("type");
JsonSerializer.Serialize(writer, receipt.Type, options);
}
writer.WritePropertyName("root");
ByteArrayConverter.Convert(writer, (receipt.Root ?? Keccak.Zero).Bytes);
writer.WritePropertyName("status");
ForcedNumberConversion.ForcedConversion.Value = NumberConversion.Hex;
JsonSerializer.Serialize(writer, receipt.Status, options);

writer.WritePropertyName("cumulativeGasUsed");
JsonSerializer.Serialize(writer, receipt.CumulativeGasUsed, options);
writer.WritePropertyName("effectiveGasPrice");
JsonSerializer.Serialize(writer, receipt.EffectiveGasPrice, options);
writer.WritePropertyName("logsBloom");
JsonSerializer.Serialize(writer, receipt.LogsBloom, options);
writer.WritePropertyName("logs");
JsonSerializer.Serialize(writer, receipt.Logs.Length == 0 ? null : receipt.Logs, options);
writer.WritePropertyName("transactionHash");
JsonSerializer.Serialize(writer, receipt.TransactionHash, options);
writer.WritePropertyName("contractAddress");
JsonSerializer.Serialize(writer, receipt.ContractAddress, options);
writer.WritePropertyName("gasUsed");
JsonSerializer.Serialize(writer, receipt.GasUsed, options);
writer.WritePropertyName("blockHash");
JsonSerializer.Serialize(writer, receipt.BlockHash ?? Hash256.Zero, options);

writer.WritePropertyName("transactionIndex");
JsonSerializer.Serialize(writer, UInt256.Parse(receipt.TransactionIndex.ToString(), NumberStyles.Integer), options);

writer.WriteEndObject();
JsonSerializer.Serialize(writer, new ReceiptForRpc(value.TxHash!, value, default), options);
}
}
4 changes: 2 additions & 2 deletions src/Nethermind/Nethermind.JsonRpc/Data/ReceiptForRpc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public ReceiptForRpc(Hash256 txHash, TxReceipt receipt, TxGasInfo gasInfo, int l
BlobGasPrice = gasInfo.BlobGasPrice;
From = receipt.Sender;
To = receipt.Recipient;
ContractAddress = receipt.ContractAddress;
ContractAddress = receipt.ContractAddress ?? Address.Zero;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would we serialize Address.Zero for transactions that don't create contracts?

This will also affect all the RPC method, are we sure we want to do it?

If we don't want to change RPC methods, but we want to change it here, you can inherit ReceiptForRpc and add this logic in the derived class.

Logs = (receipt.Logs ?? []).Select((l, idx) => new LogEntryForRpc(receipt, l, idx + logIndexStart)).ToArray();
LogsBloom = receipt.Bloom;
Root = receipt.PostTransactionState;
Expand Down Expand Up @@ -58,7 +58,7 @@ public ReceiptForRpc(Hash256 txHash, TxReceipt receipt, TxGasInfo gasInfo, int l
public Address To { get; set; }

[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public Address? ContractAddress { get; set; }
public Address ContractAddress { get; set; }
public LogEntryForRpc[] Logs { get; set; }
public Bloom? LogsBloom { get; set; }
public Hash256? Root { get; set; }
Expand Down
34 changes: 34 additions & 0 deletions tools/Evm/Evm.Test/Evm.Test.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0"/>
<PackageReference Include="NUnit" Version="4.2.2"/>
<PackageReference Include="NUnit.Analyzers" Version="3.9.0"/>
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0"/>
</ItemGroup>

<ItemGroup>
<Using Include="NUnit.Framework"/>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Evm\Evm.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="testdata\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
260 changes: 260 additions & 0 deletions tools/Evm/Evm.Test/T8nTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using Evm.T8n;
using Evm.T8n.JsonTypes;
using Nethermind.Logging;
using Nethermind.Serialization.Json;
using Newtonsoft.Json.Linq;

namespace Evm.Test;

public class InputParams(string basedir, string alloc, string env, string txs, string stateFork, string? stateReward = null)
{
public readonly string Alloc = Path.Combine(basedir, alloc);
public readonly string Env = Path.Combine(basedir, env);
public readonly string Txs = Path.Combine(basedir, txs);
public readonly string StateFork = stateFork;
public readonly string? StateReward = stateReward;
}

public class OutputParams(string? alloc = null, string? result = null, string? body = null)
{
public readonly string? Alloc = alloc;
public readonly string? Result = result;
public readonly string? Body = body;
}

public class T8nTests
{
private readonly EthereumJsonSerializer _ethereumJsonSerializer = new();

[Test]
public void Test1()
{
Execute(
new InputParams("testdata/1/", "alloc.json", "env.json", "txs.json", "Frontier+1346"),
new OutputParams(alloc: "stdout", result: "stdout"),
expectedExitCode: 3);
}

[Test]
public void Test2()
{
Execute(
new InputParams("testdata/1/", "alloc.json", "env.json", "txs.json", "Byzantium"),
new OutputParams(alloc: "stdout", result: "stdout"),
expectedExitCode: 0,
expectedOutputFile: "testdata/1/exp.json");
}

[Test]
public void Test3()
{
Execute(
new InputParams("testdata/3/", "alloc.json", "env.json", "txs.json", "Berlin"),
new OutputParams(alloc: "stdout", result: "stdout"),
expectedExitCode: 0,
expectedOutputFile: "testdata/3/exp.json");
}

[Test]
public void Test4()
{
Execute(
new InputParams("testdata/4/", "alloc.json", "env.json", "txs.json", "Berlin"),
new OutputParams(alloc: "stdout", result: "stdout"),
expectedExitCode: 4);
}

[Test]
public void Test5()
{
Execute(
new("testdata/5/", "alloc.json", "env.json", "txs.json", "Byzantium", "0x80"),
new OutputParams(alloc: "stdout", result: "stdout"),
expectedExitCode: 0,
expectedOutputFile: "testdata/5/exp.json");
}

[Test]
public void Test6()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you name tests in some sensible way? I see it is based on testdata so Test13_txs_London?

{
Execute(
new InputParams("testdata/13/", "alloc.json", "env.json", "txs.json", "London"),
new OutputParams(body: "stdout"),
expectedExitCode: 0,
expectedOutputFile: "testdata/13/exp.json");
}

[Test]
public void Test7()
{
Execute(
new InputParams("testdata/13/", "alloc.json", "env.json", "signed_txs.rlp", "London"),
new OutputParams(result: "stdout"),
expectedExitCode: 0,
expectedOutputFile: "testdata/13/exp2.json");
}

[Test]
public void Test8()
{
Execute(
new InputParams("testdata/14/", "alloc.json", "env.json", "txs.json", "London"),
new OutputParams(result: "stdout"),
expectedExitCode: 0,
expectedOutputFile: "testdata/14/exp.json");
}

[Test]
public void Test9()
{
Execute(
new InputParams("testdata/14/", "alloc.json", "env.uncles.json", "txs.json", "London"),
new OutputParams(result: "stdout"),
expectedExitCode: 0,
expectedOutputFile: "testdata/14/exp2.json");
}

[Test]
public void Test10()
{
Execute(
new InputParams("testdata/14/", "alloc.json", "env.uncles.json", "txs.json", "Berlin"),
new OutputParams(result: "stdout"),
expectedExitCode: 0,
expectedOutputFile: "testdata/14/exp_berlin.json");
}

[Test]
public void Test11()
{
Execute(
new InputParams("testdata/19/", "alloc.json", "env.json", "txs.json", "London"),
new OutputParams(result: "stdout"),
expectedExitCode: 0,
expectedOutputFile: "testdata/19/exp_london.json");
}

[Test]
public void Test12()
{
Execute(
new InputParams("testdata/19/", "alloc.json", "env.json", "txs.json", "ArrowGlacier"),
new OutputParams(result: "stdout"),
expectedExitCode: 0,
expectedOutputFile: "testdata/19/exp_arrowglacier.json");
}

[Test]
public void Test13()
{
Execute(
new InputParams("testdata/19/", "alloc.json", "env.json", "txs.json", "GrayGlacier"),
new OutputParams(result: "stdout"),
expectedExitCode: 0,
expectedOutputFile: "testdata/19/exp_grayglacier.json");
}

[Test]
public void Test14()
{
Execute(
new InputParams("testdata/23/", "alloc.json", "env.json", "txs.json", "Berlin"),
new OutputParams(result: "stdout"),
expectedExitCode: 0,
expectedOutputFile: "testdata/23/exp.json");
}

[Test]
public void Test15()
{
Execute(
new InputParams("testdata/24/", "alloc.json", "env.json", "txs.json", "Merge"),
new OutputParams(result: "stdout", alloc: "stdout"),
expectedExitCode: 0,
expectedOutputFile: "testdata/24/exp.json");
}

[Test]
public void Test16()
{
Execute(
new InputParams("testdata/24/", "alloc.json", "env-missingrandom.json", "txs.json", "Merge"),
new OutputParams(result: "stdout", alloc: "stdout"),
expectedExitCode: 3);
}

[Test]
public void Test17()
{
Execute(
new InputParams("testdata/26/", "alloc.json", "env.json", "txs.json", "Shanghai"),
new OutputParams(result: "stdout", alloc: "stdout"),
expectedExitCode: 0,
expectedOutputFile: "testdata/26/exp.json");
}

[Test]
public void Test18()
{
Execute(
new InputParams("testdata/28/", "alloc.json", "env.json", "txs.rlp", "Cancun"),
new OutputParams(result: "stdout", alloc: "stdout"),
expectedExitCode: 0,
expectedOutputFile: "testdata/28/exp.json");
}

[Test]
public void Test19()
{
Execute(
new InputParams("testdata/29/", "alloc.json", "env.json", "txs.json", "Cancun"),
new OutputParams(result: "stdout", alloc: "stdout"),
expectedExitCode: 0,
expectedOutputFile: "testdata/29/exp.json");
}

[Test]
public void Test20()
{
Execute(
new InputParams("testdata/30/", "alloc.json", "env.json", "txs_more.rlp", "Cancun"),
new OutputParams(result: "stdout", alloc: "stdout"),
expectedExitCode: 0,
expectedOutputFile: "testdata/30/exp.json");
}

private void Execute(InputParams inputParams, OutputParams outputParams, int expectedExitCode, string? expectedOutputFile = null)
{
var arguments = new T8nCommandArguments
{
InputAlloc = inputParams.Alloc,
InputEnv = inputParams.Env,
InputTxs = inputParams.Txs,
OutputBody = outputParams.Body,
StateFork = inputParams.StateFork,
};
if (outputParams.Alloc is not null) arguments.OutputAlloc = outputParams.Alloc;
if (outputParams.Result is not null) arguments.OutputResult = outputParams.Result;
if (inputParams.StateReward is not null) arguments.StateReward = inputParams.StateReward;

T8nOutput output = T8nTool.Run(arguments, NullLogManager.Instance);

Assert.That(output.ExitCode, Is.EqualTo(expectedExitCode));

if (expectedOutputFile == null) return;

var outputString = _ethereumJsonSerializer.Serialize(output, true);
var fileContent = File.ReadAllText(expectedOutputFile);
Assert.That(AreEqual(fileContent, outputString));
}

private static bool AreEqual(string json1, string json2)
{
var expected = JToken.Parse(json1);
var actual = JToken.Parse(json2);
return JToken.DeepEquals(actual, expected);
}
}
12 changes: 12 additions & 0 deletions tools/Evm/Evm.Test/testdata/1/alloc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
"balance": "0x5ffd4878be161d74",
"code": "0x",
"nonce": "0xac",
"storage": {}
},
"0x8a8eafb1cf62bfbeb1741769dae1a9dd47996192":{
"balance": "0xfeedbead",
"nonce" : "0x00"
}
}
7 changes: 7 additions & 0 deletions tools/Evm/Evm.Test/testdata/1/env.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"currentCoinbase": "0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"currentDifficulty": "0x20000",
"currentGasLimit": "0x750a163df65e8a",
"currentNumber": "1",
"currentTimestamp": "1000"
}
Loading
Loading