Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve gas control in legacy tx #74

Merged
merged 3 commits into from
Apr 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading