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

add changes for flat encoding #7516

Draft
wants to merge 6 commits into
base: pectra_fix_7702_after_merge
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
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 @@ -32,7 +32,7 @@ public void ProcessRequests(Block block, IWorldState state, TxReceipt[] receipts
requestsList.AddRange(_consolidationRequestsProcessor.ReadConsolidationRequests(block, state, spec));

ConsensusRequest[] requests = requestsList.ToArray();
Hash256 root = new RequestsTrie(requests).RootHash;
Hash256 root = requests.CalculateRootHash();
block.Body.Requests = requests;
block.Header.RequestsRoot = root;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ private static bool ValidateRequestsHashMatches(BlockHeader header, BlockBody bo
return header.RequestsRoot is null;
}

return (requestsRoot = new RequestsTrie(body.Requests).RootHash) == header.RequestsRoot;
return (requestsRoot = body.Requests.CalculateRootHash()) == header.RequestsRoot;
}

private static string Invalid(Block block) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ public BlockBuilder WithConsensusRequests(params ConsensusRequest[]? requests)

TestObjectInternal.Header.RequestsRoot = requests is null
? null
: new RequestsTrie(requests).RootHash;
: requests.CalculateRootHash();

return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System;
using System.Text.Json.Serialization;


namespace Nethermind.Core.ConsensusRequests;

public enum ConsensusRequestsType : byte
Expand All @@ -18,6 +19,21 @@ public abstract class ConsensusRequest
{
[JsonIgnore]
public ConsensusRequestsType Type { get; protected set; }

/// <summary>
/// Encodes the request into a byte array
/// reference: https://eips.ethereum.org/EIPS/eip-7685
/// </summary>
/// <returns> request = request_type ++ request_data </returns>
public abstract byte[] Encode();

/// <summary>
/// Decodes the request from a byte array
/// reference: https://eips.ethereum.org/EIPS/eip-7685
/// </summary>
/// <param name="data"> request = request_type ++ request_data </param>
/// <returns> request </returns>
public abstract ConsensusRequest Decode(byte[] data);
}

public static class ConsensusRequestExtensions
Expand Down Expand Up @@ -75,4 +91,33 @@ public static (Deposit[]? deposits, WithdrawalRequest[]? withdrawalRequests, Con

return (deposits, withdrawalRequests, consolidationRequests);
}

public static byte[][] Encode(this ConsensusRequest[]? requests)
{
if (requests is null) return Array.Empty<byte[]>();
byte[][] requestsEncoded = new byte[requests.Length][];
for (int i = 0; i < requests.Length; i++)
{
requestsEncoded[i] = requests[i].Encode();
}
return requestsEncoded;
}

public static ConsensusRequest Decode(byte[] data)
{
if (data.Length < 2)
{
throw new ArgumentException("Invalid data length");
}

ConsensusRequestsType type = (ConsensusRequestsType)data[0];
return type switch
{
ConsensusRequestsType.Deposit => new Deposit().Decode(data),
ConsensusRequestsType.WithdrawalRequest => new WithdrawalRequest().Decode(data),
ConsensusRequestsType.ConsolidationRequest => new ConsolidationRequest().Decode(data),
_ => throw new ArgumentException("Invalid request type")
};
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only
using System;
using System.Linq;
using Nethermind.Core.Extensions;

namespace Nethermind.Core.ConsensusRequests;
Expand All @@ -27,5 +28,26 @@ public string ToString(string indentation) => @$"{indentation}{nameof(Consolidat
{nameof(TargetPubkey)}: {TargetPubkey?.Span.ToHexString()},
}}";

public override byte[] Encode()
{
byte[] type = new byte[] { (byte)Type };
return type
.Concat(SourceAddress?.Bytes ?? Array.Empty<byte>())
.Concat(SourcePubkey?.ToArray() ?? Array.Empty<byte>())
.Concat(TargetPubkey?.ToArray() ?? Array.Empty<byte>()).ToArray();
}

public override ConsensusRequest Decode(byte[] data)
{
if (data.Length < 2)
{
throw new ArgumentException("Invalid data length");
}

Type = (ConsensusRequestsType)data[0];
SourceAddress = new Address(data.Slice(1, Address.Size));
SourcePubkey = data.AsMemory().Slice(1 + Address.Size);
TargetPubkey = data.AsMemory().Slice(1 + Address.Size + SourcePubkey.Value.Length);
return this;
}
}
27 changes: 27 additions & 0 deletions src/Nethermind/Nethermind.Core/ConsensusRequests/Deposit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using System.Linq;
using Nethermind.Core.Extensions;

namespace Nethermind.Core.ConsensusRequests;
Expand Down Expand Up @@ -32,5 +33,31 @@ public string ToString(string indentation) => @$"{indentation}{nameof(Deposit)}
{nameof(Signature)}: {Signature?.ToHexString()},
{nameof(Pubkey)}: {Pubkey?.Span.ToHexString()}}}";

public override byte[] Encode()
{
byte[] type = new byte[] { (byte)Type };
return type
.Concat(Pubkey?.ToArray() ?? Array.Empty<byte>())
.Concat(WithdrawalCredentials ?? Array.Empty<byte>())
.Concat(BitConverter.GetBytes(Amount))
.Concat(Signature ?? Array.Empty<byte>())
.Concat(Index.HasValue ? BitConverter.GetBytes(Index.Value) : Array.Empty<byte>()).ToArray();
}

public override ConsensusRequest Decode(byte[] data)
{
if (data.Length < 2)
{
throw new ArgumentException("Invalid data length");
}

Type = (ConsensusRequestsType)data[0];
Pubkey = data.AsMemory()[1..];
WithdrawalCredentials = data.Slice(1 + Pubkey.Value.Length, 32);
Amount = BitConverter.ToUInt64(data, 1 + Pubkey.Value.Length + 32);
Signature = data.Slice(1 + Pubkey.Value.Length + 32 + sizeof(ulong));
Index = data.Length > 1 + Pubkey.Value.Length + 32 + sizeof(ulong) + Signature!.Length ? BitConverter.ToUInt64(data, 1 + Pubkey.Value.Length + 32 + sizeof(ulong) + Signature!.Length) : null;
return this;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

using System;
using Nethermind.Core.Extensions;
using System.Text;
using System.Linq;

namespace Nethermind.Core.ConsensusRequests;

Expand All @@ -30,4 +30,26 @@ public string ToString(string indentation) => @$"{indentation}{nameof(Withdrawal
{nameof(Amount)}: {Amount}}}";


public override byte[] Encode()
{
byte[] type = new byte[] { (byte)Type };
return type
.Concat(SourceAddress?.Bytes ?? Array.Empty<byte>())
.Concat(ValidatorPubkey?.ToArray() ?? Array.Empty<byte>())
.Concat(BitConverter.GetBytes(Amount)).ToArray();
}

public override ConsensusRequest Decode(byte[] data)
{
if (data.Length < 2)
{
throw new ArgumentException("Invalid data length");
}

Type = (ConsensusRequestsType)data[0];
SourceAddress = new Address(data.Slice(1, Address.Size));
ValidatorPubkey = data.AsMemory().Slice(1 + Address.Size);
Amount = BitConverter.ToUInt64(data, 1 + Address.Size + ValidatorPubkey.Value.Length);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public override bool TryGetBlock([NotNullWhen(true)] out Block? block, UInt256?
}

block.Body.Requests = requests;
block.Header.RequestsRoot = new RequestsTrie(requests).RootHash;
block.Header.RequestsRoot = requests.CalculateRootHash();
}
else
{
Expand Down
17 changes: 5 additions & 12 deletions src/Nethermind/Nethermind.Serialization.Rlp/BlockDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,16 +116,14 @@ public class BlockDecoder : IRlpValueDecoder<Block>, IRlpStreamDecoder<Block>

if (lengthWasRead)
{
int requestsLength = rlpStream.ReadSequenceLength();
int requestsCheck = rlpStream.Position + requestsLength;
// read an array of byte arrays
byte[][] requestsEncoded = rlpStream.DecodeByteArrays();
Copy link
Member

Choose a reason for hiding this comment

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

unneeded, make it lazy, call internal decoders based on type and progressing the stream

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Pushed a commit

requests = new();

while (rlpStream.Position < requestsCheck)
for (int i = 0; i < requestsEncoded.Length; i++)
{
requests.Add(Rlp.Decode<ConsensusRequest>(rlpStream));
requests.Add(ConsensusRequestExtensions.Decode(requestsEncoded[i]));
}

rlpStream.Check(requestsCheck);
}
}

Expand Down Expand Up @@ -359,12 +357,7 @@ public void Encode(RlpStream stream, Block? item, RlpBehaviors rlpBehaviors = Rl

if (requestsLength.HasValue)
{
stream.StartSequence(requestsLength.Value);

for (int i = 0; i < item.Requests.Length; i++)
{
stream.Encode(item.Requests[i]);
}
stream.Encode(item.Requests.Encode());
}
}

Expand Down
15 changes: 15 additions & 0 deletions src/Nethermind/Nethermind.State/Proofs/RequestsTrie.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,18 @@ public static Hash256 CalculateRoot(ConsensusRequest[] requests)
return rootHash;
}
}


public static class ConsensusRequestExtensions
{
public static Hash256 CalculateRootHash(this ConsensusRequest[]? requests)
{
Rlp[] encodedRequests = new Rlp[requests!.Length];
for (int i = 0; i < encodedRequests.Length; i++)
{
encodedRequests[i] = Rlp.Encode(requests![i].Encode());
}

return Keccak.Compute(Rlp.Encode(encodedRequests).Bytes);
}
}
Loading