Skip to content

Commit

Permalink
Add eth_simulate , support array of eth_call for simulation across mu…
Browse files Browse the repository at this point in the history
…ltiple blocks (#5530)

Co-authored-by: Ahmad Bitar <33181301+smartprogrammer93@users.noreply.github.com>
Co-authored-by: Ruben Buniatyan <rubo@users.noreply.github.com>
Co-authored-by: Kamil Chodoła <kamil@nethermind.io>
Co-authored-by: Kamil Chodoła <43241881+kamilchodola@users.noreply.github.com>
Co-authored-by: Lukasz Rozmej <lukasz.rozmej@gmail.com>
Co-authored-by: Ben Adams <thundercat@illyriad.co.uk>
  • Loading branch information
7 people authored Jun 10, 2024
1 parent 424d6f3 commit 97c597f
Show file tree
Hide file tree
Showing 165 changed files with 3,771 additions and 693 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 @@ -148,9 +148,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 @@ -162,6 +164,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 @@ -71,15 +71,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 @@ -18,6 +18,7 @@
using Nethermind.Core.Extensions;
using Nethermind.Core.Test.Builders;
using Nethermind.Crypto;
using Nethermind.Facade.Eth;
using Nethermind.Int256;
using Nethermind.JsonRpc.Data;
using Nethermind.JsonRpc.Test.Modules;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ private UserOperationSimulator UserOperationSimulator(Address entryPoint)

ReadOnlyTxProcessingEnvFactory readOnlyTxProcessingEnvFactory = new(
getFromApi.WorldStateManager!,
getFromApi.BlockTree,
getFromApi.BlockTree!,
getFromApi.SpecProvider,
getFromApi.LogManager);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ ResultWrapper<Hash256> Simulate(UserOperation userOperation,
UInt256? timestamp = null,
CancellationToken cancellationToken = default);

BlockchainBridge.CallOutput EstimateGas(BlockHeader header, Transaction tx,
CallOutput EstimateGas(BlockHeader header, Transaction tx,
CancellationToken cancellationToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ private Transaction BuildSimulateValidationTransaction(
}

[Todo("Refactor once BlockchainBridge is separated")]
public BlockchainBridge.CallOutput EstimateGas(BlockHeader header, Transaction tx, CancellationToken cancellationToken)
public CallOutput EstimateGas(BlockHeader header, Transaction tx, CancellationToken cancellationToken)
{
ReadOnlyTxProcessingEnv txProcessingEnv = _readOnlyTxProcessingEnvFactory.Create();
using IReadOnlyTransactionProcessor transactionProcessor = txProcessingEnv.Build(header.StateRoot!);
Expand All @@ -202,7 +202,7 @@ public BlockchainBridge.CallOutput EstimateGas(BlockHeader header, Transaction t
GasEstimator gasEstimator = new(transactionProcessor, _stateProvider, _specProvider, _blocksConfig);
long estimate = gasEstimator.Estimate(tx, header, estimateGasTracer, GasEstimator.DefaultErrorMargin, cancellationToken);

return new BlockchainBridge.CallOutput
return new CallOutput
{
Error = tryCallResult.Success ? estimateGasTracer.Error : tryCallResult.Error,
GasSpent = estimate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ public IEnumerable<Transaction> GetTransactions(BlockHeader parent, long gasLimi
// TODO: Remove logging, just for testing
_logger.Info($"Constructed tx from {userOperationsToInclude!.Count} userOperations: {userOperationTransaction.Hash}");

BlockchainBridge.CallOutput callOutput = _userOperationSimulators[entryPoint].EstimateGas(parent, userOperationTransaction, CancellationToken.None);
CallOutput callOutput = _userOperationSimulators[entryPoint].EstimateGas(parent, userOperationTransaction, CancellationToken.None);
FailedOp? failedOp = txBuilder.DecodeEntryPointOutputError(callOutput.OutputData);
if (failedOp is not null)
{
Expand Down
10 changes: 10 additions & 0 deletions src/Nethermind/Nethermind.Api/NethermindApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
using Nethermind.Evm.TransactionProcessing;
using Nethermind.Facade;
using Nethermind.Facade.Eth;
using Nethermind.Facade.Simulate;
using Nethermind.Grpc;
using Nethermind.JsonRpc;
using Nethermind.JsonRpc.Modules;
Expand Down Expand Up @@ -81,11 +82,20 @@ public IBlockchainBridge CreateBlockchainBridge()
SpecProvider,
LogManager);

SimulateReadOnlyBlocksProcessingEnvFactory simulateReadOnlyBlocksProcessingEnvFactory =
new SimulateReadOnlyBlocksProcessingEnvFactory(
WorldStateManager!,
readOnlyTree,
DbProvider!,
SpecProvider!,
LogManager);

IMiningConfig miningConfig = ConfigProvider.GetConfig<IMiningConfig>();
IBlocksConfig blocksConfig = ConfigProvider.GetConfig<IBlocksConfig>();

return new BlockchainBridge(
readOnlyTxProcessingEnv,
simulateReadOnlyBlocksProcessingEnvFactory,
TxPool,
ReceiptFinder,
FilterStore,
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, specProvider, stateProvider, 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 @@ -57,14 +57,17 @@ public void Setup()
LimboLogs.Instance,
transactionComparerProvider.GetDefaultComparer());
BlockhashProvider blockhashProvider = new(_blockTree, specProvider, stateProvider, 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 @@ -195,7 +195,7 @@ public void Proper_transactions_selected(ProperTransactionsSelectedTestCase test
MemDb stateDb = new();
MemDb codeDb = new();
TrieStore trieStore = new(stateDb, LimboLogs.Instance);
WorldState stateProvider = new(trieStore, codeDb, LimboLogs.Instance);
IWorldState stateProvider = new WorldState(trieStore, codeDb, LimboLogs.Instance);
StateReader _ = new(new TrieStore(stateDb, LimboLogs.Instance), codeDb, LimboLogs.Instance);
ISpecProvider specProvider = Substitute.For<ISpecProvider>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ public void Proper_transactions_selected(TransactionSelectorTests.ProperTransact
MemDb stateDb = new();
MemDb codeDb = new();
TrieStore trieStore = new(stateDb, LimboLogs.Instance);
WorldState stateProvider = new(trieStore, codeDb, LimboLogs.Instance);
IWorldState stateProvider = new WorldState(trieStore, codeDb, LimboLogs.Instance);
ISpecProvider specProvider = Substitute.For<ISpecProvider>();

IReleaseSpec spec = testCase.ReleaseSpec;
Expand Down
21 changes: 8 additions & 13 deletions src/Nethermind/Nethermind.Blockchain/BlockTree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -801,22 +801,17 @@ private void DeleteBlocks(Hash256 deletePointer)
return childHash;
}

public bool IsMainChain(BlockHeader blockHeader)
{
ChainLevelInfo? chainLevelInfo = LoadLevel(blockHeader.Number);
bool isMain = chainLevelInfo is not null && chainLevelInfo.MainChainBlock?.BlockHash.Equals(blockHeader.Hash) == true;
return isMain;
}
public bool IsMainChain(BlockHeader blockHeader) =>
LoadLevel(blockHeader.Number)?.MainChainBlock?.BlockHash.Equals(blockHeader.Hash) == true;

public bool IsMainChain(Hash256 blockHash)
public bool IsMainChain(Hash256 blockHash, bool throwOnMissingHash = true)
{
BlockHeader? header = FindHeader(blockHash, BlockTreeLookupOptions.TotalDifficultyNotNeeded);
if (header is null)
{
throw new InvalidOperationException($"Not able to retrieve block number for an unknown block {blockHash}");
}

return IsMainChain(header);
return header is not null
? IsMainChain(header)
: throwOnMissingHash
? throw new InvalidOperationException($"Not able to retrieve block number for an unknown block {blockHash}")
: false;
}

public BlockHeader? FindBestSuggestedHeader() => BestSuggestedHeader;
Expand Down
Loading

0 comments on commit 97c597f

Please sign in to comment.