Skip to content

Commit

Permalink
optimize dynamic gas price calculation (#68)
Browse files Browse the repository at this point in the history
  • Loading branch information
LeoGuo621 authored Jul 16, 2024
1 parent 9fe0b4b commit 429c38b
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 47 deletions.
7 changes: 6 additions & 1 deletion cmd/rpcdaemon/commands/eth_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
lru "github.com/hashicorp/golang-lru/v2"
"github.com/holiman/uint256"
"github.com/ledgerwatch/erigon/eth/gasprice"
"github.com/ledgerwatch/erigon/zk/sequencer"
"github.com/ledgerwatch/log/v3"

"github.com/gateway-fm/cdk-erigon-lib/common"
Expand Down Expand Up @@ -384,7 +385,11 @@ func NewEthAPI(base *BaseAPI, db kv.RoDB, eth rpchelper.ApiBackend, txPool txpoo
}

// For X Layer
apii.runL2GasPricerForXLayer()
// Only Sequencer requires to calculate dynamic gas price periodically
// eth_gasPrice requests for the RPC nodes are all redirected to the Sequencer node (via zkevm.l2-sequencer-rpc-url)
if sequencer.IsSequencer() {
apii.runL2GasPricerForXLayer()
}

return apii
}
Expand Down
89 changes: 44 additions & 45 deletions cmd/rpcdaemon/commands/eth_system_xlayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,13 @@ import (
"github.com/ledgerwatch/erigon/eth/ethconfig"
"github.com/ledgerwatch/erigon/eth/gasprice"
"github.com/ledgerwatch/erigon/rpc"
"github.com/ledgerwatch/erigon/zk/sequencer"
"github.com/ledgerwatch/erigon/zkevm/jsonrpc/client"
"github.com/ledgerwatch/log/v3"
)

func (api *APIImpl) gasPriceXL(ctx context.Context) (*hexutil.Big, error) {
tx, err := api.db.BeginRo(ctx)
if err != nil {
return nil, err
}
defer tx.Rollback()
cc, err := api.chainConfig(tx)
if err != nil {
return nil, err
}
chainId := cc.ChainID
if !api.isZkNonSequencer(chainId) {
if sequencer.IsSequencer() {
return api.gasPriceNonRedirectedXL(ctx)
}

Expand All @@ -44,40 +35,8 @@ func (api *APIImpl) gasPriceXL(ctx context.Context) (*hexutil.Big, error) {
}

func (api *APIImpl) gasPriceNonRedirectedXL(ctx context.Context) (*hexutil.Big, error) {
tx, err := api.db.BeginRo(ctx)
if err != nil {
return nil, err
}
defer tx.Rollback()
cc, err := api.chainConfig(tx)
if err != nil {
return nil, err
}
oracle := gasprice.NewOracle(NewGasPriceOracleBackend(tx, cc, api.BaseAPI), ethconfig.Defaults.GPO, api.gasCache)
tipcap, err := oracle.SuggestTipCap(ctx)
gasResult := big.NewInt(0)
gasResult.Set(tipcap)
if err != nil {
return nil, err
}
if head := rawdb.ReadCurrentHeader(tx); head != nil && head.BaseFee != nil {
gasResult.Add(tipcap, head.BaseFee)
}

rgp := api.L2GasPricer.GetLastRawGP()
if gasResult.Cmp(rgp) < 0 {
gasResult = new(big.Int).Set(rgp)
}

if !api.isCongested(ctx) {
gasResult = getAvgPrice(rgp, gasResult)
}

// For X Layer
lasthash, _ := api.gasCache.GetLatest()
api.gasCache.SetLatest(lasthash, gasResult)

return (*hexutil.Big)(gasResult), err
_, gasResult := api.gasCache.GetLatest()
return (*hexutil.Big)(gasResult), nil
}

func (api *APIImpl) isCongested(ctx context.Context) bool {
Expand Down Expand Up @@ -158,11 +117,51 @@ func (api *APIImpl) runL2GasPriceSuggester() {
if err == nil {
api.L2GasPricer.UpdateGasPriceAvg(l1gp)
}
api.updateDynamicGP(ctx)
updateTimer.Reset(cfg.XLayer.UpdatePeriod)
}
}
}

func (api *APIImpl) updateDynamicGP(ctx context.Context) {
tx, err := api.db.BeginRo(ctx)
if err != nil {
log.Error(fmt.Sprintf("error db.BeginRo: %v", err))
return
}
defer tx.Rollback()
cc, err := api.chainConfig(tx)
if err != nil {
log.Error(fmt.Sprintf("error chainConfig: %v", err))
return
}
oracle := gasprice.NewOracle(NewGasPriceOracleBackend(tx, cc, api.BaseAPI), ethconfig.Defaults.GPO, api.gasCache)
tipcap, err := oracle.SuggestTipCap(ctx)
if err != nil {
log.Error(fmt.Sprintf("error SuggestTipCap: %v", err))
return
}
gasResult := big.NewInt(0)
gasResult.Set(tipcap)
if head := rawdb.ReadCurrentHeader(tx); head != nil && head.BaseFee != nil {
gasResult.Add(tipcap, head.BaseFee)
}

rgp := api.L2GasPricer.GetLastRawGP()
if gasResult.Cmp(rgp) < 0 {
gasResult = new(big.Int).Set(rgp)
}

if !api.isCongested(ctx) {
gasResult = getAvgPrice(rgp, gasResult)
}

lasthash, _ := api.gasCache.GetLatest()
api.gasCache.SetLatest(lasthash, gasResult)

log.Info(fmt.Sprintf("Updated dynamic gas price: %s", gasResult.String()))
}

func getAvgPrice(low *big.Int, high *big.Int) *big.Int {
avg := new(big.Int).Add(low, high)
avg = avg.Quo(avg, big.NewInt(2)) //nolint:gomnd
Expand Down
12 changes: 11 additions & 1 deletion eth/gasprice/gaspricecfg/config_xlayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,17 @@ type XLayerConfig struct {

var (
DefaultXLayerConfig = XLayerConfig{
Type: DefaultType,
Type: DefaultType,
UpdatePeriod: 10 * time.Second,
Factor: 0.01,
KafkaURL: "0.0.0.0",
Topic: "xlayer",
GroupID: "xlayer",
DefaultL1CoinPrice: 2000,
DefaultL2CoinPrice: 50,
GasPriceUsdt: 0.000000476190476,
EnableFollowerAdjustByL2L1Price: true,
CongestionThreshold: 0,
}
DefaultXLayerPrice = big.NewInt(1 * params.GWei)
)
Expand Down

0 comments on commit 429c38b

Please sign in to comment.