public AcceptTxResult Accept(Transaction tx, TxHandlingOptions handlingOptions)
        {
            IReleaseSpec spec           = _specProvider.GetCurrentHeadSpec();
            Account      account        = _accounts.GetAccount(tx.SenderAddress !);
            UInt256      balance        = account.Balance;
            UInt256      cumulativeCost = UInt256.Zero;
            bool         overflow       = false;

            Transaction[] transactions = _txs.GetBucketSnapshot(tx.SenderAddress);

            for (int i = 0; i < transactions.Length; i++)
            {
                if (transactions[i].Nonce < account.Nonce)
                {
                    continue;
                }

                if (transactions[i].Nonce < tx.Nonce)
                {
                    overflow |= UInt256.MultiplyOverflow(
                        transactions[i].CalculateEffectiveGasPrice(spec.IsEip1559Enabled, _headInfo.CurrentBaseFee),
                        (UInt256)transactions[i].GasLimit,
                        out UInt256 txCost);

                    overflow |= UInt256.AddOverflow(cumulativeCost, txCost, out cumulativeCost);
                    overflow |= UInt256.AddOverflow(cumulativeCost, tx.Value, out cumulativeCost);
                }
                else
                {
                    break;
                }
            }

            UInt256 affordableGasPrice = tx.CalculateAffordableGasPrice(spec.IsEip1559Enabled, _headInfo.CurrentBaseFee, balance > cumulativeCost ? balance - cumulativeCost : 0);

            overflow |= spec.IsEip1559Enabled && UInt256.AddOverflow(tx.MaxPriorityFeePerGas, tx.MaxFeePerGas, out _);
            overflow |= UInt256.MultiplyOverflow(affordableGasPrice, (UInt256)tx.GasLimit, out UInt256 cost);
            overflow |= UInt256.AddOverflow(cost, tx.Value, out cost);
            overflow |= UInt256.AddOverflow(cost, cumulativeCost, out cumulativeCost);
            if (overflow)
            {
                if (_logger.IsTrace)
                {
                    _logger.Trace($"Skipped adding transaction {tx.ToString("  ")}, cost overflow.");
                }
                return(AcceptTxResult.Int256Overflow);
            }

            if (balance < cumulativeCost)
            {
                if (_logger.IsTrace)
                {
                    _logger.Trace($"Skipped adding transaction {tx.ToString("  ")}, insufficient funds.");
                }
                return(AcceptTxResult.InsufficientFunds.WithMessage($"Account balance: {balance}, cumulative cost: {cumulativeCost}"));
            }

            return(AcceptTxResult.Accepted);
        }
Ejemplo n.º 2
0
        public AcceptTxResult Accept(Transaction tx, TxHandlingOptions txHandlingOptions)
        {
            IReleaseSpec spec = _specProvider.GetCurrentHeadSpec();

            if (!_txValidator.IsWellFormed(tx, spec))
            {
                // It may happen that other nodes send us transactions that were signed for another chain or don't have enough gas.
                if (_logger.IsTrace)
                {
                    _logger.Trace($"Skipped adding transaction {tx.ToString("  ")}, invalid transaction.");
                }
                return(AcceptTxResult.Invalid);
            }

            return(AcceptTxResult.Accepted);
        }
Ejemplo n.º 3
0
        public AcceptTxResult Accept(Transaction tx, TxHandlingOptions handlingOptions)
        {
            IReleaseSpec spec               = _specProvider.GetCurrentHeadSpec();
            Account      account            = _accounts.GetAccount(tx.SenderAddress !);
            UInt256      balance            = account.Balance;
            UInt256      affordableGasPrice = tx.CalculateAffordableGasPrice(spec.IsEip1559Enabled, _headInfo.CurrentBaseFee, balance);
            bool         isNotLocal         = (handlingOptions & TxHandlingOptions.PersistentBroadcast) != TxHandlingOptions.PersistentBroadcast;

            if (_txs.IsFull() &&
                _txs.TryGetLast(out Transaction? lastTx) &&
                affordableGasPrice <= lastTx?.GasBottleneck &&
                isNotLocal)
            {
                Metrics.PendingTransactionsTooLowFee++;
                if (_logger.IsTrace)
                {
                    _logger.Trace($"Skipped adding transaction {tx.ToString("  ")}, too low payable gas price.");
                }
                return(AcceptTxResult.FeeTooLow.WithMessage($"FeePerGas needs to be higher than {lastTx.GasBottleneck.Value} to be added to the TxPool. Affordable FeePerGas of rejected tx: {affordableGasPrice}."));
            }

            return(AcceptTxResult.Accepted);
        }
Ejemplo n.º 4
0
 public AcceptTxResult Accept(Transaction tx, TxHandlingOptions txHandlingOptions) =>
 _stateProvider.IsInvalidContractSender(_specProvider.GetCurrentHeadSpec(), tx.SenderAddress !)
         ? AcceptTxResult.SenderIsContract
         : AcceptTxResult.Accepted;