github.com/ChainSafe/chainbridge-core@v1.4.2/chains/evm/calls/evmgaspricer/london.go (about)

     1  package evmgaspricer
     2  
     3  import (
     4  	"context"
     5  	"math/big"
     6  )
     7  
     8  type LondonGasPriceDeterminant struct {
     9  	client LondonGasClient
    10  	opts   *GasPricerOpts
    11  }
    12  
    13  func NewLondonGasPriceClient(client LondonGasClient, opts *GasPricerOpts) *LondonGasPriceDeterminant {
    14  	return &LondonGasPriceDeterminant{client: client, opts: opts}
    15  }
    16  
    17  func (gasPricer *LondonGasPriceDeterminant) GasPrice(priority *uint8) ([]*big.Int, error) {
    18  	baseFee, err := gasPricer.client.BaseFee()
    19  	if err != nil {
    20  		return nil, err
    21  	}
    22  	gasPrices := make([]*big.Int, 2)
    23  	// BaseFee could be nil if eip1559 is not implemented or did not started working on the current chain
    24  	if baseFee == nil {
    25  		// we are using staticGasPriceDeterminant because it counts configs in its gasPrice calculations
    26  		// and seem to be the most favorable option
    27  		staticGasPricer := NewStaticGasPriceDeterminant(gasPricer.client, gasPricer.opts)
    28  		return staticGasPricer.GasPrice(nil)
    29  	}
    30  	gasTipCap, gasFeeCap, err := gasPricer.estimateGasLondon(baseFee)
    31  	if err != nil {
    32  		return nil, err
    33  	}
    34  	gasPrices[0] = gasTipCap
    35  	gasPrices[1] = gasFeeCap
    36  	return gasPrices, nil
    37  }
    38  
    39  func (gasPricer *LondonGasPriceDeterminant) SetClient(client LondonGasClient) {
    40  	gasPricer.client = client
    41  }
    42  func (gasPricer *LondonGasPriceDeterminant) SetOpts(opts *GasPricerOpts) {
    43  	gasPricer.opts = opts
    44  }
    45  
    46  const TwoAndTheHalfGwei = 2500000000 // Lowest MaxPriorityFee. Defined by some researches...
    47  
    48  func (gasPricer *LondonGasPriceDeterminant) estimateGasLondon(baseFee *big.Int) (*big.Int, *big.Int, error) {
    49  	var maxPriorityFeePerGas *big.Int
    50  	var maxFeePerGas *big.Int
    51  
    52  	// if gasPriceLimit is set and lower than networks baseFee then
    53  	// maxPriorityFee is set to 3 GWEI because that was practically and theoretically defined as optimum
    54  	// and Max Fee set to baseFee + maxPriorityFeePerGas
    55  	if gasPricer.opts != nil && gasPricer.opts.UpperLimitFeePerGas != nil && gasPricer.opts.UpperLimitFeePerGas.Cmp(baseFee) < 0 {
    56  		maxPriorityFeePerGas = big.NewInt(TwoAndTheHalfGwei)
    57  		maxFeePerGas = new(big.Int).Add(baseFee, maxPriorityFeePerGas)
    58  		return maxPriorityFeePerGas, maxFeePerGas, nil
    59  	}
    60  
    61  	maxPriorityFeePerGas, err := gasPricer.client.SuggestGasTipCap(context.TODO())
    62  	if err != nil {
    63  		return nil, nil, err
    64  	}
    65  	maxFeePerGas = new(big.Int).Add(
    66  		maxPriorityFeePerGas,
    67  		new(big.Int).Mul(baseFee, big.NewInt(2)),
    68  	)
    69  
    70  	// Check we aren't exceeding our limit if gasPriceLimit set
    71  	if gasPricer.opts != nil && gasPricer.opts.UpperLimitFeePerGas != nil && maxFeePerGas.Cmp(gasPricer.opts.UpperLimitFeePerGas) == 1 {
    72  		maxPriorityFeePerGas.Sub(gasPricer.opts.UpperLimitFeePerGas, baseFee)
    73  		maxFeePerGas = gasPricer.opts.UpperLimitFeePerGas
    74  	}
    75  	return maxPriorityFeePerGas, maxFeePerGas, nil
    76  }