From 71113ad65e349217f9bc310dd3f58b7d46f65293 Mon Sep 17 00:00:00 2001 From: Lukasz Rozmej Date: Wed, 15 Dec 2021 14:01:14 +0100 Subject: [PATCH] fix/Introduce Trace/NoValidation mode for transaction excecution (#3688) * Introduce Trace/NoValidation mode for transaction excecution * fix * Fix * Added test for trace_replayBlockTransactions. Co-authored-by: user --- .../Tracing/ParityStyle/ParityLikeTxTracer.cs | 12 +++++- .../ITransactionProcessor.cs | 5 +++ .../ReadOnlyTransactionProcessor.cs | 17 ++++----- .../TraceTransactionProcessorAdapter.cs | 35 +++++++++++++++++ .../TransactionProcessor.cs | 37 +++++++++++------- .../Modules/TraceRpcModuleTests.cs | 38 ++++++++++++++++++- .../Modules/RpcBlockTransactionsExecutor.cs | 2 +- 7 files changed, 120 insertions(+), 26 deletions(-) create mode 100644 src/Nethermind/Nethermind.Evm/TransactionProcessing/TraceTransactionProcessorAdapter.cs diff --git a/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs b/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs index 2191caf95de..f0caa595fd2 100644 --- a/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs +++ b/src/Nethermind/Nethermind.Evm/Tracing/ParityStyle/ParityLikeTxTracer.cs @@ -441,9 +441,17 @@ public void ReportAction(long gas, UInt256 value, Address @from, Address to, Rea PushAction(action); } - private string GetCreateMethod(ExecutionType callType) + private string? GetCreateMethod(ExecutionType callType) { - return callType == ExecutionType.Create ? "create" : "create2"; + switch (callType) + { + case ExecutionType.Create: + return "create"; + case ExecutionType.Create2: + return "create2"; + default: + return null; + } } public void ReportSelfDestruct(Address address, UInt256 balance, Address refundAddress) diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/ITransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/ITransactionProcessor.cs index 063c2403e56..fb75e77eda6 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/ITransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/ITransactionProcessor.cs @@ -35,5 +35,10 @@ public interface ITransactionProcessor /// Execute transaction, keep the state uncommitted /// void BuildUp(Transaction transaction, BlockHeader block, ITxTracer txTracer); + + /// + /// Call transaction, no validations, commit state + /// + void Trace(Transaction transaction, BlockHeader block, ITxTracer txTracer); } } diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/ReadOnlyTransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/ReadOnlyTransactionProcessor.cs index eea7ddd4108..d6158cc2794 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/ReadOnlyTransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/ReadOnlyTransactionProcessor.cs @@ -38,20 +38,19 @@ public ReadOnlyTransactionProcessor(ITransactionProcessor transactionProcessor, _stateProvider.StateRoot = startState ?? throw new ArgumentException(nameof(startState)); } - public void Execute(Transaction transaction, BlockHeader block, ITxTracer txTracer) - { + public void Execute(Transaction transaction, BlockHeader block, ITxTracer txTracer) => _transactionProcessor.Execute(transaction, block, txTracer); - } + - public void CallAndRestore(Transaction transaction, BlockHeader block, ITxTracer txTracer) - { + public void CallAndRestore(Transaction transaction, BlockHeader block, ITxTracer txTracer) => _transactionProcessor.CallAndRestore(transaction, block, txTracer); - } - public void BuildUp(Transaction transaction, BlockHeader block, ITxTracer txTracer) - { + public void BuildUp(Transaction transaction, BlockHeader block, ITxTracer txTracer) => _transactionProcessor.BuildUp(transaction, block, txTracer); - } + + public void Trace(Transaction transaction, BlockHeader block, ITxTracer txTracer) => + _transactionProcessor.Trace(transaction, block, txTracer); + public bool IsContractDeployed(Address address) => _stateProvider.IsContract(address); diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TraceTransactionProcessorAdapter.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TraceTransactionProcessorAdapter.cs new file mode 100644 index 00000000000..48f943f47dc --- /dev/null +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TraceTransactionProcessorAdapter.cs @@ -0,0 +1,35 @@ +// Copyright (c) 2021 Demerzel Solutions Limited +// This file is part of the Nethermind library. +// +// The Nethermind library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The Nethermind library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the Nethermind. If not, see . +// + +using Nethermind.Core; +using Nethermind.Evm.Tracing; + +namespace Nethermind.Evm.TransactionProcessing +{ + public class TraceTransactionProcessorAdapter : ITransactionProcessorAdapter + { + private readonly ITransactionProcessor _transactionProcessor; + + public TraceTransactionProcessorAdapter(ITransactionProcessor transactionProcessor) + { + _transactionProcessor = transactionProcessor; + } + + public void Execute(Transaction transaction, BlockHeader block, ITxTracer txTracer) => + _transactionProcessor.Trace(transaction, block, txTracer); + } +} diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index 17f37d2cdd0..a4ee12a276f 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -58,11 +58,16 @@ private enum ExecutionOptions /// Restore state after execution /// Restore = 2, + + /// + /// Skip potential fail checks + /// + NoValidation = Commit | 4, /// - /// Commit and later restore state, use for CallAndRestore + /// Commit and later restore state also skip validation, use for CallAndRestore /// - CommitAndRestore = Commit | Restore + CommitAndRestore = Commit | Restore | NoValidation } public TransactionProcessor( @@ -105,6 +110,11 @@ public void Execute(Transaction transaction, BlockHeader block, ITxTracer txTrac { Execute(transaction, block, txTracer, ExecutionOptions.Commit); } + + public void Trace(Transaction transaction, BlockHeader block, ITxTracer txTracer) + { + Execute(transaction, block, txTracer, ExecutionOptions.NoValidation); + } private void QuickFail(Transaction tx, BlockHeader block, ITxTracer txTracer, bool eip658NotEnabled, string? reason) @@ -134,9 +144,10 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra bool eip658NotEnabled = !_specProvider.GetSpec(block.Number).IsEip658Enabled; // restore is CallAndRestore - previous call, we will restore state after the execution - bool restore = (executionOptions & ExecutionOptions.Restore) != ExecutionOptions.None; + bool restore = (executionOptions & ExecutionOptions.Restore) == ExecutionOptions.Restore; + bool noValidation = (executionOptions & ExecutionOptions.NoValidation) == ExecutionOptions.NoValidation; // commit - is for standard execute, we will commit thee state after execution - bool commit = (executionOptions & ExecutionOptions.Commit) != ExecutionOptions.None || eip658NotEnabled; + bool commit = (executionOptions & ExecutionOptions.Commit) == ExecutionOptions.Commit || eip658NotEnabled; //!commit - is for build up during block production, we won't commit state after each transaction to support rollbacks //we commit only after all block is constructed bool notSystemTransaction = !transaction.IsSystem(); @@ -150,7 +161,7 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra UInt256 value = transaction.Value; - if (!transaction.TryCalculatePremiumPerGas(block.BaseFeePerGas, out UInt256 premiumPerGas) && !restore) + if (!transaction.TryCalculatePremiumPerGas(block.BaseFeePerGas, out UInt256 premiumPerGas) && !noValidation) { TraceLogInvalidTx(transaction, "MINER_PREMIUM_IS_NEGATIVE"); QuickFail(transaction, block, txTracer, eip658NotEnabled, "miner premium is negative"); @@ -174,7 +185,7 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra return; } - if (!restore && _stateProvider.IsInvalidContractSender(spec, caller)) + if (!noValidation && _stateProvider.IsInvalidContractSender(spec, caller)) { TraceLogInvalidTx(transaction, "SENDER_IS_CONTRACT"); QuickFail(transaction, block, txTracer, eip658NotEnabled, "sender has deployed code"); @@ -193,7 +204,7 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra return; } - if (!restore && gasLimit > block.GasLimit - block.GasUsed) + if (!noValidation && gasLimit > block.GasLimit - block.GasUsed) { TraceLogInvalidTx(transaction, $"BLOCK_GAS_LIMIT_EXCEEDED {gasLimit} > {block.GasLimit} - {block.GasUsed}"); @@ -220,7 +231,7 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra else { TraceLogInvalidTx(transaction, $"SENDER_ACCOUNT_DOES_NOT_EXIST {caller}"); - if (!commit || restore || effectiveGasPrice == UInt256.Zero) + if (!commit || noValidation || effectiveGasPrice == UInt256.Zero) { deleteCallerAccount = !commit || restore; _stateProvider.CreateAccount(caller, UInt256.Zero); @@ -234,13 +245,13 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra } } - UInt256 senderReservedGasPayment = restore ? UInt256.Zero : (ulong)gasLimit * effectiveGasPrice; + UInt256 senderReservedGasPayment = noValidation ? UInt256.Zero : (ulong)gasLimit * effectiveGasPrice; if (notSystemTransaction) { UInt256 senderBalance = _stateProvider.GetBalance(caller); - if (!restore && ((ulong)intrinsicGas * effectiveGasPrice + value > senderBalance || - senderReservedGasPayment + value > senderBalance)) + if (!noValidation && ((ulong)intrinsicGas * effectiveGasPrice + value > senderBalance || + senderReservedGasPayment + value > senderBalance)) { TraceLogInvalidTx(transaction, $"INSUFFICIENT_SENDER_BALANCE: ({caller})_BALANCE = {senderBalance}"); @@ -248,7 +259,7 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra return; } - if (!restore && spec.IsEip1559Enabled && !transaction.IsServiceTransaction && + if (!noValidation && spec.IsEip1559Enabled && !transaction.IsFree() && senderBalance < (UInt256)transaction.GasLimit * transaction.MaxFeePerGas + value) { TraceLogInvalidTx(transaction, @@ -451,7 +462,7 @@ private void Execute(Transaction transaction, BlockHeader block, ITxTracer txTra _stateProvider.Commit(spec, txTracer.IsTracingState ? txTracer : NullStateTracer.Instance); } - if (!restore && notSystemTransaction) + if (!noValidation && notSystemTransaction) { block.GasUsed += spentGas; } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs index 3bf7ce19716..e7e628635f7 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/TraceRpcModuleTests.cs @@ -472,7 +472,7 @@ public async Task Trace_transaction_with_error_reverted() Assert.AreEqual(transaction2.Hash!, traces.Data[0].TransactionHash); string serialized = new EthereumJsonSerializer().Serialize(traces.Data); - Assert.AreEqual("[{\"action\":{\"traceAddress\":[],\"callType\":\"create\",\"includeInTrace\":true,\"isPrecompiled\":false,\"type\":\"create\",\"creationMethod\":\"create\",\"from\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"to\":\"0xd6a48bcd4c5ad5adacfab677519c25ce7b2805a5\",\"gas\":\"0x9a6c\",\"value\":\"0x1\",\"input\":\"0x60006000600060006000736b5887043de753ecfa6269f947129068263ffbe261c350f160006000600060006000736b5887043de753ecfa6269f947129068263ffbe261c350f1fd\",\"subtraces\":[{\"traceAddress\":[0],\"callType\":\"call\",\"includeInTrace\":true,\"isPrecompiled\":false,\"type\":\"call\",\"creationMethod\":\"create2\",\"from\":\"0xd6a48bcd4c5ad5adacfab677519c25ce7b2805a5\",\"to\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"gas\":\"0x2dcd\",\"value\":\"0x0\",\"input\":\"0x\",\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":[]},{\"traceAddress\":[1],\"callType\":\"call\",\"includeInTrace\":true,\"isPrecompiled\":false,\"type\":\"call\",\"creationMethod\":\"create2\",\"from\":\"0xd6a48bcd4c5ad5adacfab677519c25ce7b2805a5\",\"to\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"gas\":\"0x2d56\",\"value\":\"0x0\",\"input\":\"0x\",\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":[]}],\"error\":\"Reverted\"},\"blockHash\":\"0xfa74e932520ee416ecb12171c115b3ad14112ffd2d612646ceaff69e54e06a94\",\"blockNumber\":18,\"result\":null,\"subtraces\":2,\"traceAddress\":[],\"transactionHash\":\"0x787616b8756424622f162fc3817331517ef941366f28db452defc0214bc36b22\",\"transactionPosition\":0,\"type\":\"create\",\"error\":\"Reverted\"},{\"action\":{\"traceAddress\":[0],\"callType\":\"call\",\"includeInTrace\":true,\"isPrecompiled\":false,\"type\":\"call\",\"creationMethod\":\"create2\",\"from\":\"0xd6a48bcd4c5ad5adacfab677519c25ce7b2805a5\",\"to\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"gas\":\"0x2dcd\",\"value\":\"0x0\",\"input\":\"0x\",\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":[]},\"blockHash\":\"0xfa74e932520ee416ecb12171c115b3ad14112ffd2d612646ceaff69e54e06a94\",\"blockNumber\":18,\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[0],\"transactionHash\":\"0x787616b8756424622f162fc3817331517ef941366f28db452defc0214bc36b22\",\"transactionPosition\":0,\"type\":\"call\"},{\"action\":{\"traceAddress\":[1],\"callType\":\"call\",\"includeInTrace\":true,\"isPrecompiled\":false,\"type\":\"call\",\"creationMethod\":\"create2\",\"from\":\"0xd6a48bcd4c5ad5adacfab677519c25ce7b2805a5\",\"to\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"gas\":\"0x2d56\",\"value\":\"0x0\",\"input\":\"0x\",\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":[]},\"blockHash\":\"0xfa74e932520ee416ecb12171c115b3ad14112ffd2d612646ceaff69e54e06a94\",\"blockNumber\":18,\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[1],\"transactionHash\":\"0x787616b8756424622f162fc3817331517ef941366f28db452defc0214bc36b22\",\"transactionPosition\":0,\"type\":\"call\"}]",serialized, serialized.Replace("\"", "\\\"")); + Assert.AreEqual("[{\"action\":{\"traceAddress\":[],\"callType\":\"create\",\"includeInTrace\":true,\"isPrecompiled\":false,\"type\":\"create\",\"creationMethod\":\"create\",\"from\":\"0x942921b14f1b1c385cd7e0cc2ef7abe5598c8358\",\"to\":\"0xd6a48bcd4c5ad5adacfab677519c25ce7b2805a5\",\"gas\":\"0x9a6c\",\"value\":\"0x1\",\"input\":\"0x60006000600060006000736b5887043de753ecfa6269f947129068263ffbe261c350f160006000600060006000736b5887043de753ecfa6269f947129068263ffbe261c350f1fd\",\"subtraces\":[{\"traceAddress\":[0],\"callType\":\"call\",\"includeInTrace\":true,\"isPrecompiled\":false,\"type\":\"call\",\"from\":\"0xd6a48bcd4c5ad5adacfab677519c25ce7b2805a5\",\"to\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"gas\":\"0x2dcd\",\"value\":\"0x0\",\"input\":\"0x\",\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":[]},{\"traceAddress\":[1],\"callType\":\"call\",\"includeInTrace\":true,\"isPrecompiled\":false,\"type\":\"call\",\"from\":\"0xd6a48bcd4c5ad5adacfab677519c25ce7b2805a5\",\"to\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"gas\":\"0x2d56\",\"value\":\"0x0\",\"input\":\"0x\",\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":[]}],\"error\":\"Reverted\"},\"blockHash\":\"0xfa74e932520ee416ecb12171c115b3ad14112ffd2d612646ceaff69e54e06a94\",\"blockNumber\":18,\"result\":null,\"subtraces\":2,\"traceAddress\":[],\"transactionHash\":\"0x787616b8756424622f162fc3817331517ef941366f28db452defc0214bc36b22\",\"transactionPosition\":0,\"type\":\"create\",\"error\":\"Reverted\"},{\"action\":{\"traceAddress\":[0],\"callType\":\"call\",\"includeInTrace\":true,\"isPrecompiled\":false,\"type\":\"call\",\"from\":\"0xd6a48bcd4c5ad5adacfab677519c25ce7b2805a5\",\"to\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"gas\":\"0x2dcd\",\"value\":\"0x0\",\"input\":\"0x\",\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":[]},\"blockHash\":\"0xfa74e932520ee416ecb12171c115b3ad14112ffd2d612646ceaff69e54e06a94\",\"blockNumber\":18,\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[0],\"transactionHash\":\"0x787616b8756424622f162fc3817331517ef941366f28db452defc0214bc36b22\",\"transactionPosition\":0,\"type\":\"call\"},{\"action\":{\"traceAddress\":[1],\"callType\":\"call\",\"includeInTrace\":true,\"isPrecompiled\":false,\"type\":\"call\",\"from\":\"0xd6a48bcd4c5ad5adacfab677519c25ce7b2805a5\",\"to\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"gas\":\"0x2d56\",\"value\":\"0x0\",\"input\":\"0x\",\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":[]},\"blockHash\":\"0xfa74e932520ee416ecb12171c115b3ad14112ffd2d612646ceaff69e54e06a94\",\"blockNumber\":18,\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[1],\"transactionHash\":\"0x787616b8756424622f162fc3817331517ef941366f28db452defc0214bc36b22\",\"transactionPosition\":0,\"type\":\"call\"}]",serialized, serialized.Replace("\"", "\\\"")); } [Test] public async Task trace_timeout_is_separate_for_rpc_calls() @@ -695,6 +695,42 @@ public async Task Trace_callMany_is_blockParameter_optional_test() Assert.AreEqual("{\"jsonrpc\":\"2.0\",\"result\":[{\"output\":\"0x\",\"stateDiff\":null,\"trace\":[{\"action\":{\"callType\":\"call\",\"from\":\"0xfe35e70599578efef562e1f1cdc9ef693b865e9d\",\"gas\":\"0x5f58ef8\",\"input\":\"0x\",\"to\":\"0x8cf85548ae57a91f8132d0831634c0fcef06e505\",\"value\":\"0x0\"},\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[],\"type\":\"call\"}],\"vmTrace\":null},{\"output\":\"0x\",\"stateDiff\":null,\"trace\":[{\"action\":{\"callType\":\"call\",\"from\":\"0x2a6ae6f33729384a00b4ffbd25e3f1bf1b9f5b8d\",\"gas\":\"0x5f58ef8\",\"input\":\"0x\",\"to\":\"0xab736519b5433974059da38da74b8db5376942cd\",\"value\":\"0x0\"},\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":0,\"traceAddress\":[],\"type\":\"call\"}],\"vmTrace\":null}],\"id\":67}", serialized_without_blockParameter_param, serialized_without_blockParameter_param.Replace("\"", "\\\"")); } + + [Test] + public async Task Trace_replayBlockTransactions_transactions_deploying_contract() + { + Context context = new(); + await context.Build(); + TestRpcBlockchain blockchain = context.Blockchain; + UInt256 currentNonceAddressA = blockchain.State.GetAccount(TestItem.AddressA).Nonce; + await blockchain.AddFunds(TestItem.AddressA, 10000.Ether()); + Address? contractAddress = ContractAddress.From(TestItem.AddressA, currentNonceAddressA); + + byte[] code = Prepare.EvmCode + .Call(contractAddress, 50000) + .Done; + + Transaction transaction1 = Build.A.Transaction.WithNonce(currentNonceAddressA++) + .WithSenderAddress(TestItem.AddressA) + .WithData(code) + .WithTo(null) + .WithGasLimit(93548).SignedAndResolved(TestItem.PrivateKeyA).TestObject; + + Transaction transaction2 = Build.A.Transaction.WithNonce(currentNonceAddressA++) + .WithSenderAddress(TestItem.AddressA) + .WithData(code).SignedAndResolved(TestItem.PrivateKeyA) + .WithTo(null) + .WithGasLimit(93548).TestObject; + string[] traceTypes = { "trace" }; + + await blockchain.AddBlock(transaction1, transaction2); + + ResultWrapper traces = context.TraceRpcModule.trace_replayBlockTransactions(new BlockParameter(blockchain.BlockFinder.FindLatestBlock().Number), traceTypes); + Assert.AreEqual(2, traces.Data.Length); + Assert.AreEqual(traces.Data[0].Action.From, traces.Data[1].Action.From); + string serialized = new EthereumJsonSerializer().Serialize(traces.Data); + Assert.AreEqual("[{\"output\":\"0x\",\"transactionHash\":\"0x8513c9083ec27fa8e3ca7e3ffa732d61562e2d17e2e1af6e773bc810dc4c3452\",\"action\":{\"traceAddress\":[],\"callType\":\"create\",\"includeInTrace\":true,\"isPrecompiled\":false,\"type\":\"create\",\"creationMethod\":\"create\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"gas\":\"0x9c70\",\"value\":\"0x1\",\"input\":\"0x60006000600060006000730ffd3e46594919c04bcfd4e146203c825567082861c350f1\",\"result\":{\"gasUsed\":\"0x79\",\"output\":\"0x\",\"address\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"code\":\"0x\"},\"subtraces\":[{\"traceAddress\":[0],\"callType\":\"call\",\"includeInTrace\":true,\"isPrecompiled\":false,\"type\":\"call\",\"from\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"to\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"gas\":\"0x9988\",\"value\":\"0x0\",\"input\":\"0x\",\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":[]}]}},{\"output\":\"0x\",\"transactionHash\":\"0xa6a56c7927deae778a749bcdab7bbf409c0d8a5d2420021a3ba328240ae832d8\",\"action\":{\"traceAddress\":[],\"callType\":\"create\",\"includeInTrace\":true,\"isPrecompiled\":false,\"type\":\"create\",\"creationMethod\":\"create\",\"from\":\"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099\",\"to\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"gas\":\"0x9c70\",\"value\":\"0x1\",\"input\":\"0x60006000600060006000730ffd3e46594919c04bcfd4e146203c825567082861c350f1\",\"result\":{\"gasUsed\":\"0xa3d\",\"output\":\"0x\",\"address\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"code\":\"0x\"},\"subtraces\":[{\"traceAddress\":[0],\"callType\":\"call\",\"includeInTrace\":true,\"isPrecompiled\":false,\"type\":\"call\",\"from\":\"0x6b5887043de753ecfa6269f947129068263ffbe2\",\"to\":\"0x0ffd3e46594919c04bcfd4e146203c8255670828\",\"gas\":\"0x8feb\",\"value\":\"0x0\",\"input\":\"0x\",\"result\":{\"gasUsed\":\"0x0\",\"output\":\"0x\"},\"subtraces\":[]}]}}]",serialized); + } } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/RpcBlockTransactionsExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/RpcBlockTransactionsExecutor.cs index 330b8450c7e..911f03816fc 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/RpcBlockTransactionsExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/RpcBlockTransactionsExecutor.cs @@ -24,7 +24,7 @@ namespace Nethermind.JsonRpc.Modules public class RpcBlockTransactionsExecutor : BlockProcessor.BlockValidationTransactionsExecutor { public RpcBlockTransactionsExecutor(ITransactionProcessor transactionProcessor, IStateProvider stateProvider) - : base(new CallAndRestoreTransactionProcessorAdapter(transactionProcessor), stateProvider) + : base(new TraceTransactionProcessorAdapter(transactionProcessor), stateProvider) { } }