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

Refactor TxDecoder #7334

Merged
merged 125 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from 117 commits
Commits
Show all changes
125 commits
Select commit Hold shift + click to select a range
3bd4a8d
Define Optimism Deposit transaction
emlautarom1 Aug 8, 2024
f46bf79
Cleanup existing `TxDecoder`
emlautarom1 Aug 8, 2024
ed2bbab
Missing assignment
emlautarom1 Aug 9, 2024
6ed28c8
Renaming
emlautarom1 Aug 9, 2024
f1ca0f5
Individual tx decoders
emlautarom1 Aug 9, 2024
6432a36
Remove intermediate interface
emlautarom1 Aug 9, 2024
d2499e9
Implement `AbstractTxDecoder`
emlautarom1 Aug 9, 2024
2716de6
Implement `AbstractTxDecoder`
emlautarom1 Aug 9, 2024
9bc577f
Implement `AbstractTxDecoder`
emlautarom1 Aug 9, 2024
03d2826
Implement `AbstractTxDecoder`
emlautarom1 Aug 9, 2024
4b3b3e7
Remove unused code
emlautarom1 Aug 9, 2024
c6bb66f
Implement `AbstractTxDecoder`
emlautarom1 Aug 9, 2024
57da69d
Add `Encode` to API
emlautarom1 Aug 9, 2024
be62cc0
Implement `Encode`
emlautarom1 Aug 9, 2024
5cf9633
Implement `Encode`
emlautarom1 Aug 9, 2024
502b313
Implement `Encode`
emlautarom1 Aug 9, 2024
1a38696
Implement `Encode`
emlautarom1 Aug 9, 2024
89045c7
Implement `Encode`
emlautarom1 Aug 9, 2024
0966cfa
Implement `Encode`
emlautarom1 Aug 9, 2024
fa51ef6
Reduce interface signature
emlautarom1 Aug 9, 2024
8f9188c
Remove encode dead code
emlautarom1 Aug 9, 2024
5d14c62
Add `GetLength` to API
emlautarom1 Aug 9, 2024
288de2c
Base `TxDecoder` implementing `IRlpStreamDecoder<Transaction>`
emlautarom1 Aug 9, 2024
5ce978b
Remove unused imports
emlautarom1 Aug 9, 2024
380eca9
Add `IRlpValueDecoder<Transaction>` impl
emlautarom1 Aug 9, 2024
16284c3
Implement ref `Decode`
emlautarom1 Aug 9, 2024
3904d06
Remove redundant code
emlautarom1 Aug 9, 2024
806830f
Implement `ref Decode`
emlautarom1 Aug 9, 2024
45bf28b
Remove unused code
emlautarom1 Aug 9, 2024
fabdcf0
Renaming
emlautarom1 Aug 9, 2024
fc9246a
Implement `ref Decode`
emlautarom1 Aug 9, 2024
93123d5
Implement `ref Decode`
emlautarom1 Aug 9, 2024
7aef17e
Implement `ref Decode`
emlautarom1 Aug 9, 2024
0f7dd60
Code cleanup
emlautarom1 Aug 9, 2024
bd9f0cf
Add `Rlp Encode(...)`
emlautarom1 Aug 9, 2024
39fd942
Add `SignatureBuilder`
emlautarom1 Aug 12, 2024
bb91078
Remove duplicated code
emlautarom1 Aug 12, 2024
85032e4
To file scoped namespace
emlautarom1 Aug 12, 2024
57cc72f
Remove `Rlp Encode(...)` method
emlautarom1 Aug 12, 2024
7e5ecd0
Reduce type switches
emlautarom1 Aug 12, 2024
da8d5fb
Refactor code
emlautarom1 Aug 12, 2024
fb2d5e2
Remove unused code
emlautarom1 Aug 12, 2024
0c0cf74
Simplify content length calculation
emlautarom1 Aug 12, 2024
afde273
Simplify content length calculation
emlautarom1 Aug 12, 2024
0f04a96
Remove unused method
emlautarom1 Aug 12, 2024
33c8515
Internal method renaming
emlautarom1 Aug 12, 2024
e90e628
Formatting
emlautarom1 Aug 12, 2024
9dffba1
Code refactor
emlautarom1 Aug 12, 2024
e7e89a8
Add `Rlp EncodeTx(...)`
emlautarom1 Aug 13, 2024
d266e3a
Implement `Rlp EncodeTx(...)` in all
emlautarom1 Aug 13, 2024
734ad27
Use primary constructor parameter
emlautarom1 Aug 13, 2024
cffa123
Make nullable parameter
emlautarom1 Aug 13, 2024
d875802
Make primary constructor
emlautarom1 Aug 13, 2024
ab76d62
Add overload to `Encode`
emlautarom1 Aug 13, 2024
143e84d
Make singleton instances static
emlautarom1 Aug 13, 2024
9a45130
Add default RlpBehaviors
emlautarom1 Aug 13, 2024
a1ea7e0
Fix infinite recursion
emlautarom1 Aug 13, 2024
55503ed
Remove unused params
emlautarom1 Aug 13, 2024
967c9ad
Default to legacy
emlautarom1 Aug 13, 2024
48fefeb
Add TODO regarding Legacy check
emlautarom1 Aug 13, 2024
fda0ae3
Fix incorrect type check
emlautarom1 Aug 13, 2024
e6b9f7b
Remove DepositTransaction subtype
emlautarom1 Aug 13, 2024
c47fc90
Fix incorrect conditional merge
emlautarom1 Aug 13, 2024
1e4eb4e
Formatting
emlautarom1 Aug 13, 2024
e28018a
Automated refactor and code cleanup
emlautarom1 Aug 13, 2024
be9e489
Starting from scratch
emlautarom1 Aug 13, 2024
4363a6e
Inline `DecodeTxTypeAndGetSequence`
emlautarom1 Aug 13, 2024
7534a39
Cleanup flag checking
emlautarom1 Aug 13, 2024
544bdc4
Reorder public methods
emlautarom1 Aug 13, 2024
fba000d
Reorder TxType initialization in `ref Decode`
emlautarom1 Aug 13, 2024
5875eb3
Add `ref Decode` method to `ITxDecoder` interface
emlautarom1 Aug 14, 2024
5780c19
Implement `ref Decode`
emlautarom1 Aug 14, 2024
7f5e34e
Dispatch to appropriate `ITxDecoder` in `ref Decode`
emlautarom1 Aug 14, 2024
5dcc43a
Remove unused code
emlautarom1 Aug 14, 2024
3c136cd
Add `EncodeTx` to `ITxDecoder`
emlautarom1 Aug 14, 2024
18b0ef5
Implement `EncodeTx`
emlautarom1 Aug 14, 2024
9a0069a
Dispatch `EncodeTx` to appropriate `ITxDecoder`
emlautarom1 Aug 14, 2024
f118008
Remove invalid `TxType` test
emlautarom1 Aug 14, 2024
44a84ae
Remove unused code
emlautarom1 Aug 14, 2024
e99d627
Add `int GetLength` to `ITxDecoder`
emlautarom1 Aug 14, 2024
c546250
Implement `int GetLength`
emlautarom1 Aug 14, 2024
ba65b9f
Dispatch to appropriate decoder
emlautarom1 Aug 14, 2024
972fdaa
Add `int GetTxLength` to `ITxDecoder`
emlautarom1 Aug 14, 2024
a4787a3
Implement `int GetTxLength`
emlautarom1 Aug 14, 2024
c58ae73
Dispatch to correct decoder
emlautarom1 Aug 14, 2024
63e95fe
Remove unused code
emlautarom1 Aug 14, 2024
4fbea8a
Merge `GetLength` and `GetTxLength`
emlautarom1 Aug 14, 2024
e42c558
Method rename
emlautarom1 Aug 14, 2024
ab78b21
Merge `GetLength` and `GetTxLength`
emlautarom1 Aug 14, 2024
9d0f35c
Method renaming
emlautarom1 Aug 14, 2024
08f7648
Param renaming
emlautarom1 Aug 14, 2024
f198b9c
Avoid infinite recursion
emlautarom1 Aug 14, 2024
dadec17
Remove default params
emlautarom1 Aug 14, 2024
99fd76a
Prefer `[]` instead of `TryGet`
emlautarom1 Aug 14, 2024
c5aead7
Renaming and parameter reordering
emlautarom1 Aug 14, 2024
22e5891
Param renaming
emlautarom1 Aug 14, 2024
18afa9b
Param and variable renaming and reordering
emlautarom1 Aug 14, 2024
1753ced
Param and var renaming and reordering
emlautarom1 Aug 14, 2024
e3a0941
Method and param renaming and reordering
emlautarom1 Aug 14, 2024
a72fa67
Method, param and var renaming and reordering
emlautarom1 Aug 14, 2024
4c1d0e1
Use `SignatureBuilder`
emlautarom1 Aug 15, 2024
6615d63
Use `SignatureBuilder`
emlautarom1 Aug 15, 2024
496bd1b
Remove redundant param
emlautarom1 Aug 15, 2024
f10fd4b
Remove const true
emlautarom1 Aug 15, 2024
0f9d0f0
Parametrize `new Transaction()`
emlautarom1 Aug 15, 2024
f29e0e6
Configure transaction factory
emlautarom1 Aug 15, 2024
faf37e4
Lift constant to interface
emlautarom1 Aug 15, 2024
f98acc6
Delete `TxFeature`
emlautarom1 Aug 15, 2024
6e83af8
Whitespace
emlautarom1 Aug 15, 2024
a6bfbb0
Delete old abstract class
emlautarom1 Aug 15, 2024
be50fda
Use the appropriate `TxType` directly
emlautarom1 Aug 15, 2024
402ce57
Whitespace
emlautarom1 Aug 15, 2024
fe87d31
Remove nullability
emlautarom1 Aug 15, 2024
4b48dc2
Merge branch 'master' into refactor/tx-decoder
emlautarom1 Aug 15, 2024
82d7b1f
Remove `lazyHash`
emlautarom1 Aug 16, 2024
04dd9ea
Remove `new` from `TxDecoder`
emlautarom1 Aug 16, 2024
acaf5a5
Merge branch 'master' into refactor/tx-decoder
emlautarom1 Aug 16, 2024
62a1e4e
Merge branch 'master' into refactor/tx-decoder
emlautarom1 Aug 28, 2024
87fdec0
Refactor decoders to class hierarchy (#7354)
LukaszRozmej Sep 2, 2024
600b16a
Merge branch 'master' into refactor/tx-decoder
emlautarom1 Sep 2, 2024
4a92361
Remove const from interface
emlautarom1 Sep 2, 2024
3647549
Merge branch 'master' into refactor/tx-decoder
emlautarom1 Sep 3, 2024
1a60acd
Merge branch 'master' into refactor/tx-decoder
emlautarom1 Sep 3, 2024
19ed1f9
fix exceptions Rlpn unsupported tx type in rlp
LukaszRozmej Sep 4, 2024
35175fa
better message
LukaszRozmej Sep 4, 2024
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 @@ -171,7 +171,6 @@ public bool Before_eip_2930_has_to_be_legacy_tx(TxType txType, bool eip2930)
[TestCase(TxType.AccessList, true, false, ExpectedResult = true)]
[TestCase(TxType.EIP1559, true, false, ExpectedResult = false)]
[TestCase(TxType.EIP1559, true, true, ExpectedResult = true)]
[TestCase((TxType)100, true, false, ExpectedResult = false)]
LukaszRozmej marked this conversation as resolved.
Show resolved Hide resolved
public bool Before_eip_1559_has_to_be_legacy_or_access_list_tx(TxType txType, bool eip2930, bool eip1559)
{
byte[] sigData = new byte[65];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace Nethermind.Core.Test.Encoding;
[TestFixture]
public partial class ShardBlobTxDecoderTests
{
private readonly TxDecoder _txDecoder = new();
private readonly TxDecoder _txDecoder = TxDecoder.Instance;

[SetUp]
public static Task SetUp() => KzgPolynomialCommitments.InitializeAsync();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace Nethermind.Core.Test.Encoding
[TestFixture]
public class TxDecoderTests
{
private readonly TxDecoder _txDecoder = new();
private readonly TxDecoder _txDecoder = TxDecoder.Instance;

public static IEnumerable<(TransactionBuilder<Transaction>, string)> TestObjectsSource()
{
Expand Down Expand Up @@ -72,12 +72,11 @@ public void CanCorrectlyCalculateTxHash_when_called_concurrently((Transaction Tx
{
Transaction tx = testCase.Tx;

TxDecoder decoder = new TxDecoder();
Rlp rlp = decoder.Encode(tx);
Rlp rlp = TxDecoder.Instance.Encode(tx);

Hash256 expectedHash = Keccak.Compute(rlp.Bytes);

Transaction decodedTx = decoder.Decode(new RlpStream(rlp.Bytes))!;
Transaction decodedTx = TxDecoder.Instance.Decode(new RlpStream(rlp.Bytes))!;

decodedTx.SetPreHash(rlp.Bytes);

Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Nethermind.Crypto/TransactionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Nethermind.Crypto
{
public static class TransactionExtensions
{
private static readonly TxDecoder _txDecoder = new();
private static readonly TxDecoder _txDecoder = TxDecoder.Instance;

public static Hash256 CalculateHash(this Transaction transaction)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public class TraceRpcModule : ITraceRpcModule
private readonly IReceiptFinder _receiptFinder;
private readonly ITracer _tracer;
private readonly IBlockFinder _blockFinder;
private readonly TxDecoder _txDecoder = new();
private readonly TxDecoder _txDecoder = TxDecoder.Instance;
private readonly IJsonRpcConfig _jsonRpcConfig;
private readonly TimeSpan _cancellationTokenTimeout;
private readonly IStateReader _stateReader;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,8 @@ public virtual async Task NewPayloadV3_should_decline_mempool_encoding(bool inMe

ExecutionPayloadV3 payload = (await rpcModule.engine_getPayloadV3(Bytes.FromHexString(payloadId!))).Data!.ExecutionPayload;

TxDecoder rlpEncoder = new();
RlpBehaviors rlpBehaviors = (inMempoolForm ? RlpBehaviors.InMempoolForm : RlpBehaviors.None) | RlpBehaviors.SkipTypedWrapping;
payload.Transactions = transactions.Select(tx => rlpEncoder.Encode(tx, rlpBehaviors).Bytes).ToArray();
payload.Transactions = transactions.Select(tx => TxDecoder.Instance.Encode(tx, rlpBehaviors).Bytes).ToArray();
byte[]?[] blobVersionedHashes = transactions.SelectMany(tx => tx.BlobVersionedHashes ?? Array.Empty<byte[]>()).ToArray();

ResultWrapper<PayloadStatusV1> result = await rpcModule.engine_newPayloadV3(payload, blobVersionedHashes, payload.ParentBeaconBlockRoot);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
using Nethermind.Network.P2P.Subprotocols.Eth.V62.Messages;
using Nethermind.Network.Rlpx;
using Nethermind.Network.Test.Builders;
using Nethermind.Serialization.Rlp;
using Nethermind.Stats;
using Nethermind.Stats.Model;
using Nethermind.Synchronization;
Expand All @@ -47,7 +46,6 @@ public class Eth62ProtocolHandlerTests
private Block _genesisBlock = null!;
private Eth62ProtocolHandler _handler = null!;
private IGossipPolicy _gossipPolicy = null!;
private readonly TxDecoder _txDecoder = new();
private ITxGossipPolicy _txGossipPolicy = null!;

[SetUp]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ private void HandleZeroMessage<T>(T msg, byte messageCode) where T : MessageBase

private void GenerateLists(int txCount, out ArrayPoolList<byte> types, out ArrayPoolList<int> sizes, out ArrayPoolList<Hash256> hashes)
{
TxDecoder txDecoder = new();
TxDecoder txDecoder = TxDecoder.Instance;
types = new(txCount);
sizes = new(txCount);
hashes = new(txCount);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ protected SyncPeerProtocolHandlerBase(ISession session,
SyncServer = syncServer ?? throw new ArgumentNullException(nameof(syncServer));
BackgroundTaskScheduler = new BackgroundTaskSchedulerWrapper(this, backgroundTaskScheduler ?? throw new ArgumentNullException(nameof(BackgroundTaskScheduler)));
_timestamper = Timestamper.Default;
_txDecoder = new TxDecoder();
_txDecoder = TxDecoder.Instance;
_headersRequests = new MessageQueue<GetBlockHeadersMessage, IOwnedReadOnlyList<BlockHeader>>(Send);
_bodiesRequests = new MessageQueue<GetBlockBodiesMessage, (OwnedBlockBodies, long)>(Send);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public BlockBodiesMessage Deserialize(IByteBuffer byteBuffer)

private class BlockBodyDecoder : IRlpValueDecoder<BlockBody>
{
private readonly TxDecoder _txDecoder = new();
private readonly TxDecoder _txDecoder = TxDecoder.Instance;
private readonly HeaderDecoder _headerDecoder = new();
private readonly WithdrawalDecoder _withdrawalDecoderDecoder = new();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Nethermind.Network.P2P.Subprotocols.Eth.V62.Messages
{
public class TransactionsMessageSerializer : IZeroInnerMessageSerializer<TransactionsMessage>
{
private readonly TxDecoder _decoder = new();
private readonly TxDecoder _decoder = TxDecoder.Instance;

public void Serialize(IByteBuffer byteBuffer, TransactionsMessage message)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Nethermind.Serialization.Rlp
public class BlockDecoder : IRlpValueDecoder<Block>, IRlpStreamDecoder<Block>
{
private readonly HeaderDecoder _headerDecoder = new();
private readonly TxDecoder _txDecoder = new();
private readonly TxDecoder _txDecoder = TxDecoder.Instance;
private readonly WithdrawalDecoder _withdrawalDecoder = new();

public Block? Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = RlpBehaviors.None)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Core.Extensions;
using Nethermind.Serialization.Rlp.Eip2930;

namespace Nethermind.Serialization.Rlp.MyTxDecoder;

public sealed class AccessListTxDecoder(Func<Transaction>? transactionFactory = null) : ITxDecoder
{
private static readonly AccessListDecoder AccessListDecoder = new();
private readonly Func<Transaction> _createTransaction = transactionFactory ?? (() => new Transaction());

public Transaction? Decode(Span<byte> transactionSequence, RlpStream rlpStream, RlpBehaviors rlpBehaviors)
{
Transaction transaction = _createTransaction();
transaction.Type = TxType.AccessList;

int transactionLength = rlpStream.ReadSequenceLength();
int lastCheck = rlpStream.Position + transactionLength;

DecodePayload(transaction, rlpStream, rlpBehaviors);

if (rlpStream.Position < lastCheck)
{
DecodeSignature(transaction, rlpStream, rlpBehaviors);
}

if ((rlpBehaviors & RlpBehaviors.AllowExtraBytes) == 0)
{
rlpStream.Check(lastCheck);
}

if ((rlpBehaviors & RlpBehaviors.ExcludeHashes) == 0)
{
if (transactionSequence.Length <= ITxDecoder.MaxDelayedHashTxnSize)
{
// Delay hash generation, as may be filtered as having too low gas etc
transaction.SetPreHashNoLock(transactionSequence);
}
else
{
// Just calculate the Hash as txn too large
transaction.Hash = Keccak.Compute(transactionSequence);
}
}

return transaction;
}

public void Decode(ref Transaction? transaction, int txSequenceStart, ReadOnlySpan<byte> transactionSequence, ref Rlp.ValueDecoderContext decoderContext, RlpBehaviors rlpBehaviors = RlpBehaviors.None)
{
transaction ??= _createTransaction();
transaction.Type = TxType.AccessList;

int transactionLength = decoderContext.ReadSequenceLength();
int lastCheck = decoderContext.Position + transactionLength;

DecodePayload(transaction, ref decoderContext, rlpBehaviors);

if (decoderContext.Position < lastCheck)
{
DecodeSignature(transaction, ref decoderContext, rlpBehaviors);
}

if ((rlpBehaviors & RlpBehaviors.AllowExtraBytes) == 0)
{
decoderContext.Check(lastCheck);
}

if ((rlpBehaviors & RlpBehaviors.ExcludeHashes) == 0)
{
if (transactionSequence.Length <= ITxDecoder.MaxDelayedHashTxnSize)
{
// Delay hash generation, as may be filtered as having too low gas etc
if (decoderContext.ShouldSliceMemory)
{
// Do not copy the memory in this case.
int currentPosition = decoderContext.Position;
decoderContext.Position = txSequenceStart;
transaction.SetPreHashMemoryNoLock(decoderContext.ReadMemory(transactionSequence.Length));
decoderContext.Position = currentPosition;
}
else
{
transaction.SetPreHashNoLock(transactionSequence);
}
}
else
{
// Just calculate the Hash immediately as txn too large
transaction.Hash = Keccak.Compute(transactionSequence);
}
}
}

public void Encode(Transaction transaction, RlpStream stream, RlpBehaviors rlpBehaviors = RlpBehaviors.None, bool forSigning = false, bool isEip155Enabled = false, ulong chainId = 0)
{
int contentLength = GetContentLength(transaction, forSigning);
int sequenceLength = Rlp.LengthOfSequence(contentLength);

if ((rlpBehaviors & RlpBehaviors.SkipTypedWrapping) == 0)
{
stream.StartByteArray(sequenceLength + 1, false);
}

stream.WriteByte((byte)TxType.AccessList);
stream.StartSequence(contentLength);

EncodePayload(transaction, stream, rlpBehaviors);
EncodeSignature(transaction, stream, forSigning);
}

public int GetLength(Transaction transaction, RlpBehaviors rlpBehaviors, bool forSigning = false, bool isEip155Enabled = false, ulong chainId = 0)
{
int txContentLength = GetContentLength(transaction, forSigning);
int txPayloadLength = Rlp.LengthOfSequence(txContentLength);

bool isForTxRoot = rlpBehaviors.HasFlag(RlpBehaviors.SkipTypedWrapping);
int result = isForTxRoot
? (1 + txPayloadLength)
: Rlp.LengthOfSequence(1 + txPayloadLength);
return result;
}

private static void DecodePayload(Transaction transaction, RlpStream rlpStream, RlpBehaviors rlpBehaviors)
{
transaction.ChainId = rlpStream.DecodeULong();
transaction.Nonce = rlpStream.DecodeUInt256();
transaction.GasPrice = rlpStream.DecodeUInt256();
transaction.GasLimit = rlpStream.DecodeLong();
transaction.To = rlpStream.DecodeAddress();
transaction.Value = rlpStream.DecodeUInt256();
transaction.Data = rlpStream.DecodeByteArray();
transaction.AccessList = AccessListDecoder.Decode(rlpStream, rlpBehaviors);
}

private static void DecodePayload(Transaction transaction, ref Rlp.ValueDecoderContext decoderContext, RlpBehaviors rlpBehaviors)
{
transaction.ChainId = decoderContext.DecodeULong();
transaction.Nonce = decoderContext.DecodeUInt256();
transaction.GasPrice = decoderContext.DecodeUInt256();
transaction.GasLimit = decoderContext.DecodeLong();
transaction.To = decoderContext.DecodeAddress();
transaction.Value = decoderContext.DecodeUInt256();
transaction.Data = decoderContext.DecodeByteArrayMemory();
transaction.AccessList = AccessListDecoder.Decode(ref decoderContext, rlpBehaviors);
}

private static void DecodeSignature(Transaction transaction, RlpStream rlpStream, RlpBehaviors rlpBehaviors)
{
ulong v = rlpStream.DecodeULong();
ReadOnlySpan<byte> rBytes = rlpStream.DecodeByteArraySpan();
ReadOnlySpan<byte> sBytes = rlpStream.DecodeByteArraySpan();
transaction.Signature = SignatureBuilder.FromBytes(v + Signature.VOffset, rBytes, sBytes, rlpBehaviors) ?? transaction.Signature;
}

private static void DecodeSignature(Transaction transaction, ref Rlp.ValueDecoderContext decoderContext, RlpBehaviors rlpBehaviors)
{
ulong v = decoderContext.DecodeULong();
ReadOnlySpan<byte> rBytes = decoderContext.DecodeByteArraySpan();
ReadOnlySpan<byte> sBytes = decoderContext.DecodeByteArraySpan();
transaction.Signature = SignatureBuilder.FromBytes(v + Signature.VOffset, rBytes, sBytes, rlpBehaviors) ?? transaction.Signature;
}

private static void EncodePayload(Transaction transaction, RlpStream stream, RlpBehaviors rlpBehaviors)
{
stream.Encode(transaction.ChainId ?? 0);
stream.Encode(transaction.Nonce);
stream.Encode(transaction.GasPrice);
stream.Encode(transaction.GasLimit);
stream.Encode(transaction.To);
stream.Encode(transaction.Value);
stream.Encode(transaction.Data);
AccessListDecoder.Encode(stream, transaction.AccessList, rlpBehaviors);
}

private static void EncodeSignature(Transaction transaction, RlpStream stream, bool forSigning)
{
if (!forSigning)
{
if (transaction.Signature is null)
{
stream.Encode(0);
stream.Encode(Bytes.Empty);
stream.Encode(Bytes.Empty);
}
else
{
stream.Encode(transaction.Signature.RecoveryId);
stream.Encode(transaction.Signature.RAsSpan.WithoutLeadingZeros());
stream.Encode(transaction.Signature.SAsSpan.WithoutLeadingZeros());
}
}
}

private static int GetContentLength(Transaction transaction, bool forSigning)
{
int payloadLength = GetPayloadLength(transaction);
int signatureLength = GetSignatureLength(transaction, forSigning);

return payloadLength + signatureLength;
}

private static int GetPayloadLength(Transaction transaction)
{
return Rlp.LengthOf(transaction.Nonce)
+ Rlp.LengthOf(transaction.GasPrice)
+ Rlp.LengthOf(transaction.GasLimit)
+ Rlp.LengthOf(transaction.To)
+ Rlp.LengthOf(transaction.Value)
+ Rlp.LengthOf(transaction.Data)
+ Rlp.LengthOf(transaction.ChainId ?? 0)
+ AccessListDecoder.GetLength(transaction.AccessList, RlpBehaviors.None);
}

private static int GetSignatureLength(Transaction transaction, bool forSigning)
{
int contentLength = 0;

if (!forSigning)
{
if (transaction.Signature is null)
{
contentLength += 1;
contentLength += 1;
contentLength += 1;
}
else
{
contentLength += Rlp.LengthOf(transaction.Signature.RecoveryId);
contentLength += Rlp.LengthOf(transaction.Signature.RAsSpan.WithoutLeadingZeros());
contentLength += Rlp.LengthOf(transaction.Signature.SAsSpan.WithoutLeadingZeros());
}
}

return contentLength;
}
}
Loading