Skip to content

Commit

Permalink
improve gas control in legacy tx (#74)
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaozhou committed Apr 7, 2024
1 parent c153e70 commit 5b86f58
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 20 deletions.
24 changes: 13 additions & 11 deletions eth/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package eth
import (
"math/big"
"strconv"
"strings"
"time"

"github.com/celer-network/goutils/log"
Expand All @@ -15,15 +16,16 @@ type txOptions struct {
ethValue *big.Int
nonce uint64
// Legacy Tx gas price
minGasGwei uint64
maxGasGwei uint64
addGasGwei uint64
forceGasGwei *uint64 // use pointer to allow forcing zero gas
minGasGwei float64
maxGasGwei float64
addGasGwei float64
forceGasGwei *float64 // use pointer to allow forcing zero gas
// EIP-1559 Tx gas price
maxFeePerGasGwei uint64 // aka GasFeeCap in gwei
maxPriorityFeePerGasGwei float64 // aka GasTipCap in gwei
addPriorityFeePerGasGwei float64
addPriorityFeeRatio float64
// For both Legacy and EIP-1559, use suggested * (1 + addGasFeeRatio)
addGasFeeRatio float64
// Gas limit
gasLimit uint64
addGasEstimateRatio float64
Expand Down Expand Up @@ -92,19 +94,19 @@ func WithNonce(n uint64) TxOption {
})
}

func WithMinGasGwei(g uint64) TxOption {
func WithMinGasGwei(g float64) TxOption {
return newFuncTxOption(func(o *txOptions) {
o.minGasGwei = g
})
}

func WithMaxGasGwei(g uint64) TxOption {
func WithMaxGasGwei(g float64) TxOption {
return newFuncTxOption(func(o *txOptions) {
o.maxGasGwei = g
})
}

func WithAddGasGwei(g uint64) TxOption {
func WithAddGasGwei(g float64) TxOption {
return newFuncTxOption(func(o *txOptions) {
o.addGasGwei = g
})
Expand All @@ -113,7 +115,7 @@ func WithAddGasGwei(g uint64) TxOption {
func WithForceGasGwei(g string) TxOption {
return newFuncTxOption(func(o *txOptions) {
if g != "" {
gwei, err := strconv.ParseUint(g, 10, 64)
gwei, err := strconv.ParseFloat(strings.TrimSpace(g), 64)
if err != nil {
log.Errorln("invalid ForceGasGwei", g)
return
Expand Down Expand Up @@ -141,9 +143,9 @@ func WithAddPriorityFeePerGasGwei(g float64) TxOption {
})
}

func WithAddPriorityFeeRatio(r float64) TxOption {
func WithAddGassFeeRatio(r float64) TxOption {
return newFuncTxOption(func(o *txOptions) {
o.addPriorityFeeRatio = r
o.addGasFeeRatio = r
})
}

Expand Down
19 changes: 10 additions & 9 deletions eth/transactor.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,7 @@ func (t *Transactor) determineGas(method TxMethod, signer *bind.TransactOpts, tx
// 1. Determine gas price
// Only accept legacy flags or EIP-1559 flags, not both
hasLegacyFlags := txopts.forceGasGwei != nil || txopts.minGasGwei > 0 || txopts.maxGasGwei > 0 || txopts.addGasGwei > 0
has1559Flags := txopts.maxFeePerGasGwei > 0 || txopts.maxPriorityFeePerGasGwei > 0 ||
txopts.addPriorityFeePerGasGwei > 0 || txopts.addPriorityFeeRatio > 0
has1559Flags := txopts.maxFeePerGasGwei > 0 || txopts.maxPriorityFeePerGasGwei > 0 || txopts.addPriorityFeePerGasGwei > 0
if hasLegacyFlags && has1559Flags {
return ErrConflictingGasFlags
}
Expand Down Expand Up @@ -295,15 +294,15 @@ func determine1559GasPrice(signer *bind.TransactOpts, txopts txOptions, client *
}
if txopts.maxPriorityFeePerGasGwei > 0 {
signer.GasTipCap = new(big.Int).SetUint64(uint64(txopts.maxPriorityFeePerGasGwei * 1e9))
} else if txopts.addPriorityFeePerGasGwei > 0 || txopts.addPriorityFeeRatio > 0 {
} else if txopts.addPriorityFeePerGasGwei > 0 || txopts.addGasFeeRatio > 0 {
suggestedGasTipCap, err := client.SuggestGasTipCap(context.Background())
if err != nil {
return fmt.Errorf("failed to call SuggestGasTipCap: %w", err)
}
if txopts.addPriorityFeePerGasGwei > 0 {
signer.GasTipCap = new(big.Int).SetUint64(uint64(txopts.addPriorityFeePerGasGwei*1e9) + suggestedGasTipCap.Uint64())
} else if txopts.addPriorityFeeRatio > 0 {
signer.GasTipCap = new(big.Int).SetUint64(uint64(float64(suggestedGasTipCap.Uint64()) * (1 + txopts.addGasEstimateRatio)))
} else if txopts.addGasFeeRatio > 0 {
signer.GasTipCap = new(big.Int).SetUint64(uint64(float64(suggestedGasTipCap.Uint64()) * (1 + txopts.addGasFeeRatio)))
}
}
return nil
Expand All @@ -313,26 +312,28 @@ func determine1559GasPrice(signer *bind.TransactOpts, txopts txOptions, client *
func determineLegacyGasPrice(
signer *bind.TransactOpts, txopts txOptions, client *ethclient.Client) error {
if txopts.forceGasGwei != nil {
signer.GasPrice = new(big.Int).SetUint64(*txopts.forceGasGwei * 1e9)
signer.GasPrice = new(big.Int).SetUint64(uint64(*txopts.forceGasGwei * 1e9))
return nil
}
gasPrice, err := client.SuggestGasPrice(context.Background())
if err != nil {
return fmt.Errorf("failed to call SuggestGasPrice: %w", err)
}
if txopts.addGasGwei > 0 { // Add gas price to the suggested value to speed up transactions
addPrice := new(big.Int).SetUint64(txopts.addGasGwei * 1e9)
addPrice := new(big.Int).SetUint64(uint64(txopts.addGasGwei * 1e9))
gasPrice.Add(gasPrice, addPrice)
} else if txopts.addGasFeeRatio > 0 {
gasPrice = new(big.Int).SetUint64(uint64(float64(gasPrice.Uint64()) * (1 + txopts.addGasFeeRatio)))
}
if txopts.minGasGwei > 0 { // gas can't be lower than minGas
minPrice := new(big.Int).SetUint64(txopts.minGasGwei * 1e9)
minPrice := new(big.Int).SetUint64(uint64(txopts.minGasGwei * 1e9))
// minPrice is larger than suggested, use minPrice
if minPrice.Cmp(gasPrice) > 0 {
gasPrice = minPrice
}
}
if txopts.maxGasGwei > 0 { // maxGas 0 means no cap on gas price
maxPrice := new(big.Int).SetUint64(txopts.maxGasGwei * 1e9)
maxPrice := new(big.Int).SetUint64(uint64(txopts.maxGasGwei * 1e9))
// GasPrice is larger than allowed cap, use maxPrice but log warning
if maxPrice.Cmp(gasPrice) < 0 {
log.Warnf("suggested gas price %s larger than cap %s", gasPrice, maxPrice)
Expand Down

0 comments on commit 5b86f58

Please sign in to comment.