diff --git a/tools/Evm/Evm/t8n/JsonTypes/InputData.cs b/tools/Evm/Evm/t8n/JsonTypes/InputData.cs
index 355daba38e5..f3945382455 100644
--- a/tools/Evm/Evm/t8n/JsonTypes/InputData.cs
+++ b/tools/Evm/Evm/t8n/JsonTypes/InputData.cs
@@ -3,7 +3,10 @@
using Ethereum.Test.Base;
using Nethermind.Core;
+using Nethermind.Core.Crypto;
using Nethermind.Core.Extensions;
+using Nethermind.Crypto;
+using Nethermind.Facade.Eth.RpcTransaction;
using Nethermind.Serialization.Rlp;
namespace Evm.t8n.JsonTypes;
@@ -12,22 +15,49 @@ public class InputData
{
public Dictionary
? Alloc { get; set; }
public EnvJson? Env { get; set; }
- public TransactionJson[]? Txs { get; set; }
+ public TransactionForRpc[]? Txs { get; set; }
+ public TransactionMetaData[]? TransactionMetaDataList { get; set; }
public string? TxRlp { get; set; }
public Transaction[] GetTransactions(TxDecoder decoder)
{
- Transaction[] transactions = [];
+ List transactions = [];
if (TxRlp is not null)
{
RlpStream rlp = new(Bytes.FromHexString(TxRlp));
- transactions = decoder.DecodeArray(rlp);
+ transactions = decoder.DecodeArray(rlp).ToList();
}
- else if (Txs is not null)
+ else if (Txs is not null && TransactionMetaDataList is not null)
{
- transactions = Txs.Select(txInfo => txInfo.ConvertToTx()).ToArray();
+ for (int i = 0; i < Txs.Length; i++)
+ {
+ var tx = Txs[i].ToTransaction();
+ tx.SenderAddress = null; // t8n does not accept SenderAddress from input, so need to reset senderAddress
+
+ var txLegacy = (LegacyTransactionForRpc) Txs[i];
+
+ var secretKey = TransactionMetaDataList[i].SecretKey;
+
+ if (secretKey is not null)
+ {
+ var privateKey = new PrivateKey(secretKey);
+ tx.SenderAddress = privateKey.Address;
+
+ EthereumEcdsa ecdsa = new(tx.ChainId ?? TestBlockchainIds.ChainId);
+
+ ecdsa.Sign(privateKey, tx, TransactionMetaDataList[i].Protected ?? true);
+ }
+ else if (txLegacy.R.HasValue && txLegacy.S.HasValue && txLegacy.V.HasValue)
+ {
+ tx.Signature = new Signature(txLegacy.R.Value, txLegacy.S.Value, txLegacy.V.Value.ToUInt64(null));
+ }
+
+ tx.Hash = tx.CalculateHash();
+
+ transactions.Add(tx);
+ }
}
- return transactions;
+ return transactions.ToArray();
}
}
diff --git a/tools/Evm/Evm/t8n/JsonTypes/TransactionJson.cs b/tools/Evm/Evm/t8n/JsonTypes/TransactionJson.cs
deleted file mode 100644
index 0602df0f529..00000000000
--- a/tools/Evm/Evm/t8n/JsonTypes/TransactionJson.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
-// SPDX-License-Identifier: LGPL-3.0-only
-
-using Ethereum.Test.Base;
-using Nethermind.Core;
-using Nethermind.Core.Crypto;
-using Nethermind.Core.Eip2930;
-using Nethermind.Core.Test.Builders;
-using Nethermind.Crypto;
-using Nethermind.Int256;
-
-namespace Evm.t8n.JsonTypes;
-
-public class TransactionJson
-{
- public byte[]? Input { get; set; }
- public long Gas { get; set; }
- public string? Hash { get; set; }
- public UInt256 Nonce { get; set; }
- public Address? To { get; set; }
- public UInt256 Value { get; set; }
- public ulong V { get; set; }
- public byte[]? R { get; set; }
- public byte[]? S { get; set; }
- public byte[]? SecretKey { get; set; }
- public ulong? ChainId { get; set; }
- public TxType Type { get; set; } = TxType.Legacy;
- public UInt256? MaxFeePerGas { get; set; }
- public UInt256 GasPrice { get; set; }
- public UInt256? MaxPriorityFeePerGas { get; set; }
- public AccessListItemJson[]? AccessList { get; set; }
- public bool? Protected { get; set; }
-
- public Transaction ConvertToTx()
- {
- TransactionBuilder transactionBuilder = new();
-
- transactionBuilder.WithValue(Value);
- if (Input is not null)
- {
- transactionBuilder.WithData(Input);
- }
- transactionBuilder.WithTo(To);
- transactionBuilder.WithNonce(Nonce);
- transactionBuilder.WithGasLimit(Gas);
- transactionBuilder.WithType(Type);
- transactionBuilder.WithGasPrice(GasPrice);
- if (AccessList is not null)
- {
- AccessList.Builder builder = new();
- JsonToEthereumTest.ProcessAccessList(AccessList, builder);
- transactionBuilder.WithAccessList(builder.Build());
- }
-
- if (MaxFeePerGas.HasValue)
- {
- transactionBuilder.WithMaxFeePerGas(MaxFeePerGas.Value);
- }
- if (MaxPriorityFeePerGas.HasValue)
- {
- transactionBuilder.WithMaxPriorityFeePerGas(MaxPriorityFeePerGas.Value);
- }
-
- if (ChainId.HasValue)
- {
- transactionBuilder.WithChainId(ChainId.Value);
- }
- if (SecretKey is not null)
- {
- var privateKey = new PrivateKey(SecretKey);
- transactionBuilder.WithSenderAddress(privateKey.Address);
- transactionBuilder.Signed(privateKey, Protected ?? true);
- }
- else
- {
- transactionBuilder.WithSignature(new Signature(R, S, V));
- }
-
- return transactionBuilder.TestObject;
- }
-}
diff --git a/tools/Evm/Evm/t8n/JsonTypes/TransactionMetaData.cs b/tools/Evm/Evm/t8n/JsonTypes/TransactionMetaData.cs
new file mode 100644
index 00000000000..d4b66eae1fe
--- /dev/null
+++ b/tools/Evm/Evm/t8n/JsonTypes/TransactionMetaData.cs
@@ -0,0 +1,10 @@
+// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
+// SPDX-License-Identifier: LGPL-3.0-only
+
+namespace Evm.t8n.JsonTypes;
+
+public class TransactionMetaData
+{
+ public bool? Protected { get; set; }
+ public byte[]? SecretKey { get; set; }
+}
diff --git a/tools/Evm/Evm/t8n/T8NInputReader.cs b/tools/Evm/Evm/t8n/T8NInputReader.cs
index dcae50a3397..4cf86c29d2e 100644
--- a/tools/Evm/Evm/t8n/T8NInputReader.cs
+++ b/tools/Evm/Evm/t8n/T8NInputReader.cs
@@ -6,8 +6,8 @@
using Evm.t8n.Errors;
using Evm.t8n.JsonTypes;
using Nethermind.Core;
+using Nethermind.Facade.Eth.RpcTransaction;
using Nethermind.Serialization.Json;
-using TransactionJson = Evm.t8n.JsonTypes.TransactionJson;
namespace Evm.t8n;
@@ -40,7 +40,8 @@ public static InputData ReadInputData(T8NCommandArguments arguments)
switch (Path.GetExtension(arguments.InputTxs))
{
case ".json":
- inputData.Txs = LoadDataFromFile(arguments.InputTxs, "txs");
+ inputData.Txs = LoadDataFromFile(arguments.InputTxs, "txs");
+ inputData.TransactionMetaDataList = LoadDataFromFile(arguments.InputTxs, "txs");
break;
case ".rlp":
inputData.TxRlp = File.ReadAllText(arguments.InputTxs).Replace("\"", "").Replace("\n", "");