Skip to content

Commit 566a157

Browse files
committed
Include withdrawals in payload id computation
1 parent 8de80c2 commit 566a157

File tree

3 files changed

+216
-175
lines changed

3 files changed

+216
-175
lines changed

src/Nethermind/Nethermind.Consensus/Producers/PayloadAttributes.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
// SPDX-FileCopyrightText: 2022 Demerzel Solutions Limited
22
// SPDX-License-Identifier: LGPL-3.0-only
33

4+
using System.Buffers.Binary;
5+
using System;
46
using System.Collections.Generic;
57
using System.Diagnostics.CodeAnalysis;
68
using System.Text;
79
using Nethermind.Core;
810
using Nethermind.Core.Crypto;
11+
using Nethermind.Core.Extensions;
912
using Nethermind.Core.Specs;
13+
using Nethermind.State.Proofs;
14+
using Nethermind.Trie;
1015

1116
namespace Nethermind.Consensus.Producers;
1217

@@ -42,6 +47,30 @@ public string ToString(string indentation)
4247

4348
return sb.ToString();
4449
}
50+
51+
public string ComputePayloadId(BlockHeader parentHeader)
52+
{
53+
bool hasWithdrawals = Withdrawals is not null;
54+
Span<byte> inputSpan = stackalloc byte[32 + 32 + 32 + 20 + (hasWithdrawals ? 32 : 0)];
55+
56+
parentHeader.Hash!.Bytes.CopyTo(inputSpan[..32]);
57+
BinaryPrimitives.WriteUInt64BigEndian(inputSpan.Slice(56, 8), Timestamp);
58+
PrevRandao.Bytes.CopyTo(inputSpan.Slice(64, 32));
59+
SuggestedFeeRecipient.Bytes.CopyTo(inputSpan.Slice(96, 20));
60+
61+
if (hasWithdrawals)
62+
{
63+
var withdrawalsRootHash = Withdrawals.Count == 0
64+
? PatriciaTree.EmptyTreeHash
65+
: new WithdrawalTrie(Withdrawals).RootHash;
66+
67+
withdrawalsRootHash.Bytes.CopyTo(inputSpan[116..]);
68+
}
69+
70+
ValueKeccak inputHash = ValueKeccak.Compute(inputSpan);
71+
72+
return inputHash.BytesAsSpan[..8].ToHexString(true);
73+
}
4574
}
4675

4776
public static class PayloadAttributesExtensions

src/Nethermind/Nethermind.Merge.Plugin.Test/EngineModuleTests.V2.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,23 @@ public void Should_print_payload_attributes_as_expected()
721721
$"PayloadAttributes {{Timestamp: {attrs.Timestamp}, PrevRandao: {attrs.PrevRandao}, SuggestedFeeRecipient: {attrs.SuggestedFeeRecipient}, Withdrawals count: {attrs.Withdrawals.Count}}}");
722722
}
723723

724+
[TestCaseSource(nameof(PayloadIdTestCases))]
725+
public void Should_compute_payload_id_with_withdrawals((IList<Withdrawal>? Withdrawals, string PayloadId) input)
726+
{
727+
var blockHeader = Build.A.BlockHeader.TestObject;
728+
var payloadAttributes = new PayloadAttributes
729+
{
730+
PrevRandao = Keccak.Zero,
731+
SuggestedFeeRecipient = Address.Zero,
732+
Timestamp = 0,
733+
Withdrawals = input.Withdrawals
734+
};
735+
736+
var payloadId = payloadAttributes.ComputePayloadId(blockHeader);
737+
738+
payloadId.Should().Be(input.PayloadId);
739+
}
740+
724741
private static async Task<GetPayloadV2Result> BuildAndGetPayloadResultV2(
725742
IEngineRpcModule rpc, MergeTestBlockchain chain, PayloadAttributes payloadAttributes)
726743
{
@@ -864,4 +881,14 @@ bool isValid
864881
Enumerable.Repeat(result, 5)
865882
);
866883
}
884+
885+
protected static IEnumerable<(
886+
IList<Withdrawal>? Withdrawals,
887+
string payloadId
888+
)> PayloadIdTestCases()
889+
{
890+
yield return (null, "0xd0666188af58eb6f");
891+
yield return (Array.Empty<Withdrawal>(), "0xb5f89745e4cfaec0");
892+
yield return (new[] { Build.A.Withdrawal.TestObject }, "0x0628b8a79468163e");
893+
}
867894
}

0 commit comments

Comments
 (0)