Skip to content

Commit

Permalink
Fix gas estimator for txs with feeCurrency + Value (#282)
Browse files Browse the repository at this point in the history
* Fix gas estimator for txs with feeCurrency + Value

---------

Co-authored-by: Maximilian Langenfeld <[email protected]>
  • Loading branch information
gastonponti and ezdac authored Dec 3, 2024
1 parent 1834e2c commit fb687af
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 13 deletions.
22 changes: 14 additions & 8 deletions eth/gasestimator/gasestimator.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ type Options struct {
// Estimate returns the lowest possible gas limit that allows the transaction to
// run successfully with the provided context options. It returns an error if the
// transaction would always revert, or if there are unexpected failures.
func Estimate(ctx context.Context, call *core.Message, opts *Options, gasCap uint64, exchangeRates common.ExchangeRates, balance *big.Int) (uint64, []byte, error) {
func Estimate(ctx context.Context, call *core.Message, opts *Options, gasCap uint64, exchangeRates common.ExchangeRates, feeCurrencyBalance *big.Int) (uint64, []byte, error) {
// Binary search the gas limit, as it may need to be higher than the amount used
var (
lo uint64 // lowest-known gas limit where tx execution fails
Expand All @@ -72,7 +72,8 @@ func Estimate(ctx context.Context, call *core.Message, opts *Options, gasCap uin
}
// Recap the highest gas limit with account's available balance.
if feeCap.BitLen() != 0 {
available := balance
celoBalance := opts.State.GetBalance(call.From).ToBig()
available := celoBalance
if call.FeeCurrency != nil {
if !call.IsFeeCurrencyDenominated() {
// CIP-66, prices are given in native token.
Expand All @@ -83,12 +84,17 @@ func Estimate(ctx context.Context, call *core.Message, opts *Options, gasCap uin
return 0, nil, err
}
}
} else {
if call.Value != nil {
if call.Value.Cmp(available) >= 0 {
available = feeCurrencyBalance
}
if call.Value != nil {
if call.Value.Cmp(celoBalance) > 0 {
return 0, nil, core.ErrInsufficientFundsForTransfer
}
if call.FeeCurrency == nil {
available.Sub(available, call.Value)
if available.Cmp(big.NewInt(0)) <= 0 {
return 0, nil, core.ErrInsufficientFundsForTransfer
}
available.Sub(available, call.Value)
}
}

Expand All @@ -114,8 +120,8 @@ func Estimate(ctx context.Context, call *core.Message, opts *Options, gasCap uin
if transfer == nil {
transfer = new(big.Int)
}
log.Debug("Gas estimation capped by limited funds", "original", hi, "balance", balance,
"sent", transfer, "maxFeePerGas", feeCap, "fundable", allowance,
log.Debug("Gas estimation capped by limited funds", "original", hi, "celo balance", celoBalance,
"feeCurrency balance", feeCurrencyBalance, "sent", transfer, "maxFeePerGas", feeCap, "fundable", allowance,
"feeCurrency", call.FeeCurrency, "maxFeeInFeeCurrency", call.MaxFeeInFeeCurrency,
)
hi = allowance.Uint64()
Expand Down
13 changes: 8 additions & 5 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1330,14 +1330,17 @@ func DoEstimateGas(ctx context.Context, b CeloBackend, args TransactionArgs, blo

call := args.ToMessage(header.BaseFee, exchangeRates)

// Celo specific: get balance
balance, err := b.GetFeeBalance(ctx, blockNrOrHash, call.From, args.FeeCurrency)
if err != nil {
return 0, err
// Celo specific: get balance of fee currency if fee currency is specified
feeCurrencyBalance := new(big.Int)
if args.FeeCurrency != nil {
feeCurrencyBalance, err = b.GetFeeBalance(ctx, blockNrOrHash, call.From, args.FeeCurrency)
if err != nil {
return 0, err
}
}

// Run the gas estimation and wrap any revertals into a custom return
estimate, revert, err := gasestimator.Estimate(ctx, call, opts, gasCap, exchangeRates, balance)
estimate, revert, err := gasestimator.Estimate(ctx, call, opts, gasCap, exchangeRates, feeCurrencyBalance)
if err != nil {
if len(revert) > 0 {
return 0, newRevertError(revert)
Expand Down

0 comments on commit fb687af

Please sign in to comment.