diff --git a/rollup/internal/controller/sender/sender.go b/rollup/internal/controller/sender/sender.go index 719f31d7f8..d580ec2853 100644 --- a/rollup/internal/controller/sender/sender.go +++ b/rollup/internal/controller/sender/sender.go @@ -222,12 +222,13 @@ func (s *Sender) SendTransaction(ID string, target *common.Address, value *big.I if feeData, err = s.getFeeData(s.auth, target, value, data, fallbackGasLimit); err != nil { s.metrics.sendTransactionFailureGetFee.WithLabelValues(s.service, s.name).Inc() - log.Error("failed to get fee data", "err", err) + log.Error("failed to get fee data", "from", s.auth.From.String(), "to", target.String(), "value", value.Uint64(), "fallback gas limit", fallbackGasLimit, "err", err) return common.Hash{}, fmt.Errorf("failed to get fee data, err: %w", err) } if tx, err = s.createAndSendTx(s.auth, feeData, target, value, data, nil); err != nil { s.metrics.sendTransactionFailureSendTx.WithLabelValues(s.service, s.name).Inc() + log.Error("failed to create and send tx (non-resubmit case)", "from", s.auth.From.String(), "to", target.String(), "nonce", s.auth.Nonce.Uint64(), "value", value.Uint64(), "err", err) return common.Hash{}, fmt.Errorf("failed to create and send transaction, err: %w", err) } @@ -303,11 +304,11 @@ func (s *Sender) createAndSendTx(auth *bind.TransactOpts, feeData *FeeData, targ // sign and send tx, err := auth.Signer(auth.From, types.NewTx(txData)) if err != nil { - log.Error("failed to sign tx", "err", err) + log.Error("failed to sign tx", "address", auth.From.String(), "err", err) return nil, err } if err = s.client.SendTransaction(s.ctx, tx); err != nil { - log.Error("failed to send tx", "tx hash", tx.Hash().String(), "err", err) + log.Error("failed to send tx", "tx hash", tx.Hash().String(), "from", auth.From.String(), "to", tx.To().String(), "nonce", tx.Nonce(), "err", err) // Check if contain nonce, and reset nonce // only reset nonce when it is not from resubmit if strings.Contains(err.Error(), "nonce") && overrideNonce == nil { @@ -356,6 +357,8 @@ func (s *Sender) resubmitTransaction(feeData *FeeData, auth *bind.TransactOpts, "tx_hash": tx.Hash().String(), "tx_type": s.config.TxType, "from": auth.From.String(), + "to": tx.To().String(), + "nonce": tx.Nonce(), } switch s.config.TxType { @@ -369,10 +372,15 @@ func (s *Sender) resubmitTransaction(feeData *FeeData, auth *bind.TransactOpts, if gasPrice.Cmp(maxGasPrice) > 0 { gasPrice = maxGasPrice } - feeData.gasPrice = gasPrice - txInfo["original_gas_price"] = originalGasPrice - txInfo["adjusted_gas_price"] = gasPrice + if originalGasPrice.Cmp(gasPrice) <= 0 { + log.Warn("gas price bump corner case, add 1 wei", "original", originalGasPrice.Uint64(), "adjusted", gasPrice.Uint64()) + gasPrice = new(big.Int).Add(gasPrice, big.NewInt(1)) + } + + feeData.gasPrice = gasPrice + txInfo["original_gas_price"] = originalGasPrice.Uint64() + txInfo["adjusted_gas_price"] = gasPrice.Uint64() default: originalGasTipCap := big.NewInt(feeData.gasTipCap.Int64()) originalGasFeeCap := big.NewInt(feeData.gasFeeCap.Int64()) @@ -406,20 +414,35 @@ func (s *Sender) resubmitTransaction(feeData *FeeData, auth *bind.TransactOpts, if gasFeeCap.Cmp(maxGasPrice) > 0 { gasFeeCap = maxGasPrice } + + if originalGasTipCap.Cmp(gasTipCap) <= 0 { + log.Warn("gas tip cap bump corner case, add 1 wei", "original", originalGasTipCap.Uint64(), "adjusted", gasTipCap.Uint64()) + gasTipCap = new(big.Int).Add(gasTipCap, big.NewInt(1)) + } + + if originalGasFeeCap.Cmp(gasFeeCap) <= 0 { + log.Warn("gas fee cap bump corner case, add 1 wei", "original", originalGasFeeCap.Uint64(), "adjusted", gasFeeCap.Uint64()) + gasFeeCap = new(big.Int).Add(gasFeeCap, big.NewInt(1)) + } + feeData.gasFeeCap = gasFeeCap feeData.gasTipCap = gasTipCap - - txInfo["original_gas_tip_cap"] = originalGasTipCap - txInfo["adjusted_gas_tip_cap"] = gasTipCap - txInfo["original_gas_fee_cap"] = originalGasFeeCap - txInfo["adjusted_gas_fee_cap"] = gasFeeCap + txInfo["original_gas_tip_cap"] = originalGasTipCap.Uint64() + txInfo["adjusted_gas_tip_cap"] = gasTipCap.Uint64() + txInfo["original_gas_fee_cap"] = originalGasFeeCap.Uint64() + txInfo["adjusted_gas_fee_cap"] = gasFeeCap.Uint64() } - log.Debug("Transaction gas adjustment details", txInfo) + log.Info("Transaction gas adjustment details", txInfo) nonce := tx.Nonce() s.metrics.resubmitTransactionTotal.WithLabelValues(s.service, s.name).Inc() - return s.createAndSendTx(auth, feeData, tx.To(), tx.Value(), tx.Data(), &nonce) + tx, err := s.createAndSendTx(auth, feeData, tx.To(), tx.Value(), tx.Data(), &nonce) + if err != nil { + log.Error("failed to create and send tx (resubmit case)", "from", s.auth.From.String(), "to", tx.To().String(), "nonce", nonce, "value", tx.Value().Uint64(), "err", err) + return nil, err + } + return tx, nil } // checkPendingTransaction checks the confirmation status of pending transactions against the latest confirmed block number. @@ -455,15 +478,16 @@ func (s *Sender) checkPendingTransaction(header *types.Header, confirmed uint64) } } } else if s.config.EscalateBlocks+pending.submitAt < number { - log.Debug("resubmit transaction", - "tx hash", pending.tx.Hash().String(), + log.Info("resubmit transaction", + "hash", pending.tx.Hash().String(), + "from", pending.signer.From.String(), + "to", pending.tx.To(), + "nonce", pending.tx.Nonce(), "submit block number", pending.submitAt, "current block number", number, - "escalateBlocks", s.config.EscalateBlocks) + "configured escalateBlocks", s.config.EscalateBlocks) - var tx *types.Transaction - tx, err := s.resubmitTransaction(pending.feeData, pending.signer, pending.tx) - if err != nil { + if tx, err := s.resubmitTransaction(pending.feeData, pending.signer, pending.tx); err != nil { // If account pool is empty, it will try again in next loop. if !errors.Is(err, ErrNoAvailableAccount) { log.Error("failed to resubmit transaction, reset submitAt", "tx hash", pending.tx.Hash().String(), "err", err)