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

Fix BeaconBlockRootHandler #7604

Merged
merged 7 commits into from
Oct 20, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
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
Loading