Beispiel #1
0
        public async Task Should_count_total_coinbase_payments()
        {
            var chain = await MevRpcModuleTests.CreateChain(1);

            chain.GasLimitCalculator.GasLimit = 10_000_000;

            Address contractAddress = await MevRpcModuleTests.Contracts.Deploy(chain, MevRpcModuleTests.Contracts.CoinbaseCode);

            BundleTransaction seedContractTx = Build.A.TypedTransaction <BundleTransaction>()
                                               .WithTo(contractAddress)
                                               .WithData(Bytes.FromHexString(MevRpcModuleTests.Contracts.CoinbaseDeposit))
                                               .WithValue(100000000000)
                                               .WithNonce(1)
                                               .WithGasLimit(1_000_000)
                                               .SignedAndResolved(TestItem.PrivateKeyC).TestObject;

            await chain.AddBlock(true, seedContractTx);

            //Console.WriteLine((await chain.EthRpcModule.eth_getBalance(contractAddress)).Data!);

            UInt256 beforeCoinbasePayments = (UInt256)Metrics.TotalCoinbasePayments;

            BundleTransaction coinbaseTx = Build.A.TypedTransaction <BundleTransaction>()
                                           .WithGasLimit(MevRpcModuleTests.Contracts.LargeGasLimit)
                                           .WithData(Bytes.FromHexString(MevRpcModuleTests.Contracts.CoinbaseInvokePay))
                                           .WithTo(contractAddress)
                                           .WithGasPrice(1ul)
                                           .WithNonce(0)
                                           .WithValue(0)
                                           .SignedAndResolved(TestItem.PrivateKeyA).TestObject;

            MevRpcModuleTests.SuccessfullySendBundle(chain, 3, coinbaseTx);

            await chain.AddBlock(true);

            MevRpcModuleTests.GetHashes(chain.BlockTree.Head !.Transactions).Should().Equal(MevRpcModuleTests.GetHashes(new [] { coinbaseTx }));

            UInt256 deltaCoinbasePayments = (UInt256)Metrics.TotalCoinbasePayments - beforeCoinbasePayments;

            deltaCoinbasePayments.Should().Be(100000000000);
        }
Beispiel #2
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);
            }
        }
        private static BundleTransaction[] Decode(byte[][] transactions, ISet <Keccak>?revertingTxHashes = null)
        {
            revertingTxHashes ??= new HashSet <Keccak>();
            BundleTransaction[] txs = new BundleTransaction[transactions.Length];
            for (int i = 0; i < transactions.Length; i++)
            {
                BundleTransaction bundleTransaction = Rlp.Decode <BundleTransaction>(transactions[i], RlpBehaviors.SkipTypedWrapping);
                Keccak            transactionHash   = bundleTransaction.Hash !;
                bundleTransaction.CanRevert = revertingTxHashes.Contains(transactionHash);
                revertingTxHashes.Remove(transactionHash);

                txs[i] = bundleTransaction;
            }

            if (revertingTxHashes.Count > 0)
            {
                throw new ArgumentException(
                          $"Bundle didn't contain some of revertingTxHashes: [{string.Join(", ", revertingTxHashes.OfType<object>())}]",
                          nameof(revertingTxHashes));
            }

            return(txs);
        }
Beispiel #4
0
        protected override SimulatedMevBundle BuildResult(MevBundle bundle, BundleBlockTracer tracer)
        {
            UInt256 eligibleGasFeePayment = UInt256.Zero;
            UInt256 totalGasFeePayment    = UInt256.Zero;
            bool    success = true;

            for (int i = 0; i < bundle.Transactions.Count; i++)
            {
                BundleTransaction tx = bundle.Transactions[i];

                tx.SimulatedBundleGasUsed = (UInt256)tracer.GasUsed;

                success &= tracer.TransactionResults[i];

                totalGasFeePayment += tracer.TxFees[i];
                if (!_txPool.IsKnown(tx.Hash))
                {
                    eligibleGasFeePayment += tracer.TxFees[i];
                }
            }

            for (int i = 0; i < bundle.Transactions.Count; i++)
            {
                bundle.Transactions[i].SimulatedBundleFee = totalGasFeePayment + tracer.CoinbasePayments;
            }

            if ((UInt256)decimal.MaxValue >= (UInt256)Metrics.TotalCoinbasePayments + tracer.CoinbasePayments)
            {
                Metrics.TotalCoinbasePayments += (decimal)tracer.CoinbasePayments;
            }
            else
            {
                Metrics.TotalCoinbasePayments = ulong.MaxValue;
            }

            return(new(bundle, tracer.GasUsed, success, tracer.BundleFee, tracer.CoinbasePayments, eligibleGasFeePayment));
        }
Beispiel #5
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);
        }