Skip to content

Commit

Permalink
Refactor TransactionForRpc (Alternative) (#7483)
Browse files Browse the repository at this point in the history
Co-authored-by: lukasz.rozmej <[email protected]>
Co-authored-by: Ben Adams <[email protected]>
  • Loading branch information
3 people authored Oct 14, 2024
1 parent 7c411aa commit 966113f
Show file tree
Hide file tree
Showing 81 changed files with 2,341 additions and 1,092 deletions.
8 changes: 6 additions & 2 deletions src/Nethermind/Nethermind.Api/INethermindApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using System;
using Nethermind.Config;
using Nethermind.Core;
using Nethermind.Facade.Eth;
using Nethermind.Facade.Eth.RpcTransaction;
using Nethermind.Serialization.Rlp;
using Nethermind.Serialization.Rlp.TxDecoders;
using Nethermind.TxPool;
Expand All @@ -23,12 +25,14 @@ public T Config<T>() where T : IConfig

public static class NethermindApiExtensions
{
public static void RegisterTxType(this INethermindApi api, TxType type, ITxDecoder decoder, ITxValidator validator)
public static void RegisterTxType<T>(this INethermindApi api, ITxDecoder decoder, ITxValidator validator) where T : TransactionForRpc, IFromTransaction<T>
{
ArgumentNullException.ThrowIfNull(api.TxValidator);
if (decoder.Type != T.TxType) throw new ArgumentException($"TxType mismatch decoder: {decoder.Type}, RPC: {T.TxType}");

api.TxValidator.RegisterValidator(type, validator);
api.TxValidator.RegisterValidator(T.TxType, validator);
TxDecoder.Instance.RegisterDecoder(decoder);
TransactionForRpc.RegisterTransactionType<T>();
}
}
}
5 changes: 2 additions & 3 deletions src/Nethermind/Nethermind.Cli.Test/ProofCliModuleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@
using Nethermind.Cli.Modules;
using Nethermind.Core.Crypto;
using Nethermind.Core.Test.Builders;
using Nethermind.Facade.Eth;
using Nethermind.Facade.Eth.RpcTransaction;
using Nethermind.JsonRpc;
using Nethermind.JsonRpc.Client;
using Nethermind.JsonRpc.Data;
using Nethermind.Logging;
using Nethermind.Serialization.Json;
using NSubstitute;
Expand Down Expand Up @@ -81,7 +80,7 @@ public void Get_transaction_receipt(bool includeHeader)
public void Call()
{
Hash256 blockHash = TestItem.KeccakA;
TransactionForRpc tx = new()
LegacyTransactionForRpc tx = new()
{
From = TestItem.AddressA,
To = TestItem.AddressB
Expand Down
19 changes: 10 additions & 9 deletions src/Nethermind/Nethermind.Cli/Modules/EthCliModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Core.Extensions;
using Nethermind.Facade.Eth;
using Nethermind.Facade.Eth.RpcTransaction;
using Nethermind.Int256;
using Nethermind.JsonRpc.Data;

namespace Nethermind.Cli.Modules
{
Expand All @@ -20,13 +19,15 @@ public class EthCliModule : CliModuleBase
{
long blockNumber = NodeManager.Post<long>("eth_blockNumber").Result;

TransactionForRpc tx = new();
tx.Value = amountInWei;
tx.Gas = Transaction.BaseTxGasCost;
tx.GasPrice = (UInt256)Engine.JintEngine.GetValue("gasPrice").AsNumber();
tx.To = address;
tx.Nonce = (ulong)NodeManager.Post<long>("eth_getTransactionCount", from, blockNumber).Result;
tx.From = from;
LegacyTransactionForRpc tx = new()
{
Value = amountInWei,
Gas = Transaction.BaseTxGasCost,
GasPrice = (UInt256)Engine.JintEngine.GetValue("gasPrice").AsNumber(),
To = address,
Nonce = (ulong)NodeManager.Post<long>("eth_getTransactionCount", from, blockNumber).Result,
From = from
};

Hash256? keccak = NodeManager.Post<Hash256>("eth_sendTransaction", tx).Result;
return keccak?.Bytes.ToHexString();
Expand Down
10 changes: 10 additions & 0 deletions src/Nethermind/Nethermind.Core.Test/Builders/TestItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ static TestItem()
Keccaks[i - 1] = Keccak.Compute(PublicKeys[i - 1].Bytes);
ValueKeccaks[i - 1] = Keccaks[i - 1];
}

byte[] r = new byte[32];
byte[] s = new byte[32];
r[1] = 1;
s[2] = 2;
RandomSignatureA = new Signature(r, s, 27);
RandomSignatureB = new Signature(r, s, 28);
}

public static Hash256 KeccakFromNumber(int i)
Expand Down Expand Up @@ -93,6 +100,9 @@ public static Hash256 KeccakFromNumber(int i)
public static Address AddressE = PublicKeyE.Address;
public static Address AddressF = PublicKeyF.Address;

public static readonly Signature RandomSignatureA;
public static readonly Signature RandomSignatureB;

public static Withdrawal WithdrawalA_1Eth = new() { Address = AddressA, Index = 1, ValidatorIndex = 2001, AmountInGwei = 1_000_000_000 };
public static Withdrawal WithdrawalB_2Eth = new() { Address = AddressB, Index = 2, ValidatorIndex = 2002, AmountInGwei = 2_000_000_000 };
public static Withdrawal WithdrawalC_3Eth = new() { Address = AddressC, Index = 3, ValidatorIndex = 2003, AmountInGwei = 3_000_000_000 };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public TransactionBuilder<T> WithCode(byte[] data)
return this;
}

public TransactionBuilder<T> WithChainId(ulong chainId)
public TransactionBuilder<T> WithChainId(ulong? chainId)
{
TestObjectInternal.ChainId = chainId;
return this;
Expand Down Expand Up @@ -298,6 +298,12 @@ public TransactionBuilder<T> WithIsServiceTransaction(bool isServiceTransaction)
return this;
}

public TransactionBuilder<T> WithSourceHash(Hash256? sourceHash)
{
TestObjectInternal.SourceHash = sourceHash;
return this;
}

public TransactionBuilder<T> From(T item)
{
TestObjectInternal = item;
Expand Down
13 changes: 13 additions & 0 deletions src/Nethermind/Nethermind.Core/Extensions/UInt256Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using Nethermind.Int256;

namespace Nethermind.Core.Extensions;

public static class UInt256Extensions
{
// value?.IsZero == false <=> x > 0
public static bool IsPositive(this UInt256? @this) => @this?.IsZero == false;
}
57 changes: 0 additions & 57 deletions src/Nethermind/Nethermind.Facade/Eth/AccessListItemForRpc.cs

This file was deleted.

43 changes: 0 additions & 43 deletions src/Nethermind/Nethermind.Facade/Eth/AuthorizationTupleForRpc.cs

This file was deleted.

6 changes: 5 additions & 1 deletion src/Nethermind/Nethermind.Facade/Eth/BlockForRpc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Nethermind.Serialization.Rlp;
using System.Text.Json.Serialization;
using System.Runtime.CompilerServices;
using Nethermind.Facade.Eth.RpcTransaction;
using Nethermind.Core.ConsensusRequests;

namespace Nethermind.Facade.Eth;
Expand Down Expand Up @@ -78,7 +79,10 @@ public BlockForRpc(Block block, bool includeFullTransactionData, ISpecProvider s
StateRoot = block.StateRoot;
Timestamp = block.Timestamp;
TotalDifficulty = block.TotalDifficulty ?? 0;
Transactions = includeFullTransactionData ? block.Transactions.Select((t, idx) => new TransactionForRpc(block.Hash, block.Number, idx, t, block.BaseFeePerGas)).ToArray() : block.Transactions.Select(t => t.Hash).OfType<object>().ToArray();
Transactions = (includeFullTransactionData
? block.Transactions.Select((t, idx) => TransactionForRpc.FromTransaction(t, block.Hash, block.Number, idx, block.BaseFeePerGas, specProvider.ChainId))
: block.Transactions.Select(t => t.Hash).OfType<object>())
.ToArray();
TransactionsRoot = block.TxRoot;
Uncles = block.Uncles.Select(o => o.Hash);
Withdrawals = block.Withdrawals;
Expand Down
24 changes: 24 additions & 0 deletions src/Nethermind/Nethermind.Facade/Eth/IFromTransaction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Facade.Eth.RpcTransaction;
using Nethermind.Int256;

namespace Nethermind.Facade.Eth;

public interface IFromTransaction<out T> : ITxTyped where T : TransactionForRpc
{
static abstract T FromTransaction(Transaction tx, TransactionConverterExtraData extraData);
}

public readonly struct TransactionConverterExtraData
{
public ulong? ChainId { get; init; }
public Hash256? BlockHash { get; init; }
public long? BlockNumber { get; init; }
public int? TxIndex { get; init; }
public UInt256? BaseFee { get; init; }
public TxReceipt Receipt { get; init; }
}
11 changes: 11 additions & 0 deletions src/Nethermind/Nethermind.Facade/Eth/ITxTyped.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using Nethermind.Core;

namespace Nethermind.Facade.Eth;

public interface ITxTyped
{
static abstract TxType TxType { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System.Collections.Generic;
using System.Linq;
using Nethermind.Core;
using Nethermind.Core.Eip2930;
using Nethermind.Int256;
using Nethermind.Serialization.Json;
using System.Text.Json.Serialization;
using System.Text.Json;
using System;

namespace Nethermind.Facade.Eth.RpcTransaction;

[JsonConverter(typeof(JsonConverter))]
public class AccessListForRpc
{
private readonly IEnumerable<Item> _items;

[JsonConstructor]
public AccessListForRpc() { }

private AccessListForRpc(IEnumerable<Item> items)
{
_items = items;
}

private class Item
{
public Address Address { get; set; }

[JsonConverter(typeof(StorageCellIndexConverter))]
public IEnumerable<UInt256>? StorageKeys { get; set; }

[JsonConstructor]
public Item() { }

public Item(Address address, IEnumerable<UInt256> storageKeys)
{
Address = address;
StorageKeys = storageKeys;
}
}

public static AccessListForRpc FromAccessList(AccessList? accessList) =>
accessList is null
? new AccessListForRpc([])
: new AccessListForRpc(accessList.Select(item => new Item(item.Address, [.. item.StorageKeys])));

public AccessList ToAccessList()
{
AccessList.Builder builder = new();
foreach (Item item in _items)
{
builder.AddAddress(item.Address);
foreach (UInt256 index in item.StorageKeys ?? [])
{
builder.AddStorage(index);
}
}

return builder.Build();
}

public class JsonConverter : JsonConverter<AccessListForRpc>
{
public override AccessListForRpc? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
List<Item>? list = JsonSerializer.Deserialize<List<Item>>(ref reader, options);
return list is null ? null : new AccessListForRpc(list);
}

public override void Write(Utf8JsonWriter writer, AccessListForRpc value, JsonSerializerOptions options)
{
JsonSerializer.Serialize(writer, value._items, options);
}
}
}
Loading

0 comments on commit 966113f

Please sign in to comment.