diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/RegisterAuRaRpcModules.cs b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/RegisterAuRaRpcModules.cs index 18022b96fe3..ec275c51d2f 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/RegisterAuRaRpcModules.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/RegisterAuRaRpcModules.cs @@ -35,6 +35,7 @@ using Nethermind.State; using Nethermind.Synchronization.ParallelSync; using Nethermind.Trie.Pruning; +using Nethermind.Facade; namespace Nethermind.Consensus.AuRa.InitializationSteps; @@ -69,6 +70,8 @@ protected override void RegisterTraceRpcModule(IRpcModuleProvider rpcModuleProvi _api.WorldStateManager, _api.BlockTree, _jsonRpcConfig, + _api.CreateBlockchainBridge(), + new BlocksConfig().SecondsPerSlot, _api.BlockPreprocessor, _api.RewardCalculatorSource, _api.ReceiptStorage, @@ -84,6 +87,8 @@ protected class AuRaTraceModuleFactory( IWorldStateManager worldStateManager, IBlockTree blockTree, IJsonRpcConfig jsonRpcConfig, + IBlockchainBridge blockchainBridge, + ulong secondsPerSlot, IBlockPreprocessorStep recoveryStep, IRewardCalculatorSource rewardCalculatorSource, IReceiptStorage receiptFinder, @@ -91,7 +96,7 @@ protected class AuRaTraceModuleFactory( IPoSSwitcher poSSwitcher, ILogManager logManager, IAuRaBlockProcessorFactory factory) - : TraceModuleFactory(worldStateManager, blockTree, jsonRpcConfig, recoveryStep, rewardCalculatorSource, + : TraceModuleFactory(worldStateManager, blockTree, jsonRpcConfig, blockchainBridge, secondsPerSlot, recoveryStep, rewardCalculatorSource, receiptFinder, specProvider, poSSwitcher, logManager) { protected override ReadOnlyChainProcessingEnv CreateChainProcessingEnv(IOverridableWorldScope worldStateManager, diff --git a/src/Nethermind/Nethermind.Core/Resettables/ResettableList.cs b/src/Nethermind/Nethermind.Core/Resettables/ResettableList.cs index 937b914848c..b8a4d4cf5e4 100644 --- a/src/Nethermind/Nethermind.Core/Resettables/ResettableList.cs +++ b/src/Nethermind/Nethermind.Core/Resettables/ResettableList.cs @@ -7,7 +7,7 @@ namespace Nethermind.Core.Resettables; -public class ResettableList : IList, IReadOnlyCollection +public class ResettableList : IList, IReadOnlyList { private readonly List _wrapped; private readonly int _startCapacity; diff --git a/src/Nethermind/Nethermind.Evm/Tracing/BlockTracerBase.cs b/src/Nethermind/Nethermind.Evm/Tracing/BlockTracerBase.cs index 3a0522018ef..d36201565bb 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/BlockTracerBase.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/BlockTracerBase.cs @@ -67,7 +67,7 @@ public virtual void EndBlockTrace() { } protected DisposableResettableList TxTraces { get; } - public IReadOnlyCollection BuildResult() => TxTraces; + public IReadOnlyList BuildResult() => TxTraces; protected virtual void AddTrace(TTrace trace) => TxTraces.Add(trace); } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/IBlockTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/IBlockTracer.cs index 09dc03e4bcf..3fd8e2c708d 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/IBlockTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/IBlockTracer.cs @@ -59,6 +59,6 @@ public interface IBlockTracer public interface IBlockTracer : IBlockTracer { - IReadOnlyCollection BuildResult(); + IReadOnlyList BuildResult(); } } diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ISimulateResult.cs b/src/Nethermind/Nethermind.Evm/Tracing/ISimulateResult.cs new file mode 100644 index 00000000000..8f0ecb37fd1 --- /dev/null +++ b/src/Nethermind/Nethermind.Evm/Tracing/ISimulateResult.cs @@ -0,0 +1,6 @@ +namespace Nethermind.Evm.Tracing; + +public interface ISimulateResult +{ + string? Error { get; set; } +} \ No newline at end of file diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTrace.cs b/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTrace.cs index c17f99201d6..31e465a03b6 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTrace.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTrace.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Text.Json.Serialization; - +// using Nethermind.Evm.Tracing; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Serialization.Json; @@ -12,6 +12,8 @@ namespace Nethermind.Evm.Tracing.ParityStyle { public class ParityLikeTxTrace { + public string? Error { get; set; } + public byte[]? Output { get; set; } public Hash256? BlockHash { get; set; } diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index f841afbbf9e..f7d6886de7a 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -15,6 +15,8 @@ using Nethermind.Int256; using Nethermind.Evm; using Nethermind.Evm.Tracing; +using Nethermind.Evm.Tracing.GethStyle; +using Nethermind.Evm.Tracing.ParityStyle; using Nethermind.Trie; using Nethermind.TxPool; using Block = Nethermind.Core.Block; @@ -29,6 +31,7 @@ using Nethermind.Facade.Find; using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.Facade.Simulate; +using Nethermind.Facade.Tracing; using Transaction = Nethermind.Core.Transaction; namespace Nethermind.Facade @@ -165,15 +168,32 @@ public CallOutput Call(BlockHeader header, Transaction tx, Dictionary payload, CancellationToken cancellationToken) + public SimulateOutput Simulate( + BlockHeader header, + SimulatePayload payload, + CancellationToken cancellationToken, + ITracerFactory tracerFactory) + where TTracer : class, IBlockTracer { - SimulateBlockTracer simulateOutputTracer = new(payload.TraceTransfers, payload.ReturnFullTransactionObjects, _specProvider); - BlockReceiptsTracer tracer = new(); - tracer.SetOtherTracer(simulateOutputTracer); - SimulateOutput result = new(); + TTracer tracer = tracerFactory.CreateTracer(payload.TraceTransfers, payload.ReturnFullTransactionObjects, _specProvider); + BlockReceiptsTracer receiptsTracer = new(); + receiptsTracer.SetOtherTracer(tracer); + + SimulateOutput result = new(); + try { - if (!_simulateBridgeHelper.TrySimulate(header, payload, simulateOutputTracer, new CancellationBlockTracer(tracer, cancellationToken), out string error)) + // if (tracer is not SimulateBlockTracer validatedTracer) + // { + // throw new InvalidOperationException($"Unsupported tracer type: {typeof(TTracer).Name}"); + // } + + if (!_simulateBridgeHelper.TrySimulate( + header, + payload, + tracer, + new CancellationBlockTracer(receiptsTracer, cancellationToken), + out string error)) { result.Error = error; } @@ -187,10 +207,10 @@ public SimulateOutput Simulate(BlockHeader header, SimulatePayload { Items = tracer.BuildResult() }; } + public CallOutput EstimateGas(BlockHeader header, Transaction tx, int errorMargin, Dictionary? stateOverride, CancellationToken cancellationToken) { using IOverridableTxProcessingScope scope = _processingEnv.BuildAndOverride(header, stateOverride); @@ -432,5 +452,68 @@ public IEnumerable FindLogs(LogFilter filter, CancellationToken cance { return _logFinder.FindLogs(filter, cancellationToken); } + + public class SimulateBlockTracerFactory : ITracerFactory> + { + public SimulateBlockTracer CreateTracer(bool traceTransfers, bool returnFullTransactionObjects, ISpecProvider specProvider) + { + return new SimulateBlockTracer(traceTransfers, returnFullTransactionObjects, specProvider); + } + } + + public class GethLikeBlockMemoryTracerFactory(GethTraceOptions options) + : ITracerFactory, SimulateBlockResult> + { + public TraceSimulateTracer CreateTracer(bool traceTransfers, bool returnFullTransactionObjects, ISpecProvider specProvider) + { + return new TraceSimulateTracer(new GethLikeBlockMemoryTracer(options), specProvider); + } + } + + public class ParityLikeBlockTracerFactory(ParityTraceTypes types) : ITracerFactory, SimulateBlockResult> + { + public TraceSimulateTracer CreateTracer(bool traceTransfers, bool returnFullTransactionObjects, ISpecProvider specProvider) + { + return new TraceSimulateTracer(new ParityLikeBlockTracer(types), specProvider); + } + } + + public class TraceSimulateTracer(IBlockTracer inner, ISpecProvider specProvider) : IBlockTracer> + { + private readonly List> _results = new(); + private Block _currentBlock; + + public IReadOnlyList> BuildResult() => _results; + + public bool IsTracingRewards => inner.IsTracingRewards; + + public void ReportReward(Address author, string rewardType, UInt256 rewardValue) + { + inner.ReportReward(author, rewardType, rewardValue); + } + + public void StartNewBlockTrace(Block block) + { + _currentBlock = block; + inner.StartNewBlockTrace(block); + } + + public ITxTracer StartNewTxTrace(Transaction? tx) + { + return inner.StartNewTxTrace(tx); + } + + public void EndTxTrace() + { + inner.EndTxTrace(); + } + + public void EndBlockTrace() + { + inner.EndBlockTrace(); + _results.Add(new SimulateBlockResult(_currentBlock, false, specProvider) { Calls = inner.BuildResult() }); + } + } + } } diff --git a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs index 459dd3f3de1..25c1c84f0e1 100644 --- a/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/IBlockchainBridge.cs @@ -8,6 +8,9 @@ using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Evm; +using Nethermind.Evm.Tracing; +using Nethermind.Facade; +using Nethermind.Facade.Tracing; using Nethermind.Facade.Filters; using Nethermind.Facade.Find; using Nethermind.Facade.Simulate; @@ -28,7 +31,7 @@ public interface IBlockchainBridge : ILogFinder (TxReceipt? Receipt, TxGasInfo? GasInfo, int LogIndexStart) GetReceiptAndGasInfo(Hash256 txHash); (TxReceipt? Receipt, Transaction? Transaction, UInt256? baseFee) GetTransaction(Hash256 txHash, bool checkTxnPool = true); CallOutput Call(BlockHeader header, Transaction tx, Dictionary? stateOverride = null, CancellationToken cancellationToken = default); - SimulateOutput Simulate(BlockHeader header, SimulatePayload payload, CancellationToken cancellationToken); + SimulateOutput Simulate(BlockHeader header, SimulatePayload payload, CancellationToken cancellationToken, ITracerFactory tracerFactory) where TTracer : class, IBlockTracer; CallOutput EstimateGas(BlockHeader header, Transaction tx, int errorMarginBasisPoints, Dictionary? stateOverride = null, CancellationToken cancellationToken = default); CallOutput CreateAccessList(BlockHeader header, Transaction tx, CancellationToken cancellationToken, bool optimize); diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/ISimulateResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/ISimulateResult.cs new file mode 100644 index 00000000000..759795e8e83 --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/ISimulateResult.cs @@ -0,0 +1,6 @@ +namespace Nethermind.Facade.Proxy.Models.Simulate; + +public interface ISimulateResult +{ + Error? Error { get; set; } +} \ No newline at end of file diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs index 934fbcf5db0..58a50f049d2 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateBlockResult.cs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited // SPDX-License-Identifier: LGPL-3.0-only +using System; using System.Collections.Generic; using Nethermind.Core; using Nethermind.Core.Specs; @@ -8,8 +9,8 @@ namespace Nethermind.Facade.Proxy.Models.Simulate; -public class SimulateBlockResult(Block source, bool includeFullTransactionData, ISpecProvider specProvider) +public class SimulateBlockResult(Block source, bool includeFullTransactionData, ISpecProvider specProvider) : BlockForRpc(source, includeFullTransactionData, specProvider) { - public List Calls { get; set; } = new(); + public IReadOnlyList Calls { get; set; } = Array.Empty(); } diff --git a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateCallResult.cs b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateCallResult.cs index 74f2f411f2d..9fd0580c954 100644 --- a/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateCallResult.cs +++ b/src/Nethermind/Nethermind.Facade/Proxy/Models/Simulate/SimulateCallResult.cs @@ -5,7 +5,7 @@ namespace Nethermind.Facade.Proxy.Models.Simulate; -public class SimulateCallResult +public class SimulateCallResult : ISimulateResult { public ulong Status { get; set; } public byte[]? ReturnData { get; set; } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs index dd0fd8e68fb..b70fadc23b7 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBlockTracer.cs @@ -10,12 +10,14 @@ namespace Nethermind.Facade.Simulate; -public class SimulateBlockTracer(bool isTracingLogs, bool includeFullTxData, ISpecProvider spec) : BlockTracer +public class SimulateBlockTracer(bool isTracingLogs, bool includeFullTxData, ISpecProvider spec) + : BlockTracer, IBlockTracer> { private readonly List _txTracers = new(); - private Block _currentBlock = null!; - public List Results { get; } = new(); + private List> Results { get; } = new(); + + public IReadOnlyList> BuildResult() => Results; public override void StartNewBlockTrace(Block block) { @@ -25,7 +27,6 @@ public override void StartNewBlockTrace(Block block) public override ITxTracer StartNewTxTrace(Transaction? tx) { - if (tx?.Hash is not null) { ulong txIndex = (ulong)_txTracers.Count; @@ -34,17 +35,15 @@ public override ITxTracer StartNewTxTrace(Transaction? tx) _txTracers.Add(result); return result; } - return NullTxTracer.Instance; } public override void EndBlockTrace() { - SimulateBlockResult? result = new(_currentBlock, includeFullTxData, spec) + SimulateBlockResult result = new(_currentBlock, includeFullTxData, spec) { Calls = _txTracers.Select(t => t.TraceResult).ToList(), }; - Results.Add(result); } } diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index 33f55e74aed..cf2b7324e52 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -56,22 +56,25 @@ private void PrepareState(BlockHeader blockHeader, blockHeader.StateRoot = stateProvider.StateRoot; } - public bool TrySimulate( + public bool TrySimulate( BlockHeader parent, SimulatePayload payload, - SimulateBlockTracer simulateOutputTracer, - IBlockTracer tracer, - [NotNullWhen(false)] out string? error) => - TrySimulate(parent, payload, simulateOutputTracer, tracer, simulateProcessingEnvFactory.Create(payload.Validation), out error); - + TTracer tracer, + IBlockTracer blockTracer, + [NotNullWhen(false)] out string? error) + where TTracer : class + { + return TrySimulate(parent, payload, tracer, blockTracer, simulateProcessingEnvFactory.Create(payload.Validation), out error); + } - private bool TrySimulate( + private bool TrySimulate( BlockHeader parent, SimulatePayload payload, - SimulateBlockTracer simulateOutputTracer, - IBlockTracer tracer, + TTracer tracer, + IBlockTracer blockTracer, SimulateReadOnlyBlocksProcessingEnv env, [NotNullWhen(false)] out string? error) + where TTracer : class { IBlockTree blockTree = env.BlockTree; IWorldState stateProvider = env.WorldState; @@ -87,7 +90,7 @@ private bool TrySimulate( { nonceCache.Clear(); - BlockHeader callHeader = GetCallHeader(blockCall, parent, payload.Validation, spec); //currentSpec is still parent spec + BlockHeader callHeader = GetCallHeader(blockCall, parent, payload.Validation, spec); spec = env.SpecProvider.GetSpec(callHeader); PrepareState(callHeader, parent, blockCall, env.WorldState, env.CodeInfoRepository, spec); Transaction[] transactions = CreateTransactions(payload, blockCall, callHeader, stateProvider, nonceCache); @@ -106,10 +109,15 @@ private bool TrySimulate( suggestedBlocks[0] = currentBlock; IBlockProcessor processor = env.GetProcessor(payload.Validation, spec.IsEip4844Enabled ? blockCall.BlockOverrides?.BlobBaseFee : null); - Block processedBlock = processor.Process(stateProvider.StateRoot, suggestedBlocks, processingFlags, tracer)[0]; + Block processedBlock = processor.Process(stateProvider.StateRoot, suggestedBlocks, processingFlags, blockTracer)[0]; FinalizeStateAndBlock(stateProvider, processedBlock, spec, currentBlock, blockTree); - CheckMisssingAndSetTracedDefaults(simulateOutputTracer, processedBlock); + + // if (tracer is SimulateBlockTracer simulateBlockTracer) + // { + // CheckMisssingAndSetTracedDefaults(simulateBlockTracer.Results, processedBlock); + // } + parent = processedBlock.Header; } @@ -119,18 +127,6 @@ private bool TrySimulate( return true; } - private static void CheckMisssingAndSetTracedDefaults(SimulateBlockTracer simulateOutputTracer, Block processedBlock) - { - SimulateBlockResult current = simulateOutputTracer.Results.Last(); - current.StateRoot = processedBlock.StateRoot ?? Hash256.Zero; - current.ParentBeaconBlockRoot = processedBlock.ParentBeaconBlockRoot ?? Hash256.Zero; - current.TransactionsRoot = processedBlock.Header.TxRoot; - current.WithdrawalsRoot = processedBlock.WithdrawalsRoot ?? Keccak.EmptyTreeHash; - current.ExcessBlobGas = processedBlock.ExcessBlobGas ?? 0; - current.Withdrawals = processedBlock.Withdrawals ?? []; - current.Author = null; - } - private static void FinalizeStateAndBlock(IWorldState stateProvider, Block processedBlock, IReleaseSpec currentSpec, Block currentBlock, IBlockTree blockTree) { stateProvider.StateRoot = processedBlock.StateRoot!; diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs index 448147f8566..ecec1e93221 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs @@ -6,10 +6,10 @@ namespace Nethermind.Facade.Simulate; -public class SimulateOutput +public class SimulateOutput { public string? Error { get; set; } public int? ErrorCode { get; set; } - public IReadOnlyList Items { get; set; } + public IReadOnlyList Items { get; set; } } diff --git a/src/Nethermind/Nethermind.Facade/Tracing/ITracerFactory.cs b/src/Nethermind/Nethermind.Facade/Tracing/ITracerFactory.cs new file mode 100644 index 00000000000..9c76bfce53e --- /dev/null +++ b/src/Nethermind/Nethermind.Facade/Tracing/ITracerFactory.cs @@ -0,0 +1,11 @@ +using Nethermind.Consensus.Tracing; +using Nethermind.Core.Specs; +using Nethermind.Evm.Tracing; + +namespace Nethermind.Facade.Tracing +{ + public interface ITracerFactory where TTracer : IBlockTracer + { + TTracer CreateTracer(bool traceTransfers, bool returnFullTransactionObjects, ISpecProvider specProvider); + } +} diff --git a/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs b/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs index 926181193dd..6c39e542452 100644 --- a/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs +++ b/src/Nethermind/Nethermind.Init/Steps/RegisterRpcModules.cs @@ -285,6 +285,8 @@ protected ModuleFactoryBase CreateTraceModuleFactory() _api.WorldStateManager, _api.BlockTree, _jsonRpcConfig, + _api.CreateBlockchainBridge(), + new BlocksConfig().SecondsPerSlot, _api.BlockPreprocessor, _api.RewardCalculatorSource, _api.ReceiptStorage, diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs index e1253ae2f81..bd8d3f40e33 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/JsonRpcServiceTests.cs @@ -99,9 +99,9 @@ public void CanRunEthSimulateV1Empty() string serializedCall = new EthereumJsonSerializer().Serialize(payload); IEthRpcModule ethRpcModule = Substitute.For(); ethRpcModule.eth_simulateV1(payload).ReturnsForAnyArgs(static _ => - ResultWrapper>.Success(Array.Empty())); + ResultWrapper>>.Success(Array.Empty>())); JsonRpcSuccessResponse? response = TestRequest(ethRpcModule, "eth_simulateV1", serializedCall) as JsonRpcSuccessResponse; - Assert.That(response?.Result, Is.EqualTo(Array.Empty())); + Assert.That(response?.Result, Is.EqualTo(Array.Empty>())); } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs index d41e9f31085..3273efdf44a 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthSimulateTestsPrecompilesWithRedirection.cs @@ -63,7 +63,7 @@ public async Task Test_eth_simulate_create() //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig(), new BlocksConfig().SecondsPerSlot); - ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); + ResultWrapper>> result = executor.Execute(payload, BlockParameter.Latest); //Check results byte[]? returnData = result.Data[0].Calls.First().ReturnData; @@ -181,7 +181,7 @@ function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns( Debug.Assert(contractAddress is not null, nameof(contractAddress) + " is not null"); Assert.That(chain.State.AccountExists(contractAddress), Is.True); - ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); + ResultWrapper>> result = executor.Execute(payload, BlockParameter.Latest); //Check results byte[] addressBytes = result.Data[0].Calls[0].ReturnData!.SliceWithZeroPaddingEmptyOnError(12, 20); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs index 184cafd0e12..7876f81b754 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsBlocksAndTransactions.cs @@ -76,11 +76,11 @@ public async Task Test_eth_simulate_serialisation() //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig(), new BlocksConfig().SecondsPerSlot); - ResultWrapper> result = executor.Execute(payload, BlockParameter.Latest); - IReadOnlyList data = result.Data; + ResultWrapper>> result = executor.Execute(payload, BlockParameter.Latest); + IReadOnlyList> data = result.Data; Assert.That(data.Count, Is.EqualTo(7)); - SimulateBlockResult blockResult = data.Last(); + SimulateBlockResult blockResult = data.Last(); blockResult.Calls.Select(static c => c.Status).Should().BeEquivalentTo(new[] { (ulong)ResultType.Success, (ulong)ResultType.Success }); } @@ -150,13 +150,13 @@ public async Task Test_eth_simulate_eth_moved() //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig(), new BlocksConfig().SecondsPerSlot); - ResultWrapper> result = + ResultWrapper>> result = executor.Execute(payload, BlockParameter.Latest); - IReadOnlyList data = result.Data; + IReadOnlyList> data = result.Data; Assert.That(data.Count, Is.EqualTo(9)); - SimulateBlockResult blockResult = data[0]; + SimulateBlockResult blockResult = data[0]; Assert.That(blockResult.Calls.Count, Is.EqualTo(2)); blockResult = data.Last(); Assert.That(blockResult.Calls.Count, Is.EqualTo(2)); @@ -235,7 +235,7 @@ public async Task Test_eth_simulate_transactions_forced_fail() //will mock our GetCachedCodeInfo function - it shall be called 3 times if redirect is working, 2 times if not SimulateTxExecutor executor = new(chain.Bridge, chain.BlockFinder, new JsonRpcConfig(), new BlocksConfig().SecondsPerSlot); - ResultWrapper> result = + ResultWrapper>> result = executor.Execute(payload, BlockParameter.Latest); Assert.That(result.Result!.Error!.Contains("higher than sender balance"), Is.True); } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs index 5653e15fffa..9b3ff72377e 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsHiveBase.cs @@ -72,7 +72,7 @@ public async Task TestsimulateHive(string name, string data) SimulatePayload? payload = serializer.Deserialize>(data); TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain(); Console.WriteLine($"current test: {name}"); - ResultWrapper> result = + ResultWrapper>> result = chain.EthRpcModule.eth_simulateV1(payload!, BlockParameter.Latest); Console.WriteLine(); diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsSimplePrecompiles.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsSimplePrecompiles.cs index 020049685cd..2f189be4400 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsSimplePrecompiles.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/Simulate/EthSimulateTestsSimplePrecompiles.cs @@ -14,6 +14,7 @@ using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.Facade.Simulate; using NUnit.Framework; +using Nethermind.Facade; namespace Nethermind.JsonRpc.Test.Modules.Eth; @@ -94,7 +95,12 @@ public async Task Test_eth_simulate_erc() TraceTransfers = true }; - SimulateOutput result = chain.Bridge.Simulate(chain.BlockFinder.Head?.Header!, payload, CancellationToken.None); + SimulateOutput> result = chain.Bridge.Simulate( + chain.BlockFinder.Head?.Header!, + payload, + CancellationToken.None, + new BlockchainBridge.SimulateBlockTracerFactory() + ); byte[] addressBytes = result.Items[0].Calls[0].ReturnData!.SliceWithZeroPaddingEmptyOnError(12, 20); Address resultingAddress = new(addressBytes); diff --git a/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStoreRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStoreRpcModule.cs index fb559dd532c..3cdb8c98de1 100644 --- a/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStoreRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc.TraceStore/TraceStoreRpcModule.cs @@ -13,6 +13,7 @@ using Nethermind.JsonRpc.Modules; using Nethermind.JsonRpc.Modules.Trace; using Nethermind.Logging; +using Nethermind.Facade.Proxy.Models.Simulate; namespace Nethermind.JsonRpc.TraceStore; @@ -57,6 +58,9 @@ public ResultWrapper trace_call(TransactionForRpc call, Dictionary? stateOverride = null) => _traceModule.trace_call(call, traceTypes, blockParameter, stateOverride); + public ResultWrapper>> trace_simulateV1( + SimulatePayload payload, BlockParameter? blockParameter = null) => _traceModule.trace_simulateV1(payload, blockParameter); + public ResultWrapper> trace_callMany(TransactionForRpcWithTraceTypes[] calls, BlockParameter? blockParameter = null) => _traceModule.trace_callMany(calls, blockParameter); diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugRpcModule.cs index dce860a1a30..3f16d11db4d 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/IDebugRpcModule.cs @@ -7,6 +7,7 @@ using Nethermind.Core.Crypto; using Nethermind.Evm.Tracing.GethStyle; using Nethermind.Facade.Eth.RpcTransaction; +using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.JsonRpc.Data; using Nethermind.JsonRpc.Modules.Eth; using Nethermind.Synchronization.Reporting; @@ -115,4 +116,7 @@ public interface IDebugRpcModule : IRpcModule [JsonRpcMethod(Description = "Return list of invalid blocks.")] ResultWrapper> debug_getBadBlocks(); + + // ResultWrapper>> debug_traceSimulateV1( + // SimulatePayload payload, BlockParameter? blockParameter = null); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs index 7ea3bbee58d..d77914dc4eb 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs @@ -342,9 +342,12 @@ public ResultWrapper eth_call(TransactionForRpc transactionCall, BlockPa new CallTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) .ExecuteTx(transactionCall, blockParameter, stateOverride); - public ResultWrapper> eth_simulateV1(SimulatePayload payload, BlockParameter? blockParameter = null) => - new SimulateTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig, _secondsPerSlot) + public ResultWrapper>> eth_simulateV1( + SimulatePayload payload, BlockParameter? blockParameter = null) + { + return new SimulateTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig, _secondsPerSlot) .Execute(payload, blockParameter); + } public ResultWrapper eth_estimateGas(TransactionForRpc transactionCall, BlockParameter? blockParameter, Dictionary? stateOverride = null) => new EstimateGasTxExecutor(_blockchainBridge, _blockFinder, _rpcConfig) diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs index 70f98a767c3..efe8738b964 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs @@ -158,7 +158,7 @@ public interface IEthRpcModule : IRpcModule Description = "Executes a simulation across multiple blocks (does not create a transaction or block)", IsSharable = false, ExampleResponse = "0x")] - ResultWrapper> eth_simulateV1([JsonRpcParameter(ExampleValue = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0000000000000000000000000000000000000001\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061003a5760003560e01c806305fdbc81146101ee578063c00692601461020a5761003b565b5b600036606060008060008086868101906100559190610462565b93509350935093506000806000868686866040516020016100799493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101bb576000806212345673ffffffffffffffffffffffffffffffffffffffff166127108b8b6040516101249291906105ad565b60006040518083038160008787f1925050503d8060008114610162576040519150601f19603f3d011682016040523d82523d6000602084013e610167565b606091505b5091509150816101ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a39061066f565b60405180910390fd5b809750505050505050506101e3565b806040516020016101cc9190610709565b604051602081830303815290604052955050505050505b915050805190602001f35b6102086004803603810190610203919061093a565b610226565b005b610224600480360381019061021f9190610983565b6102ec565b005b60005b81518110156102e8576102d5828281518110610248576102476109fe565b5b602002602001015160000151838381518110610267576102666109fe565b5b602002602001015160200151848481518110610286576102856109fe565b5b6020026020010151604001518585815181106102a5576102a46109fe565b5b6020026020010151606001518686815181106102c4576102c36109fe565b5b6020026020010151608001516102ec565b80806102e090610a66565b915050610229565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361035b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035290610afa565b60405180910390fd5b80600080878787876040516020016103769493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b610406816103f3565b811461041157600080fd5b50565b600081359050610423816103fd565b92915050565b600060ff82169050919050565b61043f81610429565b811461044a57600080fd5b50565b60008135905061045c81610436565b92915050565b6000806000806080858703121561047c5761047b6103e9565b5b600061048a87828801610414565b945050602061049b8782880161044d565b93505060406104ac87828801610414565b92505060606104bd87828801610414565b91505092959194509250565b6000819050919050565b6104e46104df826103f3565b6104c9565b82525050565b60008160f81b9050919050565b6000610502826104ea565b9050919050565b61051a61051582610429565b6104f7565b82525050565b600061052c82876104d3565b60208201915061053c8286610509565b60018201915061054c82856104d3565b60208201915061055c82846104d3565b60208201915081905095945050505050565b600081905092915050565b82818337600083830152505050565b6000610594838561056e565b93506105a1838584610579565b82840190509392505050565b60006105ba828486610588565b91508190509392505050565b600082825260208201905092915050565b7f6661696c656420746f2063616c6c206d6f7665642065637265636f766572206160008201527f742061646472657373203078303030303030303030303030303030303030303060208201527f3030303030303030303030303030313233343536000000000000000000000000604082015250565b60006106596054836105c6565b9150610664826105d7565b606082019050919050565b600060208201905081810360008301526106888161064c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106ba8261068f565b9050919050565b60008160601b9050919050565b60006106d9826106c1565b9050919050565b60006106eb826106ce565b9050919050565b6107036106fe826106af565b6106e0565b82525050565b600061071582846106f2565b60148201915081905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61077282610729565b810181811067ffffffffffffffff821117156107915761079061073a565b5b80604052505050565b60006107a46103df565b90506107b08282610769565b919050565b600067ffffffffffffffff8211156107d0576107cf61073a565b5b602082029050602081019050919050565b600080fd5b600080fd5b6107f4816106af565b81146107ff57600080fd5b50565b600081359050610811816107eb565b92915050565b600060a0828403121561082d5761082c6107e6565b5b61083760a061079a565b9050600061084784828501610414565b600083015250602061085b8482850161044d565b602083015250604061086f84828501610414565b604083015250606061088384828501610414565b606083015250608061089784828501610802565b60808301525092915050565b60006108b66108b1846107b5565b61079a565b90508083825260208201905060a084028301858111156108d9576108d86107e1565b5b835b8181101561090257806108ee8882610817565b84526020840193505060a0810190506108db565b5050509392505050565b600082601f83011261092157610920610724565b5b81356109318482602086016108a3565b91505092915050565b6000602082840312156109505761094f6103e9565b5b600082013567ffffffffffffffff81111561096e5761096d6103ee565b5b61097a8482850161090c565b91505092915050565b600080600080600060a0868803121561099f5761099e6103e9565b5b60006109ad88828901610414565b95505060206109be8882890161044d565b94505060406109cf88828901610414565b93505060606109e088828901610414565b92505060806109f188828901610802565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000610a7182610a5c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610aa357610aa2610a2d565b5b600182019050919050565b7f72657475726e20616464726573732063616e6e6f742062652030783000000000600082015250565b6000610ae4601c836105c6565b9150610aef82610aae565b602082019050919050565b60006020820190508181036000830152610b1381610ad7565b905091905056fea2646970667358221220154f5b68ccfa5be744e7245765a3530dac4035052284a68b5dded1945b45075e64736f6c63430008120033\",\"MovePrecompileToAddress\":\"0x0000000000000000000000000000000000123456\"},\"0xc100000000000000000000000000000000000000\":{\"balance\":\"0x30d40\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0xc00692604554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554490000000000000000000000000000000000000000000000000000000000\"}]}]}")] SimulatePayload payload, + ResultWrapper>> eth_simulateV1([JsonRpcParameter(ExampleValue = "{\"blockStateCalls\":[{\"stateOverrides\":{\"0x0000000000000000000000000000000000000001\":{\"code\":\"0x608060405234801561001057600080fd5b506004361061003a5760003560e01c806305fdbc81146101ee578063c00692601461020a5761003b565b5b600036606060008060008086868101906100559190610462565b93509350935093506000806000868686866040516020016100799493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101bb576000806212345673ffffffffffffffffffffffffffffffffffffffff166127108b8b6040516101249291906105ad565b60006040518083038160008787f1925050503d8060008114610162576040519150601f19603f3d011682016040523d82523d6000602084013e610167565b606091505b5091509150816101ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101a39061066f565b60405180910390fd5b809750505050505050506101e3565b806040516020016101cc9190610709565b604051602081830303815290604052955050505050505b915050805190602001f35b6102086004803603810190610203919061093a565b610226565b005b610224600480360381019061021f9190610983565b6102ec565b005b60005b81518110156102e8576102d5828281518110610248576102476109fe565b5b602002602001015160000151838381518110610267576102666109fe565b5b602002602001015160200151848481518110610286576102856109fe565b5b6020026020010151604001518585815181106102a5576102a46109fe565b5b6020026020010151606001518686815181106102c4576102c36109fe565b5b6020026020010151608001516102ec565b80806102e090610a66565b915050610229565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361035b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035290610afa565b60405180910390fd5b80600080878787876040516020016103769493929190610520565b60405160208183030381529060405280519060200120815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b610406816103f3565b811461041157600080fd5b50565b600081359050610423816103fd565b92915050565b600060ff82169050919050565b61043f81610429565b811461044a57600080fd5b50565b60008135905061045c81610436565b92915050565b6000806000806080858703121561047c5761047b6103e9565b5b600061048a87828801610414565b945050602061049b8782880161044d565b93505060406104ac87828801610414565b92505060606104bd87828801610414565b91505092959194509250565b6000819050919050565b6104e46104df826103f3565b6104c9565b82525050565b60008160f81b9050919050565b6000610502826104ea565b9050919050565b61051a61051582610429565b6104f7565b82525050565b600061052c82876104d3565b60208201915061053c8286610509565b60018201915061054c82856104d3565b60208201915061055c82846104d3565b60208201915081905095945050505050565b600081905092915050565b82818337600083830152505050565b6000610594838561056e565b93506105a1838584610579565b82840190509392505050565b60006105ba828486610588565b91508190509392505050565b600082825260208201905092915050565b7f6661696c656420746f2063616c6c206d6f7665642065637265636f766572206160008201527f742061646472657373203078303030303030303030303030303030303030303060208201527f3030303030303030303030303030313233343536000000000000000000000000604082015250565b60006106596054836105c6565b9150610664826105d7565b606082019050919050565b600060208201905081810360008301526106888161064c565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106ba8261068f565b9050919050565b60008160601b9050919050565b60006106d9826106c1565b9050919050565b60006106eb826106ce565b9050919050565b6107036106fe826106af565b6106e0565b82525050565b600061071582846106f2565b60148201915081905092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61077282610729565b810181811067ffffffffffffffff821117156107915761079061073a565b5b80604052505050565b60006107a46103df565b90506107b08282610769565b919050565b600067ffffffffffffffff8211156107d0576107cf61073a565b5b602082029050602081019050919050565b600080fd5b600080fd5b6107f4816106af565b81146107ff57600080fd5b50565b600081359050610811816107eb565b92915050565b600060a0828403121561082d5761082c6107e6565b5b61083760a061079a565b9050600061084784828501610414565b600083015250602061085b8482850161044d565b602083015250604061086f84828501610414565b604083015250606061088384828501610414565b606083015250608061089784828501610802565b60808301525092915050565b60006108b66108b1846107b5565b61079a565b90508083825260208201905060a084028301858111156108d9576108d86107e1565b5b835b8181101561090257806108ee8882610817565b84526020840193505060a0810190506108db565b5050509392505050565b600082601f83011261092157610920610724565b5b81356109318482602086016108a3565b91505092915050565b6000602082840312156109505761094f6103e9565b5b600082013567ffffffffffffffff81111561096e5761096d6103ee565b5b61097a8482850161090c565b91505092915050565b600080600080600060a0868803121561099f5761099e6103e9565b5b60006109ad88828901610414565b95505060206109be8882890161044d565b94505060406109cf88828901610414565b93505060606109e088828901610414565b92505060806109f188828901610802565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000610a7182610a5c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610aa357610aa2610a2d565b5b600182019050919050565b7f72657475726e20616464726573732063616e6e6f742062652030783000000000600082015250565b6000610ae4601c836105c6565b9150610aef82610aae565b602082019050919050565b60006020820190508181036000830152610b1381610ad7565b905091905056fea2646970667358221220154f5b68ccfa5be744e7245765a3530dac4035052284a68b5dded1945b45075e64736f6c63430008120033\",\"MovePrecompileToAddress\":\"0x0000000000000000000000000000000000123456\"},\"0xc100000000000000000000000000000000000000\":{\"balance\":\"0x30d40\"}},\"calls\":[{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000123456\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0xc00692604554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554480000000000000000000000000000000000000000000000000000000000\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8000000000000000000000000000000000000000000000000000000000000001cb7cf302145348387b9e69fde82d8e634a0f8761e78da3bfa059efced97cbed0d2a66b69167cafe0ccfc726aec6ee393fea3cf0e4f3f9c394705e0f56d9bfe1c9\"},{\"from\":\"0xc100000000000000000000000000000000000000\",\"to\":\"0x0000000000000000000000000000000000000001\",\"input\":\"0x4554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b45544800000000000000000000000000000000000000000000000000000000004554490000000000000000000000000000000000000000000000000000000000\"}]}]}")] SimulatePayload payload, BlockParameter? blockParameter = null); [JsonRpcMethod(IsImplemented = true, diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs index d41cc5496ef..4a6cbb75263 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs @@ -8,17 +8,20 @@ using Nethermind.Blockchain.Find; using Nethermind.Config; using Nethermind.Core; +using Nethermind.Facade.Tracing; using Nethermind.Evm; using Nethermind.Facade; using Nethermind.Facade.Eth.RpcTransaction; using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.Facade.Simulate; +using Nethermind.Evm.Tracing.ParityStyle; +using Nethermind.Evm.Tracing; namespace Nethermind.JsonRpc.Modules.Eth; -public class SimulateTxExecutor(IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig, ulong? secondsPerSlot = null) - : ExecutorBase, SimulatePayload, - SimulatePayload>(blockchainBridge, blockFinder, rpcConfig) +public class SimulateTxExecutor (IBlockchainBridge blockchainBridge, IBlockFinder blockFinder, IJsonRpcConfig rpcConfig, ulong? secondsPerSlot = null) + : ExecutorBase>, SimulatePayload, + SimulatePayload>(blockchainBridge, blockFinder, rpcConfig) where TTrace : class { private readonly long _blocksLimit = rpcConfig.MaxSimulateBlocksCap ?? 256; private long _gasCapBudget = rpcConfig.GasCap ?? long.MaxValue; @@ -92,31 +95,31 @@ private static TransactionForRpc UpdateTxType(TransactionForRpc rpcTransaction) return rpcTransaction; } - public override ResultWrapper> Execute( + public override ResultWrapper>> Execute( SimulatePayload call, BlockParameter? blockParameter, Dictionary? stateOverride = null) { if (call.BlockStateCalls is null) - return ResultWrapper>.Fail("Must contain BlockStateCalls", ErrorCodes.InvalidParams); + return ResultWrapper>>.Fail("Must contain BlockStateCalls", ErrorCodes.InvalidParams); if (call.BlockStateCalls!.Count > _rpcConfig.MaxSimulateBlocksCap) - return ResultWrapper>.Fail( + return ResultWrapper>>.Fail( $"This node is configured to support only {_rpcConfig.MaxSimulateBlocksCap} blocks", ErrorCodes.InvalidInputTooManyBlocks); SearchResult searchResult = _blockFinder.SearchForBlock(blockParameter); if (searchResult.IsError || searchResult.Object is null) - return ResultWrapper>.Fail(searchResult); + return ResultWrapper>>.Fail(searchResult); BlockHeader header = searchResult.Object.Header; if (!_blockchainBridge.HasStateForBlock(header!)) - return ResultWrapper>.Fail($"No state available for block {header.Hash}", + return ResultWrapper>>.Fail($"No state available for block {header.Hash}", ErrorCodes.ResourceUnavailable); if (call.BlockStateCalls?.Count > _blocksLimit) - return ResultWrapper>.Fail( + return ResultWrapper>>.Fail( $"Too many blocks provided, node is configured to simulate up to {_blocksLimit} while {call.BlockStateCalls?.Count} were given", ErrorCodes.InvalidParams); @@ -133,11 +136,11 @@ public override ResultWrapper> Execute( (lastBlockNumber == -1 ? (ulong)header.Number + 1 : (ulong)lastBlockNumber + 1); if (givenNumber > long.MaxValue) - return ResultWrapper>.Fail( + return ResultWrapper>>.Fail( $"Block number too big {givenNumber}!", ErrorCodes.InvalidParams); if (givenNumber < (ulong)header.Number) - return ResultWrapper>.Fail( + return ResultWrapper>>.Fail( $"Block number out of order {givenNumber} is < than given base number of {header.Number}!", ErrorCodes.InvalidInputBlocksOutOfOrder); long given = (long)givenNumber; @@ -147,7 +150,7 @@ public override ResultWrapper> Execute( } else { - return ResultWrapper>.Fail( + return ResultWrapper>>.Fail( $"Block number out of order {givenNumber}!", ErrorCodes.InvalidInputBlocksOutOfOrder); } @@ -160,7 +163,7 @@ public override ResultWrapper> Execute( : lastBlockTime + secondsPerSlot.Value); if (givenTime < header.Timestamp) - return ResultWrapper>.Fail( + return ResultWrapper>>.Fail( $"Block timestamp out of order {givenTime} is < than given base timestamp of {header.Timestamp}!", ErrorCodes.BlockTimestampNotIncreased); if (givenTime > lastBlockTime) @@ -169,7 +172,7 @@ public override ResultWrapper> Execute( } else { - return ResultWrapper>.Fail( + return ResultWrapper>>.Fail( $"Block timestamp out of order {givenTime}!", ErrorCodes.BlockTimestampNotIncreased); } @@ -212,21 +215,32 @@ .. call.BlockStateCalls.Select(b => (long)(b.BlockOverrides?.Number ?? ulong.Min return Execute(header.Clone(), toProcess, stateOverride, timeout.Token); } - protected override ResultWrapper> Execute(BlockHeader header, + protected override ResultWrapper>> Execute(BlockHeader header, SimulatePayload tx, Dictionary? stateOverride, CancellationToken token) { - SimulateOutput results = _blockchainBridge.Simulate(header, tx, token); - - foreach (SimulateBlockResult result in results.Items) - { - foreach (SimulateCallResult? call in result.Calls) - { - if (call?.Error is not null && call.Error.Message != "") - { - call.Error.Code = ErrorCodes.ExecutionError; - } - } - } + ITracerFactory>, SimulateBlockResult> tracerFactory = + typeof(TTrace) == typeof(ParityLikeTxTrace) + ? (ITracerFactory>, SimulateBlockResult>) + new BlockchainBridge.ParityLikeBlockTracerFactory(ParityTraceTypes.Trace | ParityTraceTypes.Rewards) + : throw new NotSupportedException($"Tracer for {typeof(TTrace).Name} is not supported."); + + SimulateOutput>? results = + _blockchainBridge.Simulate>, SimulateBlockResult>( + header, tx, token, tracerFactory + ); + + + + // foreach (SimulateBlockResult result in results.Items) + // { + // foreach (TTrace? call in result.Calls) + // { + // if (call is ISimulateResult result && result.Error is not null && result.Error.Message != "") + // { + // result.Error.Code = ErrorCodes.ExecutionError; + // } + // } + // } if (results.Error is not null) { @@ -241,9 +255,9 @@ var x when x.Contains("below intrinsic gas") => ErrorCodes.InsufficientIntrinsic } return results.Error is null - ? ResultWrapper>.Success(results.Items) + ? ResultWrapper>>.Success(results.Items) : results.ErrorCode is not null - ? ResultWrapper>.Fail(results.Error!, results.ErrorCode!.Value, results.Items) - : ResultWrapper>.Fail(results.Error, results.Items); + ? ResultWrapper>>.Fail(results.Error!, results.ErrorCode!.Value, results.Items) + : ResultWrapper>>.Fail(results.Error, results.Items); } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/ITraceRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/ITraceRpcModule.cs index ef339ab2612..81e1ff34bef 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/ITraceRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/ITraceRpcModule.cs @@ -6,7 +6,9 @@ using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Evm; +using Nethermind.Evm.Tracing.ParityStyle; using Nethermind.Facade.Eth.RpcTransaction; +using Nethermind.Facade.Proxy.Models.Simulate; using Nethermind.JsonRpc.Data; namespace Nethermind.JsonRpc.Modules.Trace @@ -63,5 +65,8 @@ ResultWrapper> trace_get( IsSharable = false, ExampleResponse = "[{\"action\":{\"callType\":\"call\",\"from\":\"0x3c436c8ec40e0679fe64168545812ac13220f150\",\"gas\":\"0xc118\",\"input\":\"0xd46eb119\",\"to\":\"0x9e00de186f33e9fac9e28d69127f7f637b96c177\",\"value\":\"0xde0b6b3a7640000\"},\"blockHash\":\"0xf40b4c9faaeaf116a50380ce3795297bc02068b062f1797cd507875347c3372e\",\"blockNumber\":8970132,\"result\":{\"gasUsed\":\"0xc118\",\"output\":\"0x\"},\"subtraces\":4,\"traceAddress\":[],\"transactionHash\":\"0x203abf19610ce15bc509d4b341e907ff8c5a8287ae61186fd4da82146408c28c\",\"transactionPosition\":9,\"type\":\"call\"},(...)]")] ResultWrapper> trace_transaction([JsonRpcParameter(ExampleValue = "\"0x203abf19610ce15bc509d4b341e907ff8c5a8287ae61186fd4da82146408c28c\"")] Hash256 txHash); + + ResultWrapper>> trace_simulateV1( + SimulatePayload payload, BlockParameter? blockParameter = null); } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/TraceModuleFactory.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/TraceModuleFactory.cs index 166de6fb581..2847557c37f 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/TraceModuleFactory.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/TraceModuleFactory.cs @@ -14,6 +14,9 @@ using Nethermind.Evm.TransactionProcessing; using Nethermind.Logging; using Nethermind.State; +using Nethermind.Facade.Proxy.Models.Simulate; +using Nethermind.Facade; +using Nethermind.JsonRpc.Modules.Eth; namespace Nethermind.JsonRpc.Modules.Trace; @@ -21,6 +24,8 @@ public class TraceModuleFactory( IWorldStateManager worldStateManager, IBlockTree blockTree, IJsonRpcConfig jsonRpcConfig, + IBlockchainBridge blockchainBridge, + ulong secondsPerSlot, IBlockPreprocessorStep recoveryStep, IRewardCalculatorSource rewardCalculatorSource, IReceiptStorage receiptFinder, @@ -30,6 +35,8 @@ public class TraceModuleFactory( { protected readonly IReadOnlyBlockTree _blockTree = blockTree.AsReadOnly(); protected readonly IJsonRpcConfig _jsonRpcConfig = jsonRpcConfig ?? throw new ArgumentNullException(nameof(jsonRpcConfig)); + protected readonly IBlockchainBridge _blockchainBridge = blockchainBridge ?? throw new ArgumentNullException(nameof(blockchainBridge)); + protected readonly ulong _secondsPerSlot = secondsPerSlot; protected readonly IReceiptStorage _receiptStorage = receiptFinder ?? throw new ArgumentNullException(nameof(receiptFinder)); protected readonly ISpecProvider _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); protected readonly ILogManager _logManager = logManager ?? throw new ArgumentNullException(nameof(logManager)); @@ -70,6 +77,6 @@ public override ITraceRpcModule Create() Tracer tracer = new(scope.WorldState, traceProcessingEnv.ChainProcessor, executeProcessingEnv.ChainProcessor, traceOptions: ProcessingOptions.TraceTransactions); - return new TraceRpcModule(_receiptStorage, tracer, _blockTree, _jsonRpcConfig, txProcessingEnv); + return new TraceRpcModule(_receiptStorage, tracer, _blockTree, _jsonRpcConfig, txProcessingEnv, _blockchainBridge, _jsonRpcConfig, _secondsPerSlot); } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/TraceRpcModule.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/TraceRpcModule.cs index 9f6e4bb9665..c3446256d78 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/TraceRpcModule.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Trace/TraceRpcModule.cs @@ -21,6 +21,9 @@ using Nethermind.JsonRpc.Data; using Nethermind.Serialization.Rlp; using Nethermind.State; +using Nethermind.Facade.Proxy.Models.Simulate; +using Nethermind.Facade; +using Nethermind.JsonRpc.Modules.Eth; namespace Nethermind.JsonRpc.Modules.Trace { @@ -41,8 +44,11 @@ public class TraceRpcModule : ITraceRpcModule private readonly IJsonRpcConfig _jsonRpcConfig; private readonly IStateReader _stateReader; private readonly IOverridableTxProcessorSource _env; + private readonly IBlockchainBridge _blockchainBridge; + private readonly IJsonRpcConfig _rpcConfig; + private readonly ulong _secondsPerSlot; - public TraceRpcModule(IReceiptFinder? receiptFinder, ITracer? tracer, IBlockFinder? blockFinder, IJsonRpcConfig? jsonRpcConfig, IStateReader? stateReader, IOverridableTxProcessorSource? env) + public TraceRpcModule(IReceiptFinder? receiptFinder, ITracer? tracer, IBlockFinder? blockFinder, IJsonRpcConfig? jsonRpcConfig, IStateReader? stateReader, IOverridableTxProcessorSource? env, IBlockchainBridge? blockchainBridge, IJsonRpcConfig rpcConfig, ulong? secondsPerSlot) { _receiptFinder = receiptFinder ?? throw new ArgumentNullException(nameof(receiptFinder)); _tracer = tracer ?? throw new ArgumentNullException(nameof(tracer)); @@ -50,10 +56,13 @@ public TraceRpcModule(IReceiptFinder? receiptFinder, ITracer? tracer, IBlockFind _jsonRpcConfig = jsonRpcConfig ?? throw new ArgumentNullException(nameof(jsonRpcConfig)); _stateReader = stateReader ?? throw new ArgumentNullException(nameof(stateReader)); _env = env ?? throw new ArgumentNullException(nameof(env)); + _blockchainBridge = blockchainBridge ?? throw new ArgumentNullException(nameof(blockchainBridge)); + _rpcConfig = rpcConfig ?? throw new ArgumentNullException(nameof(rpcConfig)); + _secondsPerSlot = secondsPerSlot ?? throw new ArgumentNullException(nameof(secondsPerSlot)); } - public TraceRpcModule(IReceiptFinder? receiptFinder, ITracer? tracer, IBlockFinder? blockFinder, IJsonRpcConfig? jsonRpcConfig, OverridableTxProcessingEnv? env) - : this(receiptFinder, tracer, blockFinder, jsonRpcConfig, env?.StateReader, env) { } + public TraceRpcModule(IReceiptFinder? receiptFinder, ITracer? tracer, IBlockFinder? blockFinder, IJsonRpcConfig? jsonRpcConfig, OverridableTxProcessingEnv? env, IBlockchainBridge? blockchainBridge, IJsonRpcConfig? rpcConfig, ulong? secondsPerSlot) + : this(receiptFinder, tracer, blockFinder, jsonRpcConfig, env?.StateReader, env, blockchainBridge, rpcConfig, secondsPerSlot) { } public static ParityTraceTypes GetParityTypes(string[] types) => types.Select(static s => FastEnum.Parse(s, true)).Aggregate(static (t1, t2) => t1 | t2); @@ -315,5 +324,17 @@ private static ResultWrapper GetStateFailureResult(BlockHeader private CancellationTokenSource BuildTimeoutCancellationTokenSource() => _jsonRpcConfig.BuildTimeoutCancellationToken(); + + + /// + /// Simulate transactions using ParityLikeBlockTracer + /// + public ResultWrapper>> trace_simulateV1( + SimulatePayload payload, BlockParameter? blockParameter = null) + { + return new SimulateTxExecutor (_blockchainBridge, _blockFinder, _rpcConfig, _secondsPerSlot) + .Execute(payload, blockParameter); + } + } } diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismTraceModuleFactory.cs b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismTraceModuleFactory.cs index d2658eb974d..70851bab0c5 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/OptimismTraceModuleFactory.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/OptimismTraceModuleFactory.cs @@ -13,6 +13,7 @@ using Nethermind.JsonRpc; using Nethermind.JsonRpc.Modules.Trace; using Nethermind.Logging; +using Nethermind.Facade; using Nethermind.State; namespace Nethermind.Optimism.Rpc; @@ -21,6 +22,8 @@ public class OptimismTraceModuleFactory( IWorldStateManager worldStateManager, IBlockTree blockTree, IJsonRpcConfig jsonRpcConfig, + IBlockchainBridge blockchainBridge, + ulong secondsPerSlot, IBlockPreprocessorStep recoveryStep, IRewardCalculatorSource rewardCalculatorSource, IReceiptStorage receiptFinder, @@ -34,6 +37,8 @@ public class OptimismTraceModuleFactory( worldStateManager, blockTree, jsonRpcConfig, + blockchainBridge, + secondsPerSlot, recoveryStep, rewardCalculatorSource, receiptFinder, diff --git a/src/Nethermind/Nethermind.Optimism/Rpc/RegisterOptimismRpcModules.cs b/src/Nethermind/Nethermind.Optimism/Rpc/RegisterOptimismRpcModules.cs index 28359637edd..7dd2a30ca4f 100644 --- a/src/Nethermind/Nethermind.Optimism/Rpc/RegisterOptimismRpcModules.cs +++ b/src/Nethermind/Nethermind.Optimism/Rpc/RegisterOptimismRpcModules.cs @@ -102,6 +102,8 @@ protected override void RegisterTraceRpcModule(IRpcModuleProvider rpcModuleProvi _api.WorldStateManager, _api.BlockTree, _jsonRpcConfig, + _api.CreateBlockchainBridge(), + new BlocksConfig().SecondsPerSlot, _api.BlockPreprocessor, _api.RewardCalculatorSource, _api.ReceiptStorage, diff --git a/src/Nethermind/Nethermind.Taiko/Rpc/RegisterTaikoRpcModules.cs b/src/Nethermind/Nethermind.Taiko/Rpc/RegisterTaikoRpcModules.cs index 307bb2355c2..26801119526 100644 --- a/src/Nethermind/Nethermind.Taiko/Rpc/RegisterTaikoRpcModules.cs +++ b/src/Nethermind/Nethermind.Taiko/Rpc/RegisterTaikoRpcModules.cs @@ -80,6 +80,8 @@ protected override void RegisterTraceRpcModule(IRpcModuleProvider rpcModuleProvi _api.WorldStateManager, _api.BlockTree.AsReadOnly(), _jsonRpcConfig, + _api.CreateBlockchainBridge(), + new BlocksConfig().SecondsPerSlot, _api.BlockPreprocessor, _api.RewardCalculatorSource, _api.ReceiptStorage, diff --git a/src/Nethermind/Nethermind.Taiko/Rpc/TaikoTraceModuleFactory.cs b/src/Nethermind/Nethermind.Taiko/Rpc/TaikoTraceModuleFactory.cs index f5d50f57c78..4dedd5670d6 100644 --- a/src/Nethermind/Nethermind.Taiko/Rpc/TaikoTraceModuleFactory.cs +++ b/src/Nethermind/Nethermind.Taiko/Rpc/TaikoTraceModuleFactory.cs @@ -11,15 +11,16 @@ using Nethermind.JsonRpc.Modules.Trace; using Nethermind.Logging; using Nethermind.State; +using Nethermind.Facade; namespace Nethermind.Taiko.Rpc; class TaikoTraceModuleFactory( IWorldStateManager worldStateManager, - IBlockTree blockTree, IJsonRpcConfig jsonRpcConfig, + IBlockTree blockTree, IJsonRpcConfig jsonRpcConfig, IBlockchainBridge blockchainBridge, ulong secondsPerSlot, IBlockPreprocessorStep recoveryStep, IRewardCalculatorSource rewardCalculatorSource, IReceiptStorage receiptFinder, ISpecProvider specProvider, IPoSSwitcher poSSwitcher, ILogManager logManager) : - TraceModuleFactory(worldStateManager, blockTree, jsonRpcConfig, recoveryStep, rewardCalculatorSource, receiptFinder, specProvider, poSSwitcher, logManager) + TraceModuleFactory(worldStateManager, blockTree, jsonRpcConfig, blockchainBridge, secondsPerSlot, recoveryStep, rewardCalculatorSource, receiptFinder, specProvider, poSSwitcher, logManager) { protected override OverridableTxProcessingEnv CreateTxProcessingEnv(IOverridableWorldScope worldStateManager) => new TaikoReadOnlyTxProcessingEnv(worldStateManager, _blockTree, _specProvider, _logManager); }