Skip to content

Commit

Permalink
Fix BeaconBlockRootHandler (#7604)
Browse files Browse the repository at this point in the history
  • Loading branch information
yerke26 authored Oct 20, 2024
1 parent 07def8d commit 70a4780
Show file tree
Hide file tree
Showing 32 changed files with 193 additions and 37 deletions.
2 changes: 1 addition & 1 deletion src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ protected async Task<EthereumTestResult> RunTest(BlockchainTest test, Stopwatch?
stateProvider,
receiptStorage,
transactionProcessor,
new BeaconBlockRootHandler(transactionProcessor),
new BeaconBlockRootHandler(transactionProcessor, stateProvider),
new BlockhashStore(specProvider, stateProvider),
_logManager);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ void Process(AuRaBlockProcessor auRaBlockProcessor, int blockNumber, Hash256 sta
new BlockProcessor.BlockValidationTransactionsExecutor(transactionProcessor, stateProvider),
stateProvider,
NullReceiptStorage.Instance,
new BeaconBlockRootHandler(transactionProcessor),
new BeaconBlockRootHandler(transactionProcessor, stateProvider),
LimboLogs.Instance,
Substitute.For<IBlockTree>(),
new WithdrawalProcessor(stateProvider, LimboLogs.Instance),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ protected override BlockProcessor CreateBlockProcessor()
new BlockProcessor.BlockValidationTransactionsExecutor(TxProcessor, State),
State,
ReceiptStorage,
new BeaconBlockRootHandler(TxProcessor),
new BeaconBlockRootHandler(TxProcessor, State),
LimboLogs.Instance,
BlockTree,
NullWithdrawalProcessor.Instance,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ protected override BlockProcessor CreateBlockProcessor()
new BlockProcessor.BlockValidationTransactionsExecutor(TxProcessor, State),
State,
ReceiptStorage,
new BeaconBlockRootHandler(TxProcessor),
new BeaconBlockRootHandler(TxProcessor, State),
LimboLogs.Instance,
BlockTree,
NullWithdrawalProcessor.Instance,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ protected override BlockProcessor CreateBlockProcessor()
new BlockProcessor.BlockValidationTransactionsExecutor(TxProcessor, State),
State,
ReceiptStorage,
new BeaconBlockRootHandler(TxProcessor),
new BeaconBlockRootHandler(TxProcessor, State),
LimboLogs.Instance,
BlockTree,
NullWithdrawalProcessor.Instance,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using Nethermind.Blockchain.BeaconBlockRoot;
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Core.Eip2930;
using Nethermind.Core.Test.Builders;
using Nethermind.Crypto;
using Nethermind.Evm;
using Nethermind.Evm.Tracing;
using Nethermind.Evm.TransactionProcessing;
using Nethermind.Int256;
using Nethermind.Specs.Forks;
using Nethermind.State;
using NSubstitute;
using NUnit.Framework;

namespace Nethermind.Blockchain.Test;

public class BeaconBlockRootHandlerTests
{
private BeaconBlockRootHandler _beaconBlockRootHandler;
private ITransactionProcessor _transactionProcessor;
private IWorldState _worldState;

[SetUp]
public void Setup()
{
_worldState = Substitute.For<IWorldState>();
_transactionProcessor = Substitute.For<ITransactionProcessor>();
_beaconBlockRootHandler = new BeaconBlockRootHandler(_transactionProcessor, _worldState);
}

[Test]
public void Test_BeaconRootsAccessList_IsBeaconBlockRootAvailableFalse()
{
BlockHeader header = Build.A.BlockHeader.WithNumber(1).WithParentBeaconBlockRoot(Hash256.Zero).TestObject;
Block block = Build.A.Block.WithHeader(header).TestObject;
_worldState.AccountExists(Arg.Any<Address>()).Returns(true);

(Address? toAddress, AccessList? accessList) result = _beaconBlockRootHandler
.BeaconRootsAccessList(block, Shanghai.Instance);

Assert.That(result.accessList, Is.Null);
Assert.That(result.toAddress, Is.Null);
}

[Test]
public void Test_BeaconRootsAccessList_HeaderIsGenesis()
{
BlockHeader header = Build.A.BlockHeader.WithParentBeaconBlockRoot(Hash256.Zero).TestObject;
Block block = Build.A.Block.WithHeader(header).TestObject;
_worldState.AccountExists(Arg.Any<Address>()).Returns(true);

(Address? toAddress, AccessList? accessList) result = _beaconBlockRootHandler
.BeaconRootsAccessList(block, Cancun.Instance);

Assert.That(result.accessList, Is.Null);
Assert.That(result.toAddress, Is.Null);
}

[Test]
public void Test_BeaconRootsAccessList_ParentBeaconBlockRootIsNull()
{
BlockHeader header = Build.A.BlockHeader.WithNumber(1).TestObject;
Block block = Build.A.Block.WithHeader(header).TestObject;
_worldState.AccountExists(Arg.Any<Address>()).Returns(true);

(Address? toAddress, AccessList? accessList) result = _beaconBlockRootHandler
.BeaconRootsAccessList(block, Cancun.Instance);

Assert.That(result.accessList, Is.Null);
Assert.That(result.toAddress, Is.Null);
}

[Test]
public void Test_BeaconRootsAccessList_canInsertBeaconRootIsTrue_AccountNotExist()
{
BlockHeader header = Build.A.BlockHeader.WithNumber(1).WithParentBeaconBlockRoot(Hash256.Zero).TestObject;
Block block = Build.A.Block.WithHeader(header).TestObject;
_worldState.AccountExists(Arg.Any<Address>()).Returns(false);

(Address? toAddress, AccessList? accessList) result = _beaconBlockRootHandler
.BeaconRootsAccessList(block, Cancun.Instance);

Assert.That(result.accessList, Is.Null);
Assert.That(result.toAddress, Is.Null);
}

[Test]
public void Test_BeaconRootsAccessList_canInsertBeaconRootIsTrue_AccountExists()
{
BlockHeader header = Build.A.BlockHeader.WithNumber(1).WithParentBeaconBlockRoot(Hash256.Zero).TestObject;
Block block = Build.A.Block.WithHeader(header).TestObject;
_worldState.AccountExists(Arg.Any<Address>()).Returns(true);

(Address? toAddress, AccessList? accessList) result = _beaconBlockRootHandler
.BeaconRootsAccessList(block, Cancun.Instance);

Assert.That(result.accessList, Is.Not.Null);
Assert.That(result.accessList.Count.AddressesCount, Is.EqualTo(1));
Assert.That(result.accessList.Count.StorageKeysCount, Is.EqualTo(1));
}

[Test]
public void Test_BeaconRootsAccessList_canInsertBeaconRootIsTrue_AccountExists_IncludeStorageCellsIsFalse()
{
BlockHeader header = Build.A.BlockHeader.WithNumber(1).WithParentBeaconBlockRoot(Hash256.Zero).TestObject;
Block block = Build.A.Block.WithHeader(header).TestObject;
_worldState.AccountExists(Arg.Any<Address>()).Returns(true);

(Address? toAddress, AccessList? accessList) result = _beaconBlockRootHandler
.BeaconRootsAccessList(block, Cancun.Instance, false);

Assert.That(result.accessList, Is.Not.Null);
Assert.That(result.accessList.Count.AddressesCount, Is.EqualTo(1));
Assert.That(result.accessList.Count.StorageKeysCount, Is.EqualTo(0));
}

[Test]
public void Test_StoreBeaconRoot_AccessListIsNull()
{
BlockHeader header = Build.A.BlockHeader.TestObject;
Block block = Build.A.Block.WithHeader(header).TestObject;

_beaconBlockRootHandler.StoreBeaconRoot(block, Cancun.Instance);

_transactionProcessor.DidNotReceive().Execute(Arg.Any<Transaction>(), Arg.Any<BlockExecutionContext>(), Arg.Any<ITxTracer>());
}

[Test]
public void Test_StoreBeaconRoot_AccessListNotNull()
{
BlockHeader header = Build.A.BlockHeader.WithNumber(1).WithParentBeaconBlockRoot(Hash256.Zero).TestObject;
Block block = Build.A.Block.WithHeader(header).TestObject;
_worldState.AccountExists(Arg.Any<Address>()).Returns(true);

_beaconBlockRootHandler.StoreBeaconRoot(block, Cancun.Instance);

Transaction transaction = new()
{
Value = UInt256.Zero,
Data = header.ParentBeaconBlockRoot!.Bytes.ToArray(),
To = Eip4788Constants.BeaconRootsAddress,
SenderAddress = Address.SystemUser,
GasLimit = 30_000_000L,
GasPrice = UInt256.Zero,
AccessList = new AccessList.Builder().AddAddress(Eip4788Constants.BeaconRootsAddress).Build()
};

transaction.Hash = transaction.CalculateHash();
_transactionProcessor.Received().Execute(Arg.Is<Transaction>(t =>
t.Hash == transaction.Hash), header, NullTxTracer.Instance);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public void Prepared_block_contains_author_field()
stateProvider,
NullReceiptStorage.Instance,
transactionProcessor,
new BeaconBlockRootHandler(transactionProcessor),
new BeaconBlockRootHandler(transactionProcessor, stateProvider),
Substitute.For<IBlockhashStore>(),
LimboLogs.Instance);

Expand Down Expand Up @@ -81,7 +81,7 @@ public void Recovers_state_on_cancel()
stateProvider,
NullReceiptStorage.Instance,
transactionProcessor,
new BeaconBlockRootHandler(transactionProcessor),
new BeaconBlockRootHandler(transactionProcessor, stateProvider),
Substitute.For<IBlockhashStore>(),
LimboLogs.Instance);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public void Test()
stateProvider,
NullReceiptStorage.Instance,
txProcessor,
new BeaconBlockRootHandler(txProcessor),
new BeaconBlockRootHandler(txProcessor, stateProvider),
new BlockhashStore(specProvider, stateProvider),
LimboLogs.Instance);
BlockchainProcessor blockchainProcessor = new(
Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public void Setup()
stateProvider,
NullReceiptStorage.Instance,
transactionProcessor,
new BeaconBlockRootHandler(transactionProcessor),
new BeaconBlockRootHandler(transactionProcessor, stateProvider),
new BlockhashStore(MainnetSpecProvider.Instance, stateProvider),
LimboLogs.Instance);
_blockchainProcessor = new BlockchainProcessor(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using Nethermind.Core;
using Nethermind.Core.Eip2930;
using Nethermind.Core.Specs;
using Nethermind.Crypto;
using Nethermind.Evm.Tracing;
using Nethermind.Evm.TransactionProcessing;
using Nethermind.Int256;
using Nethermind.State;

namespace Nethermind.Blockchain.BeaconBlockRoot;
public class BeaconBlockRootHandler(ITransactionProcessor processor) : IBeaconBlockRootHandler
public class BeaconBlockRootHandler(ITransactionProcessor processor, IWorldState stateProvider) : IBeaconBlockRootHandler
{
private const long GasLimit = 30_000_000L;

Expand All @@ -26,7 +26,7 @@ public class BeaconBlockRootHandler(ITransactionProcessor processor) : IBeaconBl
spec.Eip4788ContractAddress ?? Eip4788Constants.BeaconRootsAddress :
null;

if (eip4788ContractAddress is null)
if (eip4788ContractAddress is null || !stateProvider.AccountExists(eip4788ContractAddress))
{
return (null, null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Nethermind.Core;
using Nethermind.Core.Eip2930;
using Nethermind.Core.Specs;
using Nethermind.State;

namespace Nethermind.Blockchain.BeaconBlockRoot;
public interface IBeaconBlockRootHandler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = f
stateProvider,
NullReceiptStorage.Instance,
transactionProcessor,
new BeaconBlockRootHandler(transactionProcessor),
new BeaconBlockRootHandler(transactionProcessor, stateProvider),
new BlockhashStore(goerliSpecProvider, stateProvider),
nodeLogManager);

Expand All @@ -161,7 +161,7 @@ public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = f
minerStateProvider,
NullReceiptStorage.Instance,
minerTransactionProcessor,
new BeaconBlockRootHandler(minerTransactionProcessor),
new BeaconBlockRootHandler(minerTransactionProcessor, minerStateProvider),
new BlockhashStore(goerliSpecProvider, minerStateProvider),
nodeLogManager);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ protected virtual AuRaBlockProcessor NewAuraBlockProcessor(ITxFilter txFilter, B
new BlockProcessor.BlockValidationTransactionsExecutor(_api.TransactionProcessor, worldState),
worldState,
_api.ReceiptStorage!,
new BeaconBlockRootHandler(_api.TransactionProcessor!),
new BeaconBlockRootHandler(_api.TransactionProcessor!, worldState),
_api.LogManager,
_api.BlockTree!,
NullWithdrawalProcessor.Instance,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ private BlockProcessor CreateBlockProcessor(IReadOnlyTxProcessingScope changeabl
_api.BlockProducerEnvFactory.TransactionsExecutorFactory.Create(changeableTxProcessingEnv),
changeableTxProcessingEnv.WorldState,
_api.ReceiptStorage,
new BeaconBlockRootHandler(changeableTxProcessingEnv.TransactionProcessor),
new BeaconBlockRootHandler(changeableTxProcessingEnv.TransactionProcessor, changeableTxProcessingEnv.WorldState),
_api.LogManager,
_api.BlockTree,
NullWithdrawalProcessor.Instance,
Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Nethermind.Consensus.Clique/CliquePlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public IBlockProducer InitBlockProducer(ITxSource? additionalTxSource = null)
scope.WorldState,
NullReceiptStorage.Instance,
getFromApi.TransactionProcessor,
new BeaconBlockRootHandler(scope.TransactionProcessor),
new BeaconBlockRootHandler(scope.TransactionProcessor, scope.WorldState),
new BlockhashStore(getFromApi.SpecProvider, scope.WorldState),
getFromApi.LogManager,
new BlockProductionWithdrawalProcessor(new WithdrawalProcessor(scope.WorldState, getFromApi.LogManager)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public IBlockProducer InitBlockProducer(ITxSource? additionalTxSource = null)
scope.WorldState,
NullReceiptStorage.Instance,
scope.TransactionProcessor,
new BeaconBlockRootHandler(scope.TransactionProcessor),
new BeaconBlockRootHandler(scope.TransactionProcessor, scope.WorldState),
new BlockhashStore(getFromApi.SpecProvider, scope.WorldState),
getFromApi.LogManager);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ IBlockProcessor.IBlockTransactionsExecutor transactionsExecutor
scope.WorldState,
receiptStorage,
scope.TransactionProcessor,
new BeaconBlockRootHandler(scope.TransactionProcessor),
new BeaconBlockRootHandler(scope.TransactionProcessor, scope.WorldState),
new BlockhashStore(specProvider, scope.WorldState),
logManager);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ protected virtual BlockProcessor CreateBlockProcessor(
readOnlyTxProcessingEnv.WorldState,
receiptStorage,
readOnlyTxProcessingEnv.TransactionProcessor,
new BeaconBlockRootHandler(readOnlyTxProcessingEnv.TransactionProcessor),
new BeaconBlockRootHandler(readOnlyTxProcessingEnv.TransactionProcessor, readOnlyTxProcessingEnv.WorldState),
new BlockhashStore(_specProvider, readOnlyTxProcessingEnv.WorldState),
logManager,
new BlockProductionWithdrawalProcessor(new WithdrawalProcessor(readOnlyTxProcessingEnv.WorldState, logManager)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ protected virtual async Task<TestBlockchain> Build(ISpecProvider? specProvider =
HeaderValidator = new HeaderValidator(BlockTree, Always.Valid, SpecProvider, LogManager);

_canonicalityMonitor ??= new ReceiptCanonicalityMonitor(ReceiptStorage, LogManager);
BeaconBlockRootHandler = new BeaconBlockRootHandler(TxProcessor);
BeaconBlockRootHandler = new BeaconBlockRootHandler(TxProcessor, State);

BlockValidator = new BlockValidator(
new TxValidator(SpecProvider.ChainId),
Expand All @@ -216,7 +216,6 @@ protected virtual async Task<TestBlockchain> Build(ISpecProvider? specProvider =
BloomStorage bloomStorage = new(new BloomConfig(), new MemDb(), new InMemoryDictionaryFileStoreFactory());
ReceiptsRecovery receiptsRecovery = new(new EthereumEcdsa(SpecProvider.ChainId), SpecProvider);
LogFinder = new LogFinder(BlockTree, ReceiptStorage, ReceiptStorage, bloomStorage, LimboLogs.Instance, receiptsRecovery);
BeaconBlockRootHandler = new BeaconBlockRootHandler(TxProcessor);
BlockProcessor = CreateBlockProcessor();

BlockchainProcessor chainProcessor = new(BlockTree, BlockProcessor, BlockPreprocessorStep, StateReader, LogManager, Consensus.Processing.BlockchainProcessor.Options.Default);
Expand Down Expand Up @@ -390,7 +389,7 @@ protected virtual IBlockProcessor CreateBlockProcessor() =>
State,
ReceiptStorage,
TxProcessor,
new BeaconBlockRootHandler(TxProcessor),
new BeaconBlockRootHandler(TxProcessor, State),
new BlockhashStore(SpecProvider, State),
LogManager,
preWarmer: CreateBlockCachePreWarmer(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public IBlockProcessor GetProcessor(bool validate, UInt256? blobBaseFeeOverride)
StateProvider,
NullReceiptStorage.Instance,
_transactionProcessor,
new BeaconBlockRootHandler(_transactionProcessor),
new BeaconBlockRootHandler(_transactionProcessor, StateProvider),
new BlockhashStore(SpecProvider, StateProvider),
_logManager);
}
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ protected virtual BlockProcessor CreateBlockProcessor(BlockCachePreWarmer? preWa
worldState,
_api.ReceiptStorage,
_api.TransactionProcessor,
new BeaconBlockRootHandler(_api.TransactionProcessor),
new BeaconBlockRootHandler(_api.TransactionProcessor, worldState),
new BlockhashStore(_api.SpecProvider!, worldState),
_api.LogManager,
preWarmer: preWarmer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ TransactionProcessor transactionProcessor
stateProvider,
NullReceiptStorage.Instance,
transactionProcessor,
new BeaconBlockRootHandler(transactionProcessor),
new BeaconBlockRootHandler(transactionProcessor, stateProvider),
new BlockhashStore(specProvider, stateProvider),
LimboLogs.Instance);

Expand Down
Loading

0 comments on commit 70a4780

Please sign in to comment.