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);
        }
Example #2
0
        private TxAction ProcessBundle(Block block,
                                       List <BundleTransaction> bundleTransactions,
                                       LinkedHashSet <Transaction> transactionsInBlock,
                                       BlockReceiptsTracer receiptsTracer,
                                       ProcessingOptions processingOptions)
        {
            Snapshot snapshot        = _worldState.TakeSnapshot();
            int      receiptSnapshot = receiptsTracer.TakeSnapshot();
            UInt256  initialBalance  = _stateProvider.GetBalance(block.Header.GasBeneficiary !);

            bool CheckFeeNotManipulated()
            {
                UInt256 finalBalance = _stateProvider.GetBalance(block.Header.GasBeneficiary !);
                UInt256 feeReceived  = finalBalance - initialBalance;
                UInt256 originalSimulatedGasPrice = bundleTransactions[0].SimulatedBundleFee / bundleTransactions[0].SimulatedBundleGasUsed;
                UInt256 actualGasPrice            = feeReceived / (UInt256)receiptsTracer.LastReceipt.GasUsed !;

                return(actualGasPrice >= originalSimulatedGasPrice);
            }

            bool     bundleSucceeded = bundleTransactions.Count > 0;
            TxAction txAction        = TxAction.Skip;

            for (int index = 0; index < bundleTransactions.Count && bundleSucceeded; index++)
            {
                txAction         = ProcessBundleTransaction(block, bundleTransactions[index], index, receiptsTracer, processingOptions, transactionsInBlock);
                bundleSucceeded &= txAction == TxAction.Add;

                // if we need to stop on not first tx in the bundle, we actually want to skip the bundle
                txAction = txAction == TxAction.Stop && index != 0 ? TxAction.Skip : txAction;
            }

            if (bundleSucceeded)
            {
                bundleSucceeded &= CheckFeeNotManipulated();
            }

            if (bundleSucceeded)
            {
                for (int index = 0; index < bundleTransactions.Count; index++)
                {
                    BundleTransaction bundleTransaction = bundleTransactions[index];
                    transactionsInBlock.Add(bundleTransaction);
                    int txIndex = receiptSnapshot + index;
                    _transactionProcessed?.Invoke(this, new TxProcessedEventArgs(txIndex, bundleTransaction, receiptsTracer.TxReceipts[txIndex]));
                }
            }
            else
            {
                _worldState.Restore(snapshot);
                receiptsTracer.Restore(receiptSnapshot);
                for (int index = 0; index < bundleTransactions.Count; index++)
                {
                    transactionsInBlock.Remove(bundleTransactions[index]);
                }
            }

            bundleTransactions.Clear();

            return(txAction);
        }