Skip to content

Commit

Permalink
add sample engineAPI support
Browse files Browse the repository at this point in the history
  • Loading branch information
rjnrohit committed Mar 12, 2024
1 parent 1addf34 commit 4e0cb0f
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 1 deletion.
56 changes: 55 additions & 1 deletion src/Nethermind/Nethermind.Merge.Plugin/Data/ExecutionPayload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public ExecutionPayload(Block block)
Withdrawals = block.Withdrawals;

SetTransactions(block.Transactions);
SetInclusionList(block?.InclusionList);
}

public UInt256 BaseFeePerGas { get; set; }
Expand Down Expand Up @@ -69,6 +70,7 @@ public ExecutionPayload(Block block)
public ulong Timestamp { get; set; }

private byte[][] _encodedTransactions = Array.Empty<byte[]>();
private byte[][]? _encodedInclusionList =null;

/// <summary>
/// Gets or sets an array of RLP-encoded transaction where each item is a byte list (data)
Expand All @@ -92,6 +94,20 @@ public byte[][] Transactions
public Withdrawal[]? Withdrawals { get; set; }


/// <summary>
/// Gets or sets <see cref="Inclusion List"/> as defined in
/// <see href="https://eips.ethereum.org/EIPS/eip-7547">EIP-7547</see>.
/// </summary>
public byte[][]? InclusionList
{
get { return _encodedInclusionList; }
set
{
_encodedInclusionList = value;
_inclusionList = null;
}
}

/// <summary>
/// Gets or sets <see cref="Block.BlobGasUsed"/> as defined in
/// <see href="https://eips.ethereum.org/EIPS/eip-4844">EIP-4844</see>.
Expand Down Expand Up @@ -124,6 +140,7 @@ public virtual bool TryGetBlock(out Block? block, UInt256? totalDifficulty = nul
try
{
var transactions = GetTransactions();
var inclusionList = GetInclusionList();
var header = new BlockHeader(
ParentHash,
Keccak.OfAnEmptySequenceRlp,
Expand All @@ -146,10 +163,11 @@ public virtual bool TryGetBlock(out Block? block, UInt256? totalDifficulty = nul
IsPostMerge = true,
TotalDifficulty = totalDifficulty,
TxRoot = TxTrie.CalculateRoot(transactions),
InclusionListTxRoot = inclusionList is null ? null : TxTrie.CalculateRoot(inclusionList),
WithdrawalsRoot = Withdrawals is null ? null : new WithdrawalTrie(Withdrawals).RootHash,
};

block = new(header, transactions, Array.Empty<BlockHeader>(), Withdrawals);
block = new(header, transactions, Array.Empty<BlockHeader>(), Withdrawals, inclusionList);

return true;
}
Expand All @@ -161,6 +179,7 @@ public virtual bool TryGetBlock(out Block? block, UInt256? totalDifficulty = nul
}

private Transaction[]? _transactions = null;
private byte[][]? _inclusionList = null;

/// <summary>
/// Decodes and returns an array of <see cref="Transaction"/> from <see cref="Transactions"/>.
Expand Down Expand Up @@ -191,6 +210,41 @@ public void SetTransactions(params Transaction[] transactions)
_transactions = transactions;
}


/// <summary>
/// Decodes and returns an array of <see cref="Transaction"/> from <see cref="InclusionList"/>.
/// </summary>
public Transaction[]? GetInclusionList() => (_inclusionList ??= InclusionList)?.Select((t, i) =>
{
try
{
return Rlp.Decode<Transaction>(t, RlpBehaviors.SkipTypedWrapping);
}
catch (RlpException e)
{
throw new RlpException($"Transaction {i} is not valid", e);
}
}).ToArray();


/// <summary>
/// Decodes and returns an array of <see cref="Transaction"/> from <see cref="InclusionList"/>.
/// </summary>
/// <Param name="inclusionList">An array of transactions to encode.</Param>
public void SetInclusionList(params Transaction[]? inclusionList){

if (inclusionList is null)
{
InclusionList = null;
return;
}

InclusionList = inclusionList
.Select(t => Rlp.Encode(t, RlpBehaviors.SkipTypedWrapping).Bytes)
.ToArray();
}


public override string ToString() => $"{BlockNumber} ({BlockHash.ToShortString()})";

ExecutionPayload IExecutionPayloadParams.ExecutionPayload => this;
Expand Down
15 changes: 15 additions & 0 deletions src/Nethermind/Nethermind.Merge.Plugin/Data/ExecutionPayloadV4.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using Nethermind.Core.Specs;

namespace Nethermind.Merge.Plugin.Data;

/// <summary>
/// Represent an object mapping the <c>ExecutionPayloadV4</c> structure of the beacon chain spec.
/// </summary>
public class ExecutionPayloadV4: ExecutionPayloadV3
{
public override bool ValidateFork(ISpecProvider specProvider) =>
specProvider.GetSpec(BlockNumber, Timestamp).IsEip7547Enabled;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System.Threading.Tasks;
using Nethermind.Consensus;
using Nethermind.Consensus.Producers;
using Nethermind.Core.Crypto;
using Nethermind.JsonRpc;
using Nethermind.Merge.Plugin.Data;
using Nethermind.Merge.Plugin.Handlers;

namespace Nethermind.Merge.Plugin;

public partial class EngineRpcModule : IEngineRpcModule
{
private readonly IAsyncHandler<byte[], GetPayloadV3Result?> _getPayloadHandlerV4;

Check failure on line 16 in src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.InclusionList.cs

View workflow job for this annotation

GitHub Actions / Build (release, Nethermind)

Field 'EngineRpcModule._getPayloadHandlerV4' is never assigned to, and will always have its default value null

Check failure on line 16 in src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.InclusionList.cs

View workflow job for this annotation

GitHub Actions / Build (release, Nethermind)

Field 'EngineRpcModule._getPayloadHandlerV4' is never assigned to, and will always have its default value null

Check failure on line 16 in src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.InclusionList.cs

View workflow job for this annotation

GitHub Actions / Build (debug, Nethermind)

Field 'EngineRpcModule._getPayloadHandlerV4' is never assigned to, and will always have its default value null

Check failure on line 16 in src/Nethermind/Nethermind.Merge.Plugin/EngineRpcModule.InclusionList.cs

View workflow job for this annotation

GitHub Actions / Build (debug, Nethermind)

Field 'EngineRpcModule._getPayloadHandlerV4' is never assigned to, and will always have its default value null

public Task<ResultWrapper<ForkchoiceUpdatedV1Result>> engine_forkchoiceUpdatedV4(ForkchoiceStateV1 forkchoiceState, PayloadAttributes? payloadAttributes = null)
=> ForkchoiceUpdated(forkchoiceState, payloadAttributes, EngineApiVersions.Cancun);

public Task<ResultWrapper<PayloadStatusV1>> engine_newPayloadV4(ExecutionPayloadV4 executionPayload, byte[]?[] blobVersionedHashes, Hash256? parentBeaconBlockRoot) =>
NewPayload(new ExecutionPayloadV3Params(executionPayload, blobVersionedHashes, parentBeaconBlockRoot), EngineApiVersions.Cancun);

public async Task<ResultWrapper<GetPayloadV3Result?>> engine_getPayloadV4(byte[] payloadId) =>
await _getPayloadHandlerV4.HandleAsync(payloadId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System.Threading.Tasks;
using Nethermind.Consensus.Producers;
using Nethermind.Core.Crypto;
using Nethermind.JsonRpc;
using Nethermind.JsonRpc.Modules;
using Nethermind.Merge.Plugin.Data;

namespace Nethermind.Merge.Plugin;

public partial interface IEngineRpcModule : IRpcModule
{

[JsonRpcMethod(
Description = "Verifies the payload according to the execution environment rules and returns the verification status and hash of the last valid block.",
IsSharable = true,
IsImplemented = true)]
Task<ResultWrapper<ForkchoiceUpdatedV1Result>> engine_forkchoiceUpdatedV4(ForkchoiceStateV1 forkchoiceState, PayloadAttributes? payloadAttributes = null);

[JsonRpcMethod(
Description = "Verifies the payload according to the execution environment rules and returns the verification status and hash of the last valid block.",
IsSharable = true,
IsImplemented = true)]
Task<ResultWrapper<PayloadStatusV1>> engine_newPayloadV4(ExecutionPayloadV4 executionPayload, byte[]?[] blobVersionedHashes, Hash256? parentBeaconBlockRoot);

[JsonRpcMethod(
Description = "Returns the most recent version of an execution payload and fees with respect to the transaction set contained by the mempool.",
IsSharable = true,
IsImplemented = true)]
public Task<ResultWrapper<GetPayloadV3Result?>> engine_getPayloadV4(byte[] payloadId);
}

0 comments on commit 4e0cb0f

Please sign in to comment.