diff --git a/src/Nethermind/Ethereum.Basic.Test/TransactionTests.cs b/src/Nethermind/Ethereum.Basic.Test/TransactionTests.cs index 4d1b4cfea7d..bef75e44fe9 100644 --- a/src/Nethermind/Ethereum.Basic.Test/TransactionTests.cs +++ b/src/Nethermind/Ethereum.Basic.Test/TransactionTests.cs @@ -50,9 +50,9 @@ public void Test(TransactionTest test) Transaction decodedSigned = Rlp.Decode(test.Signed); ethereumEcdsa.Sign(test.PrivateKey, decodedUnsigned, false); - Assert.That(decodedUnsigned.Signature.R, Is.EqualTo(decodedSigned.Signature.R), "R"); - BigInteger expectedS = decodedSigned.Signature.S.ToUnsignedBigInteger(); - BigInteger actualS = decodedUnsigned.Signature.S.ToUnsignedBigInteger(); + Assert.That(decodedUnsigned.Signature.R.Span.SequenceEqual(decodedSigned.Signature.R.Span), "R"); + BigInteger expectedS = decodedSigned.Signature.S.Span.ToUnsignedBigInteger(); + BigInteger actualS = decodedUnsigned.Signature.S.Span.ToUnsignedBigInteger(); BigInteger otherS = EthereumEcdsa.LowSTransform - actualS; // test does not use normalized signature @@ -62,7 +62,7 @@ public void Test(TransactionTest test) } ulong vToCompare = decodedUnsigned.Signature.V; - if (otherS == decodedSigned.Signature.S.ToUnsignedBigInteger()) + if (otherS == decodedSigned.Signature.S.Span.ToUnsignedBigInteger()) { vToCompare = vToCompare == 27ul ? 28ul : 27ul; } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Consensus/ClefSignerTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Consensus/ClefSignerTests.cs index fec0f25713b..f0729770df6 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Consensus/ClefSignerTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Consensus/ClefSignerTests.cs @@ -29,7 +29,7 @@ public async Task Sign_SigningHash_RequestHasCorrectParameters() var result = sut.Sign(Keccak.Zero); - Assert.That(new Signature(returnValue).Bytes, Is.EqualTo(result.Bytes)); + Assert.That(new Signature(returnValue).Bytes.SequenceEqual(result.Bytes)); } [Test] diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Consensus/NullSignerTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Consensus/NullSignerTests.cs index cfac44513dd..628ff7f9c60 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Consensus/NullSignerTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Consensus/NullSignerTests.cs @@ -27,7 +27,7 @@ public async Task Test_signing() { NullSigner signer = NullSigner.Instance; await signer.Sign((Transaction)null!); - signer.Sign((Hash256)null!).Bytes.Should().HaveCount(64); + signer.Sign((Hash256)null!).Bytes.Length.Should().Be(64); } } } diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Consensus/SignerTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Consensus/SignerTests.cs index 23957d53a0c..edd88c1a722 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Consensus/SignerTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Consensus/SignerTests.cs @@ -64,7 +64,7 @@ public async Task Test_signing() { Signer signer = new(1, TestItem.PrivateKeyA, LimboLogs.Instance); await signer.Sign(Build.A.Transaction.TestObject); - signer.Sign(Keccak.Zero).Bytes.Should().HaveCount(64); + signer.Sign(Keccak.Zero).Bytes.Length.Should().Be(64); } } } diff --git a/src/Nethermind/Nethermind.Consensus.Clique/CliqueSealer.cs b/src/Nethermind/Nethermind.Consensus.Clique/CliqueSealer.cs index c445b5e591f..48e1d01c63f 100644 --- a/src/Nethermind/Nethermind.Consensus.Clique/CliqueSealer.cs +++ b/src/Nethermind/Nethermind.Consensus.Clique/CliqueSealer.cs @@ -77,8 +77,8 @@ public CliqueSealer(ISigner signer, ICliqueConfig config, ISnapshotManager snaps } // Copy signature bytes (R and S) - byte[] signatureBytes = signature.Bytes; - Array.Copy(signatureBytes, 0, header.ExtraData, header.ExtraData.Length - Clique.ExtraSealLength, signatureBytes.Length); + ReadOnlySpan signatureBytes = signature.Bytes; + signatureBytes.CopyTo(header.ExtraData.AsSpan(header.ExtraData.Length - Clique.ExtraSealLength)); // Copy signature's recovery id (V) byte recoveryId = signature.RecoveryId; header.ExtraData[^1] = recoveryId; diff --git a/src/Nethermind/Nethermind.Core.Test/Crypto/SignatureTests.cs b/src/Nethermind/Nethermind.Core.Test/Crypto/SignatureTests.cs index b521707ded0..d810fd16248 100644 --- a/src/Nethermind/Nethermind.Core.Test/Crypto/SignatureTests.cs +++ b/src/Nethermind/Nethermind.Core.Test/Crypto/SignatureTests.cs @@ -41,7 +41,7 @@ public void can_recover_from_message() var signatureObject = new Signature(signatureSlice, recoveryId); var keccak = Keccak.Compute(Bytes.Concat(messageType, data)); Span publicKey = stackalloc byte[65]; - bool result = SpanSecP256k1.RecoverKeyFromCompact(publicKey, keccak.Bytes, signatureObject.Bytes, signatureObject.RecoveryId, false); + bool result = SpanSecP256k1.RecoverKeyFromCompact(publicKey, keccak.Bytes, signatureObject.Bytes.ToArray(), signatureObject.RecoveryId, false); result.Should().BeTrue(); } } diff --git a/src/Nethermind/Nethermind.Core/Crypto/Signature.cs b/src/Nethermind/Nethermind.Core/Crypto/Signature.cs index 7f64c7b56a7..36823e91268 100644 --- a/src/Nethermind/Nethermind.Core/Crypto/Signature.cs +++ b/src/Nethermind/Nethermind.Core/Crypto/Signature.cs @@ -2,22 +2,25 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; +using System.Buffers; using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; using Nethermind.Core.Attributes; using Nethermind.Core.Extensions; using Nethermind.Int256; namespace Nethermind.Core.Crypto { - public class Signature : IEquatable + public class Signature : MemoryManager, IEquatable { public const int VOffset = 27; + private Vector512 _signature; public Signature(ReadOnlySpan bytes, int recoveryId) { ArgumentOutOfRangeException.ThrowIfNotEqual(bytes.Length, 64); - bytes.CopyTo(Bytes.AsSpan()); + bytes.CopyTo(Bytes); V = (ulong)recoveryId + VOffset; } @@ -25,7 +28,7 @@ public Signature(ReadOnlySpan bytes) { ArgumentOutOfRangeException.ThrowIfNotEqual(bytes.Length, 65); - bytes[..64].CopyTo(Bytes.AsSpan()); + bytes[..64].CopyTo(Bytes); V = bytes[64]; } @@ -33,8 +36,9 @@ public Signature(ReadOnlySpan r, ReadOnlySpan s, ulong v) { ArgumentOutOfRangeException.ThrowIfLessThan(v, (ulong)VOffset); - r.CopyTo(Bytes.AsSpan(32 - r.Length, r.Length)); - s.CopyTo(Bytes.AsSpan(64 - s.Length, s.Length)); + Span span = Bytes; + r.CopyTo(span.Slice(32 - r.Length, r.Length)); + s.CopyTo(span.Slice(64 - s.Length, s.Length)); V = v; } @@ -42,8 +46,9 @@ public Signature(in UInt256 r, in UInt256 s, ulong v) { ArgumentOutOfRangeException.ThrowIfLessThan(v, (ulong)VOffset); - r.ToBigEndian(Bytes.AsSpan(0, 32)); - s.ToBigEndian(Bytes.AsSpan(32, 32)); + Span span = Bytes; + r.ToBigEndian(span.Slice(0, 32)); + s.ToBigEndian(span.Slice(32, 32)); V = v; } @@ -52,18 +57,19 @@ public Signature(string hexString) : this(Core.Extensions.Bytes.FromHexString(hexString)) { } + public Span Bytes => MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref _signature, 1)); + public override Memory Memory => CreateMemory(64); - public byte[] Bytes { get; } = new byte[64]; public ulong V { get; set; } public ulong? ChainId => V < 35 ? null : (ulong?)(V + (V % 2) - 36) / 2; public byte RecoveryId => V <= VOffset + 1 ? (byte)(V - VOffset) : (byte)(1 - V % 2); - public byte[] R => Bytes.Slice(0, 32); - public Span RAsSpan => Bytes.AsSpan(0, 32); - public byte[] S => Bytes.Slice(32, 32); - public Span SAsSpan => Bytes.AsSpan(32, 32); + public Memory R => Memory.Slice(0, 32); + public ReadOnlySpan RAsSpan => Bytes.Slice(0, 32); + public Memory S => Memory.Slice(32, 32); + public ReadOnlySpan SAsSpan => Bytes.Slice(32, 32); [Todo("Change signature to store 65 bytes and just slice it for normal Bytes.")] public byte[] BytesWithRecovery @@ -71,7 +77,7 @@ public byte[] BytesWithRecovery get { var result = new byte[65]; - Array.Copy(Bytes, result, 64); + Bytes.CopyTo(result); result[64] = RecoveryId; return result; } @@ -87,7 +93,7 @@ public bool Equals(Signature? other) { if (other is null) return false; if (ReferenceEquals(this, other)) return true; - return Core.Extensions.Bytes.AreEqual(Bytes, other.Bytes) && V == other.V; + return _signature == other._signature && V == other.V; } public override bool Equals(object? obj) @@ -102,5 +108,11 @@ public override int GetHashCode() { return MemoryMarshal.Read(Bytes); } + + public void Dispose() { } + protected override void Dispose(bool disposing) { } + public override Span GetSpan() => Bytes; + public override MemoryHandle Pin(int elementIndex = 0) => default; + public override void Unpin() { } } } diff --git a/src/Nethermind/Nethermind.Core/Extensions/Bytes.cs b/src/Nethermind/Nethermind.Core/Extensions/Bytes.cs index 39d8429cec8..8a1705705cb 100644 --- a/src/Nethermind/Nethermind.Core/Extensions/Bytes.cs +++ b/src/Nethermind/Nethermind.Core/Extensions/Bytes.cs @@ -346,6 +346,14 @@ public static byte[] Concat(byte[] bytes, byte suffix) return result; } + public static byte[] Concat(ReadOnlySpan bytes, byte suffix) + { + byte[] result = new byte[bytes.Length + 1]; + result[^1] = suffix; + bytes.CopyTo(result); + return result; + } + public static byte[] Reverse(byte[] bytes) { byte[] result = new byte[bytes.Length]; diff --git a/src/Nethermind/Nethermind.Core/Transaction.cs b/src/Nethermind/Nethermind.Core/Transaction.cs index 8018975a0ce..8d7b10d2e76 100644 --- a/src/Nethermind/Nethermind.Core/Transaction.cs +++ b/src/Nethermind/Nethermind.Core/Transaction.cs @@ -231,7 +231,7 @@ public string ToString(string indent) builder.AppendLine($"{indent}Nonce: {Nonce}"); builder.AppendLine($"{indent}Value: {Value}"); builder.AppendLine($"{indent}Data: {(Data.AsArray() ?? []).ToHexString()}"); - builder.AppendLine($"{indent}Signature: {(Signature?.Bytes ?? []).ToHexString()}"); + builder.AppendLine($"{indent}Signature: {Signature?.Bytes.ToHexString()}"); builder.AppendLine($"{indent}V: {Signature?.V}"); builder.AppendLine($"{indent}ChainId: {Signature?.ChainId}"); builder.AppendLine($"{indent}Timestamp: {Timestamp}"); diff --git a/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/AuthorizationListForRpc.cs b/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/AuthorizationListForRpc.cs index ec6f7407eef..38bc0484741 100644 --- a/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/AuthorizationListForRpc.cs +++ b/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/AuthorizationListForRpc.cs @@ -56,8 +56,8 @@ authorizationList is null tuple.Nonce, tuple.CodeAddress, tuple.AuthoritySignature.RecoveryId, - new UInt256(tuple.AuthoritySignature.S), - new UInt256(tuple.AuthoritySignature.R)))); + new UInt256(tuple.AuthoritySignature.S.Span), + new UInt256(tuple.AuthoritySignature.R.Span)))); public AuthorizationTuple[] ToAuthorizationList() => _tuples .Select(static tuple => new AuthorizationTuple( diff --git a/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/LegacyTransactionForRpc.cs b/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/LegacyTransactionForRpc.cs index 3b77fc2dc88..d3940047940 100644 --- a/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/LegacyTransactionForRpc.cs +++ b/src/Nethermind/Nethermind.Facade/Eth/RpcTransaction/LegacyTransactionForRpc.cs @@ -73,9 +73,19 @@ public LegacyTransactionForRpc(Transaction transaction, int? txIndex = null, Has GasPrice = transaction.GasPrice; ChainId = transaction.ChainId; - R = new UInt256(transaction.Signature?.R ?? [], true); - S = new UInt256(transaction.Signature?.S ?? [], true); - V = transaction.Signature?.V ?? 0; + Signature? signature = transaction.Signature; + if (signature is null) + { + R = UInt256.Zero; + S = UInt256.Zero; + V = 0; + } + else + { + R = new UInt256(signature.R.Span, true); + S = new UInt256(signature.S.Span, true); + V = signature.V; + } } public override Transaction ToTransaction() diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs index 50a822efecf..643bb241982 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcSimulateTestsBase.cs @@ -127,7 +127,7 @@ protected static byte[] GenerateTransactionDataForEcRecover(Hash256 keccak, Sign { AbiDefinition call = new AbiDefinitionParser().Parse(GetEcRecoverContractJsonAbi(name)); AbiEncodingInfo functionInfo = call.GetFunction(name).GetCallInfo(); - return AbiEncoder.Instance.Encode(functionInfo.EncodingStyle, functionInfo.Signature, keccak, signature.V, signature.R, signature.S); + return AbiEncoder.Instance.Encode(functionInfo.EncodingStyle, functionInfo.Signature, keccak, signature.V, signature.R.ToArray(), signature.S.ToArray()); } private static Address? ParseEcRecoverAddress(byte[] data, string name = "recover") diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index 1a1989f322f..876fb0ba938 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -264,7 +264,7 @@ public ResultWrapper eth_getCode(Address address, BlockParameter? blockP : []); } - public ResultWrapper eth_sign(Address addressData, byte[] message) + public ResultWrapper> eth_sign(Address addressData, byte[] message) { Signature sig; try @@ -277,15 +277,15 @@ public ResultWrapper eth_sign(Address addressData, byte[] message) } catch (SecurityException e) { - return ResultWrapper.Fail(e.Message, ErrorCodes.AccountLocked); + return ResultWrapper>.Fail(e.Message, ErrorCodes.AccountLocked); } catch (Exception) { - return ResultWrapper.Fail($"Unable to sign as {addressData}"); + return ResultWrapper>.Fail($"Unable to sign as {addressData}"); } if (_logger.IsTrace) _logger.Trace($"eth_sign request {addressData}, {message}, result: {sig}"); - return ResultWrapper.Success(sig.Bytes); + return ResultWrapper>.Success(sig.Memory); } public virtual Task> eth_sendTransaction(TransactionForRpc rpcTx) diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs index 4e7f22a9665..70f98a767c3 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using System.Collections.Generic; using System.Threading.Tasks; using Nethermind.Blockchain.Find; @@ -132,7 +133,7 @@ public interface IEthRpcModule : IRpcModule ResultWrapper eth_getCode(Address address, BlockParameter? blockParameter = null); [JsonRpcMethod(IsImplemented = false, Description = "Signs a transaction", IsSharable = true)] - ResultWrapper eth_sign(Address addressData, byte[] message); + ResultWrapper> eth_sign(Address addressData, byte[] message); [JsonRpcMethod(IsImplemented = true, Description = "Send a transaction to the tx pool and broadcasting", diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Parity/ParityTransaction.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Parity/ParityTransaction.cs index e1217254547..5aeb8b1d20a 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Parity/ParityTransaction.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Parity/ParityTransaction.cs @@ -1,12 +1,13 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; +using System.Text.Json.Serialization; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; using Nethermind.Int256; using Nethermind.Evm; -using System.Text.Json.Serialization; namespace Nethermind.JsonRpc.Modules.Parity { @@ -34,8 +35,8 @@ public class ParityTransaction public ulong? ChainId { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public object Condition { get; set; } - public byte[] R { get; set; } - public byte[] S { get; set; } + public Memory R { get; set; } + public Memory S { get; set; } public UInt256 V { get; set; } public UInt256 StandardV { get; set; } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Personal/IPersonalRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Personal/IPersonalRpcModule.cs index 81805f149bd..8b280b7a07e 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Personal/IPersonalRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Personal/IPersonalRpcModule.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Facade.Eth.RpcTransaction; @@ -36,6 +37,6 @@ public interface IPersonalRpcModule : IRpcModule [JsonRpcMethod(Description = "The sign method calculates an Ethereum specific signature with: sign(keccack256(\"\x19Ethereum Signed Message:\n\" + len(message) + message))).", IsImplemented = false, ExampleResponse = "0xa3f20717a250c2b0b729b7e5becbff67fdaef7e0699da4de7ca5895b02a170a12d887fd3b17bfdce3481f10bea41f45ba9f709d39ce8325427b57afcfc994cee1b")] - ResultWrapper personal_sign([JsonRpcParameter(ExampleValue = "[\"0xdeadbeaf\", \"0x9b2055d370f73ec7d8a03e965129118dc8f5bf83\"]")] byte[] message, Address address, string passphrase = null); + ResultWrapper> personal_sign([JsonRpcParameter(ExampleValue = "[\"0xdeadbeaf\", \"0x9b2055d370f73ec7d8a03e965129118dc8f5bf83\"]")] byte[] message, Address address, string passphrase = null); } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Personal/PersonalRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Personal/PersonalRpcModule.cs index db941f73ed6..0967e9bd03f 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Personal/PersonalRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Personal/PersonalRpcModule.cs @@ -15,7 +15,6 @@ namespace Nethermind.JsonRpc.Modules.Personal { public class PersonalRpcModule : IPersonalRpcModule { - private readonly Encoding _messageEncoding = Encoding.UTF8; private readonly IEcdsa _ecdsa; private readonly IWallet _wallet; private readonly IKeyStore _keyStore; @@ -84,7 +83,7 @@ private static byte[] ToEthSignedMessage(byte[] message) } [RequiresSecurityReview("Consider removing any operations that allow to provide passphrase in JSON RPC")] - public ResultWrapper personal_sign(byte[] message, Address address, string passphrase = null) + public ResultWrapper> personal_sign(byte[] message, Address address, string passphrase = null) { if (!_wallet.IsUnlocked(address)) { @@ -96,7 +95,7 @@ public ResultWrapper personal_sign(byte[] message, Address address, stri } message = ToEthSignedMessage(message); - return ResultWrapper.Success(_wallet.Sign(Keccak.Compute(message), address).Bytes); + return ResultWrapper>.Success(_wallet.Sign(Keccak.Compute(message), address).Memory); } } } diff --git a/src/Nethermind/Nethermind.Network.Discovery/Serializers/DiscoveryMsgSerializerBase.cs b/src/Nethermind/Nethermind.Network.Discovery/Serializers/DiscoveryMsgSerializerBase.cs index ff17a82c6f9..03b443249b7 100644 --- a/src/Nethermind/Nethermind.Network.Discovery/Serializers/DiscoveryMsgSerializerBase.cs +++ b/src/Nethermind/Nethermind.Network.Discovery/Serializers/DiscoveryMsgSerializerBase.cs @@ -48,7 +48,7 @@ protected void Serialize(byte type, Span data, IByteBuffer byteBuffer) Signature signature = _ecdsa.Sign(_privateKey, toSign); byteBuffer.SetWriterIndex(startWriteIndex + 32); - byteBuffer.WriteBytes(signature.Bytes, 0, 64); + byteBuffer.WriteBytes(signature.Bytes); byteBuffer.WriteByte(signature.RecoveryId); byteBuffer.SetReaderIndex(startReadIndex + 32); @@ -76,7 +76,7 @@ protected void AddSignatureAndMdc(IByteBuffer byteBuffer, int dataLength) Signature signature = _ecdsa.Sign(_privateKey, toSign); byteBuffer.SetWriterIndex(startWriteIndex + 32); - byteBuffer.WriteBytes(signature.Bytes, 0, 64); + byteBuffer.WriteBytes(signature.Bytes); byteBuffer.WriteByte(signature.RecoveryId); byteBuffer.SetWriterIndex(startWriteIndex + length); diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/Eip7702/AuthorizationTupleDecoder.cs b/src/Nethermind/Nethermind.Serialization.Rlp/Eip7702/AuthorizationTupleDecoder.cs index 192f4a64e49..aabe1727043 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/Eip7702/AuthorizationTupleDecoder.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/Eip7702/AuthorizationTupleDecoder.cs @@ -78,8 +78,8 @@ public void Encode(RlpStream stream, AuthorizationTuple item, RlpBehaviors rlpBe stream.Encode(item.CodeAddress); stream.Encode(item.Nonce); stream.Encode(item.AuthoritySignature.V - Signature.VOffset); - stream.Encode(new UInt256(item.AuthoritySignature.R, true)); - stream.Encode(new UInt256(item.AuthoritySignature.S, true)); + stream.Encode(new UInt256(item.AuthoritySignature.R.Span, true)); + stream.Encode(new UInt256(item.AuthoritySignature.S.Span, true)); } public NettyRlpStream EncodeWithoutSignature(UInt256 chainId, Address codeAddress, ulong nonce) @@ -106,8 +106,8 @@ public void EncodeWithoutSignature(RlpStream stream, UInt256 chainId, Address co private static int GetContentLength(AuthorizationTuple tuple) => GetContentLengthWithoutSig(tuple.ChainId, tuple.CodeAddress, tuple.Nonce) + Rlp.LengthOf(tuple.AuthoritySignature.V - Signature.VOffset) - + Rlp.LengthOf(new UInt256(tuple.AuthoritySignature.R.AsSpan(), true)) - + Rlp.LengthOf(new UInt256(tuple.AuthoritySignature.S.AsSpan(), true)); + + Rlp.LengthOf(new UInt256(tuple.AuthoritySignature.R.Span, true)) + + Rlp.LengthOf(new UInt256(tuple.AuthoritySignature.S.Span, true)); private static int GetContentLengthWithoutSig(UInt256 chainId, Address codeAddress, ulong nonce) => Rlp.LengthOf(chainId)