Commit 5c83435e authored by Matthew Slipper's avatar Matthew Slipper Committed by GitHub

Merge pull request #2291 from cfromknecht/bss-gas-estimation-limit

feat: extract gas limit estimation to driver, add 20% buffer
parents 0eb52d63 aca0684e
---
'@eth-optimism/batch-submitter-service': patch
---
Add 20% buffer to gas estimation on tx-batch submission to prevent OOG reverts
...@@ -12,6 +12,7 @@ import ( ...@@ -12,6 +12,7 @@ import (
"github.com/ethereum-optimism/optimism/go/bss-core/metrics" "github.com/ethereum-optimism/optimism/go/bss-core/metrics"
"github.com/ethereum-optimism/optimism/go/bss-core/txmgr" "github.com/ethereum-optimism/optimism/go/bss-core/txmgr"
l2ethclient "github.com/ethereum-optimism/optimism/l2geth/ethclient" l2ethclient "github.com/ethereum-optimism/optimism/l2geth/ethclient"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
...@@ -274,6 +275,46 @@ func (d *Driver) UpdateGasPrice( ...@@ -274,6 +275,46 @@ func (d *Driver) UpdateGasPrice(
tx *types.Transaction, tx *types.Transaction,
) (*types.Transaction, error) { ) (*types.Transaction, error) {
gasTipCap, err := d.cfg.L1Client.SuggestGasTipCap(ctx)
if err != nil {
// If the transaction failed because the backend does not support
// eth_maxPriorityFeePerGas, fallback to using the default constant.
// Currently Alchemy is the only backend provider that exposes this
// method, so in the event their API is unreachable we can fallback to a
// degraded mode of operation. This also applies to our test
// environments, as hardhat doesn't support the query either.
if !drivers.IsMaxPriorityFeePerGasNotFoundError(err) {
return nil, err
}
log.Warn(d.cfg.Name + " eth_maxPriorityFeePerGas is unsupported " +
"by current backend, using fallback gasTipCap")
gasTipCap = drivers.FallbackGasTipCap
}
header, err := d.cfg.L1Client.HeaderByNumber(ctx, nil)
if err != nil {
return nil, err
}
gasFeeCap := txmgr.CalcGasFeeCap(header.BaseFee, gasTipCap)
// The estimated gas limits performed by RawTransact fail semi-regularly
// with out of gas exceptions. To remedy this we extract the internal calls
// to perform gas price/gas limit estimation here and add a buffer to
// account for any network variability.
gasLimit, err := d.cfg.L1Client.EstimateGas(ctx, ethereum.CallMsg{
From: d.walletAddr,
To: &d.cfg.CTCAddr,
GasPrice: nil,
GasTipCap: gasTipCap,
GasFeeCap: gasFeeCap,
Value: nil,
Data: tx.Data(),
})
if err != nil {
return nil, err
}
opts, err := bind.NewKeyedTransactorWithChainID( opts, err := bind.NewKeyedTransactorWithChainID(
d.cfg.PrivKey, d.cfg.ChainID, d.cfg.PrivKey, d.cfg.ChainID,
) )
...@@ -282,28 +323,12 @@ func (d *Driver) UpdateGasPrice( ...@@ -282,28 +323,12 @@ func (d *Driver) UpdateGasPrice(
} }
opts.Context = ctx opts.Context = ctx
opts.Nonce = new(big.Int).SetUint64(tx.Nonce()) opts.Nonce = new(big.Int).SetUint64(tx.Nonce())
opts.GasTipCap = gasTipCap
opts.GasFeeCap = gasFeeCap
opts.GasLimit = 6 * gasLimit / 5 // add 20% buffer to gas limit
opts.NoSend = true opts.NoSend = true
finalTx, err := d.rawCtcContract.RawTransact(opts, tx.Data()) return d.rawCtcContract.RawTransact(opts, tx.Data())
switch {
case err == nil:
return finalTx, nil
// If the transaction failed because the backend does not support
// eth_maxPriorityFeePerGas, fallback to using the default constant.
// Currently Alchemy is the only backend provider that exposes this method,
// so in the event their API is unreachable we can fallback to a degraded
// mode of operation. This also applies to our test environments, as hardhat
// doesn't support the query either.
case drivers.IsMaxPriorityFeePerGasNotFoundError(err):
log.Warn(d.cfg.Name + " eth_maxPriorityFeePerGas is unsupported " +
"by current backend, using fallback gasTipCap")
opts.GasTipCap = drivers.FallbackGasTipCap
return d.rawCtcContract.RawTransact(opts, tx.Data())
default:
return nil, err
}
} }
// SendTransaction injects a signed transaction into the pending pool for // SendTransaction injects a signed transaction into the pending pool for
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment