Skip to content

Commit

Permalink
Feature/eth multicall refactor (#6175)
Browse files Browse the repository at this point in the history
* refactor

* refactoring

* More refactoring and fixes

* whitespace

* fix tests

* more fix

* more improvements
  • Loading branch information
LukaszRozmej authored Oct 11, 2023
1 parent 42b2e3a commit b6c3b21
Show file tree
Hide file tree
Showing 82 changed files with 891 additions and 902 deletions.
3 changes: 3 additions & 0 deletions src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,11 @@ protected async Task<EthereumTestResult> RunTest(BlockchainTest test, Stopwatch?
IHeaderValidator headerValidator = new HeaderValidator(blockTree, Sealer, specProvider, _logManager);
IUnclesValidator unclesValidator = new UnclesValidator(blockTree, headerValidator, _logManager);
IBlockValidator blockValidator = new BlockValidator(txValidator, headerValidator, unclesValidator, specProvider, _logManager);
CodeInfoRepository codeInfoRepository = new();
IVirtualMachine virtualMachine = new VirtualMachine(
blockhashProvider,
specProvider,
codeInfoRepository,
_logManager);

IBlockProcessor blockProcessor = new BlockProcessor(
Expand All @@ -155,6 +157,7 @@ protected async Task<EthereumTestResult> RunTest(BlockchainTest test, Stopwatch?
specProvider,
stateProvider,
virtualMachine,
codeInfoRepository,
_logManager),
stateProvider),
stateProvider,
Expand Down
3 changes: 3 additions & 0 deletions src/Nethermind/Ethereum.Test.Base/GeneralTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,18 @@ protected EthereumTestResult RunTest(GeneralStateTest test, ITxTracer txTracer)
TrieStore trieStore = new(stateDb, _logManager);
WorldState stateProvider = new(trieStore, codeDb, _logManager);
IBlockhashProvider blockhashProvider = new TestBlockhashProvider();
CodeInfoRepository codeInfoRepository = new();
IVirtualMachine virtualMachine = new VirtualMachine(
blockhashProvider,
specProvider,
codeInfoRepository,
_logManager);

TransactionProcessor transactionProcessor = new(
specProvider,
stateProvider,
virtualMachine,
codeInfoRepository,
_logManager);

InitializeTestState(test, stateProvider, specProvider);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace Nethermind.AccountAbstraction.Test
{
[TestFixture]
[Parallelizable(ParallelScope.All)]
[SetCulture("en-US")]
public class StandardTests
{
[Test]
Expand Down
4 changes: 2 additions & 2 deletions src/Nethermind/Nethermind.Api/Extensions/IConsensusPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Task<IBlockProducer> InitBlockProducer(
/// </remarks>
IBlockProductionTrigger DefaultBlockProductionTrigger { get; }

INethermindApi CreateApi(IConfigProvider configProvider, IJsonSerializer jsonSerializer,
ILogManager logManager, ChainSpec chainSpec) => new NethermindApi(configProvider, jsonSerializer, logManager, chainSpec);
INethermindApi CreateApi(IConfigProvider configProvider, IJsonSerializer jsonSerializer, ILogManager logManager, ChainSpec chainSpec) =>
new NethermindApi(configProvider, jsonSerializer, logManager, chainSpec);
}
}
4 changes: 2 additions & 2 deletions src/Nethermind/Nethermind.Api/IBasicApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ public interface IBasicApi
ILogManager LogManager { get; set; }
ProtectedPrivateKey? OriginalSignerKey { get; set; }
IReadOnlyList<INethermindPlugin> Plugins { get; }
string SealEngineType { get; set; }
ISpecProvider? SpecProvider { get; set; }
string SealEngineType => ChainSpec.SealEngineType;
ISpecProvider SpecProvider { get; }
ISyncModeSelector? SyncModeSelector { get; set; }
ISyncProgressResolver? SyncProgressResolver { get; set; }
IBetterPeerStrategy? BetterPeerStrategy { get; set; }
Expand Down
39 changes: 22 additions & 17 deletions src/Nethermind/Nethermind.Api/NethermindApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
using Nethermind.Evm.TransactionProcessing;
using Nethermind.Facade;
using Nethermind.Facade.Eth;
using Nethermind.Facade.Multicall;
using Nethermind.Grpc;
using Nethermind.JsonRpc;
using Nethermind.JsonRpc.Modules;
Expand Down Expand Up @@ -60,9 +61,15 @@ namespace Nethermind.Api
{
public class NethermindApi : INethermindApi
{
public NethermindApi(IConfigProvider configProvider, IJsonSerializer jsonSerializer, ILogManager logManager, ChainSpec chainSpec)
public NethermindApi(
IConfigProvider configProvider,
IJsonSerializer jsonSerializer,
ILogManager logManager,
ChainSpec chainSpec,
ISpecProvider? specProvider = null)
{
ConfigProvider = configProvider;
SpecProvider = specProvider ?? new ChainSpecBasedSpecProvider(chainSpec, logManager);
EthereumJsonSerializer = jsonSerializer;
LogManager = logManager;
ChainSpec = chainSpec;
Expand All @@ -72,6 +79,8 @@ public NethermindApi(IConfigProvider configProvider, IJsonSerializer jsonSeriali

private IReadOnlyDbProvider? _readOnlyDbProvider;
private IReadOnlyDbProvider? _multiCallReadOnlyDbProvider;
private ISealEngine? _sealEngine;
private IGasLimitCalculator? _gasLimitCalculator;

public IBlockchainBridge CreateBlockchainBridge()
{
Expand Down Expand Up @@ -169,27 +178,18 @@ public IBlockchainBridge CreateBlockchainBridge()
public IRpcAuthentication? RpcAuthentication { get; set; }
public IJsonRpcLocalStats? JsonRpcLocalStats { get; set; }
public ISealer? Sealer { get; set; } = NullSealEngine.Instance;
public string SealEngineType { get; set; } = Nethermind.Core.SealEngineType.None;
public ISealValidator? SealValidator { get; set; } = NullSealEngine.Instance;
private ISealEngine? _sealEngine;

public ISealEngine SealEngine
{
get
{
return _sealEngine ??= new SealEngine(Sealer, SealValidator);
}

set
{
_sealEngine = value;
}
get => _sealEngine ??= new SealEngine(Sealer, SealValidator);
set => _sealEngine = value;
}

public ISessionMonitor? SessionMonitor { get; set; }
public ISpecProvider? SpecProvider { get; set; }
public ISpecProvider SpecProvider { get; set; }
public IPoSSwitcher PoSSwitcher { get; set; } = NoPoS.Instance;
public ISyncModeSelector? SyncModeSelector { get; set; }

public ISyncProgressResolver? SyncProgressResolver { get; set; }
public IBetterPeerStrategy? BetterPeerStrategy { get; set; }
public IBlockDownloaderFactory? BlockDownloaderFactory { get; set; }
Expand All @@ -202,8 +202,8 @@ public ISealEngine SealEngine
public IReadOnlyStateProvider? ChainHeadStateProvider { get; set; }
public IStateReader? StateReader { get; set; }
public IStaticNodesManager? StaticNodesManager { get; set; }
public ITimestamper Timestamper { get; } = Core.Timestamper.Default;
public ITimerFactory TimerFactory { get; } = Core.Timers.TimerFactory.Default;
public ITimestamper Timestamper => Core.Timestamper.Default;
public ITimerFactory TimerFactory => Core.Timers.TimerFactory.Default;
public ITransactionProcessor? TransactionProcessor { get; set; }
public ITrieStore? TrieStore { get; set; }
public IReadOnlyTrieStore? ReadOnlyTrieStore { get; set; }
Expand All @@ -215,7 +215,12 @@ public ISealEngine SealEngine
public IRpcCapabilitiesProvider? RpcCapabilitiesProvider { get; set; }
public TxValidator? TxValidator { get; set; }
public IBlockFinalizationManager? FinalizationManager { get; set; }
public IGasLimitCalculator? GasLimitCalculator { get; set; }

public IGasLimitCalculator? GasLimitCalculator
{
get => _gasLimitCalculator ??= new FollowOtherMiners(SpecProvider);
set => _gasLimitCalculator = value;
}

public IBlockProducerEnvFactory? BlockProducerEnvFactory { get; set; }
public IGasPriceOracle? GasPriceOracle { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,17 @@ public void Test()
LimboLogs.Instance);
StateReader stateReader = new(trieStore, dbProvider.GetDb<IDb>(DbNames.State), LimboLogs.Instance);
BlockhashProvider blockhashProvider = new(blockTree, LimboLogs.Instance);
CodeInfoRepository codeInfoRepository = new();
VirtualMachine virtualMachine = new(
blockhashProvider,
specProvider,
codeInfoRepository,
LimboLogs.Instance);
TransactionProcessor txProcessor = new(
specProvider,
stateProvider,
virtualMachine,
codeInfoRepository,
LimboLogs.Instance);
BlockProcessor blockProcessor = new(
specProvider,
Expand Down
3 changes: 3 additions & 0 deletions src/Nethermind/Nethermind.Blockchain.Test/ReorgTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,17 @@ public void Setup()
LimboLogs.Instance,
transactionComparerProvider.GetDefaultComparer());
BlockhashProvider blockhashProvider = new(_blockTree, LimboLogs.Instance);
CodeInfoRepository codeInfoRepository = new();
VirtualMachine virtualMachine = new(
blockhashProvider,
specProvider,
codeInfoRepository,
LimboLogs.Instance);
TransactionProcessor transactionProcessor = new(
specProvider,
stateProvider,
virtualMachine,
codeInfoRepository,
LimboLogs.Instance);

BlockProcessor blockProcessor = new(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,10 @@ public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = f
_genesis.Header.Hash = _genesis.Header.CalculateHash();
_genesis3Validators.Header.Hash = _genesis3Validators.Header.CalculateHash();

CodeInfoRepository codeInfoRepository = new();
TransactionProcessor transactionProcessor = new(goerliSpecProvider, stateProvider,
new VirtualMachine(blockhashProvider, specProvider, nodeLogManager),
new VirtualMachine(blockhashProvider, specProvider, codeInfoRepository, nodeLogManager),
codeInfoRepository,
nodeLogManager);
BlockProcessor blockProcessor = new(
goerliSpecProvider,
Expand All @@ -140,8 +142,8 @@ public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = f
IReadOnlyTrieStore minerTrieStore = trieStore.AsReadOnly();

WorldState minerStateProvider = new(minerTrieStore, codeDb, nodeLogManager);
VirtualMachine minerVirtualMachine = new(blockhashProvider, specProvider, nodeLogManager);
TransactionProcessor minerTransactionProcessor = new(goerliSpecProvider, minerStateProvider, minerVirtualMachine, nodeLogManager);
VirtualMachine minerVirtualMachine = new(blockhashProvider, specProvider, codeInfoRepository, nodeLogManager);
TransactionProcessor minerTransactionProcessor = new(goerliSpecProvider, minerStateProvider, minerVirtualMachine, codeInfoRepository, nodeLogManager);

BlockProcessor minerBlockProcessor = new(
goerliSpecProvider,
Expand Down
1 change: 1 addition & 0 deletions src/Nethermind/Nethermind.Clique.Test/StandardTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace Nethermind.Clique.Test
{
[TestFixture]
[Parallelizable(ParallelScope.All)]
[SetCulture("en-US")]
public class StandardTests
{
[Test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Nethermind.Consensus.AuRa.Validators;
using Nethermind.Core.Caching;
using Nethermind.Core.Crypto;
using Nethermind.Core.Specs;
using Nethermind.Int256;
using Nethermind.Logging;
using Nethermind.Serialization.Json;
Expand All @@ -17,7 +18,11 @@ namespace Nethermind.Consensus.AuRa.InitializationSteps
{
public class AuRaNethermindApi : NethermindApi
{
public AuRaNethermindApi(IConfigProvider configProvider, IJsonSerializer jsonSerializer, ILogManager logManager, ChainSpec chainSpec)
public AuRaNethermindApi(
IConfigProvider configProvider,
IJsonSerializer jsonSerializer,
ILogManager logManager,
ChainSpec chainSpec)
: base(configProvider, jsonSerializer, logManager, chainSpec)
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public BlockValidationTransactionsExecutor(ITransactionProcessorAdapter transact

public TxReceipt[] ProcessTransactions(Block block, ProcessingOptions processingOptions, BlockReceiptsTracer receiptsTracer, IReleaseSpec spec)
{
Evm.Metrics.ResetBlockStats();
Metrics.ResetBlockStats();
BlockExecutionContext blkCtx = new(block.Header);
for (int i = 0; i < block.Transactions.Length; i++)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public enum ProcessingOptions
/// <summary>
/// Processing options for engine_NewPayload
/// </summary>
EthereumMerge = MarkAsProcessed | DoNotUpdateHead | IgnoreParentNotOnMainChain
EthereumMerge = MarkAsProcessed | DoNotUpdateHead | IgnoreParentNotOnMainChain,
}

public static class ProcessingOptionsExtensions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ public ReadOnlyTxProcessingEnv(
ILogManager? logManager
) : base(readOnlyDbProvider, trieStore, blockTree, logManager)
{
IVirtualMachine machine = new VirtualMachine(BlockhashProvider, specProvider, logManager);
TransactionProcessor = new TransactionProcessor(specProvider, StateProvider, machine, logManager);
CodeInfoRepository codeInfoRepository = new();
IVirtualMachine machine = new VirtualMachine(BlockhashProvider, specProvider, codeInfoRepository, logManager);
TransactionProcessor = new TransactionProcessor(specProvider, StateProvider, machine, codeInfoRepository, logManager);
}

public IReadOnlyTransactionProcessor Build(Keccak stateRoot) => new ReadOnlyTransactionProcessor(TransactionProcessor, StateProvider, stateRoot);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,18 @@ public class ReadOnlyTxProcessingEnvBase
public IReadOnlyDbProvider DbProvider { get; }
public IBlockhashProvider BlockhashProvider { get; }

public ReadOnlyTxProcessingEnvBase(
IReadOnlyDbProvider? readOnlyDbProvider,
protected ReadOnlyTxProcessingEnvBase(
IReadOnlyDbProvider readOnlyDbProvider,
ITrieStore? trieStore,
IBlockTree? blockTree,
IBlockTree blockTree,
ILogManager? logManager
)
{
DbProvider = readOnlyDbProvider ?? throw new ArgumentNullException(nameof(readOnlyDbProvider));
DbProvider = readOnlyDbProvider;
ReadOnlyDb codeDb = readOnlyDbProvider.CodeDb.AsReadOnly(true);

StateReader = new StateReader(trieStore, codeDb, logManager);
StateProvider = new WorldState(trieStore, codeDb, logManager);

BlockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree));
BlockTree = blockTree;
BlockhashProvider = new BlockhashProvider(BlockTree, logManager);

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public bool ValidateSuggestedBlock(Block block)
/// <param name="receipts">List of tx receipts from the processed block (required only for better diagnostics when the receipt root is invalid).</param>
/// <param name="suggestedBlock">Block received from the network - unchanged.</param>
/// <returns><c>true</c> if the <paramref name="processedBlock"/> is valid; otherwise, <c>false</c>.</returns>
public virtual bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock)
public bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock)
{
bool isValid = processedBlock.Header.Hash == suggestedBlock.Header.Hash;
if (!isValid)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,23 @@ public class MultiCallBlockValidatorProxy : IBlockValidator
{
private readonly IBlockValidator _baseBlockValidator;

public MultiCallBlockValidatorProxy(IBlockValidator baseBlockValidator)
{
public MultiCallBlockValidatorProxy(IBlockValidator baseBlockValidator) =>
_baseBlockValidator = baseBlockValidator;
}

public bool Validate(BlockHeader header, BlockHeader? parent, bool isUncle = false)
{
return _baseBlockValidator.Validate(header, parent, isUncle);
}

public bool Validate(BlockHeader header, bool isUncle = false)
{
return _baseBlockValidator.Validate(header, isUncle);
}

public bool ValidateWithdrawals(Block block, out string? error)
{
return _baseBlockValidator.ValidateWithdrawals(block, out error);
}

public bool ValidateOrphanedBlock(Block block, out string? error)
{
return _baseBlockValidator.ValidateOrphanedBlock(block, out error);
}

public bool ValidateSuggestedBlock(Block block)
{
return _baseBlockValidator.ValidateSuggestedBlock(block);
}

public bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock)
{
return true;
}

public bool Validate(BlockHeader header, BlockHeader? parent, bool isUncle = false) =>
_baseBlockValidator.Validate(header, parent, isUncle);

public bool Validate(BlockHeader header, bool isUncle = false) =>
_baseBlockValidator.Validate(header, isUncle);

public bool ValidateWithdrawals(Block block, out string? error) =>
_baseBlockValidator.ValidateWithdrawals(block, out error);

public bool ValidateOrphanedBlock(Block block, out string? error) =>
_baseBlockValidator.ValidateOrphanedBlock(block, out error);

public bool ValidateSuggestedBlock(Block block) =>
_baseBlockValidator.ValidateSuggestedBlock(block);

public bool ValidateProcessedBlock(Block processedBlock, TxReceipt[] receipts, Block suggestedBlock) => true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,9 @@ protected virtual async Task<TestBlockchain> Build(ISpecProvider? specProvider =
_trieStoreWatcher = new TrieStoreBoundaryWatcher(TrieStore, BlockTree, LogManager);

ReceiptStorage = new InMemoryReceiptStorage();
VirtualMachine virtualMachine = new(new BlockhashProvider(BlockTree, LogManager), SpecProvider, LogManager);
TxProcessor = new TransactionProcessor(SpecProvider, State, virtualMachine, LogManager);
CodeInfoRepository codeInfoRepository = new();
VirtualMachine virtualMachine = new(new BlockhashProvider(BlockTree, LogManager), SpecProvider, codeInfoRepository, LogManager);
TxProcessor = new TransactionProcessor(SpecProvider, State, virtualMachine, codeInfoRepository, LogManager);
BlockPreprocessorStep = new RecoverSignatures(EthereumEcdsa, TxPool, SpecProvider, LogManager);
HeaderValidator = new HeaderValidator(BlockTree, Always.Valid, SpecProvider, LogManager);

Expand Down
9 changes: 9 additions & 0 deletions src/Nethermind/Nethermind.Core/Extensions/Bytes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,15 @@ public static Span<byte> WithoutLeadingZeros(this Span<byte> bytes)
return nonZeroIndex < 0 ? bytes[^1..] : bytes[nonZeroIndex..];
}

public static ReadOnlySpan<byte> WithoutLeadingZeros(this ReadOnlySpan<byte> bytes)
{
if (bytes.Length == 0) return new byte[] { 0 };

int nonZeroIndex = bytes.IndexOfAnyExcept((byte)0);
// Keep one or it will be interpreted as null
return nonZeroIndex < 0 ? bytes[^1..] : bytes[nonZeroIndex..];
}

public static byte[] Concat(byte prefix, byte[] bytes)
{
byte[] result = new byte[1 + bytes.Length];
Expand Down
Loading

0 comments on commit b6c3b21

Please sign in to comment.