Example #1
0
 public BlockProcessor(ISpecProvider specProvider,
                       IBlockValidator blockValidator,
                       IRewardCalculator rewardCalculator,
                       ITransactionProcessor transactionProcessor,
                       ISnapshotableDb stateDb,
                       ISnapshotableDb codeDb,
                       IStateProvider stateProvider,
                       IStorageProvider storageProvider,
                       ITxPool txPool,
                       IReceiptStorage receiptStorage,
                       ILogManager logManager)
 {
     _logger               = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));
     _specProvider         = specProvider ?? throw new ArgumentNullException(nameof(specProvider));
     _blockValidator       = blockValidator ?? throw new ArgumentNullException(nameof(blockValidator));
     _stateProvider        = stateProvider ?? throw new ArgumentNullException(nameof(stateProvider));
     _storageProvider      = storageProvider ?? throw new ArgumentNullException(nameof(storageProvider));
     _txPool               = txPool ?? throw new ArgumentNullException(nameof(txPool));
     _receiptStorage       = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage));
     _rewardCalculator     = rewardCalculator ?? throw new ArgumentNullException(nameof(rewardCalculator));
     _transactionProcessor = transactionProcessor ?? throw new ArgumentNullException(nameof(transactionProcessor));
     _stateDb              = stateDb ?? throw new ArgumentNullException(nameof(stateDb));
     _codeDb               = codeDb ?? throw new ArgumentNullException(nameof(codeDb));
     _receiptsTracer       = new BlockReceiptsTracer();
 }
        private BlockProcessor.TxAction ProcessAccountAbstractionTransaction(
            Block block,
            Transaction currentTx,
            int index,
            BlockReceiptsTracer receiptsTracer,
            ProcessingOptions processingOptions,
            LinkedHashSet <Transaction> transactionsInBlock)
        {
            int snapshot = receiptsTracer.TakeSnapshot();

            BlockProcessor.TxAction action = ProcessTransaction(block, currentTx, index, receiptsTracer, processingOptions, transactionsInBlock, false);
            if (action != BlockProcessor.TxAction.Add)
            {
                return(action);
            }

            string?error = receiptsTracer.LastReceipt.Error;
            bool   transactionSucceeded = string.IsNullOrEmpty(error);

            if (!transactionSucceeded)
            {
                receiptsTracer.Restore(snapshot);
                return(BlockProcessor.TxAction.Skip);
            }

            transactionsInBlock.Add(currentTx);
            _transactionProcessed?.Invoke(this, new TxProcessedEventArgs(index, currentTx, receiptsTracer.TxReceipts[index]));
            return(BlockProcessor.TxAction.Add);
        }
 private void Execute(BlockReceiptsTracer tracer, Transaction tx, Block block)
 {
     tracer.StartNewBlockTrace(block);
     tracer.StartNewTxTrace(tx.Hash);
     _transactionProcessor.Execute(tx, block.Header, tracer);
     tracer.EndTxTrace();
 }
Example #4
0
        public BlockProcessor(
            ISpecProvider?specProvider,
            IBlockValidator?blockValidator,
            IRewardCalculator?rewardCalculator,
            ITransactionProcessor?transactionProcessor,
            IStateProvider?stateProvider,
            IStorageProvider?storageProvider,
            ITxPool?txPool,
            IReceiptStorage?receiptStorage,
            IWitnessCollector?witnessCollector,
            ILogManager?logManager)
        {
            _logger               = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));
            _specProvider         = specProvider ?? throw new ArgumentNullException(nameof(specProvider));
            _blockValidator       = blockValidator ?? throw new ArgumentNullException(nameof(blockValidator));
            _stateProvider        = stateProvider ?? throw new ArgumentNullException(nameof(stateProvider));
            _storageProvider      = storageProvider ?? throw new ArgumentNullException(nameof(storageProvider));
            _txPool               = txPool ?? throw new ArgumentNullException(nameof(txPool));
            _receiptStorage       = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage));
            _witnessCollector     = witnessCollector ?? throw new ArgumentNullException(nameof(witnessCollector));
            _rewardCalculator     = rewardCalculator ?? throw new ArgumentNullException(nameof(rewardCalculator));
            _transactionProcessor = transactionProcessor ?? throw new ArgumentNullException(nameof(transactionProcessor));

            _receiptsTracer = new BlockReceiptsTracer();
        }
Example #5
0
 public BlockchainBridge(TransactionProcessor processor, IReleaseSpec spec)
 {
     _spec           = spec;
     _receiptsTracer = new BlockReceiptsTracer();
     _processor      = processor;
     _receiptsTracer.SetOtherTracer(GethTracer);
     _receiptsTracer.StartNewBlockTrace(_headBlock);
 }
Example #6
0
 public BlockchainBridge(TransactionProcessor processor, IReleaseSpec spec)
 {
     _spec           = spec;
     _receiptsTracer = new BlockReceiptsTracer(new SingleReleaseSpecProvider(_spec, 99), Substitute.For <IStateProvider>());
     _processor      = processor;
     _receiptsTracer.SetOtherTracer(GethTracer);
     _receiptsTracer.StartNewBlockTrace(_headBlock);
 }
Example #7
0
            public BlockchainBridge(TransactionProcessor processor)
            {
                _receiptsTracer = new BlockReceiptsTracer();
                _processor      = processor;
                _tx             = Build.A.Transaction.SignedAndResolved(new EthereumEcdsa(ChainId.Mainnet, LimboLogs.Instance), TestItem.PrivateKeyA).TestObject;
                _headBlock      = Build.A.Block.WithNumber(1).WithTransactions(Enumerable.Repeat(_tx, 100).ToArray()).TestObject;

                _receiptsTracer.SetOtherTracer(GethTracer);
                _receiptsTracer.StartNewBlockTrace(_headBlock);
            }
        public void Can_handle_quick_fail_on_non_existing_sender_account(bool withStateDiff, bool withTrace)
        {
            Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyB, _isEip155Enabled).WithGasLimit(100000).TestObject;

            Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject;

            BlockReceiptsTracer tracer = BuildTracer(block, tx, withTrace, withTrace);

            Execute(tracer, tx, block);

            Assert.AreEqual(StatusCode.Failure, tracer.TxReceipts[0].StatusCode);
        }
Example #9
0
        public void Can_process_simple_transaction(bool withStateDiff, bool withTrace)
        {
            Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, 1).WithGasLimit(100000).TestObject;

            Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject;

            BlockReceiptsTracer tracer = BuildTracer(block, tx, withTrace, withTrace);

            Execute(tracer, tx, block);

            Assert.AreEqual(StatusCode.Success, tracer.TxReceipts[0].StatusCode);
        }
        public void Can_handle_quick_fail_on_above_block_gas_limit(bool withStateDiff, bool withTrace)
        {
            Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, 1).TestObject;

            Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).WithGasLimit(20000).TestObject;

            BlockReceiptsTracer tracer = BuildTracer(block, tx, withTrace, withTrace);

            Execute(tracer, tx, block);

            Assert.AreEqual(StatusCode.Failure, tracer.TxReceipts[0].StatusCode);
        }
Example #11
0
        public void Sets_state_root_on_receipts_before_eip658(bool withStateDiff, bool withTrace)
        {
            Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, 1).WithGasLimit(100000).TestObject;

            Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject;

            BlockReceiptsTracer tracer = BuildTracer(block, tx, withTrace, withTrace);

            Execute(tracer, tx, block);

            Assert.NotNull(tracer.TxReceipts[0].PostTransactionState);
        }
        public void Can_handle_quick_fail_on_not_enough_balance(bool withStateDiff, bool withTrace)
        {
            Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumSigner, TestObject.PrivateKeyA, 1).TestObject;

            Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject;

            BlockReceiptsTracer tracer = BuildTracer(block, tx, withTrace, withTrace);

            Execute(tracer, tx, block);

            Assert.AreEqual(StatusCode.Failure, tracer.TransactionReceipts[0].StatusCode);
        }
Example #13
0
        public void Will_not_cause_quick_fail_above_block_gas_limit_during_calls(bool withStateDiff, bool withTrace)
        {
            Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, 1).WithGasLimit(100000).TestObject;

            Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).WithGasLimit(20000).TestObject;

            BlockReceiptsTracer tracer = BuildTracer(block, tx, withTrace, withTrace);

            CallAndRestore(tracer, tx, block);

            Assert.AreEqual(StatusCode.Success, tracer.TxReceipts[0].StatusCode);
        }
Example #14
0
        public void Sets_state_root_if_provided_on_failure()
        {
            Block block = Build.A.Block.WithTransactions(MuirGlacier.Instance, Build.A.Transaction.TestObject).TestObject;

            BlockReceiptsTracer tracer = new BlockReceiptsTracer();

            tracer.SetOtherTracer(NullBlockTracer.Instance);
            tracer.StartNewBlockTrace(block);
            tracer.StartNewTxTrace(block.Transactions[0].Hash);
            tracer.MarkAsFailed(TestItem.AddressA, 100, new byte[0], "error", TestItem.KeccakF);

            Assert.AreEqual(TestItem.KeccakF, tracer.TxReceipts[0].PostTransactionState);
        }
        public void Can_handle_quick_fail_on_intrinsic_gas(bool withStateDiff, bool withTrace)
        {
            GiveEtherToA();
            Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumSigner, TestObject.PrivateKeyA, 1).WithGasLimit(20000).TestObject;

            Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject;

            BlockReceiptsTracer tracer = BuildTracer(block, tx, withTrace, withTrace);

            Execute(tracer, tx, block);

            Assert.AreEqual(StatusCode.Failure, tracer.TransactionReceipts[0].StatusCode);
        }
        public void Can_handle_quick_fail_on_missing_sender(bool withStateDiff, bool withTrace)
        {
            GiveEtherToA();
            Transaction tx = Build.A.Transaction.Signed(_ethereumEcdsa, TestItem.PrivateKeyA, 1).TestObject;

            Block block = Build.A.Block.WithNumber(1).WithTransactions(tx).TestObject;

            BlockReceiptsTracer tracer = BuildTracer(block, tx, withTrace, withTrace);

            Execute(tracer, tx, block);

            Assert.AreEqual(StatusCode.Failure, tracer.TxReceipts[0].StatusCode);
        }
Example #17
0
        public void Sets_state_root_if_provided_on_success()
        {
            Block block = Build.A.Block.WithTransactions(Build.A.Transaction.TestObject).TestObject;

            BlockReceiptsTracer tracer = new BlockReceiptsTracer();

            tracer.SetOtherTracer(NullBlockTracer.Instance);
            tracer.StartNewBlockTrace(block);
            tracer.StartNewTxTrace(block.Transactions[0].Hash);
            tracer.MarkAsSuccess(TestItem.AddressA, 100, new byte[0], new LogEntry[0], TestItem.KeccakF);

            Assert.AreEqual(TestItem.KeccakF, tracer.TxReceipts[0].PostTransactionState);
        }
Example #18
0
        public void Invokes_other_tracer_mark_as_failed_if_other_block_tracer_is_tx_tracer_too()
        {
            Block block = Build.A.Block.WithTransactions(MuirGlacier.Instance, Build.A.Transaction.TestObject).TestObject;

            IBlockTracer        otherTracer = Substitute.For <IBlockTracer, ITxTracer>();
            BlockReceiptsTracer tracer      = new BlockReceiptsTracer();

            tracer.SetOtherTracer(otherTracer);
            tracer.StartNewBlockTrace(block);
            tracer.StartNewTxTrace(block.Transactions[0].Hash);
            tracer.MarkAsFailed(TestItem.AddressA, 100, Array.Empty <byte>(), "error", TestItem.KeccakF);

            (otherTracer as ITxTracer).Received().MarkAsFailed(TestItem.AddressA, 100, Array.Empty <byte>(), "error", TestItem.KeccakF);
        }
        public void Can_handle_quick_fail_on_not_enough_balance(bool withStateDiff, bool withTrace)
        {
            Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, _isEip155Enabled).WithGasLimit(100000).TestObject;

            tx.Value = 2.Ether();

            Block block = Build.A.Block.WithNumber(1).WithTransactions(MuirGlacier.Instance, tx).TestObject;

            BlockReceiptsTracer tracer = BuildTracer(block, tx, withTrace, withTrace);

            Execute(tracer, tx, block);

            Assert.AreEqual(StatusCode.Failure, tracer.TxReceipts[0].StatusCode);
        }
Example #20
0
        public static void ProcessTransaction(this ITransactionProcessorAdapter transactionProcessor,
                                              Block block,
                                              Transaction currentTx,
                                              BlockReceiptsTracer receiptsTracer,
                                              ProcessingOptions processingOptions,
                                              IStateProvider stateProvider)
        {
            if (processingOptions.ContainsFlag(ProcessingOptions.DoNotVerifyNonce))
            {
                currentTx.Nonce = stateProvider.GetNonce(currentTx.SenderAddress);
            }

            receiptsTracer.StartNewTxTrace(currentTx);
            transactionProcessor.Execute(currentTx, block.Header, receiptsTracer);
            receiptsTracer.EndTxTrace();
        }
        public void Sets_state_root_on_receipts_before_eip658(bool withStateDiff, bool withTrace)
        {
            Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, _isEip155Enabled).WithGasLimit(100000).TestObject;

            long blockNumber = _isEip155Enabled
                ? MainnetSpecProvider.ByzantiumBlockNumber
                : MainnetSpecProvider.ByzantiumBlockNumber - 1;
            Block block = Build.A.Block.WithNumber(blockNumber).WithTransactions(tx).TestObject;

            BlockReceiptsTracer tracer = BuildTracer(block, tx, withTrace, withTrace);

            Execute(tracer, tx, block);

            if (_isEip155Enabled) // we use eip155 check just as a proxy on 658
            {
                Assert.Null(tracer.TxReceipts ![0].PostTransactionState);
Example #22
0
        public void Invokes_other_tracer_mark_as_success_if_other_block_tracer_is_tx_tracer_too()
        {
            Block block = Build.A.Block.WithTransactions(Build.A.Transaction.TestObject).TestObject;

            IBlockTracer        otherTracer = Substitute.For <IBlockTracer, ITxTracer>();
            BlockReceiptsTracer tracer      = new BlockReceiptsTracer();

            tracer.SetOtherTracer(otherTracer);
            tracer.StartNewBlockTrace(block);
            tracer.StartNewTxTrace(block.Transactions[0].Hash);
            var logEntries = new LogEntry[0];

            tracer.MarkAsSuccess(TestItem.AddressA, 100, Array.Empty <byte>(), logEntries, TestItem.KeccakF);

            (otherTracer as ITxTracer).Received().MarkAsSuccess(TestItem.AddressA, 100, Array.Empty <byte>(), logEntries, TestItem.KeccakF);
        }
Example #23
0
        public void Disables_Eip158_for_system_transactions()
        {
            _stateProvider.CreateAccount(TestItem.PrivateKeyA.Address, 0.Ether());
            _stateProvider.Commit(_specProvider.GetSpec(1));

            var         blockNumber = MainNetSpecProvider.SpuriousDragonBlockNumber + 1;
            Transaction tx          = Build.A.SystemTransaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, blockNumber)
                                      .WithGasPrice(0)
                                      .WithValue(0)
                                      .TestObject;

            Block block = Build.A.Block.WithNumber(blockNumber).WithTransactions(tx).TestObject;

            BlockReceiptsTracer tracer = BuildTracer(block, tx, false, false);

            Execute(tracer, tx, block);
            _stateProvider.AccountExists(tx.SenderAddress).Should().BeTrue();
        }
        public void Sets_state_root_on_receipts_before_eip658(bool withStateDiff, bool withTrace)
        {
            Transaction tx = Build.A.Transaction.SignedAndResolved(_ethereumEcdsa, TestItem.PrivateKeyA, _isEip155Enabled).WithGasLimit(100000).TestObject;

            Block block = Build.A.Block.WithNumber(1).WithTransactions(MuirGlacier.Instance, tx).TestObject;

            BlockReceiptsTracer tracer = BuildTracer(block, tx, withTrace, withTrace);

            Execute(tracer, tx, block);

            if (_isEip155Enabled) // we use eip155 check just as a proxy on 658
            {
                Assert.Null(tracer.TxReceipts[0].PostTransactionState);
            }
            else
            {
                Assert.NotNull(tracer.TxReceipts[0].PostTransactionState);
            }
        }
        private BlockReceiptsTracer BuildTracer(Block block, Transaction tx, bool stateDiff, bool trace)
        {
            ParityTraceTypes types = ParityTraceTypes.None;

            if (stateDiff)
            {
                types = types | ParityTraceTypes.StateDiff;
            }

            if (trace)
            {
                types = types | ParityTraceTypes.Trace;
            }

            IBlockTracer        otherTracer = types != ParityTraceTypes.None ? new ParityLikeBlockTracer(tx.Hash, ParityTraceTypes.Trace | ParityTraceTypes.StateDiff) : (IBlockTracer)NullBlockTracer.Instance;
            BlockReceiptsTracer tracer      = new BlockReceiptsTracer(_specProvider, _stateProvider);

            tracer.SetOtherTracer(otherTracer);
            return(tracer);
        }
Example #26
0
        private TxAction ProcessBundleTransaction(
            Block block,
            BundleTransaction currentTx,
            int index,
            BlockReceiptsTracer receiptsTracer,
            ProcessingOptions processingOptions,
            LinkedHashSet <Transaction> transactionsInBlock)
        {
            TxAction action = ProcessTransaction(block, currentTx, index, receiptsTracer, processingOptions, transactionsInBlock, false);

            if (action == TxAction.Add)
            {
                string?error = receiptsTracer.LastReceipt.Error;
                bool   transactionSucceeded = string.IsNullOrEmpty(error) || (error == "revert" && currentTx.CanRevert);
                return(transactionSucceeded ? TxAction.Add : TxAction.Skip);
            }
            else
            {
                return(action);
            }
        }
Example #27
0
        public BlockProcessor(ISpecProvider specProvider,
                              IBlockValidator blockValidator,
                              IRewardCalculator rewardCalculator,
                              ITransactionProcessor transactionProcessor,
                              ISnapshotableDb stateDb,
                              ISnapshotableDb codeDb,
                              IDb traceDb,
                              IStateProvider stateProvider,
                              IStorageProvider storageProvider,
                              ITxPool txPool,
                              IReceiptStorage receiptStorage,
                              ILogManager logManager,
                              IEnumerable <IAdditionalBlockProcessor> additionalBlockProcessors = null)
        {
            _logger               = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager));
            _specProvider         = specProvider ?? throw new ArgumentNullException(nameof(specProvider));
            _blockValidator       = blockValidator ?? throw new ArgumentNullException(nameof(blockValidator));
            _stateProvider        = stateProvider ?? throw new ArgumentNullException(nameof(stateProvider));
            _storageProvider      = storageProvider ?? throw new ArgumentNullException(nameof(storageProvider));
            _txPool               = txPool ?? throw new ArgumentNullException(nameof(txPool));
            _receiptStorage       = receiptStorage ?? throw new ArgumentNullException(nameof(receiptStorage));
            _rewardCalculator     = rewardCalculator ?? throw new ArgumentNullException(nameof(rewardCalculator));
            _transactionProcessor = transactionProcessor ?? throw new ArgumentNullException(nameof(transactionProcessor));
            _stateDb              = stateDb ?? throw new ArgumentNullException(nameof(stateDb));
            _codeDb               = codeDb ?? throw new ArgumentNullException(nameof(codeDb));
            _traceDb              = traceDb ?? throw new ArgumentNullException(nameof(traceDb));
            _receiptsTracer       = new BlockReceiptsTracer(_specProvider, _stateProvider);

            if (additionalBlockProcessors != null)
            {
                var additionalBlockProcessorsArray = additionalBlockProcessors.ToArray();
                if (additionalBlockProcessorsArray.Length > 0)
                {
                    _additionalBlockProcessor = additionalBlockProcessorsArray.Length == 1
                        ? additionalBlockProcessorsArray[0]
                        : new CompositeAdditionalBlockProcessor(additionalBlockProcessorsArray);
                }
            }
        }
Example #28
0
        public ResultWrapper <ReceiptWithProof> proof_getTransactionReceipt(Keccak txHash, bool includeHeader)
        {
            Keccak blockHash = _receiptFinder.FindBlockHash(txHash);

            if (blockHash == null)
            {
                return(ResultWrapper <ReceiptWithProof> .Fail($"{txHash} receipt could not be found", ErrorCodes.ResourceNotFound));
            }

            SearchResult <Block> searchResult = _blockFinder.SearchForBlock(new BlockParameter(blockHash));

            if (searchResult.IsError)
            {
                return(ResultWrapper <ReceiptWithProof> .Fail(searchResult));
            }

            Block     block   = searchResult.Object;
            TxReceipt receipt = _receiptFinder.Get(block).ForTransaction(txHash);

            BlockReceiptsTracer receiptsTracer = new BlockReceiptsTracer();

            receiptsTracer.SetOtherTracer(NullBlockTracer.Instance);
            _tracer.Trace(block, receiptsTracer);

            TxReceipt[]   receipts = receiptsTracer.TxReceipts;
            Transaction[] txs      = block.Transactions;

            ReceiptWithProof receiptWithProof = new ReceiptWithProof();

            receiptWithProof.Receipt      = new ReceiptForRpc(txHash, receipt);
            receiptWithProof.ReceiptProof = BuildReceiptProofs(block.Number, receipts, receipt.Index);
            receiptWithProof.TxProof      = BuildTxProofs(txs, _specProvider.GetSpec(block.Number), receipt.Index);
            if (includeHeader)
            {
                receiptWithProof.BlockHeader = _headerDecoder.Encode(block.Header).Bytes;
            }

            return(ResultWrapper <ReceiptWithProof> .Success(receiptWithProof));
        }
        public override TxReceipt[] ProcessTransactions(
            Block block,
            ProcessingOptions processingOptions,
            BlockReceiptsTracer receiptsTracer,
            IReleaseSpec spec)
        {
            IEnumerable <Transaction> transactions = GetTransactions(block);

            int i = 0;
            LinkedHashSet <Transaction> transactionsInBlock = new(ByHashTxComparer.Instance);

            foreach (Transaction transaction in transactions)
            {
                if (IsAccountAbstractionTransaction(transaction))
                {
                    BlockProcessor.TxAction action = ProcessAccountAbstractionTransaction(block, transaction, i++, receiptsTracer, processingOptions, transactionsInBlock);
                    if (action == BlockProcessor.TxAction.Stop)
                    {
                        break;
                    }
                }
                else
                {
                    BlockProcessor.TxAction action = ProcessTransaction(block, transaction, i++, receiptsTracer, processingOptions, transactionsInBlock);
                    if (action == BlockProcessor.TxAction.Stop)
                    {
                        break;
                    }
                }
            }

            _stateProvider.Commit(spec, receiptsTracer);
            _storageProvider.Commit(receiptsTracer);

            SetTransactions(block, transactionsInBlock);
            return(receiptsTracer.TxReceipts.ToArray());
        }
Example #30
0
 private void ProcessTransaction(Block block, Transaction currentTx, int index, BlockReceiptsTracer receiptsTracer, ProcessingOptions processingOptions)
 {
     _transactionProcessor.ProcessTransaction(block, currentTx, receiptsTracer, processingOptions, _stateProvider);
     TransactionProcessed?.Invoke(this, new TxProcessedEventArgs(index, currentTx, receiptsTracer.TxReceipts[index]));
 }