Skip to content

Commit

Permalink
Changes for EIP7685, 7002 & 6110: Flat Encoding of requests (#7670)
Browse files Browse the repository at this point in the history
Co-authored-by: ak88 <[email protected]>
Co-authored-by: MarekM25 <[email protected]>
Co-authored-by: Ahmad Bitar <[email protected]>
Co-authored-by: lukasz.rozmej <[email protected]>
Co-authored-by: ak88 <[email protected]>
  • Loading branch information
6 people authored Nov 6, 2024
1 parent 6bfee29 commit 9acde37
Show file tree
Hide file tree
Showing 93 changed files with 795 additions and 2,362 deletions.
2 changes: 1 addition & 1 deletion src/Nethermind/Ethereum.Test.Base/GeneralStateTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class GeneralStateTest : IEthereumTest
public UInt256? ParentBlobGasUsed { get; set; }
public UInt256? ParentExcessBlobGas { get; set; }

public Hash256? RequestsRoot { get; set; }
public Hash256? RequestsHash { get; set; }

public override string ToString()
{
Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer)
header.ParentBeaconBlockRoot = test.CurrentBeaconRoot;
header.ExcessBlobGas = test.CurrentExcessBlobGas ?? (test.Fork is Cancun ? 0ul : null);
header.BlobGasUsed = BlobGasCalculator.CalculateBlobGas(test.Transaction);
header.RequestsRoot = test.RequestsRoot;
header.RequestsHash = test.RequestsHash;

Stopwatch stopwatch = Stopwatch.StartNew();
IReleaseSpec? spec = specProvider.GetSpec((ForkActivation)test.CurrentNumber);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// SPDX-License-Identifier: LGPL-3.0-only

using Nethermind.Consensus.Validators;
using Nethermind.Core.ConsensusRequests;
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Core.Specs;
Expand Down Expand Up @@ -199,51 +198,4 @@ public void ValidateSuggestedBlock_SuggestedBlockIsInvalid_CorrectErrorIsSet(Blo

Assert.That(error, Does.StartWith(expectedError));
}

[Test]
public void ValidateBodyAgainstHeader_BlockHasInvalidRequestRoot_ReturnsFalse()
{
Block block = Build.A.Block
.WithConsensusRequests(new ConsensusRequest[] {
Build.A.Deposit.WithIndex(0).TestObject,
Build.A.WithdrawalRequest.TestObject
})
.TestObject;
block.Header.RequestsRoot = Keccak.OfAnEmptyString;

Assert.That(
BlockValidator.ValidateBodyAgainstHeader(block.Header, block.Body),
Is.False);
}

[Test]
public void ValidateBodyRequests_BlockHasReuests_InOrder_ReturnsTrue()
{
Block block = Build.A.Block
.WithConsensusRequests(new ConsensusRequest[] {
Build.A.Deposit.WithIndex(0).TestObject,
Build.A.WithdrawalRequest.TestObject
})
.TestObject;

Assert.That(
BlockValidator.ValidateRequestsOrder(block, out string? _),
Is.True);
}

[Test]
public void ValidateBodyRequests_BlockHasReuests_OutOfOrder_ReturnsFalse()
{
Block block = Build.A.Block
.WithConsensusRequests(new ConsensusRequest[] {
Build.A.WithdrawalRequest.TestObject,
Build.A.Deposit.WithIndex(0).TestObject
})
.TestObject;

Assert.That(
BlockValidator.ValidateRequestsOrder(block, out string? _),
Is.False);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
using Nethermind.Blockchain.Find;
using Nethermind.Blockchain.Receipts;
using Nethermind.Consensus.AuRa.Validators;
using Nethermind.Consensus.ExecutionRequests;
using Nethermind.Consensus.Processing;
using Nethermind.Consensus.Requests;
using Nethermind.Consensus.Rewards;
using Nethermind.Consensus.Transactions;
using Nethermind.Consensus.Validators;
Expand Down Expand Up @@ -51,7 +51,7 @@ public AuRaBlockProcessor(
AuRaContractGasLimitOverride? gasLimitOverride = null,
ContractRewriter? contractRewriter = null,
IBlockCachePreWarmer? preWarmer = null,
IConsensusRequestsProcessor? consensusRequestsProcessor = null)
IExecutionRequestsProcessor? executionRequestsProcessor = null)
: base(
specProvider,
blockValidator,
Expand All @@ -65,7 +65,7 @@ public AuRaBlockProcessor(
logManager,
withdrawalProcessor,
preWarmer: preWarmer,
consensusRequestsProcessor: consensusRequestsProcessor)
executionRequestsProcessor: executionRequestsProcessor)
{
_specProvider = specProvider;
_blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
using Nethermind.Consensus.Producers;
using Nethermind.Consensus.Transactions;
using Nethermind.Core;
using Nethermind.Core.ConsensusRequests;
using Nethermind.Core.Crypto;
using Nethermind.Core.Specs;
using Nethermind.Crypto;
Expand Down Expand Up @@ -500,8 +499,7 @@ ILogManager logManager
header,
selectedTxs,
Array.Empty<BlockHeader>(),
spec.WithdrawalsEnabled ? Enumerable.Empty<Withdrawal>() : null,
spec.RequestsEnabled ? Enumerable.Empty<ConsensusRequest>() : null
spec.WithdrawalsEnabled ? Enumerable.Empty<Withdrawal>() : null
);
header.TxRoot = TxTrie.CalculateRoot(block.Transactions);
block.Header.Author = _sealer.Address;
Expand Down
70 changes: 0 additions & 70 deletions src/Nethermind/Nethermind.Consensus.Test/DepositProcessorTests.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using System.Linq;
using Nethermind.Abi;
using Nethermind.Consensus.ExecutionRequests;
using Nethermind.Core;
using Nethermind.Core.Collections;
using Nethermind.Core.Crypto;
using Nethermind.Core.ExecutionRequest;
using Nethermind.Core.Extensions;
using Nethermind.Core.Specs;
using Nethermind.Core.Test.Builders;
using Nethermind.Db;
using Nethermind.Evm;
using Nethermind.Evm.Tracing;
using Nethermind.Evm.TransactionProcessing;
using Nethermind.Int256;
using Nethermind.Logging;
using Nethermind.Specs;
using Nethermind.State;
using Nethermind.Trie.Pruning;
using NSubstitute;
using NUnit.Framework;

namespace Nethermind.Consensus.Test;

public class ExecutionProcessorTests
{
private ISpecProvider _specProvider;
private ITransactionProcessor _transactionProcessor;
private WorldState _stateProvider;
private IReleaseSpec _spec;
private static readonly UInt256 AccountBalance = 1.Ether();
private static readonly Address DepositContractAddress = Eip6110Constants.MainnetDepositContractAddress;
private static readonly Address eip7002Account = Eip7002Constants.WithdrawalRequestPredeployAddress;
private static readonly Address eip7251Account = Eip7251Constants.ConsolidationRequestPredeployAddress;
private static readonly AbiSignature _depositEventABI = new("DepositEvent", AbiType.DynamicBytes, AbiType.DynamicBytes, AbiType.DynamicBytes, AbiType.DynamicBytes, AbiType.DynamicBytes);
private static readonly AbiEncoder _abiEncoder = AbiEncoder.Instance;

private static readonly TestExecutionRequest[] _executionDepositRequests = [TestItem.ExecutionRequestA, TestItem.ExecutionRequestB, TestItem.ExecutionRequestC];
private static readonly TestExecutionRequest[] _executionWithdrawalRequests = [TestItem.ExecutionRequestD, TestItem.ExecutionRequestE, TestItem.ExecutionRequestF];
private static readonly TestExecutionRequest[] _executionConsolidationRequests = [TestItem.ExecutionRequestG, TestItem.ExecutionRequestH, TestItem.ExecutionRequestI];

private void FlatEncodeWithoutType(ExecutionRequest[] requests, Span<byte> buffer)
{
int currentPosition = 0;

foreach (ExecutionRequest request in requests)
{
// Ensure the buffer has enough space to accommodate the new data
if (currentPosition + request.RequestData!.Length > buffer.Length)
{
throw new InvalidOperationException("Buffer is not large enough to hold all data of requests");
}

// Copy the RequestData to the buffer at the current position
request.RequestData.CopyTo(buffer.Slice(currentPosition, request.RequestData.Length));
currentPosition += request.RequestData.Length;
}
}

[SetUp]
public void Setup()
{
_specProvider = MainnetSpecProvider.Instance;
MemDb stateDb = new();
TrieStore trieStore = new(stateDb, LimboLogs.Instance);

_stateProvider = new WorldState(trieStore, new MemDb(), LimboLogs.Instance);
_stateProvider.CreateAccount(eip7002Account, AccountBalance);
_stateProvider.CreateAccount(eip7251Account, AccountBalance);
_stateProvider.Commit(_specProvider.GenesisSpec);
_stateProvider.CommitTree(0);

_spec = Substitute.For<IReleaseSpec>();

_spec.RequestsEnabled.Returns(true);
_spec.DepositsEnabled.Returns(true);
_spec.WithdrawalRequestsEnabled.Returns(true);
_spec.ConsolidationRequestsEnabled.Returns(true);

_spec.DepositContractAddress.Returns(DepositContractAddress);
_spec.Eip7002ContractAddress.Returns(eip7002Account);
_spec.Eip7251ContractAddress.Returns(eip7251Account);

_transactionProcessor = Substitute.For<ITransactionProcessor>();

_transactionProcessor.Execute(Arg.Any<Transaction>(), Arg.Any<BlockExecutionContext>(), Arg.Any<CallOutputTracer>())
.Returns(ci =>
{
Transaction transaction = ci.Arg<Transaction>();
CallOutputTracer tracer = ci.Arg<CallOutputTracer>();
if (transaction.To == eip7002Account)
{
Span<byte> buffer = new byte[_executionWithdrawalRequests.GetRequestsByteSize()];
FlatEncodeWithoutType(_executionWithdrawalRequests, buffer);
tracer.ReturnValue = buffer.ToArray();
}
else if (transaction.To == eip7251Account)
{
Span<byte> buffer = new byte[_executionConsolidationRequests.GetRequestsByteSize()];
FlatEncodeWithoutType(_executionConsolidationRequests, buffer);
tracer.ReturnValue = buffer.ToArray();
}
else
{
tracer.ReturnValue = Array.Empty<byte>();
}
return new TransactionResult();
});
}


public static Hash256 CalculateHash(
TestExecutionRequest[] depositRequests,
TestExecutionRequest[] withdrawalRequests,
TestExecutionRequest[] consolidationRequests
)
{
using ArrayPoolList<byte[]> requests = TestExecutionRequestExtensions.GetFlatEncodedRequests(depositRequests, withdrawalRequests, consolidationRequests);
return ExecutionRequestExtensions.CalculateHashFromFlatEncodedRequests(requests.ToArray());
}

[Test]
public void ShouldProcessExecutionRequests()
{
Block block = Build.A.Block.TestObject;
ExecutionRequestsProcessor executionRequestsProcessor = new(_transactionProcessor);

TxReceipt[] txReceipts = [
Build.A.Receipt.WithLogs(
CreateLogEntry(TestItem.ExecutionRequestA.RequestDataParts),
CreateLogEntry(TestItem.ExecutionRequestB.RequestDataParts),
CreateLogEntry(TestItem.ExecutionRequestC.RequestDataParts)
).TestObject
];
executionRequestsProcessor.ProcessExecutionRequests(block, _stateProvider, txReceipts, _spec);

Assert.That(block.Header.RequestsHash, Is.EqualTo(
CalculateHash(_executionDepositRequests, _executionWithdrawalRequests, _executionConsolidationRequests)
));


static LogEntry CreateLogEntry(byte[][] requestDataParts) =>
Build.A.LogEntry
.WithData(_abiEncoder.Encode(AbiEncodingStyle.None, _depositEventABI, requestDataParts!))
.WithAddress(DepositContractAddress).TestObject;
}
}
Loading

0 comments on commit 9acde37

Please sign in to comment.