Skip to content

Commit

Permalink
fix: Metamask keeps failing sending transactions (evmos#968)
Browse files Browse the repository at this point in the history
* Problem: Metamask keeps failing sending transactions

Closes: evmos#967
Solution:
- add 1/8 buffer on top of base fee for default gas price

* changelog

* fix typo

Co-authored-by: Freddy Caceres <freddy.caceres@crypto.com>
Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
  • Loading branch information
3 people committed Mar 7, 2022
1 parent 2aa231f commit cc1805a
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 16 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (feemarket) [tharsis#919](https://github.com/tharsis/ethermint/pull/919) Initialize baseFee in default genesis state.
* (evm) [tharsis#932](https://github.com/tharsis/ethermint/pull/932) Fix base fee check logic in state transition.
* (log) [#948](https://github.com/tharsis/ethermint/pull/948) redirect go-ethereum's logs to cosmos-sdk logger.
* (rpc) [#968](https://github.com/tharsis/ethermint/pull/968) Add some buffer to returned gas price to provide better default UX for client.

### Bug Fixes

Expand Down
33 changes: 29 additions & 4 deletions rpc/ethereum/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ type Backend interface {
RPCTxFeeCap() float64 // RPCTxFeeCap is the global transaction fee(price * gaslimit) cap for send-transaction variants. The unit is ether.

RPCMinGasPrice() int64
SuggestGasTipCap() (*big.Int, error)
SuggestGasTipCap(baseFee *big.Int) (*big.Int, error)

// Blockchain API
BlockNumber() (hexutil.Uint64, error)
Expand Down Expand Up @@ -954,9 +954,34 @@ func (e *EVMBackend) ChainConfig() *params.ChainConfig {
}

// SuggestGasTipCap returns the suggested tip cap
// always return zero since we don't support tx prioritization yet.
func (e *EVMBackend) SuggestGasTipCap() (*big.Int, error) {
return big.NewInt(0), nil
// Although we don't support tx prioritization yet, but we return a positive value to help client to
// mitigate the base fee changes.
func (e *EVMBackend) SuggestGasTipCap(baseFee *big.Int) (*big.Int, error) {
if baseFee == nil {
// london hardfork not enabled or feemarket not enabeld
return big.NewInt(0), nil
}

params, err := e.queryClient.FeeMarket.Params(e.ctx, &feemarkettypes.QueryParamsRequest{})
if err != nil {
return nil, err
}
// calculate the maximum base fee delta in current block, assuming all block gas limit is consumed
// ```
// GasTarget = GasLimit / ElasticityMultiplier
// Delta = BaseFee * (GasUsed - GasTarget) / GasTarget / Denominator
// ```
// The delta is at maximum when `GasUsed` is equal to `GasLimit`, which is:
// ```
// MaxDelta = BaseFee * (GasLimit - GasLimit / ElasticityMultiplier) / (GasLimit / ElasticityMultiplier) / Denominator
// = BaseFee * (ElasticityMultiplier - 1) / Denominator
// ```
maxDelta := baseFee.Int64() * (int64(params.Params.ElasticityMultiplier) - 1) / int64(params.Params.BaseFeeChangeDenominator)
if maxDelta < 0 {
// impossible if the parameter validation passed.
maxDelta = 0
}
return big.NewInt(maxDelta), nil
}

// BaseFee returns the base fee tracked by the Fee Market module. If the base fee is not enabled,
Expand Down
12 changes: 4 additions & 8 deletions rpc/ethereum/backend/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,16 @@ func (e *EVMBackend) SetTxDefaults(args evmtypes.TransactionArgs) (evmtypes.Tran
return args, errors.New("latest header is nil")
}

cfg := e.ChainConfig()

// If user specifies both maxPriorityfee and maxFee, then we do not
// need to consult the chain for defaults. It's definitely a London tx.
if args.MaxPriorityFeePerGas == nil || args.MaxFeePerGas == nil {
// In this clause, user left some fields unspecified.
if cfg.IsLondon(head.Number) && args.GasPrice == nil {
if head.BaseFee != nil && args.GasPrice == nil {
if args.MaxPriorityFeePerGas == nil {
tip, err := e.SuggestGasTipCap()
tip, err := e.SuggestGasTipCap(head.BaseFee)
if err != nil {
return args, err
}

args.MaxPriorityFeePerGas = (*hexutil.Big)(tip)
}

Expand All @@ -65,12 +62,11 @@ func (e *EVMBackend) SetTxDefaults(args evmtypes.TransactionArgs) (evmtypes.Tran
}

if args.GasPrice == nil {
price, err := e.SuggestGasTipCap()
price, err := e.SuggestGasTipCap(head.BaseFee)
if err != nil {
return args, err
}

if cfg.IsLondon(head.Number) {
if head.BaseFee != nil {
// The legacy tx gas price suggestion should not add 2x base fee
// because all fees are consumed, so it would result in a spiral
// upwards.
Expand Down
7 changes: 3 additions & 4 deletions rpc/ethereum/namespaces/eth/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,11 +198,10 @@ func (e *PublicAPI) GasPrice() (*hexutil.Big, error) {
err error
)
if head := e.backend.CurrentHeader(); head.BaseFee != nil {
result, err = e.backend.SuggestGasTipCap()
result, err = e.backend.SuggestGasTipCap(head.BaseFee)
if err != nil {
return nil, err
}

result = result.Add(result, head.BaseFee)
} else {
result = big.NewInt(e.backend.RPCMinGasPrice())
Expand All @@ -214,11 +213,11 @@ func (e *PublicAPI) GasPrice() (*hexutil.Big, error) {
// MaxPriorityFeePerGas returns a suggestion for a gas tip cap for dynamic fee transactions.
func (e *PublicAPI) MaxPriorityFeePerGas() (*hexutil.Big, error) {
e.logger.Debug("eth_maxPriorityFeePerGas")
tipcap, err := e.backend.SuggestGasTipCap()
head := e.backend.CurrentHeader()
tipcap, err := e.backend.SuggestGasTipCap(head.BaseFee)
if err != nil {
return nil, err
}

return (*hexutil.Big)(tipcap), nil
}

Expand Down

0 comments on commit cc1805a

Please sign in to comment.