From b049d89f9092906162f2940d4f1c7a099c4f11be Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Fri, 14 Jun 2024 18:29:16 +0800 Subject: [PATCH 01/21] support follower --- cmd/rpcdaemon/commands/eth_api.go | 11 +- cmd/rpcdaemon/commands/eth_system.go | 24 ++- eth/gasprice/follower_xlayer.go | 118 +++++++++++ eth/gasprice/gaspricecfg/gaspricecfg.go | 35 +++ eth/gasprice/gaspricesuggester.go | 66 ++++++ eth/gasprice/kafka_proc_xlayer.go | 270 ++++++++++++++++++++++++ go.mod | 2 + go.sum | 24 +++ 8 files changed, 546 insertions(+), 4 deletions(-) create mode 100644 eth/gasprice/follower_xlayer.go create mode 100644 eth/gasprice/gaspricesuggester.go create mode 100644 eth/gasprice/kafka_proc_xlayer.go diff --git a/cmd/rpcdaemon/commands/eth_api.go b/cmd/rpcdaemon/commands/eth_api.go index 8aaa21fd992..a59538b25f8 100644 --- a/cmd/rpcdaemon/commands/eth_api.go +++ b/cmd/rpcdaemon/commands/eth_api.go @@ -11,6 +11,7 @@ import ( lru "github.com/hashicorp/golang-lru/v2" "github.com/holiman/uint256" + "github.com/ledgerwatch/erigon/eth/gasprice" "github.com/ledgerwatch/log/v3" "github.com/gateway-fm/cdk-erigon-lib/common" @@ -347,6 +348,7 @@ type APIImpl struct { MaxGasPrice uint64 GasPriceFactor float64 L1GasPrice L1GasPrice + L2GasPircer gasprice.L2GasPricer } // NewEthAPI returns APIImpl instance @@ -355,7 +357,7 @@ func NewEthAPI(base *BaseAPI, db kv.RoDB, eth rpchelper.ApiBackend, txPool txpoo gascap = uint64(math.MaxUint64 / 2) } - return &APIImpl{ + apii := &APIImpl{ BaseAPI: base, db: db, ethBackend: eth, @@ -373,7 +375,14 @@ func NewEthAPI(base *BaseAPI, db kv.RoDB, eth rpchelper.ApiBackend, txPool txpoo MaxGasPrice: ethCfg.MaxGasPrice, GasPriceFactor: ethCfg.GasPriceFactor, L1GasPrice: L1GasPrice{}, + //todo: confirm config + L2GasPircer: gasprice.NewL2GasPriceSuggester(context.Background(), ethconfig.Defaults.GPO), } + + apii.L2GasPircer.UpdateGasPriceAvg(apii.L1RpcUrl) + go apii.runL2GasPriceSuggester() + + return apii } // RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction diff --git a/cmd/rpcdaemon/commands/eth_system.go b/cmd/rpcdaemon/commands/eth_system.go index b389123bb95..be3ebef03ec 100644 --- a/cmd/rpcdaemon/commands/eth_system.go +++ b/cmd/rpcdaemon/commands/eth_system.go @@ -3,21 +3,21 @@ package commands import ( "context" "math/big" + "time" libcommon "github.com/gateway-fm/cdk-erigon-lib/common" "github.com/gateway-fm/cdk-erigon-lib/kv" "github.com/ledgerwatch/erigon/chain" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/eth/ethconfig" "github.com/ledgerwatch/erigon/eth/gasprice" - "github.com/ledgerwatch/erigon/rpc" - "github.com/ledgerwatch/erigon/eth/stagedsync/stages" + "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/rpchelper" stageszk "github.com/ledgerwatch/erigon/zk/stages" + "github.com/ledgerwatch/log/v3" ) // BlockNumber implements eth_blockNumber. Returns the block number of most recent block. @@ -152,6 +152,24 @@ func (api *APIImpl) MaxPriorityFeePerGas(ctx context.Context) (*hexutil.Big, err return (*hexutil.Big)(tipcap), err } +func (api *APIImpl) runL2GasPriceSuggester() { + cfg := api.L2GasPircer.GetConfig() + ctx := api.L2GasPircer.GetCtx() + + //todo: apollo + updateTimer := time.NewTimer(cfg.UpdatePeriod) + for { + select { + case <-ctx.Done(): + log.Info("Finishing l2 gas price suggester...") + return + case <-updateTimer.C: + api.L2GasPircer.UpdateGasPriceAvg(api.L1RpcUrl) + updateTimer.Reset(cfg.UpdatePeriod) + } + } +} + type feeHistoryResult struct { OldestBlock *hexutil.Big `json:"oldestBlock"` Reward [][]*hexutil.Big `json:"reward,omitempty"` diff --git a/eth/gasprice/follower_xlayer.go b/eth/gasprice/follower_xlayer.go new file mode 100644 index 00000000000..4d7dfb8fd65 --- /dev/null +++ b/eth/gasprice/follower_xlayer.go @@ -0,0 +1,118 @@ +package gasprice + +import ( + "context" + "fmt" + "math/big" + "strconv" + + "github.com/ledgerwatch/erigon/eth/gasprice/gaspricecfg" + "github.com/ledgerwatch/log/v3" +) + +const ( + // OKBWei OKB wei + OKBWei = 1e18 + minCoinPrice = 1e-18 +) + +// FollowerGasPrice struct. +type FollowerGasPrice struct { + cfg gaspricecfg.Config + ctx context.Context + lastRawGP *big.Int + kafkaPrc *KafkaProcessor +} + +// newFollowerGasPriceSuggester inits l2 follower gas price suggester which is based on the l1 gas price. +func newFollowerGasPriceSuggester(ctx context.Context, cfg gaspricecfg.Config) *FollowerGasPrice { + gps := &FollowerGasPrice{ + cfg: cfg, + ctx: ctx, + lastRawGP: new(big.Int).SetUint64(1), + } + if cfg.EnableFollowerAdjustByL2L1Price { + gps.kafkaPrc = newKafkaProcessor(cfg, ctx) + } + + return gps +} + +// UpdateGasPriceAvg updates the gas price. +func (f *FollowerGasPrice) UpdateGasPriceAvg(l1RpcUrl string) { + //todo: apollo + + // Get L1 gasprice + l1GasPrice, err := GetL1GasPrice(l1RpcUrl) + if err != nil { + log.Error("cannot get l1 gas price. Skipping update...") + return + } + + if big.NewInt(0).Cmp(l1GasPrice) == 0 { + log.Warn("gas price 0 received. Skipping update...") + return + } + + // Apply factor to calculate l2 gasPrice + factor := big.NewFloat(0).SetFloat64(f.cfg.Factor) + res := new(big.Float).Mul(factor, big.NewFloat(0).SetInt(l1GasPrice)) + + // convert the eth gas price to okb gas price + if f.cfg.EnableFollowerAdjustByL2L1Price { + l1CoinPrice, l2CoinPrice := f.kafkaPrc.GetL1L2CoinPrice() + if l1CoinPrice < minCoinPrice || l2CoinPrice < minCoinPrice { + log.Warn("the L1 or L2 native coin price too small...") + return + } + res = new(big.Float).Mul(big.NewFloat(0).SetFloat64(l1CoinPrice/l2CoinPrice), res) + log.Debug("L2 pre gas price value: ", res.String(), ". L1 coin price: ", l1CoinPrice, ". L2 coin price: ", l2CoinPrice) + } + + // Cache l2 gasPrice calculated + result := new(big.Int) + res.Int(result) + minGasPrice := new(big.Int).Set(f.cfg.Default) + if minGasPrice.Cmp(result) == 1 { // minGasPrice > result + log.Warn("setting DefaultGasPrice for L2") + result = minGasPrice + } + maxGasPrice := new(big.Int).Set(f.cfg.MaxPrice) + if maxGasPrice.Int64() > 0 && result.Cmp(maxGasPrice) == 1 { // result > maxGasPrice + log.Warn("setting MaxGasPriceWei for L2") + result = maxGasPrice + } + var truncateValue *big.Int + log.Debug("Full L2 gas price value: ", result, ". Length: ", len(result.String())) + numLength := len(result.String()) + if numLength > 3 { //nolint:gomnd + aux := "%0" + strconv.Itoa(numLength-3) + "d" //nolint:gomnd + var ok bool + value := result.String()[:3] + fmt.Sprintf(aux, 0) + truncateValue, ok = new(big.Int).SetString(value, 10) + if !ok { + log.Error("error converting: ", truncateValue) + } + } else { + truncateValue = result + } + + if truncateValue != nil { + log.Info("Set l2 raw gas price: ", truncateValue.Uint64()) + f.lastRawGP = truncateValue + } else { + log.Error("nil value detected. Skipping...") + } +} + +func (f *FollowerGasPrice) GetLastRawGP() *big.Int { + return f.lastRawGP +} + +func (f *FollowerGasPrice) GetConfig() gaspricecfg.Config { + return f.cfg +} + +func (f *FollowerGasPrice) GetCtx() context.Context { + return f.ctx +} diff --git a/eth/gasprice/gaspricecfg/gaspricecfg.go b/eth/gasprice/gaspricecfg/gaspricecfg.go index af364b0a220..c8fde5c988c 100644 --- a/eth/gasprice/gaspricecfg/gaspricecfg.go +++ b/eth/gasprice/gaspricecfg/gaspricecfg.go @@ -2,6 +2,7 @@ package gaspricecfg import ( "math/big" + "time" "github.com/ledgerwatch/erigon/params" ) @@ -20,4 +21,38 @@ type Config struct { Default *big.Int `toml:",omitempty"` MaxPrice *big.Int `toml:",omitempty"` IgnorePrice *big.Int `toml:",omitempty"` + + // XLayer config + Type EstimatorType `toml:",omitempty"` + UpdatePeriod time.Duration `toml:",omitempty"` + Factor float64 `toml:",omitempty"` + KafkaURL string `toml:",omitempty"` + Topic string `toml:",omitempty"` + GroupID string `toml:",omitempty"` + Username string `toml:",omitempty"` + Password string `toml:",omitempty"` + RootCAPath string `toml:",omitempty"` + L1CoinId int `toml:",omitempty"` + L2CoinId int `toml:",omitempty"` + // DefaultL1CoinPrice is the L1 token's coin price + DefaultL1CoinPrice float64 `toml:",omitempty"` + // DefaultL2CoinPrice is the native token's coin price + DefaultL2CoinPrice float64 `toml:",omitempty"` + GasPriceUsdt float64 `toml:",omitempty"` + + // EnableFollowerAdjustByL2L1Price is dynamic adjust the factor through the L1 and L2 coins price in follower strategy + EnableFollowerAdjustByL2L1Price bool `toml:",omitempty"` } + +type EstimatorType string + +const ( + // DefaultType default gas price from config is set. + DefaultType EstimatorType = "default" + + // FollowerType calculate the gas price basing on the L1 gasPrice. + FollowerType EstimatorType = "follower" + + // FixedType the gas price from config that the unit is usdt, XLayer config + FixedType EstimatorType = "fixed" +) diff --git a/eth/gasprice/gaspricesuggester.go b/eth/gasprice/gaspricesuggester.go new file mode 100644 index 00000000000..2947cab5084 --- /dev/null +++ b/eth/gasprice/gaspricesuggester.go @@ -0,0 +1,66 @@ +package gasprice + +import ( + "context" + "encoding/json" + "fmt" + "math/big" + + "github.com/ledgerwatch/erigon/eth/gasprice/gaspricecfg" + "github.com/ledgerwatch/erigon/zkevm/jsonrpc/client" + "github.com/ledgerwatch/log/v3" +) + +// L2GasPricer interface for gas price suggester. +type L2GasPricer interface { + UpdateGasPriceAvg(string) + GetLastRawGP() *big.Int + GetConfig() gaspricecfg.Config + GetCtx() context.Context +} + +// NewL2GasPriceSuggester init. +func NewL2GasPriceSuggester(ctx context.Context, cfg gaspricecfg.Config) L2GasPricer { + var gpricer L2GasPricer + switch cfg.Type { + case gaspricecfg.FollowerType: + log.Info("Follower type selected") + gpricer = newFollowerGasPriceSuggester(ctx, cfg) + //case DefaultType: + // log.Info("Default type selected") + // gpricer = newDefaultGasPriceSuggester(ctx, cfg, pool) + //case FixedType: + // log.Info("Fixed type selected") + // gpricer = newFixedGasPriceSuggester(ctx, cfg, pool, ethMan) + default: + log.Error("unknown l2 gas price suggester type ", cfg.Type, ". Please specify a valid one: 'follower' or 'default'") + } + + return gpricer +} + +func GetL1GasPrice(l1RpcUrl string) (*big.Int, error) { + res, err := client.JSONRPCCall(l1RpcUrl, "eth_gasPrice") + if err != nil { + return nil, err + } + + if res.Error != nil { + return nil, fmt.Errorf("RPC error response: %s", res.Error.Message) + } + if res.Error != nil { + return nil, fmt.Errorf("RPC error response: %s", res.Error.Message) + } + + var resultString string + if err := json.Unmarshal(res.Result, &resultString); err != nil { + return nil, fmt.Errorf("failed to unmarshal result: %v", err) + } + + price, ok := big.NewInt(0).SetString(resultString[2:], 16) + if !ok { + return nil, fmt.Errorf("failed to convert result to big.Int") + } + + return price, nil +} diff --git a/eth/gasprice/kafka_proc_xlayer.go b/eth/gasprice/kafka_proc_xlayer.go new file mode 100644 index 00000000000..dacfbb86d03 --- /dev/null +++ b/eth/gasprice/kafka_proc_xlayer.go @@ -0,0 +1,270 @@ +package gasprice + +import ( + "context" + "crypto/tls" + "crypto/x509" + "encoding/json" + "errors" + "fmt" + "os" + "strings" + "sync" + "time" + + "github.com/ledgerwatch/erigon/eth/gasprice/gaspricecfg" + "github.com/ledgerwatch/log/v3" + kafka "github.com/segmentio/kafka-go" + "github.com/segmentio/kafka-go/sasl/plain" +) + +const ( + okbcoinId = 7184 + ethcoinId = 15756 + defaultTime = 10 + defaultMaxData = 10e6 // 10M +) + +var ( + // ErrNotFindCoinPrice not find a correct coin price + ErrNotFindCoinPrice = errors.New("not find a correct coin price") +) + +// MsgInfo msg info +type MsgInfo struct { + Topic string `json:"topic"` + Data *Body `json:"data"` +} + +// Body msg body +type Body struct { + Id string `json:"id"` + PriceList []*Price `json:"priceList"` +} + +// Price coin price +type Price struct { + CoinId int `json:"coinId"` + Symbol string `json:"symbol"` + FullName string `json:"fullName"` + Price float64 `json:"price"` + PriceStatus int `json:"priceStatus"` + MaxPrice24H float64 `json:"maxPrice24H"` + MinPrice24H float64 `json:"minPrice24H"` + MarketCap float64 `json:"marketCap"` + Timestamp int64 `json:"timestamp"` + Vol24H float64 `json:"vol24h"` + CirculatingSupply float64 `json:"circulatingSupply"` + MaxSupply float64 `json:"maxSupply"` + TotalSupply float64 `json:"totalSupply"` + PriceChange24H float64 `json:"priceChange24H"` + PriceChangeRate24H float64 `json:"priceChangeRate24H"` + CirculatingMarketCap float64 `json:"circulatingMarketCap"` + PriceChange7D float64 `json:"priceChange7D"` + PriceChangeRate7D float64 `json:"priceChangeRate7D"` + PriceChange30D float64 `json:"priceChange30D"` + PriceChangeRate30D float64 `json:"priceChangeRate30D"` + PriceChangeYearStart float64 `json:"priceChangeYearStart"` + PriceChangeRateYearStart float64 `json:"priceChangeRateYearStart"` + ExceptionStatus int `json:"exceptionStatus"` + Source int `json:"source"` + Type string `json:"type"` + Id string `json:"id"` +} + +// L1L2PriceRecord l1 l2 coin price record +type L1L2PriceRecord struct { + l1Price float64 + l2Price float64 + l1Update bool + l2Update bool +} + +// KafkaProcessor kafka processor +type KafkaProcessor struct { + cfg gaspricecfg.Config + kreader *kafka.Reader + ctx context.Context + rwLock sync.RWMutex + l1CoinId int + l2CoinId int + l1Price float64 + l2Price float64 + tmpPrices L1L2PriceRecord +} + +func newKafkaProcessor(cfg gaspricecfg.Config, ctx context.Context) *KafkaProcessor { + rp := &KafkaProcessor{ + cfg: cfg, + kreader: getKafkaReader(cfg), + l1Price: cfg.DefaultL1CoinPrice, + l2Price: cfg.DefaultL2CoinPrice, + ctx: ctx, + l2CoinId: okbcoinId, + l1CoinId: ethcoinId, + } + if cfg.L2CoinId != 0 { + rp.l2CoinId = cfg.L2CoinId + } + if cfg.L1CoinId != 0 { + rp.l1CoinId = cfg.L1CoinId + } + + go rp.processor() + return rp +} + +func getKafkaReader(cfg gaspricecfg.Config) *kafka.Reader { + brokers := strings.Split(cfg.KafkaURL, ",") + + var dialer *kafka.Dialer + if cfg.Password != "" && cfg.Username != "" && cfg.RootCAPath != "" { + rootCA, err := os.ReadFile(cfg.RootCAPath) + if err != nil { + panic("kafka read root ca fail") + } + caCertPool := x509.NewCertPool() + if ok := caCertPool.AppendCertsFromPEM(rootCA); !ok { + panic("caCertPool.AppendCertsFromPEM") + } + dialer = &kafka.Dialer{ + Timeout: defaultTime * time.Second, + DualStack: true, + SASLMechanism: plain.Mechanism{Username: cfg.Username, Password: cfg.Password}, + } + { // #nosec G402 + dialer.TLS = &tls.Config{RootCAs: caCertPool, InsecureSkipVerify: true} + } + } + + return kafka.NewReader(kafka.ReaderConfig{ + Brokers: brokers, + GroupID: cfg.GroupID, + Topic: cfg.Topic, + MinBytes: 1, // 1 + MaxBytes: defaultMaxData, + Dialer: dialer, + StartOffset: kafka.LastOffset, // read data from new message + }) +} + +func (rp *KafkaProcessor) processor() { + //todo:log + //log.Info("kafka processor start processor ") + defer rp.kreader.Close() + for { + select { + case <-rp.ctx.Done(): + return + default: + err := rp.ReadAndUpdate(rp.ctx) + if err != nil && err != ErrNotFindCoinPrice { + //todo:log + //log.Warn("get the destion data fail ", err) + time.Sleep(time.Second * defaultTime) + continue + } + } + } +} + +// ReadAndUpdate read and update +func (rp *KafkaProcessor) ReadAndUpdate(ctx context.Context) error { + m, err := rp.kreader.ReadMessage(ctx) + if err != nil { + return err + } + return rp.Update(m.Value) +} + +// Update update the coin price +func (rp *KafkaProcessor) Update(data []byte) error { + if rp.cfg.Type == gaspricecfg.FixedType { + price, err := rp.parseCoinPrice(data, []int{rp.l2CoinId}) + if err == nil { + rp.updateL2CoinPrice(price[rp.l2CoinId]) + } + return err + } else if rp.cfg.Type == gaspricecfg.FollowerType { + prices, err := rp.parseCoinPrice(data, []int{rp.l1CoinId, rp.l2CoinId}) + if err == nil { + rp.updateL1L2CoinPrice(prices) + } + return err + } + return nil +} + +func (rp *KafkaProcessor) updateL2CoinPrice(price float64) { + rp.rwLock.Lock() + defer rp.rwLock.Unlock() + rp.l2Price = price +} + +// GetL2CoinPrice get L2 coin price +func (rp *KafkaProcessor) GetL2CoinPrice() float64 { + rp.rwLock.RLock() + defer rp.rwLock.RUnlock() + return rp.l2Price +} + +func (rp *KafkaProcessor) updateL1L2CoinPrice(prices map[int]float64) { + if len(prices) == 0 { + return + } + rp.rwLock.Lock() + defer rp.rwLock.Unlock() + if v, ok := prices[rp.l1CoinId]; ok { + rp.tmpPrices.l1Price = v + rp.tmpPrices.l1Update = true + } + if v, ok := prices[rp.l2CoinId]; ok { + rp.tmpPrices.l2Price = v + rp.tmpPrices.l2Update = true + } + if rp.tmpPrices.l1Update && rp.tmpPrices.l2Update { + rp.l1Price = rp.tmpPrices.l1Price + rp.l2Price = rp.tmpPrices.l2Price + rp.tmpPrices.l1Update = false + rp.tmpPrices.l2Update = false + return + } +} + +// GetL1L2CoinPrice get l1, L2 coin price +func (rp *KafkaProcessor) GetL1L2CoinPrice() (float64, float64) { + rp.rwLock.RLock() + defer rp.rwLock.RUnlock() + return rp.l1Price, rp.l2Price +} + +func (rp *KafkaProcessor) parseCoinPrice(value []byte, coinIds []int) (map[int]float64, error) { + if len(coinIds) == 0 { + return nil, fmt.Errorf("the params coinIds is empty") + } + msgI := &MsgInfo{} + err := json.Unmarshal(value, &msgI) + if err != nil { + return nil, err + } + if msgI.Data == nil || len(msgI.Data.PriceList) == 0 { + return nil, fmt.Errorf("the data PriceList is empty") + } + mp := make(map[int]*Price) + for _, price := range msgI.Data.PriceList { + mp[price.CoinId] = price + } + + results := make(map[int]float64) + for _, coinId := range coinIds { + if coin, ok := mp[coinId]; ok { + results[coinId] = coin.Price + } else { + log.Debug("not find a correct coin price coin id is =", coinId) + } + } + if len(results) == 0 { + return results, ErrNotFindCoinPrice + } + return results, nil +} diff --git a/go.mod b/go.mod index 6fcd361c1b2..8475c21f304 100644 --- a/go.mod +++ b/go.mod @@ -78,6 +78,7 @@ require ( github.com/prysmaticlabs/gohashtree v0.0.3-alpha github.com/quasilyte/go-ruleguard/dsl v0.3.22 github.com/rs/cors v1.8.3 + github.com/segmentio/kafka-go v0.4.47 github.com/shirou/gopsutil/v3 v3.23.2 github.com/spf13/cobra v1.6.1 github.com/spf13/pflag v1.0.5 @@ -221,6 +222,7 @@ require ( github.com/multiformats/go-varint v0.0.7 // indirect github.com/onsi/ginkgo/v2 v2.8.0 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect + github.com/pierrec/lz4/v4 v4.1.15 // indirect github.com/pion/datachannel v1.5.2 // indirect github.com/pion/dtls/v2 v2.2.4 // indirect github.com/pion/ice/v2 v2.2.6 // indirect diff --git a/go.sum b/go.sum index 98ac9464704..b400bbbc773 100644 --- a/go.sum +++ b/go.sum @@ -488,6 +488,7 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= @@ -680,6 +681,8 @@ github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6 github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0= +github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pion/datachannel v1.5.2 h1:piB93s8LGmbECrpO84DnkIVWasRMk3IimbcXkTQLE6E= github.com/pion/datachannel v1.5.2/go.mod h1:FTGQWaHrdCwIJ1rw6xBIfZVkslikjShim5yr05XFuCQ= github.com/pion/dtls/v2 v2.1.3/go.mod h1:o6+WvyLDAlXF7YiPB/RlskRoeK+/JtuaZa5emwQcWus= @@ -809,6 +812,8 @@ github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 h1:GHRpF1pTW19a github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= +github.com/segmentio/kafka-go v0.4.47 h1:IqziR4pA3vrZq7YdRxaT3w1/5fvIH5qpCwstUanQQB0= +github.com/segmentio/kafka-go v0.4.47/go.mod h1:HjF6XbOKh0Pjlkr5GVZxt6CsjjwnmhVOfURM5KMd8qg= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= @@ -918,6 +923,12 @@ github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49u github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= +github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/xsleonard/go-merkle v1.1.0 h1:fHe1fuhJjGH22ZzVTAH0jqHLhTGhOq3wQjJN+8P0jQg= @@ -989,6 +1000,7 @@ golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220516162934-403b01795ae8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1007,6 +1019,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1046,6 +1059,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1062,6 +1077,7 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1122,6 +1138,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -1130,6 +1148,8 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -1137,9 +1157,12 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1173,6 +1196,7 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 47e7c6819acd5bc985cb5c34d569c46e20a53c4e Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Mon, 17 Jun 2024 09:49:26 +0800 Subject: [PATCH 02/21] support fixed --- eth/gasprice/fixed_xlayer.go | 96 +++++++++++++++++++++++++++++++ eth/gasprice/gaspricesuggester.go | 6 +- 2 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 eth/gasprice/fixed_xlayer.go diff --git a/eth/gasprice/fixed_xlayer.go b/eth/gasprice/fixed_xlayer.go new file mode 100644 index 00000000000..c0037fa9a40 --- /dev/null +++ b/eth/gasprice/fixed_xlayer.go @@ -0,0 +1,96 @@ +package gasprice + +import ( + "context" + "fmt" + "math/big" + "strconv" + + "github.com/ledgerwatch/erigon/eth/gasprice/gaspricecfg" + "github.com/ledgerwatch/erigon/zkevm/encoding" + "github.com/ledgerwatch/log/v3" +) + +// FixedGasPrice struct +type FixedGasPrice struct { + cfg gaspricecfg.Config + ctx context.Context + lastRawGP *big.Int + ratePrc *KafkaProcessor +} + +// newFixedGasPriceSuggester inits l2 fixed price suggester. +func newFixedGasPriceSuggester(ctx context.Context, cfg gaspricecfg.Config) *FixedGasPrice { + gps := &FixedGasPrice{ + cfg: cfg, + ctx: ctx, + ratePrc: newKafkaProcessor(cfg, ctx), + } + return gps +} + +// UpdateGasPriceAvg updates the gas price. +func (f *FixedGasPrice) UpdateGasPriceAvg(l1RpcUrl string) { + //todo:apollo + + // Get L1 gasprice + l1GasPrice, err := GetL1GasPrice(l1RpcUrl) + if err != nil { + log.Error("cannot get l1 gas price. Skipping update...") + return + } + + l2CoinPrice := f.ratePrc.GetL2CoinPrice() + if l2CoinPrice < minCoinPrice { + log.Warn("the L2 native coin price too small...") + return + } + res := new(big.Float).Mul(big.NewFloat(0).SetFloat64(f.cfg.GasPriceUsdt/l2CoinPrice), big.NewFloat(0).SetFloat64(OKBWei)) + // Store l2 gasPrice calculated + result := new(big.Int) + res.Int(result) + minGasPrice := new(big.Int).Set(f.cfg.Default) + if minGasPrice.Cmp(result) == 1 { // minGasPrice > result + log.Warn("setting DefaultGasPriceWei for L2") + result = minGasPrice + } + maxGasPrice := new(big.Int).Set(f.cfg.MaxPrice) + if maxGasPrice.Int64() > 0 && result.Cmp(maxGasPrice) == 1 { // result > maxGasPrice + log.Warn("setting MaxGasPriceWei for L2") + result = maxGasPrice + } + var truncateValue *big.Int + log.Debug("Full L2 gas price value: ", result, ". Length: ", len(result.String()), ". L1 gas price value: ", l1GasPrice) + + numLength := len(result.String()) + if numLength > 3 { //nolint:gomnd + aux := "%0" + strconv.Itoa(numLength-3) + "d" //nolint:gomnd + var ok bool + value := result.String()[:3] + fmt.Sprintf(aux, 0) + truncateValue, ok = new(big.Int).SetString(value, encoding.Base10) + if !ok { + log.Error("error converting: ", truncateValue) + } + } else { + truncateValue = result + } + log.Debug("Storing truncated L2 gas price: ", truncateValue, ", L2 native coin price: ", l2CoinPrice) + if truncateValue != nil { + log.Info("Set l2 raw gas price: ", truncateValue.Uint64()) + f.lastRawGP = truncateValue + } else { + log.Error("nil value detected. Skipping...") + } +} + +func (f *FixedGasPrice) GetLastRawGP() *big.Int { + return f.lastRawGP +} + +func (f *FixedGasPrice) GetConfig() gaspricecfg.Config { + return f.cfg +} + +func (f *FixedGasPrice) GetCtx() context.Context { + return f.ctx +} diff --git a/eth/gasprice/gaspricesuggester.go b/eth/gasprice/gaspricesuggester.go index 2947cab5084..48cb36bb881 100644 --- a/eth/gasprice/gaspricesuggester.go +++ b/eth/gasprice/gaspricesuggester.go @@ -29,9 +29,9 @@ func NewL2GasPriceSuggester(ctx context.Context, cfg gaspricecfg.Config) L2GasPr //case DefaultType: // log.Info("Default type selected") // gpricer = newDefaultGasPriceSuggester(ctx, cfg, pool) - //case FixedType: - // log.Info("Fixed type selected") - // gpricer = newFixedGasPriceSuggester(ctx, cfg, pool, ethMan) + case gaspricecfg.FixedType: + log.Info("Fixed type selected") + gpricer = newFixedGasPriceSuggester(ctx, cfg) default: log.Error("unknown l2 gas price suggester type ", cfg.Type, ". Please specify a valid one: 'follower' or 'default'") } From 2ab5bcfca215fb06785e307d387486e9942690be Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Mon, 17 Jun 2024 10:46:39 +0800 Subject: [PATCH 03/21] support default --- eth/gasprice/default_xlayer.go | 41 +++++++++++++++++++++++++++++++ eth/gasprice/fixed_xlayer.go | 3 +-- eth/gasprice/gaspricesuggester.go | 6 ++--- 3 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 eth/gasprice/default_xlayer.go diff --git a/eth/gasprice/default_xlayer.go b/eth/gasprice/default_xlayer.go new file mode 100644 index 00000000000..d65e84dd114 --- /dev/null +++ b/eth/gasprice/default_xlayer.go @@ -0,0 +1,41 @@ +package gasprice + +import ( + "context" + "math/big" + + "github.com/ledgerwatch/erigon/eth/gasprice/gaspricecfg" +) + +// DefaultGasPricer gas price from config is set. +type DefaultGasPricer struct { + cfg gaspricecfg.Config + ctx context.Context + lastRawGP *big.Int +} + +// newDefaultGasPriceSuggester init default gas price suggester. +func newDefaultGasPriceSuggester(ctx context.Context, cfg gaspricecfg.Config) *DefaultGasPricer { + gpe := &DefaultGasPricer{ + ctx: ctx, + cfg: cfg, + } + return gpe +} + +// UpdateGasPriceAvg not needed for default strategy. +func (d *DefaultGasPricer) UpdateGasPriceAvg(l1RpcUrl string) { + d.lastRawGP = d.cfg.Default +} + +func (d *DefaultGasPricer) GetLastRawGP() *big.Int { + return d.lastRawGP +} + +func (d *DefaultGasPricer) GetConfig() gaspricecfg.Config { + return d.cfg +} + +func (d *DefaultGasPricer) GetCtx() context.Context { + return d.ctx +} diff --git a/eth/gasprice/fixed_xlayer.go b/eth/gasprice/fixed_xlayer.go index c0037fa9a40..d126146f969 100644 --- a/eth/gasprice/fixed_xlayer.go +++ b/eth/gasprice/fixed_xlayer.go @@ -7,7 +7,6 @@ import ( "strconv" "github.com/ledgerwatch/erigon/eth/gasprice/gaspricecfg" - "github.com/ledgerwatch/erigon/zkevm/encoding" "github.com/ledgerwatch/log/v3" ) @@ -67,7 +66,7 @@ func (f *FixedGasPrice) UpdateGasPriceAvg(l1RpcUrl string) { aux := "%0" + strconv.Itoa(numLength-3) + "d" //nolint:gomnd var ok bool value := result.String()[:3] + fmt.Sprintf(aux, 0) - truncateValue, ok = new(big.Int).SetString(value, encoding.Base10) + truncateValue, ok = new(big.Int).SetString(value, 10) if !ok { log.Error("error converting: ", truncateValue) } diff --git a/eth/gasprice/gaspricesuggester.go b/eth/gasprice/gaspricesuggester.go index 48cb36bb881..03edf8326f9 100644 --- a/eth/gasprice/gaspricesuggester.go +++ b/eth/gasprice/gaspricesuggester.go @@ -26,9 +26,9 @@ func NewL2GasPriceSuggester(ctx context.Context, cfg gaspricecfg.Config) L2GasPr case gaspricecfg.FollowerType: log.Info("Follower type selected") gpricer = newFollowerGasPriceSuggester(ctx, cfg) - //case DefaultType: - // log.Info("Default type selected") - // gpricer = newDefaultGasPriceSuggester(ctx, cfg, pool) + case gaspricecfg.DefaultType: + log.Info("Default type selected") + gpricer = newDefaultGasPriceSuggester(ctx, cfg) case gaspricecfg.FixedType: log.Info("Fixed type selected") gpricer = newFixedGasPriceSuggester(ctx, cfg) From 7c02f9f27c8b4ae0a07052c75a69895d32175b5b Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Tue, 18 Jun 2024 09:41:23 +0800 Subject: [PATCH 04/21] Update eth_system.go --- cmd/rpcdaemon/commands/eth_system.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/cmd/rpcdaemon/commands/eth_system.go b/cmd/rpcdaemon/commands/eth_system.go index be3ebef03ec..43670e720b7 100644 --- a/cmd/rpcdaemon/commands/eth_system.go +++ b/cmd/rpcdaemon/commands/eth_system.go @@ -130,6 +130,11 @@ func (api *APIImpl) GasPrice_deprecated(ctx context.Context) (*hexutil.Big, erro gasResult.Add(tipcap, head.BaseFee) } + rgp := api.L2GasPircer.GetLastRawGP() + if gasResult.Cmp(rgp) < 0 { + gasResult = new(big.Int).Set(rgp) + } + return (*hexutil.Big)(gasResult), err } @@ -149,6 +154,20 @@ func (api *APIImpl) MaxPriorityFeePerGas(ctx context.Context) (*hexutil.Big, err if err != nil { return nil, err } + + rgp := api.L2GasPircer.GetLastRawGP() + if head := rawdb.ReadCurrentHeader(tx); head != nil && head.BaseFee != nil { + if rgp.Cmp(head.BaseFee) > 0 { + rgp.Sub(rgp, head.BaseFee) + } else { + rgp.SetUint64(0) + } + } + + if tipcap.Cmp(rgp) < 0 { + tipcap = new(big.Int).Set(rgp) + } + return (*hexutil.Big)(tipcap), err } From 6b5858e86d6c5ea5cbd9aa23f1a7012047a08b7e Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Wed, 19 Jun 2024 14:33:52 +0800 Subject: [PATCH 05/21] modify config --- cmd/utils/flags.go | 156 +++++++++++++++++++++++- eth/gasprice/gaspricecfg/gaspricecfg.go | 10 +- test/config/test.erigon.seq.config.yaml | 4 +- turbo/cli/default_flags.go | 14 +++ 4 files changed, 176 insertions(+), 8 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 9d993e9fdd7..6558f58c713 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -46,6 +46,8 @@ import ( "os" "path" + "time" + "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cmd/downloader/downloadernat" "github.com/ledgerwatch/erigon/common/paths" @@ -60,7 +62,6 @@ import ( "github.com/ledgerwatch/erigon/p2p/netutil" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/params/networkname" - "time" ) // These are all the command line flags we support. @@ -846,6 +847,96 @@ var ( Value: ethconfig.Defaults.GPO.MaxPrice.Int64(), } + GpoTypeFlag = cli.StringFlag{ + Name: "gpo.type", + Usage: "raw gas price strategy type: default, follower, fixed", + Value: "default", + } + + GpoUpdatePeriodFlag = cli.StringFlag{ + Name: "gpo.update-period", + Usage: "raw gas price update period", + Value: "10s", + } + + GpoFactorFlag = cli.Float64Flag{ + Name: "gpo.factor", + Usage: "raw gas price facotr", + Value: 0.15, + } + + GpoKafkaURLFlag = cli.StringFlag{ + Name: "gpo.kafka-url", + Usage: "raw gas price kafka url", + Value: "", + } + + GpoTopicFlag = cli.StringFlag{ + Name: "gpo.topic", + Usage: "raw gas price topic", + Value: "", + } + + GpoGroupIDFlag = cli.StringFlag{ + Name: "gpo.group-id", + Usage: "raw gas price group id", + Value: "", + } + + GpoUsernameFlag = cli.StringFlag{ + Name: "gpo.username", + Usage: "raw gas price username", + Value: "", + } + + GpoPasswordFlag = cli.StringFlag{ + Name: "gpo.password", + Usage: "raw gas price password", + Value: "", + } + + GpoRootCAPathFlag = cli.StringFlag{ + Name: "gpo.root-ca-path", + Usage: "raw gas price root ca path", + Value: "", + } + + GpoL1CoinIdFlag = cli.IntFlag{ + Name: "gpo.l1-coin-id", + Usage: "raw gas price l1 coin id", + Value: 0, + } + + GpoL2CoinIdFlag = cli.IntFlag{ + Name: "gpo.l2-coin-id", + Usage: "raw gas price l2 coin id", + Value: 0, + } + + GpoDefaultL1CoinPriceFlag = cli.Float64Flag{ + Name: "gpo.default-l1-coin-price", + Usage: "raw gas price default l1 coin price", + Value: 0, + } + + GpoDefaultL2CoinPriceFlag = cli.Float64Flag{ + Name: "gpo.default-l2-coin-price", + Usage: "raw gas price default l2 coin price", + Value: 0, + } + + GpoGasPriceUsdtFlag = cli.Float64Flag{ + Name: "gpo.gas-price-usdt", + Usage: "raw gas price usdt", + Value: 0, + } + + GpoEnableFollowerAdjustByL2L1PriceFlag = cli.BoolFlag{ + Name: "gpo.enable-follower-adjust", + Usage: "enable dynamic adjust the factor through the L1 and L2 coins price in follower strategy", + Value: true, + } + // Metrics flags MetricsEnabledFlag = cli.BoolFlag{ Name: "metrics", @@ -1455,6 +1546,69 @@ func setGPO(ctx *cli.Context, cfg *gaspricecfg.Config) { if ctx.IsSet(GpoMaxGasPriceFlag.Name) { cfg.MaxPrice = big.NewInt(ctx.Int64(GpoMaxGasPriceFlag.Name)) } + if ctx.IsSet(GpoTypeFlag.Name) { + cfg.Type = ctx.String(GpoTypeFlag.Name) + } + + if ctx.IsSet(GpoUpdatePeriodFlag.Name) { + period, err := time.ParseDuration(ctx.String(GpoUpdatePeriodFlag.Name)) + if err != nil { + panic(fmt.Sprintf("could not parse GpoUpdatePeriodFlag value %s", ctx.String(GpoUpdatePeriodFlag.Name))) + } + cfg.UpdatePeriod = period + } + + if ctx.IsSet(GpoFactorFlag.Name) { + cfg.Factor = ctx.Float64(GpoFactorFlag.Name) + } + + if ctx.IsSet(GpoKafkaURLFlag.Name) { + cfg.KafkaURL = ctx.String(GpoKafkaURLFlag.Name) + } + + if ctx.IsSet(GpoTopicFlag.Name) { + cfg.Topic = ctx.String(GpoTopicFlag.Name) + } + + if ctx.IsSet(GpoGroupIDFlag.Name) { + cfg.GroupID = ctx.String(GpoGroupIDFlag.Name) + } + + if ctx.IsSet(GpoUsernameFlag.Name) { + cfg.Username = ctx.String(GpoUsernameFlag.Name) + } + + if ctx.IsSet(GpoPasswordFlag.Name) { + cfg.Password = ctx.String(GpoPasswordFlag.Name) + } + + if ctx.IsSet(GpoRootCAPathFlag.Name) { + cfg.RootCAPath = ctx.String(GpoRootCAPathFlag.Name) + } + + if ctx.IsSet(GpoL1CoinIdFlag.Name) { + cfg.L1CoinId = ctx.Int(GpoL1CoinIdFlag.Name) + } + + if ctx.IsSet(GpoL2CoinIdFlag.Name) { + cfg.L2CoinId = ctx.Int(GpoL2CoinIdFlag.Name) + } + + if ctx.IsSet(GpoDefaultL1CoinPriceFlag.Name) { + cfg.DefaultL1CoinPrice = ctx.Float64(GpoDefaultL1CoinPriceFlag.Name) + } + + if ctx.IsSet(GpoDefaultL2CoinPriceFlag.Name) { + cfg.DefaultL2CoinPrice = ctx.Float64(GpoDefaultL2CoinPriceFlag.Name) + } + + if ctx.IsSet(GpoGasPriceUsdtFlag.Name) { + cfg.GasPriceUsdt = ctx.Float64(GpoGasPriceUsdtFlag.Name) + } + + if ctx.IsSet(GpoEnableFollowerAdjustByL2L1PriceFlag.Name) { + cfg.EnableFollowerAdjustByL2L1Price = ctx.Bool(GpoEnableFollowerAdjustByL2L1PriceFlag.Name) + } } // nolint diff --git a/eth/gasprice/gaspricecfg/gaspricecfg.go b/eth/gasprice/gaspricecfg/gaspricecfg.go index c8fde5c988c..721fce841e3 100644 --- a/eth/gasprice/gaspricecfg/gaspricecfg.go +++ b/eth/gasprice/gaspricecfg/gaspricecfg.go @@ -23,7 +23,7 @@ type Config struct { IgnorePrice *big.Int `toml:",omitempty"` // XLayer config - Type EstimatorType `toml:",omitempty"` + Type string `toml:",omitempty"` UpdatePeriod time.Duration `toml:",omitempty"` Factor float64 `toml:",omitempty"` KafkaURL string `toml:",omitempty"` @@ -44,15 +44,13 @@ type Config struct { EnableFollowerAdjustByL2L1Price bool `toml:",omitempty"` } -type EstimatorType string - const ( // DefaultType default gas price from config is set. - DefaultType EstimatorType = "default" + DefaultType string = "default" // FollowerType calculate the gas price basing on the L1 gasPrice. - FollowerType EstimatorType = "follower" + FollowerType string = "follower" // FixedType the gas price from config that the unit is usdt, XLayer config - FixedType EstimatorType = "fixed" + FixedType string = "fixed" ) diff --git a/test/config/test.erigon.seq.config.yaml b/test/config/test.erigon.seq.config.yaml index 2e9fa105c09..2f860e27169 100644 --- a/test/config/test.erigon.seq.config.yaml +++ b/test/config/test.erigon.seq.config.yaml @@ -43,4 +43,6 @@ ws: true db.read.concurrency: 20000 txpool.globalslots: 100000 txpool.globalbasefeeslots: 100000 -txpool.globalqueue: 100000 \ No newline at end of file +txpool.globalqueue: 100000 + +gpo.type: "default" \ No newline at end of file diff --git a/turbo/cli/default_flags.go b/turbo/cli/default_flags.go index 738731926a9..1f0864cf541 100644 --- a/turbo/cli/default_flags.go +++ b/turbo/cli/default_flags.go @@ -116,6 +116,20 @@ var DefaultFlags = []cli.Flag{ &utils.FakePoWFlag, &utils.GpoBlocksFlag, &utils.GpoPercentileFlag, + &utils.GpoTypeFlag, + &utils.GpoUpdatePeriodFlag, + &utils.GpoFactorFlag, + &utils.GpoKafkaURLFlag, + &utils.GpoTopicFlag, + &utils.GpoGroupIDFlag, + &utils.GpoUsernameFlag, + &utils.GpoPasswordFlag, + &utils.GpoRootCAPathFlag, + &utils.GpoL1CoinIdFlag, + &utils.GpoL2CoinIdFlag, + &utils.GpoDefaultL1CoinPriceFlag, + &utils.GpoDefaultL2CoinPriceFlag, + &utils.GpoEnableFollowerAdjustByL2L1PriceFlag, &utils.InsecureUnlockAllowedFlag, &utils.MetricsEnabledFlag, &utils.MetricsHTTPFlag, From 09f9296a55655655c75d65381ddb11d18668645c Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Wed, 19 Jun 2024 16:14:38 +0800 Subject: [PATCH 06/21] Update test.erigon.seq.config.yaml --- test/config/test.erigon.seq.config.yaml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/config/test.erigon.seq.config.yaml b/test/config/test.erigon.seq.config.yaml index 2f860e27169..b53c94a6e78 100644 --- a/test/config/test.erigon.seq.config.yaml +++ b/test/config/test.erigon.seq.config.yaml @@ -45,4 +45,12 @@ txpool.globalslots: 100000 txpool.globalbasefeeslots: 100000 txpool.globalqueue: 100000 -gpo.type: "default" \ No newline at end of file +gpo.type: "follower" +gpo.update-period: "10s" +gpo.factor: 0.01 +gpo.kafka-url: "127.0.0.1" +gpo.topic: "explorer_coinPrice_push" +gpo.group-id: "web3_okbc_explorerchainprice" +gpo.default-l1-coin-price: 2000 +gpo.default-l2-coin-price: 50 +gpo.enable-follower-adjust: true \ No newline at end of file From af54cd4c9555ba03ba3c10575cfe8288991be4bc Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Thu, 20 Jun 2024 17:49:06 +0800 Subject: [PATCH 07/21] add GpoTrustedGasPriceProviderUrl config --- cmd/rpcdaemon/commands/eth_system.go | 44 +++++++++++++++++-------- cmd/utils/flags.go | 10 ++++++ eth/gasprice/gaspricecfg/gaspricecfg.go | 2 ++ turbo/cli/default_flags.go | 1 + 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_system.go b/cmd/rpcdaemon/commands/eth_system.go index 43670e720b7..a704fb3f7c6 100644 --- a/cmd/rpcdaemon/commands/eth_system.go +++ b/cmd/rpcdaemon/commands/eth_system.go @@ -2,6 +2,8 @@ package commands import ( "context" + "encoding/json" + "errors" "math/big" "time" @@ -17,6 +19,7 @@ import ( "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/rpchelper" stageszk "github.com/ledgerwatch/erigon/zk/stages" + "github.com/ledgerwatch/erigon/zkevm/jsonrpc/client" "github.com/ledgerwatch/log/v3" ) @@ -106,8 +109,35 @@ func (api *APIImpl) ProtocolVersion(ctx context.Context) (hexutil.Uint, error) { return hexutil.Uint(ver), nil } +func (api *APIImpl) getGPFromTrustedNode() (*hexutil.Big, error) { + res, err := client.JSONRPCCall(api.L2GasPircer.GetConfig().TrustedGasPriceProviderUrl, "eth_gasPrice") + if err != nil { + return nil, errors.New("failed to get gas price from trusted node") + } + + if res.Error != nil { + return nil, errors.New(res.Error.Message) + } + + var gasPrice uint64 + err = json.Unmarshal(res.Result, &gasPrice) + if err != nil { + return nil, errors.New("failed to read gas price from trusted node") + } + return (*hexutil.Big)(new(big.Int).SetUint64(gasPrice)), nil +} + // GasPrice implements eth_gasPrice. Returns the current price per gas in wei. func (api *APIImpl) GasPrice_deprecated(ctx context.Context) (*hexutil.Big, error) { + + if api.L2GasPircer.GetConfig().TrustedGasPriceProviderUrl != "" { + gp, err := api.getGPFromTrustedNode() + if err != nil { + return (*hexutil.Big)(api.L2GasPircer.GetConfig().Default), nil + } + return gp, nil + } + tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err @@ -154,20 +184,6 @@ func (api *APIImpl) MaxPriorityFeePerGas(ctx context.Context) (*hexutil.Big, err if err != nil { return nil, err } - - rgp := api.L2GasPircer.GetLastRawGP() - if head := rawdb.ReadCurrentHeader(tx); head != nil && head.BaseFee != nil { - if rgp.Cmp(head.BaseFee) > 0 { - rgp.Sub(rgp, head.BaseFee) - } else { - rgp.SetUint64(0) - } - } - - if tipcap.Cmp(rgp) < 0 { - tipcap = new(big.Int).Set(rgp) - } - return (*hexutil.Big)(tipcap), err } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 6558f58c713..7706f50caf4 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -937,6 +937,12 @@ var ( Value: true, } + GpoTrustedGasPriceProviderUrl = cli.StringFlag{ + Name: "gpo.trusted-gp-provider-url", + Usage: "trusted provider url to get available gas price", + Value: "", + } + // Metrics flags MetricsEnabledFlag = cli.BoolFlag{ Name: "metrics", @@ -1609,6 +1615,10 @@ func setGPO(ctx *cli.Context, cfg *gaspricecfg.Config) { if ctx.IsSet(GpoEnableFollowerAdjustByL2L1PriceFlag.Name) { cfg.EnableFollowerAdjustByL2L1Price = ctx.Bool(GpoEnableFollowerAdjustByL2L1PriceFlag.Name) } + + if ctx.IsSet(GpoTrustedGasPriceProviderUrl.Name) { + cfg.TrustedGasPriceProviderUrl = ctx.String(GpoTrustedGasPriceProviderUrl.Name) + } } // nolint diff --git a/eth/gasprice/gaspricecfg/gaspricecfg.go b/eth/gasprice/gaspricecfg/gaspricecfg.go index 721fce841e3..4e1996923a9 100644 --- a/eth/gasprice/gaspricecfg/gaspricecfg.go +++ b/eth/gasprice/gaspricecfg/gaspricecfg.go @@ -42,6 +42,8 @@ type Config struct { // EnableFollowerAdjustByL2L1Price is dynamic adjust the factor through the L1 and L2 coins price in follower strategy EnableFollowerAdjustByL2L1Price bool `toml:",omitempty"` + + TrustedGasPriceProviderUrl string `toml:",omitempty"` } const ( diff --git a/turbo/cli/default_flags.go b/turbo/cli/default_flags.go index 1f0864cf541..898b60e0c10 100644 --- a/turbo/cli/default_flags.go +++ b/turbo/cli/default_flags.go @@ -130,6 +130,7 @@ var DefaultFlags = []cli.Flag{ &utils.GpoDefaultL1CoinPriceFlag, &utils.GpoDefaultL2CoinPriceFlag, &utils.GpoEnableFollowerAdjustByL2L1PriceFlag, + &utils.GpoTrustedGasPriceProviderUrl, &utils.InsecureUnlockAllowedFlag, &utils.MetricsEnabledFlag, &utils.MetricsHTTPFlag, From 7aeda62a54a3176e2f0e4e952aceaae4a2912682 Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Mon, 24 Jun 2024 09:01:53 +0800 Subject: [PATCH 08/21] refactor code --- cmd/rpcdaemon/commands/eth_system.go | 59 ++------------------- cmd/rpcdaemon/commands/eth_system_xlayer.go | 49 +++++++++++++++++ cmd/utils/flags.go | 10 ---- eth/gasprice/gaspricecfg/gaspricecfg.go | 2 - turbo/cli/default_flags.go | 1 - 5 files changed, 52 insertions(+), 69 deletions(-) create mode 100644 cmd/rpcdaemon/commands/eth_system_xlayer.go diff --git a/cmd/rpcdaemon/commands/eth_system.go b/cmd/rpcdaemon/commands/eth_system.go index a704fb3f7c6..b389123bb95 100644 --- a/cmd/rpcdaemon/commands/eth_system.go +++ b/cmd/rpcdaemon/commands/eth_system.go @@ -2,25 +2,22 @@ package commands import ( "context" - "encoding/json" - "errors" "math/big" - "time" libcommon "github.com/gateway-fm/cdk-erigon-lib/common" "github.com/gateway-fm/cdk-erigon-lib/kv" "github.com/ledgerwatch/erigon/chain" + "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/eth/ethconfig" "github.com/ledgerwatch/erigon/eth/gasprice" - "github.com/ledgerwatch/erigon/eth/stagedsync/stages" "github.com/ledgerwatch/erigon/rpc" + + "github.com/ledgerwatch/erigon/eth/stagedsync/stages" "github.com/ledgerwatch/erigon/turbo/rpchelper" stageszk "github.com/ledgerwatch/erigon/zk/stages" - "github.com/ledgerwatch/erigon/zkevm/jsonrpc/client" - "github.com/ledgerwatch/log/v3" ) // BlockNumber implements eth_blockNumber. Returns the block number of most recent block. @@ -109,35 +106,8 @@ func (api *APIImpl) ProtocolVersion(ctx context.Context) (hexutil.Uint, error) { return hexutil.Uint(ver), nil } -func (api *APIImpl) getGPFromTrustedNode() (*hexutil.Big, error) { - res, err := client.JSONRPCCall(api.L2GasPircer.GetConfig().TrustedGasPriceProviderUrl, "eth_gasPrice") - if err != nil { - return nil, errors.New("failed to get gas price from trusted node") - } - - if res.Error != nil { - return nil, errors.New(res.Error.Message) - } - - var gasPrice uint64 - err = json.Unmarshal(res.Result, &gasPrice) - if err != nil { - return nil, errors.New("failed to read gas price from trusted node") - } - return (*hexutil.Big)(new(big.Int).SetUint64(gasPrice)), nil -} - // GasPrice implements eth_gasPrice. Returns the current price per gas in wei. func (api *APIImpl) GasPrice_deprecated(ctx context.Context) (*hexutil.Big, error) { - - if api.L2GasPircer.GetConfig().TrustedGasPriceProviderUrl != "" { - gp, err := api.getGPFromTrustedNode() - if err != nil { - return (*hexutil.Big)(api.L2GasPircer.GetConfig().Default), nil - } - return gp, nil - } - tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err @@ -160,11 +130,6 @@ func (api *APIImpl) GasPrice_deprecated(ctx context.Context) (*hexutil.Big, erro gasResult.Add(tipcap, head.BaseFee) } - rgp := api.L2GasPircer.GetLastRawGP() - if gasResult.Cmp(rgp) < 0 { - gasResult = new(big.Int).Set(rgp) - } - return (*hexutil.Big)(gasResult), err } @@ -187,24 +152,6 @@ func (api *APIImpl) MaxPriorityFeePerGas(ctx context.Context) (*hexutil.Big, err return (*hexutil.Big)(tipcap), err } -func (api *APIImpl) runL2GasPriceSuggester() { - cfg := api.L2GasPircer.GetConfig() - ctx := api.L2GasPircer.GetCtx() - - //todo: apollo - updateTimer := time.NewTimer(cfg.UpdatePeriod) - for { - select { - case <-ctx.Done(): - log.Info("Finishing l2 gas price suggester...") - return - case <-updateTimer.C: - api.L2GasPircer.UpdateGasPriceAvg(api.L1RpcUrl) - updateTimer.Reset(cfg.UpdatePeriod) - } - } -} - type feeHistoryResult struct { OldestBlock *hexutil.Big `json:"oldestBlock"` Reward [][]*hexutil.Big `json:"reward,omitempty"` diff --git a/cmd/rpcdaemon/commands/eth_system_xlayer.go b/cmd/rpcdaemon/commands/eth_system_xlayer.go new file mode 100644 index 00000000000..03e0a1f8051 --- /dev/null +++ b/cmd/rpcdaemon/commands/eth_system_xlayer.go @@ -0,0 +1,49 @@ +package commands + +import ( + "encoding/json" + "errors" + "math/big" + "time" + + "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon/zkevm/jsonrpc/client" + "github.com/ledgerwatch/log/v3" +) + +func (api *APIImpl) getGPFromTrustedNode() (*hexutil.Big, error) { + res, err := client.JSONRPCCall(api.l2RpcUrl, "eth_gasPrice") + if err != nil { + return nil, errors.New("failed to get gas price from trusted node") + } + + if res.Error != nil { + return nil, errors.New(res.Error.Message) + } + + var gasPrice uint64 + err = json.Unmarshal(res.Result, &gasPrice) + if err != nil { + return nil, errors.New("failed to read gas price from trusted node") + } + return (*hexutil.Big)(new(big.Int).SetUint64(gasPrice)), nil +} + +func (api *APIImpl) runL2GasPriceSuggester() { + cfg := api.L2GasPircer.GetConfig() + ctx := api.L2GasPircer.GetCtx() + + //todo: apollo + api.L2GasPircer.UpdateGasPriceAvg(api.L1RpcUrl) + updateTimer := time.NewTimer(cfg.UpdatePeriod) + for { + select { + case <-ctx.Done(): + log.Info("Finishing l2 gas price suggester...") + return + case <-updateTimer.C: + api.L2GasPircer.UpdateGasPriceAvg(api.L1RpcUrl) + updateTimer.Reset(cfg.UpdatePeriod) + } + } +} diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 7706f50caf4..6558f58c713 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -937,12 +937,6 @@ var ( Value: true, } - GpoTrustedGasPriceProviderUrl = cli.StringFlag{ - Name: "gpo.trusted-gp-provider-url", - Usage: "trusted provider url to get available gas price", - Value: "", - } - // Metrics flags MetricsEnabledFlag = cli.BoolFlag{ Name: "metrics", @@ -1615,10 +1609,6 @@ func setGPO(ctx *cli.Context, cfg *gaspricecfg.Config) { if ctx.IsSet(GpoEnableFollowerAdjustByL2L1PriceFlag.Name) { cfg.EnableFollowerAdjustByL2L1Price = ctx.Bool(GpoEnableFollowerAdjustByL2L1PriceFlag.Name) } - - if ctx.IsSet(GpoTrustedGasPriceProviderUrl.Name) { - cfg.TrustedGasPriceProviderUrl = ctx.String(GpoTrustedGasPriceProviderUrl.Name) - } } // nolint diff --git a/eth/gasprice/gaspricecfg/gaspricecfg.go b/eth/gasprice/gaspricecfg/gaspricecfg.go index 4e1996923a9..721fce841e3 100644 --- a/eth/gasprice/gaspricecfg/gaspricecfg.go +++ b/eth/gasprice/gaspricecfg/gaspricecfg.go @@ -42,8 +42,6 @@ type Config struct { // EnableFollowerAdjustByL2L1Price is dynamic adjust the factor through the L1 and L2 coins price in follower strategy EnableFollowerAdjustByL2L1Price bool `toml:",omitempty"` - - TrustedGasPriceProviderUrl string `toml:",omitempty"` } const ( diff --git a/turbo/cli/default_flags.go b/turbo/cli/default_flags.go index 898b60e0c10..1f0864cf541 100644 --- a/turbo/cli/default_flags.go +++ b/turbo/cli/default_flags.go @@ -130,7 +130,6 @@ var DefaultFlags = []cli.Flag{ &utils.GpoDefaultL1CoinPriceFlag, &utils.GpoDefaultL2CoinPriceFlag, &utils.GpoEnableFollowerAdjustByL2L1PriceFlag, - &utils.GpoTrustedGasPriceProviderUrl, &utils.InsecureUnlockAllowedFlag, &utils.MetricsEnabledFlag, &utils.MetricsHTTPFlag, From edb7dc87a38c3ba6d200d1460faf70e549a3cf91 Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Mon, 24 Jun 2024 09:30:22 +0800 Subject: [PATCH 09/21] modify eth_gasPrice --- cmd/rpcdaemon/commands/eth_api.go | 1 - cmd/rpcdaemon/commands/eth_system_xlayer.go | 5 +- cmd/rpcdaemon/commands/eth_system_zk.go | 97 ++++++--------------- 3 files changed, 27 insertions(+), 76 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_api.go b/cmd/rpcdaemon/commands/eth_api.go index a59538b25f8..a686a9bfe0e 100644 --- a/cmd/rpcdaemon/commands/eth_api.go +++ b/cmd/rpcdaemon/commands/eth_api.go @@ -379,7 +379,6 @@ func NewEthAPI(base *BaseAPI, db kv.RoDB, eth rpchelper.ApiBackend, txPool txpoo L2GasPircer: gasprice.NewL2GasPriceSuggester(context.Background(), ethconfig.Defaults.GPO), } - apii.L2GasPircer.UpdateGasPriceAvg(apii.L1RpcUrl) go apii.runL2GasPriceSuggester() return apii diff --git a/cmd/rpcdaemon/commands/eth_system_xlayer.go b/cmd/rpcdaemon/commands/eth_system_xlayer.go index 03e0a1f8051..f5573b3844f 100644 --- a/cmd/rpcdaemon/commands/eth_system_xlayer.go +++ b/cmd/rpcdaemon/commands/eth_system_xlayer.go @@ -6,12 +6,11 @@ import ( "math/big" "time" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/zkevm/jsonrpc/client" "github.com/ledgerwatch/log/v3" ) -func (api *APIImpl) getGPFromTrustedNode() (*hexutil.Big, error) { +func (api *APIImpl) getGPFromTrustedNode() (*big.Int, error) { res, err := client.JSONRPCCall(api.l2RpcUrl, "eth_gasPrice") if err != nil { return nil, errors.New("failed to get gas price from trusted node") @@ -26,7 +25,7 @@ func (api *APIImpl) getGPFromTrustedNode() (*hexutil.Big, error) { if err != nil { return nil, errors.New("failed to read gas price from trusted node") } - return (*hexutil.Big)(new(big.Int).SetUint64(gasPrice)), nil + return new(big.Int).SetUint64(gasPrice), nil } func (api *APIImpl) runL2GasPriceSuggester() { diff --git a/cmd/rpcdaemon/commands/eth_system_zk.go b/cmd/rpcdaemon/commands/eth_system_zk.go index 620d65f7519..16671fca1c0 100644 --- a/cmd/rpcdaemon/commands/eth_system_zk.go +++ b/cmd/rpcdaemon/commands/eth_system_zk.go @@ -5,11 +5,12 @@ import ( "encoding/json" "fmt" "math/big" - "strconv" "time" "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/zkevm/encoding" + "github.com/ledgerwatch/erigon/core/rawdb" + "github.com/ledgerwatch/erigon/eth/ethconfig" + "github.com/ledgerwatch/erigon/eth/gasprice" "github.com/ledgerwatch/erigon/zkevm/jsonrpc/client" "github.com/ledgerwatch/log/v3" ) @@ -34,90 +35,42 @@ func (api *APIImpl) GasPrice(ctx context.Context) (*hexutil.Big, error) { return api.GasPrice_nonRedirected(ctx) } - if api.BaseAPI.gasless { - var price hexutil.Big - return &price, nil - } - - res, err := client.JSONRPCCall(api.l2RpcUrl, "eth_gasPrice") + price, err := api.getGPFromTrustedNode() if err != nil { - return nil, err - } - - if res.Error != nil { - return nil, fmt.Errorf("RPC error response: %s", res.Error.Message) - } - if res.Error != nil { - return nil, fmt.Errorf("RPC error response: %s", res.Error.Message) - } - - var resultString string - if err := json.Unmarshal(res.Result, &resultString); err != nil { - return nil, fmt.Errorf("failed to unmarshal result: %v", err) - } - - price, ok := big.NewInt(0).SetString(resultString[2:], 16) - if !ok { - return nil, fmt.Errorf("failed to convert result to big.Int") + log.Error("eth_gasPrice error: ", err) + return (*hexutil.Big)(api.L2GasPircer.GetConfig().Default), nil } return (*hexutil.Big)(price), nil } func (api *APIImpl) GasPrice_nonRedirected(ctx context.Context) (*hexutil.Big, error) { - if api.BaseAPI.gasless { - var price hexutil.Big - return &price, nil - } - - // if gas price timestamp is older than 3 seconds, update it - if time.Since(api.L1GasPrice.timestamp) > 3*time.Second || api.L1GasPrice.gasPrice == nil { - l1GasPrice, err := api.l1GasPrice() - if err != nil { - return nil, err - } - api.L1GasPrice = L1GasPrice{ - timestamp: time.Now(), - gasPrice: l1GasPrice, - } + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err } - - // Apply factor to calculate l2 gasPrice - factor := big.NewFloat(0).SetFloat64(api.GasPriceFactor) - res := new(big.Float).Mul(factor, big.NewFloat(0).SetInt(api.L1GasPrice.gasPrice)) - - // Store l2 gasPrice calculated - result := new(big.Int) - res.Int(result) - minGasPrice := big.NewInt(0).SetUint64(api.DefaultGasPrice) - if minGasPrice.Cmp(result) == 1 { // minGasPrice > result - result = minGasPrice + defer tx.Rollback() + cc, err := api.chainConfig(tx) + if err != nil { + return nil, err } - maxGasPrice := new(big.Int).SetUint64(api.MaxGasPrice) - if api.MaxGasPrice > 0 && result.Cmp(maxGasPrice) == 1 { // result > maxGasPrice - result = maxGasPrice + 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 } - - var truncateValue *big.Int - log.Debug("Full L2 gas price value: ", result, ". Length: ", len(result.String())) - numLength := len(result.String()) - if numLength > 3 { //nolint:gomnd - aux := "%0" + strconv.Itoa(numLength-3) + "d" //nolint:gomnd - var ok bool - value := result.String()[:3] + fmt.Sprintf(aux, 0) - truncateValue, ok = new(big.Int).SetString(value, encoding.Base10) - if !ok { - return nil, fmt.Errorf("failed to convert result to big.Int") - } - } else { - truncateValue = result + if head := rawdb.ReadCurrentHeader(tx); head != nil && head.BaseFee != nil { + gasResult.Add(tipcap, head.BaseFee) } - if truncateValue == nil { - return nil, fmt.Errorf("truncateValue nil value detected") + rgp := api.L2GasPircer.GetLastRawGP() + if gasResult.Cmp(rgp) < 0 { + gasResult = new(big.Int).Set(rgp) } - return (*hexutil.Big)(truncateValue), nil + return (*hexutil.Big)(gasResult), err } func (api *APIImpl) l1GasPrice() (*big.Int, error) { From 924e51c0ff5fac3933d3e900fa5a7c8a7057b4f3 Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Mon, 24 Jun 2024 16:27:57 +0800 Subject: [PATCH 10/21] modify code --- cmd/rpcdaemon/commands/eth_api.go | 4 ++-- cmd/utils/flags.go | 13 +++++++++++- eth/gasprice/fixed_xlayer.go | 9 ++++---- eth/gasprice/follower_xlayer.go | 8 +++---- eth/gasprice/gasprice.go | 28 +++++++++++++++++-------- test/config/test.erigon.seq.config.yaml | 8 ++++--- turbo/cli/default_flags.go | 3 +++ 7 files changed, 49 insertions(+), 24 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_api.go b/cmd/rpcdaemon/commands/eth_api.go index a686a9bfe0e..c2ceb17c38f 100644 --- a/cmd/rpcdaemon/commands/eth_api.go +++ b/cmd/rpcdaemon/commands/eth_api.go @@ -375,10 +375,10 @@ func NewEthAPI(base *BaseAPI, db kv.RoDB, eth rpchelper.ApiBackend, txPool txpoo MaxGasPrice: ethCfg.MaxGasPrice, GasPriceFactor: ethCfg.GasPriceFactor, L1GasPrice: L1GasPrice{}, - //todo: confirm config - L2GasPircer: gasprice.NewL2GasPriceSuggester(context.Background(), ethconfig.Defaults.GPO), + L2GasPircer: gasprice.NewL2GasPriceSuggester(context.Background(), ethconfig.Defaults.GPO), } + apii.gasCache.latestPrice = apii.L2GasPircer.GetConfig().Default go apii.runL2GasPriceSuggester() return apii diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 6558f58c713..94e73ef0253 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -842,11 +842,17 @@ var ( Value: ethconfig.Defaults.GPO.Percentile, } GpoMaxGasPriceFlag = cli.Int64Flag{ - Name: "gpo.maxprice", + Name: "gpo.max-price", Usage: "Maximum gas price will be recommended by gpo", Value: ethconfig.Defaults.GPO.MaxPrice.Int64(), } + GpoDefaultGasPriceFlag = cli.Int64Flag{ + Name: "gpo.default-price", + Usage: "Default gas price will be recommended by gpo", + Value: ethconfig.Defaults.GPO.Default.Int64(), + } + GpoTypeFlag = cli.StringFlag{ Name: "gpo.type", Usage: "raw gas price strategy type: default, follower, fixed", @@ -1546,6 +1552,11 @@ func setGPO(ctx *cli.Context, cfg *gaspricecfg.Config) { if ctx.IsSet(GpoMaxGasPriceFlag.Name) { cfg.MaxPrice = big.NewInt(ctx.Int64(GpoMaxGasPriceFlag.Name)) } + + if ctx.IsSet(GpoDefaultGasPriceFlag.Name) { + cfg.Default = big.NewInt(ctx.Int64(GpoDefaultGasPriceFlag.Name)) + } + if ctx.IsSet(GpoTypeFlag.Name) { cfg.Type = ctx.String(GpoTypeFlag.Name) } diff --git a/eth/gasprice/fixed_xlayer.go b/eth/gasprice/fixed_xlayer.go index d126146f969..16d838e646c 100644 --- a/eth/gasprice/fixed_xlayer.go +++ b/eth/gasprice/fixed_xlayer.go @@ -50,7 +50,7 @@ func (f *FixedGasPrice) UpdateGasPriceAvg(l1RpcUrl string) { res.Int(result) minGasPrice := new(big.Int).Set(f.cfg.Default) if minGasPrice.Cmp(result) == 1 { // minGasPrice > result - log.Warn("setting DefaultGasPriceWei for L2") + log.Warn(fmt.Sprintf("setting DefaultGasPrice for L2: %s", f.cfg.Default.String())) result = minGasPrice } maxGasPrice := new(big.Int).Set(f.cfg.MaxPrice) @@ -59,8 +59,7 @@ func (f *FixedGasPrice) UpdateGasPriceAvg(l1RpcUrl string) { result = maxGasPrice } var truncateValue *big.Int - log.Debug("Full L2 gas price value: ", result, ". Length: ", len(result.String()), ". L1 gas price value: ", l1GasPrice) - + log.Debug(fmt.Sprintf("Full L2 gas price value: %s. Length: %d. L1 gas price: %s", result.String(), len(result.String()), l1GasPrice.String())) numLength := len(result.String()) if numLength > 3 { //nolint:gomnd aux := "%0" + strconv.Itoa(numLength-3) + "d" //nolint:gomnd @@ -73,9 +72,9 @@ func (f *FixedGasPrice) UpdateGasPriceAvg(l1RpcUrl string) { } else { truncateValue = result } - log.Debug("Storing truncated L2 gas price: ", truncateValue, ", L2 native coin price: ", l2CoinPrice) + log.Debug(fmt.Sprintf("Storing truncated L2 gas price: %s, L2 native coin price: %g.", truncateValue.String(), l2CoinPrice)) if truncateValue != nil { - log.Info("Set l2 raw gas price: ", truncateValue.Uint64()) + log.Info(fmt.Sprintf("Set l2 raw gas price: %d", truncateValue.Uint64())) f.lastRawGP = truncateValue } else { log.Error("nil value detected. Skipping...") diff --git a/eth/gasprice/follower_xlayer.go b/eth/gasprice/follower_xlayer.go index 4d7dfb8fd65..b1a4c3b8bc5 100644 --- a/eth/gasprice/follower_xlayer.go +++ b/eth/gasprice/follower_xlayer.go @@ -66,7 +66,7 @@ func (f *FollowerGasPrice) UpdateGasPriceAvg(l1RpcUrl string) { return } res = new(big.Float).Mul(big.NewFloat(0).SetFloat64(l1CoinPrice/l2CoinPrice), res) - log.Debug("L2 pre gas price value: ", res.String(), ". L1 coin price: ", l1CoinPrice, ". L2 coin price: ", l2CoinPrice) + log.Debug(fmt.Sprintf("L2 pre gas price value: %s. L1 coin price: %f. L2 coin price: %f", res.String(), l1CoinPrice, l2CoinPrice)) } // Cache l2 gasPrice calculated @@ -74,7 +74,7 @@ func (f *FollowerGasPrice) UpdateGasPriceAvg(l1RpcUrl string) { res.Int(result) minGasPrice := new(big.Int).Set(f.cfg.Default) if minGasPrice.Cmp(result) == 1 { // minGasPrice > result - log.Warn("setting DefaultGasPrice for L2") + log.Warn(fmt.Sprintf("setting DefaultGasPrice for L2: %s", f.cfg.Default.String())) result = minGasPrice } maxGasPrice := new(big.Int).Set(f.cfg.MaxPrice) @@ -83,7 +83,7 @@ func (f *FollowerGasPrice) UpdateGasPriceAvg(l1RpcUrl string) { result = maxGasPrice } var truncateValue *big.Int - log.Debug("Full L2 gas price value: ", result, ". Length: ", len(result.String())) + log.Debug(fmt.Sprintf("Full L2 gas price value: %s. Length: %d", result.String(), len(result.String()))) numLength := len(result.String()) if numLength > 3 { //nolint:gomnd aux := "%0" + strconv.Itoa(numLength-3) + "d" //nolint:gomnd @@ -98,7 +98,7 @@ func (f *FollowerGasPrice) UpdateGasPriceAvg(l1RpcUrl string) { } if truncateValue != nil { - log.Info("Set l2 raw gas price: ", truncateValue.Uint64()) + log.Info(fmt.Sprintf("Set l2 raw gas price: %d", truncateValue.Uint64())) f.lastRawGP = truncateValue } else { log.Error("nil value detected. Skipping...") diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index dfad5cfc3c7..427998095ca 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -22,8 +22,8 @@ import ( "errors" "math/big" - "github.com/holiman/uint256" libcommon "github.com/gateway-fm/cdk-erigon-lib/common" + "github.com/holiman/uint256" "github.com/ledgerwatch/erigon/chain" "github.com/ledgerwatch/erigon/eth/gasprice/gaspricecfg" "github.com/ledgerwatch/log/v3" @@ -52,12 +52,12 @@ type Cache interface { // Oracle recommends gas prices based on the content of recent // blocks. Suitable for both light and full clients. type Oracle struct { - backend OracleBackend - lastHead libcommon.Hash - lastPrice *big.Int - maxPrice *big.Int - ignorePrice *big.Int - cache Cache + backend OracleBackend + lastHead libcommon.Hash + defaultPrice *big.Int + maxPrice *big.Int + ignorePrice *big.Int + cache Cache checkBlocks int percentile int @@ -93,7 +93,7 @@ func NewOracle(backend OracleBackend, params gaspricecfg.Config, cache Cache) *O } return &Oracle{ backend: backend, - lastPrice: params.Default, + defaultPrice: params.Default, maxPrice: maxPrice, ignorePrice: ignorePrice, checkBlocks: blocks, @@ -151,10 +151,14 @@ func (oracle *Oracle) SuggestTipCap(ctx context.Context) (*big.Int, error) { // Don't need to pop it, just take from the top of the heap price = txPrices[0].ToBig() } - if price.Cmp(oracle.maxPrice) > 0 { + if oracle.maxPrice.Int64() > 0 && price.Cmp(oracle.maxPrice) > 0 { price = new(big.Int).Set(oracle.maxPrice) } + if price.Cmp(oracle.defaultPrice) < 0 { + price = new(big.Int).Set(oracle.defaultPrice) + } + oracle.cache.SetLatest(headHash, price) return price, nil @@ -254,6 +258,12 @@ func (oracle *Oracle) getBlockPrices(ctx context.Context, blockNum uint64, limit count = count + 1 } } + + if count == 0 { + defaultGP := uint256.NewInt(oracle.defaultPrice.Uint64()) + heap.Push(s, defaultGP) + } + return nil } diff --git a/test/config/test.erigon.seq.config.yaml b/test/config/test.erigon.seq.config.yaml index b53c94a6e78..e0b1ede5800 100644 --- a/test/config/test.erigon.seq.config.yaml +++ b/test/config/test.erigon.seq.config.yaml @@ -46,11 +46,13 @@ txpool.globalbasefeeslots: 100000 txpool.globalqueue: 100000 gpo.type: "follower" +gpo.default-price: 1000000000 gpo.update-period: "10s" gpo.factor: 0.01 -gpo.kafka-url: "127.0.0.1" -gpo.topic: "explorer_coinPrice_push" -gpo.group-id: "web3_okbc_explorerchainprice" +gpo.kafka-url: "0.0.0.0" +gpo.topic: "explorer" +gpo.group-id: "web3" gpo.default-l1-coin-price: 2000 gpo.default-l2-coin-price: 50 +gpo.gas-price-usdt: 0.000000476190476 gpo.enable-follower-adjust: true \ No newline at end of file diff --git a/turbo/cli/default_flags.go b/turbo/cli/default_flags.go index 1f0864cf541..ee673074f12 100644 --- a/turbo/cli/default_flags.go +++ b/turbo/cli/default_flags.go @@ -116,6 +116,8 @@ var DefaultFlags = []cli.Flag{ &utils.FakePoWFlag, &utils.GpoBlocksFlag, &utils.GpoPercentileFlag, + &utils.GpoMaxGasPriceFlag, + &utils.GpoDefaultGasPriceFlag, &utils.GpoTypeFlag, &utils.GpoUpdatePeriodFlag, &utils.GpoFactorFlag, @@ -129,6 +131,7 @@ var DefaultFlags = []cli.Flag{ &utils.GpoL2CoinIdFlag, &utils.GpoDefaultL1CoinPriceFlag, &utils.GpoDefaultL2CoinPriceFlag, + &utils.GpoGasPriceUsdtFlag, &utils.GpoEnableFollowerAdjustByL2L1PriceFlag, &utils.InsecureUnlockAllowedFlag, &utils.MetricsEnabledFlag, From da2e6250f4fa0f31a067ce8cd95185095eaadcab Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Mon, 24 Jun 2024 16:34:11 +0800 Subject: [PATCH 11/21] Update eth_api.go --- cmd/rpcdaemon/commands/eth_api.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_api.go b/cmd/rpcdaemon/commands/eth_api.go index f572c59bb1b..c7122815d18 100644 --- a/cmd/rpcdaemon/commands/eth_api.go +++ b/cmd/rpcdaemon/commands/eth_api.go @@ -348,11 +348,8 @@ type APIImpl struct { MaxGasPrice uint64 GasPriceFactor float64 L1GasPrice L1GasPrice -<<<<<<< leo/migrate-gp-model L2GasPircer gasprice.L2GasPricer -======= EnableInnerTx bool // XLayer ->>>>>>> dev } // NewEthAPI returns APIImpl instance @@ -379,11 +376,8 @@ func NewEthAPI(base *BaseAPI, db kv.RoDB, eth rpchelper.ApiBackend, txPool txpoo MaxGasPrice: ethCfg.MaxGasPrice, GasPriceFactor: ethCfg.GasPriceFactor, L1GasPrice: L1GasPrice{}, -<<<<<<< leo/migrate-gp-model L2GasPircer: gasprice.NewL2GasPriceSuggester(context.Background(), ethconfig.Defaults.GPO), -======= EnableInnerTx: ethCfg.EnableInnerTx, ->>>>>>> dev } apii.gasCache.latestPrice = apii.L2GasPircer.GetConfig().Default From 18c69eebda6e5441c2bb474405bb436f034875c6 Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Mon, 24 Jun 2024 17:02:25 +0800 Subject: [PATCH 12/21] Update gasprice.go --- eth/gasprice/gasprice.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index 427998095ca..d411b539199 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -159,6 +159,8 @@ func (oracle *Oracle) SuggestTipCap(ctx context.Context) (*big.Int, error) { price = new(big.Int).Set(oracle.defaultPrice) } + //todo: judge congestion + oracle.cache.SetLatest(headHash, price) return price, nil From 0a2b5d40abcb26bfff416a0490ce199d2d96c2d7 Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Tue, 25 Jun 2024 18:43:29 +0800 Subject: [PATCH 13/21] add ut --- cmd/rpcdaemon/commands/eth_system_xlayer.go | 12 +- eth/gasprice/default_xlayer.go | 2 +- eth/gasprice/fixed_xlayer.go | 9 +- eth/gasprice/fixed_xlayer_test.go | 130 ++++++++++++++++++++ eth/gasprice/follower_xlayer.go | 9 +- eth/gasprice/follower_xlayer_test.go | 43 +++++++ eth/gasprice/gaspricesuggester.go | 2 +- 7 files changed, 187 insertions(+), 20 deletions(-) create mode 100644 eth/gasprice/fixed_xlayer_test.go create mode 100644 eth/gasprice/follower_xlayer_test.go diff --git a/cmd/rpcdaemon/commands/eth_system_xlayer.go b/cmd/rpcdaemon/commands/eth_system_xlayer.go index f5573b3844f..211d3e8b144 100644 --- a/cmd/rpcdaemon/commands/eth_system_xlayer.go +++ b/cmd/rpcdaemon/commands/eth_system_xlayer.go @@ -6,6 +6,7 @@ import ( "math/big" "time" + "github.com/ledgerwatch/erigon/eth/gasprice" "github.com/ledgerwatch/erigon/zkevm/jsonrpc/client" "github.com/ledgerwatch/log/v3" ) @@ -33,7 +34,11 @@ func (api *APIImpl) runL2GasPriceSuggester() { ctx := api.L2GasPircer.GetCtx() //todo: apollo - api.L2GasPircer.UpdateGasPriceAvg(api.L1RpcUrl) + l1gp, err := gasprice.GetL1GasPrice(api.L1RpcUrl) + // if err != nil, do nothing + if err == nil { + api.L2GasPircer.UpdateGasPriceAvg(l1gp) + } updateTimer := time.NewTimer(cfg.UpdatePeriod) for { select { @@ -41,7 +46,10 @@ func (api *APIImpl) runL2GasPriceSuggester() { log.Info("Finishing l2 gas price suggester...") return case <-updateTimer.C: - api.L2GasPircer.UpdateGasPriceAvg(api.L1RpcUrl) + l1gp, err := gasprice.GetL1GasPrice(api.L1RpcUrl) + if err == nil { + api.L2GasPircer.UpdateGasPriceAvg(l1gp) + } updateTimer.Reset(cfg.UpdatePeriod) } } diff --git a/eth/gasprice/default_xlayer.go b/eth/gasprice/default_xlayer.go index d65e84dd114..7d369c26ca3 100644 --- a/eth/gasprice/default_xlayer.go +++ b/eth/gasprice/default_xlayer.go @@ -24,7 +24,7 @@ func newDefaultGasPriceSuggester(ctx context.Context, cfg gaspricecfg.Config) *D } // UpdateGasPriceAvg not needed for default strategy. -func (d *DefaultGasPricer) UpdateGasPriceAvg(l1RpcUrl string) { +func (d *DefaultGasPricer) UpdateGasPriceAvg(l1gp *big.Int) { d.lastRawGP = d.cfg.Default } diff --git a/eth/gasprice/fixed_xlayer.go b/eth/gasprice/fixed_xlayer.go index 16d838e646c..85308fb3a71 100644 --- a/eth/gasprice/fixed_xlayer.go +++ b/eth/gasprice/fixed_xlayer.go @@ -29,16 +29,9 @@ func newFixedGasPriceSuggester(ctx context.Context, cfg gaspricecfg.Config) *Fix } // UpdateGasPriceAvg updates the gas price. -func (f *FixedGasPrice) UpdateGasPriceAvg(l1RpcUrl string) { +func (f *FixedGasPrice) UpdateGasPriceAvg(l1GasPrice *big.Int) { //todo:apollo - // Get L1 gasprice - l1GasPrice, err := GetL1GasPrice(l1RpcUrl) - if err != nil { - log.Error("cannot get l1 gas price. Skipping update...") - return - } - l2CoinPrice := f.ratePrc.GetL2CoinPrice() if l2CoinPrice < minCoinPrice { log.Warn("the L2 native coin price too small...") diff --git a/eth/gasprice/fixed_xlayer_test.go b/eth/gasprice/fixed_xlayer_test.go new file mode 100644 index 00000000000..b8646032493 --- /dev/null +++ b/eth/gasprice/fixed_xlayer_test.go @@ -0,0 +1,130 @@ +package gasprice + +import ( + "context" + "math/big" + "testing" + "time" + + . "github.com/ledgerwatch/erigon/eth/gasprice/gaspricecfg" +) + +func TestUpdateGasPriceFixed(t *testing.T) { + ctx := context.Background() + var d time.Duration = 1000000000 + cfg := Config{ + Default: new(big.Int).SetUint64(1000000000), + MaxPrice: new(big.Int).SetUint64(0), + Type: FixedType, + UpdatePeriod: d, + Factor: 0.5, + KafkaURL: "127.0.0.1:9092", + Topic: "middle_coinPrice_push", + DefaultL2CoinPrice: 40, + GasPriceUsdt: 0.001, + } + l1GasPrice := big.NewInt(10000000000) + f := newFixedGasPriceSuggester(ctx, cfg) + + f.UpdateGasPriceAvg(l1GasPrice) +} + +func TestUpdateGasPriceAvgCases(t *testing.T) { + var d time.Duration = 1000000000 + testcases := []struct { + cfg Config + l1GasPrice *big.Int + l2GasPrice uint64 + }{ + { + cfg: Config{ + Type: FixedType, + Default: new(big.Int).SetUint64(1000000000), + MaxPrice: new(big.Int).SetUint64(0), + UpdatePeriod: d, + KafkaURL: "127.0.0.1:9092", + Topic: "middle_coinPrice_push", + DefaultL2CoinPrice: 40, + GasPriceUsdt: 0.001, + }, + l1GasPrice: big.NewInt(10000000000), + l2GasPrice: uint64(25000000000000), + }, + { + cfg: Config{ + Type: FixedType, + Default: new(big.Int).SetUint64(1000000000), + MaxPrice: new(big.Int).SetUint64(0), + UpdatePeriod: d, + KafkaURL: "127.0.0.1:9092", + Topic: "middle_coinPrice_push", + DefaultL2CoinPrice: 1e-19, + GasPriceUsdt: 0.001, + }, + l1GasPrice: big.NewInt(10000000000), + l2GasPrice: uint64(25000000000000), + }, + { // the gas price less than the min gas price + cfg: Config{ + Type: FixedType, + Default: new(big.Int).SetUint64(26000000000000), + MaxPrice: new(big.Int).SetUint64(0), + UpdatePeriod: d, + KafkaURL: "127.0.0.1:9092", + Topic: "middle_coinPrice_push", + DefaultL2CoinPrice: 40, + GasPriceUsdt: 0.001, + }, + l1GasPrice: big.NewInt(10000000000), + l2GasPrice: uint64(26000000000000), + }, + { // the gas price bigger than the max gas price + cfg: Config{ + Type: FixedType, + Default: new(big.Int).SetUint64(1000000000000), + MaxPrice: new(big.Int).SetUint64(23000000000000), + UpdatePeriod: d, + KafkaURL: "127.0.0.1:9092", + Topic: "middle_coinPrice_push", + DefaultL2CoinPrice: 40, + GasPriceUsdt: 0.001, + }, + l1GasPrice: big.NewInt(10000000000), + l2GasPrice: uint64(23000000000000), + }, + { + cfg: Config{ + Type: FixedType, + Default: new(big.Int).SetUint64(1000000000), + MaxPrice: new(big.Int).SetUint64(0), + UpdatePeriod: d, + KafkaURL: "127.0.0.1:9092", + Topic: "middle_coinPrice_push", + DefaultL2CoinPrice: 30, + GasPriceUsdt: 0.001, + }, + l1GasPrice: big.NewInt(10000000000), + l2GasPrice: uint64(33300000000000), + }, + { + cfg: Config{ + Type: FixedType, + Default: new(big.Int).SetUint64(10), + MaxPrice: new(big.Int).SetUint64(0), + UpdatePeriod: d, + KafkaURL: "127.0.0.1:9092", + Topic: "middle_coinPrice_push", + DefaultL2CoinPrice: 30, + GasPriceUsdt: 1e-15, + }, + l1GasPrice: big.NewInt(10000000000), + l2GasPrice: uint64(33), + }, + } + + for _, tc := range testcases { + ctx := context.Background() + f := newFixedGasPriceSuggester(ctx, tc.cfg) + f.UpdateGasPriceAvg(tc.l1GasPrice) + } +} diff --git a/eth/gasprice/follower_xlayer.go b/eth/gasprice/follower_xlayer.go index b1a4c3b8bc5..f4f0b31bac2 100644 --- a/eth/gasprice/follower_xlayer.go +++ b/eth/gasprice/follower_xlayer.go @@ -39,16 +39,9 @@ func newFollowerGasPriceSuggester(ctx context.Context, cfg gaspricecfg.Config) * } // UpdateGasPriceAvg updates the gas price. -func (f *FollowerGasPrice) UpdateGasPriceAvg(l1RpcUrl string) { +func (f *FollowerGasPrice) UpdateGasPriceAvg(l1GasPrice *big.Int) { //todo: apollo - // Get L1 gasprice - l1GasPrice, err := GetL1GasPrice(l1RpcUrl) - if err != nil { - log.Error("cannot get l1 gas price. Skipping update...") - return - } - if big.NewInt(0).Cmp(l1GasPrice) == 0 { log.Warn("gas price 0 received. Skipping update...") return diff --git a/eth/gasprice/follower_xlayer_test.go b/eth/gasprice/follower_xlayer_test.go new file mode 100644 index 00000000000..1b967c334b0 --- /dev/null +++ b/eth/gasprice/follower_xlayer_test.go @@ -0,0 +1,43 @@ +package gasprice + +import ( + "context" + "math/big" + "testing" + "time" + + . "github.com/ledgerwatch/erigon/eth/gasprice/gaspricecfg" +) + +func TestUpdateGasPriceFollower(t *testing.T) { + ctx := context.Background() + var d time.Duration = 1000000000 + + cfg := Config{ + Type: FollowerType, + Default: new(big.Int).SetUint64(1000000000), + MaxPrice: new(big.Int).SetUint64(0), + UpdatePeriod: d, + Factor: 0.5, + } + l1GasPrice := big.NewInt(10000000000) + f := newFollowerGasPriceSuggester(ctx, cfg) + + f.UpdateGasPriceAvg(l1GasPrice) +} + +func TestLimitMasGasPrice(t *testing.T) { + ctx := context.Background() + var d time.Duration = 1000000000 + + cfg := Config{ + Type: FollowerType, + Default: new(big.Int).SetUint64(100000000), + MaxPrice: new(big.Int).SetUint64(50000000), + UpdatePeriod: d, + Factor: 0.5, + } + l1GasPrice := big.NewInt(1000000000) + f := newFollowerGasPriceSuggester(ctx, cfg) + f.UpdateGasPriceAvg(l1GasPrice) +} diff --git a/eth/gasprice/gaspricesuggester.go b/eth/gasprice/gaspricesuggester.go index 03edf8326f9..e10e6ae033b 100644 --- a/eth/gasprice/gaspricesuggester.go +++ b/eth/gasprice/gaspricesuggester.go @@ -13,7 +13,7 @@ import ( // L2GasPricer interface for gas price suggester. type L2GasPricer interface { - UpdateGasPriceAvg(string) + UpdateGasPriceAvg(*big.Int) GetLastRawGP() *big.Int GetConfig() gaspricecfg.Config GetCtx() context.Context From 673019afcec81b08955f9b1e0c3c950353bf7b9b Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Wed, 26 Jun 2024 09:45:27 +0800 Subject: [PATCH 14/21] Create kafka_proc_xlayer_test.go --- eth/gasprice/kafka_proc_xlayer_test.go | 256 +++++++++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 eth/gasprice/kafka_proc_xlayer_test.go diff --git a/eth/gasprice/kafka_proc_xlayer_test.go b/eth/gasprice/kafka_proc_xlayer_test.go new file mode 100644 index 00000000000..0fa662be83c --- /dev/null +++ b/eth/gasprice/kafka_proc_xlayer_test.go @@ -0,0 +1,256 @@ +package gasprice + +import ( + "context" + "fmt" + "testing" + + . "github.com/ledgerwatch/erigon/eth/gasprice/gaspricecfg" + "github.com/stretchr/testify/require" +) + +func TestParseCoinPrice(t *testing.T) { + testcases := []struct { + coinIds []int + msg string + check func(prices map[int]float64, err error) + }{ + { + // param err + coinIds: []int{}, + msg: "{\"topic\":\"middle_coinPrice_push\"}", + check: func(prices map[int]float64, err error) { + require.Error(t, err) + }, + }, + { + // param err + coinIds: []int{ethcoinId, okbcoinId}, + msg: "{\"topic\":\"middle_coinPrice_push\"}", + check: func(prices map[int]float64, err error) { + require.Error(t, err) + }, + }, + { + // not find all, find one + coinIds: []int{ethcoinId, okbcoinId}, + msg: fmt.Sprintf("{\"topic\":\"middle_coinPrice_push\",\"source\":null,\"type\":null,\"data\":{\"priceList\":[{\"coinId\":%d,\"price\":0.02}],\"id\":\"98a797ce-f61b-4e90-87ac-445e77ad3599\"}}", ethcoinId), + check: func(prices map[int]float64, err error) { + require.NoError(t, err) + require.Equal(t, prices[ethcoinId], 0.02) + }, + }, + { + // not find all + coinIds: []int{ethcoinId, okbcoinId}, + msg: fmt.Sprintf("{\"topic\":\"middle_coinPrice_push\",\"source\":null,\"type\":null,\"data\":{\"priceList\":[{\"coinId\":%d,\"price\":0.02}],\"id\":\"98a797ce-f61b-4e90-87ac-445e77ad3599\"}}", okbcoinId), + check: func(prices map[int]float64, err error) { + require.NoError(t, err) + require.Equal(t, prices[okbcoinId], 0.02) + }, + }, + { + // correct + coinIds: []int{ethcoinId, okbcoinId, okbcoinId + 1}, + msg: fmt.Sprintf("{\"topic\":\"middle_coinPrice_push\",\"source\":null,\"type\":null,\"data\":{\"priceList\":[{\"coinId\":%d,\"price\":0.001}, {\"coinId\":%d,\"price\":0.002}, {\"coinId\":%d,\"price\":0.003}],\"id\":\"98a797ce-f61b-4e90-87ac-445e77ad3599\"}}", ethcoinId, okbcoinId, okbcoinId+1), + check: func(prices map[int]float64, err error) { + require.NoError(t, err) + require.Equal(t, len(prices), 3) + require.Equal(t, prices[ethcoinId], 0.001) + require.Equal(t, prices[okbcoinId], 0.002) + require.Equal(t, prices[okbcoinId+1], 0.003) + }, + }, + { + // correct + coinIds: []int{ethcoinId, okbcoinId}, + msg: fmt.Sprintf("{\"topic\":\"middle_coinPrice_push\",\"source\":null,\"type\":null,\"data\":{\"priceList\":[{\"coinId\":%d,\"price\":0.02}, {\"coinId\":%d,\"price\":0.002}],\"id\":\"98a797ce-f61b-4e90-87ac-445e77ad3599\"}}", ethcoinId, okbcoinId), + check: func(prices map[int]float64, err error) { + require.NoError(t, err) + require.Equal(t, len(prices), 2) + require.Equal(t, prices[ethcoinId], 0.02) + require.Equal(t, prices[okbcoinId], 0.002) + }, + }, + { + // correct + coinIds: []int{ethcoinId, okbcoinId}, + msg: fmt.Sprintf("{\"topic\":\"middle_coinPrice_push\",\"source\":null,\"type\":null,\"data\":{\"priceList\":[{\"coinId\":%d,\"price\":0.02}, {\"coinId\":%d,\"price\":0.002}],\"id\":\"98a797ce-f61b-4e90-87ac-445e77ad3599\"}}", okbcoinId, ethcoinId), + check: func(prices map[int]float64, err error) { + require.NoError(t, err) + require.Equal(t, len(prices), 2) + require.Equal(t, prices[ethcoinId], 0.002) + require.Equal(t, prices[okbcoinId], 0.02) + }, + }, + { + // correct + coinIds: []int{okbcoinId, ethcoinId}, + msg: fmt.Sprintf("{\"topic\":\"middle_coinPrice_push\",\"source\":null,\"type\":null,\"data\":{\"priceList\":[{\"coinId\":%d,\"price\":0.02}, {\"coinId\":%d,\"price\":0.002}, {\"coinId\":%d,\"price\":0.003}],\"id\":\"98a797ce-f61b-4e90-87ac-445e77ad3599\"}}", okbcoinId, ethcoinId, ethcoinId+1), + check: func(prices map[int]float64, err error) { + require.NoError(t, err) + require.Equal(t, len(prices), 2) + require.Equal(t, prices[okbcoinId], 0.02) + require.Equal(t, prices[ethcoinId], 0.002) + }, + }, + { + // correct + coinIds: []int{okbcoinId}, + msg: fmt.Sprintf("{\"topic\":\"middle_coinPrice_push\",\"source\":null,\"type\":null,\"data\":{\"priceList\":[{\"coinId\":%d,\"price\":0.04}, {\"coinId\":%d,\"price\":0.002}, {\"coinId\":123,\"price\":0.005}],\"id\":\"98a797ce-f61b-4e90-87ac-445e77ad3599\"}}", ethcoinId, okbcoinId), + check: func(prices map[int]float64, err error) { + require.NoError(t, err) + require.Equal(t, len(prices), 1) + require.Equal(t, prices[okbcoinId], 0.002) + }, + }, + } + + for _, tc := range testcases { + rp := newKafkaProcessor(Config{Topic: "middle_coinPrice_push"}, context.Background()) + rt, err := rp.parseCoinPrice([]byte(tc.msg), tc.coinIds) + tc.check(rt, err) + } +} + +func TestUpdateL1L2CoinPrice(t *testing.T) { + testcases := []struct { + check func() + }{ + { + check: func() { + rp := newKafkaProcessor(Config{Topic: "middle_coinPrice_push"}, context.Background()) + prices := map[int]float64{ethcoinId: 1.5, okbcoinId: 0.5} + rp.updateL1L2CoinPrice(prices) + l1, l2 := rp.GetL1L2CoinPrice() + require.Equal(t, l1, 1.5) + require.Equal(t, l2, 0.5) + }, + }, + { + check: func() { + rp := newKafkaProcessor(Config{Topic: "middle_coinPrice_push"}, context.Background()) + prices := map[int]float64{ethcoinId: 1.5} + rp.updateL1L2CoinPrice(prices) + l1, l2 := rp.GetL1L2CoinPrice() + require.Equal(t, l1, 0.0) + require.Equal(t, l2, 0.0) + require.Equal(t, rp.tmpPrices.l1Update, true) + require.Equal(t, rp.tmpPrices.l2Update, false) + + prices = map[int]float64{okbcoinId: 0.5} + rp.updateL1L2CoinPrice(prices) + l1, l2 = rp.GetL1L2CoinPrice() + require.Equal(t, l1, 1.5) + require.Equal(t, l2, 0.5) + require.Equal(t, rp.tmpPrices.l1Update, false) + require.Equal(t, rp.tmpPrices.l2Update, false) + }, + }, + { + check: func() { + rp := newKafkaProcessor(Config{Topic: "middle_coinPrice_push"}, context.Background()) + prices := map[int]float64{okbcoinId: 0.5} + rp.updateL1L2CoinPrice(prices) + l1, l2 := rp.GetL1L2CoinPrice() + require.Equal(t, l1, 0.0) + require.Equal(t, l2, 0.0) + require.Equal(t, rp.tmpPrices.l1Update, false) + require.Equal(t, rp.tmpPrices.l2Update, true) + + prices = map[int]float64{ethcoinId: 1.5} + rp.updateL1L2CoinPrice(prices) + l1, l2 = rp.GetL1L2CoinPrice() + require.Equal(t, l1, 1.5) + require.Equal(t, l2, 0.5) + require.Equal(t, rp.tmpPrices.l1Update, false) + require.Equal(t, rp.tmpPrices.l2Update, false) + }, + }, + } + for _, tc := range testcases { + tc.check() + } +} + +func TestUpdate(t *testing.T) { + testcases := []struct { + msg string + cfg Config + check func(rp *KafkaProcessor, err error) + }{ + // FixedType + { // correct + msg: fmt.Sprintf("{\"topic\":\"middle_coinPrice_push\",\"source\":null,\"type\":null,\"data\":{\"priceList\":[{\"coinId\":%d,\"price\":0.04}, {\"coinId\":%d,\"price\":0.002}, {\"coinId\":123,\"price\":0.005}],\"id\":\"98a797ce-f61b-4e90-87ac-445e77ad3599\"}}", ethcoinId, okbcoinId), + cfg: Config{Topic: "middle_coinPrice_push", Type: FixedType}, + check: func(rp *KafkaProcessor, err error) { + require.NoError(t, err) + require.Equal(t, rp.GetL2CoinPrice(), 0.002) + }, + }, + { // not find + msg: fmt.Sprintf("{\"topic\":\"middle_coinPrice_push\",\"source\":null,\"type\":null,\"data\":{\"priceList\":[{\"coinId\":%d,\"price\":0.04}],\"id\":\"98a797ce-f61b-4e90-87ac-445e77ad3599\"}}", ethcoinId), + cfg: Config{Topic: "middle_coinPrice_push", Type: FixedType}, + check: func(rp *KafkaProcessor, err error) { + require.Equal(t, err, ErrNotFindCoinPrice) + require.Equal(t, rp.GetL2CoinPrice(), float64(0)) + }, + }, + { // not find + msg: "{\"topic\":\"middle_coinPrice_push\",\"source\":null,\"type\":null,\"data\":{\"id\":\"98a797ce-f61b-4e90-87ac-445e77ad3599\"}}", + cfg: Config{Topic: "middle_coinPrice_push", Type: FixedType}, + check: func(rp *KafkaProcessor, err error) { + require.EqualError(t, err, "the data PriceList is empty") + require.Equal(t, rp.GetL2CoinPrice(), float64(0)) + }, + }, + + // FollowerType + { // correct + msg: fmt.Sprintf("{\"topic\":\"middle_coinPrice_push\",\"source\":null,\"type\":null,\"data\":{\"priceList\":[{\"coinId\":%d,\"price\":0.04}, {\"coinId\":%d,\"price\":0.002}, {\"coinId\":123,\"price\":0.005}],\"id\":\"98a797ce-f61b-4e90-87ac-445e77ad3599\"}}", ethcoinId, okbcoinId), + cfg: Config{Topic: "middle_coinPrice_push", Type: FollowerType}, + check: func(rp *KafkaProcessor, err error) { + require.NoError(t, err) + l1, l2 := rp.GetL1L2CoinPrice() + require.Equal(t, l1, 0.04) + require.Equal(t, l2, 0.002) + }, + }, + { // not find + msg: fmt.Sprintf("{\"topic\":\"middle_coinPrice_push\",\"source\":null,\"type\":null,\"data\":{\"priceList\":[{\"coinId\":%d,\"price\":0.04}],\"id\":\"98a797ce-f61b-4e90-87ac-445e77ad3599\"}}", ethcoinId+1), + cfg: Config{Topic: "middle_coinPrice_push", Type: FollowerType}, + check: func(rp *KafkaProcessor, err error) { + require.Equal(t, err, ErrNotFindCoinPrice) + l1, l2 := rp.GetL1L2CoinPrice() + require.Equal(t, l1, float64(0)) + require.Equal(t, l2, float64(0)) + }, + }, + { // find one but not update + msg: fmt.Sprintf("{\"topic\":\"middle_coinPrice_push\",\"source\":null,\"type\":null,\"data\":{\"priceList\":[{\"coinId\":%d,\"price\":0.04}],\"id\":\"98a797ce-f61b-4e90-87ac-445e77ad3599\"}}", ethcoinId), + cfg: Config{Topic: "middle_coinPrice_push", Type: FollowerType}, + check: func(rp *KafkaProcessor, err error) { + require.NoError(t, err) + l1, l2 := rp.GetL1L2CoinPrice() + require.Equal(t, l1, float64(0)) + require.Equal(t, l2, float64(0)) + }, + }, + { // find one but not update + msg: fmt.Sprintf("{\"topic\":\"middle_coinPrice_push\",\"source\":null,\"type\":null,\"data\":{\"priceList\":[{\"coinId\":%d,\"price\":0.04}],\"id\":\"98a797ce-f61b-4e90-87ac-445e77ad3599\"}}", okbcoinId), + cfg: Config{Topic: "middle_coinPrice_push", Type: FollowerType}, + check: func(rp *KafkaProcessor, err error) { + require.NoError(t, err) + l1, l2 := rp.GetL1L2CoinPrice() + require.Equal(t, l1, float64(0)) + require.Equal(t, l2, float64(0)) + }, + }, + } + + for _, tc := range testcases { + rp := newKafkaProcessor(tc.cfg, context.Background()) + err := rp.Update([]byte(tc.msg)) + tc.check(rp, err) + } +} From 6bb170a98e97e96ed1167f4d80765d8af9014f28 Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Wed, 26 Jun 2024 10:26:30 +0800 Subject: [PATCH 15/21] update rpc config --- eth/gasprice/gaspricesuggester.go | 2 +- test/config/test.erigon.rpc.config.yaml | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/eth/gasprice/gaspricesuggester.go b/eth/gasprice/gaspricesuggester.go index e10e6ae033b..151e54fc904 100644 --- a/eth/gasprice/gaspricesuggester.go +++ b/eth/gasprice/gaspricesuggester.go @@ -33,7 +33,7 @@ func NewL2GasPriceSuggester(ctx context.Context, cfg gaspricecfg.Config) L2GasPr log.Info("Fixed type selected") gpricer = newFixedGasPriceSuggester(ctx, cfg) default: - log.Error("unknown l2 gas price suggester type ", cfg.Type, ". Please specify a valid one: 'follower' or 'default'") + log.Error("unknown l2 gas price suggester type ", cfg.Type, ". Please specify a valid one: 'follower', 'fixed' or 'default'") } return gpricer diff --git a/test/config/test.erigon.rpc.config.yaml b/test/config/test.erigon.rpc.config.yaml index 7ae2e3c03cf..209f5c05153 100644 --- a/test/config/test.erigon.rpc.config.yaml +++ b/test/config/test.erigon.rpc.config.yaml @@ -45,4 +45,16 @@ ws: true db.read.concurrency: 20000 txpool.globalslots: 100000 txpool.globalbasefeeslots: 100000 -txpool.globalqueue: 100000 \ No newline at end of file +txpool.globalqueue: 100000 + +gpo.type: "follower" +gpo.default-price: 1000000000 +gpo.update-period: "10s" +gpo.factor: 0.01 +gpo.kafka-url: "0.0.0.0" +gpo.topic: "explorer" +gpo.group-id: "web3" +gpo.default-l1-coin-price: 2000 +gpo.default-l2-coin-price: 50 +gpo.gas-price-usdt: 0.000000476190476 +gpo.enable-follower-adjust: true \ No newline at end of file From ead3d9cf054e38de992cf9f2802bd7600990e343 Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Wed, 26 Jun 2024 16:56:41 +0800 Subject: [PATCH 16/21] judge congestion --- cmd/rpcdaemon/commands/eth_system_zk.go | 44 +++++++++++++++++++++++++ cmd/utils/flags.go | 9 +++++ eth/gasprice/gasprice.go | 2 -- eth/gasprice/gaspricecfg/gaspricecfg.go | 2 ++ turbo/cli/default_flags.go | 1 + 5 files changed, 56 insertions(+), 2 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_system_zk.go b/cmd/rpcdaemon/commands/eth_system_zk.go index 16671fca1c0..57d9fd1082d 100644 --- a/cmd/rpcdaemon/commands/eth_system_zk.go +++ b/cmd/rpcdaemon/commands/eth_system_zk.go @@ -7,10 +7,12 @@ import ( "math/big" "time" + proto_txpool "github.com/gateway-fm/cdk-erigon-lib/gointerfaces/txpool" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/eth/ethconfig" "github.com/ledgerwatch/erigon/eth/gasprice" + "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/zkevm/jsonrpc/client" "github.com/ledgerwatch/log/v3" ) @@ -70,9 +72,45 @@ func (api *APIImpl) GasPrice_nonRedirected(ctx context.Context) (*hexutil.Big, e gasResult = new(big.Int).Set(rgp) } + if !api.isCongested(ctx) { + gasResult = getAvgPrice(rgp, gasResult) + } + return (*hexutil.Big)(gasResult), err } +func (api *APIImpl) isCongested(ctx context.Context) bool { + + latestBlockTxNum, err := api.getLatestBlockTxNum(ctx) + if err != nil { + return false + } + isLatestBlockEmpty := latestBlockTxNum == 0 + + poolStatus, err := api.txPool.Status(ctx, &proto_txpool.StatusRequest{}) + if err != nil { + return false + } + + isPendingTxCongested := int(poolStatus.PendingCount) >= api.L2GasPircer.GetConfig().CongestionThreshold + + return !isLatestBlockEmpty && isPendingTxCongested +} + +func (api *APIImpl) getLatestBlockTxNum(ctx context.Context) (int, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return 0, err + } + defer tx.Rollback() + + b, err := api.blockByNumber(ctx, rpc.LatestBlockNumber, tx) + if err != nil { + return 0, err + } + return len(b.Transactions()), nil +} + func (api *APIImpl) l1GasPrice() (*big.Int, error) { res, err := client.JSONRPCCall(api.L1RpcUrl, "eth_gasPrice") if err != nil { @@ -98,3 +136,9 @@ func (api *APIImpl) l1GasPrice() (*big.Int, error) { return price, nil } + +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 + return avg +} diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 172a8fe8028..b7f694e3bf5 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -984,6 +984,11 @@ var ( Value: true, } + GpoCongestionThresholdFlag = cli.IntFlag{ + Name: "gpo.congestion-threshold", + Usage: "Used to determine whether pending tx has reached the threshold for congestion", + Value: 0, + } // Metrics flags MetricsEnabledFlag = cli.BoolFlag{ Name: "metrics", @@ -1661,6 +1666,10 @@ func setGPO(ctx *cli.Context, cfg *gaspricecfg.Config) { if ctx.IsSet(GpoEnableFollowerAdjustByL2L1PriceFlag.Name) { cfg.EnableFollowerAdjustByL2L1Price = ctx.Bool(GpoEnableFollowerAdjustByL2L1PriceFlag.Name) } + + if ctx.IsSet(GpoCongestionThresholdFlag.Name) { + cfg.CongestionThreshold = ctx.Int(GpoCongestionThresholdFlag.Name) + } } // nolint diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index d411b539199..427998095ca 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -159,8 +159,6 @@ func (oracle *Oracle) SuggestTipCap(ctx context.Context) (*big.Int, error) { price = new(big.Int).Set(oracle.defaultPrice) } - //todo: judge congestion - oracle.cache.SetLatest(headHash, price) return price, nil diff --git a/eth/gasprice/gaspricecfg/gaspricecfg.go b/eth/gasprice/gaspricecfg/gaspricecfg.go index 721fce841e3..6f84787a11c 100644 --- a/eth/gasprice/gaspricecfg/gaspricecfg.go +++ b/eth/gasprice/gaspricecfg/gaspricecfg.go @@ -42,6 +42,8 @@ type Config struct { // EnableFollowerAdjustByL2L1Price is dynamic adjust the factor through the L1 and L2 coins price in follower strategy EnableFollowerAdjustByL2L1Price bool `toml:",omitempty"` + + CongestionThreshold int `toml:",omitempty"` } const ( diff --git a/turbo/cli/default_flags.go b/turbo/cli/default_flags.go index 4eef0ea57fa..9b80c01ee33 100644 --- a/turbo/cli/default_flags.go +++ b/turbo/cli/default_flags.go @@ -136,6 +136,7 @@ var DefaultFlags = []cli.Flag{ &utils.GpoDefaultL2CoinPriceFlag, &utils.GpoGasPriceUsdtFlag, &utils.GpoEnableFollowerAdjustByL2L1PriceFlag, + &utils.GpoCongestionThresholdFlag, &utils.InsecureUnlockAllowedFlag, &utils.MetricsEnabledFlag, &utils.MetricsHTTPFlag, From fad035f8dc07f8a5e6775edfbafcf38c9ec52809 Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Thu, 27 Jun 2024 11:02:49 +0800 Subject: [PATCH 17/21] refactor oracle.defaultPrice --- eth/gasprice/gasprice.go | 20 ++++++++++---------- test/config/test.erigon.seq.config.yaml | 3 ++- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index 427998095ca..bb4bac3f2f8 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -52,12 +52,12 @@ type Cache interface { // Oracle recommends gas prices based on the content of recent // blocks. Suitable for both light and full clients. type Oracle struct { - backend OracleBackend - lastHead libcommon.Hash - defaultPrice *big.Int - maxPrice *big.Int - ignorePrice *big.Int - cache Cache + backend OracleBackend + lastHead libcommon.Hash + lastPrice *big.Int + maxPrice *big.Int + ignorePrice *big.Int + cache Cache checkBlocks int percentile int @@ -93,7 +93,7 @@ func NewOracle(backend OracleBackend, params gaspricecfg.Config, cache Cache) *O } return &Oracle{ backend: backend, - defaultPrice: params.Default, + lastPrice: params.Default, maxPrice: maxPrice, ignorePrice: ignorePrice, checkBlocks: blocks, @@ -155,8 +155,8 @@ func (oracle *Oracle) SuggestTipCap(ctx context.Context) (*big.Int, error) { price = new(big.Int).Set(oracle.maxPrice) } - if price.Cmp(oracle.defaultPrice) < 0 { - price = new(big.Int).Set(oracle.defaultPrice) + if price.Cmp(oracle.lastPrice) < 0 { + price = new(big.Int).Set(oracle.lastPrice) } oracle.cache.SetLatest(headHash, price) @@ -260,7 +260,7 @@ func (oracle *Oracle) getBlockPrices(ctx context.Context, blockNum uint64, limit } if count == 0 { - defaultGP := uint256.NewInt(oracle.defaultPrice.Uint64()) + defaultGP := uint256.NewInt(oracle.lastPrice.Uint64()) heap.Push(s, defaultGP) } diff --git a/test/config/test.erigon.seq.config.yaml b/test/config/test.erigon.seq.config.yaml index b8fee221edc..55cd20fce4b 100644 --- a/test/config/test.erigon.seq.config.yaml +++ b/test/config/test.erigon.seq.config.yaml @@ -56,4 +56,5 @@ gpo.group-id: "web3" gpo.default-l1-coin-price: 2000 gpo.default-l2-coin-price: 50 gpo.gas-price-usdt: 0.000000476190476 -gpo.enable-follower-adjust: true \ No newline at end of file +gpo.enable-follower-adjust: true +gpo.congestion-threshold: 0 \ No newline at end of file From 4342e87d31bf94431315517f41677b3e9dbb7a24 Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Thu, 27 Jun 2024 11:20:11 +0800 Subject: [PATCH 18/21] reduce conflict --- cmd/rpcdaemon/commands/eth_system_xlayer.go | 95 ++++++++++++++ cmd/rpcdaemon/commands/eth_system_zk.go | 134 +++++++++++--------- 2 files changed, 167 insertions(+), 62 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_system_xlayer.go b/cmd/rpcdaemon/commands/eth_system_xlayer.go index 211d3e8b144..4008a41b5db 100644 --- a/cmd/rpcdaemon/commands/eth_system_xlayer.go +++ b/cmd/rpcdaemon/commands/eth_system_xlayer.go @@ -1,16 +1,111 @@ package commands import ( + "context" "encoding/json" "errors" "math/big" "time" + proto_txpool "github.com/gateway-fm/cdk-erigon-lib/gointerfaces/txpool" + "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon/core/rawdb" + "github.com/ledgerwatch/erigon/eth/ethconfig" "github.com/ledgerwatch/erigon/eth/gasprice" + "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/zkevm/jsonrpc/client" "github.com/ledgerwatch/log/v3" ) +func (api *APIImpl) GasPrice_xlayer(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) { + return api.GasPrice_nonRedirectedXL(ctx) + } + + price, err := api.getGPFromTrustedNode() + if err != nil { + log.Error("eth_gasPrice error: ", err) + return (*hexutil.Big)(api.L2GasPircer.GetConfig().Default), nil + } + + return (*hexutil.Big)(price), nil +} + +func (api *APIImpl) GasPrice_nonRedirectedXL(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.L2GasPircer.GetLastRawGP() + if gasResult.Cmp(rgp) < 0 { + gasResult = new(big.Int).Set(rgp) + } + + if !api.isCongested(ctx) { + gasResult = getAvgPrice(rgp, gasResult) + } + + return (*hexutil.Big)(gasResult), err +} + +func (api *APIImpl) isCongested(ctx context.Context) bool { + + latestBlockTxNum, err := api.getLatestBlockTxNum(ctx) + if err != nil { + return false + } + isLatestBlockEmpty := latestBlockTxNum == 0 + + poolStatus, err := api.txPool.Status(ctx, &proto_txpool.StatusRequest{}) + if err != nil { + return false + } + + isPendingTxCongested := int(poolStatus.PendingCount) >= api.L2GasPircer.GetConfig().CongestionThreshold + + return !isLatestBlockEmpty && isPendingTxCongested +} + +func (api *APIImpl) getLatestBlockTxNum(ctx context.Context) (int, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return 0, err + } + defer tx.Rollback() + + b, err := api.blockByNumber(ctx, rpc.LatestBlockNumber, tx) + if err != nil { + return 0, err + } + return len(b.Transactions()), nil +} + func (api *APIImpl) getGPFromTrustedNode() (*big.Int, error) { res, err := client.JSONRPCCall(api.l2RpcUrl, "eth_gasPrice") if err != nil { diff --git a/cmd/rpcdaemon/commands/eth_system_zk.go b/cmd/rpcdaemon/commands/eth_system_zk.go index 57d9fd1082d..58b017ee51e 100644 --- a/cmd/rpcdaemon/commands/eth_system_zk.go +++ b/cmd/rpcdaemon/commands/eth_system_zk.go @@ -5,14 +5,11 @@ import ( "encoding/json" "fmt" "math/big" + "strconv" "time" - proto_txpool "github.com/gateway-fm/cdk-erigon-lib/gointerfaces/txpool" "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/core/rawdb" - "github.com/ledgerwatch/erigon/eth/ethconfig" - "github.com/ledgerwatch/erigon/eth/gasprice" - "github.com/ledgerwatch/erigon/rpc" + "github.com/ledgerwatch/erigon/zkevm/encoding" "github.com/ledgerwatch/erigon/zkevm/jsonrpc/client" "github.com/ledgerwatch/log/v3" ) @@ -23,6 +20,7 @@ type L1GasPrice struct { } func (api *APIImpl) GasPrice(ctx context.Context) (*hexutil.Big, error) { + return api.GasPrice_xlayer(ctx) tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err @@ -37,78 +35,90 @@ func (api *APIImpl) GasPrice(ctx context.Context) (*hexutil.Big, error) { return api.GasPrice_nonRedirected(ctx) } - price, err := api.getGPFromTrustedNode() - if err != nil { - log.Error("eth_gasPrice error: ", err) - return (*hexutil.Big)(api.L2GasPircer.GetConfig().Default), nil + if api.BaseAPI.gasless { + var price hexutil.Big + return &price, nil } - return (*hexutil.Big)(price), nil -} - -func (api *APIImpl) GasPrice_nonRedirected(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) + res, err := client.JSONRPCCall(api.l2RpcUrl, "eth_gasPrice") 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.L2GasPircer.GetLastRawGP() - if gasResult.Cmp(rgp) < 0 { - gasResult = new(big.Int).Set(rgp) + if res.Error != nil { + return nil, fmt.Errorf("RPC error response: %s", res.Error.Message) } - - if !api.isCongested(ctx) { - gasResult = getAvgPrice(rgp, gasResult) + if res.Error != nil { + return nil, fmt.Errorf("RPC error response: %s", res.Error.Message) } - return (*hexutil.Big)(gasResult), err -} - -func (api *APIImpl) isCongested(ctx context.Context) bool { - - latestBlockTxNum, err := api.getLatestBlockTxNum(ctx) - if err != nil { - return false + var resultString string + if err := json.Unmarshal(res.Result, &resultString); err != nil { + return nil, fmt.Errorf("failed to unmarshal result: %v", err) } - isLatestBlockEmpty := latestBlockTxNum == 0 - poolStatus, err := api.txPool.Status(ctx, &proto_txpool.StatusRequest{}) - if err != nil { - return false + price, ok := big.NewInt(0).SetString(resultString[2:], 16) + if !ok { + return nil, fmt.Errorf("failed to convert result to big.Int") } - isPendingTxCongested := int(poolStatus.PendingCount) >= api.L2GasPircer.GetConfig().CongestionThreshold - - return !isLatestBlockEmpty && isPendingTxCongested + return (*hexutil.Big)(price), nil } -func (api *APIImpl) getLatestBlockTxNum(ctx context.Context) (int, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return 0, err - } - defer tx.Rollback() - - b, err := api.blockByNumber(ctx, rpc.LatestBlockNumber, tx) - if err != nil { - return 0, err - } - return len(b.Transactions()), nil +func (api *APIImpl) GasPrice_nonRedirected(ctx context.Context) (*hexutil.Big, error) { + if api.BaseAPI.gasless { + var price hexutil.Big + return &price, nil + } + + // if gas price timestamp is older than 3 seconds, update it + if time.Since(api.L1GasPrice.timestamp) > 3*time.Second || api.L1GasPrice.gasPrice == nil { + l1GasPrice, err := api.l1GasPrice() + if err != nil { + return nil, err + } + api.L1GasPrice = L1GasPrice{ + timestamp: time.Now(), + gasPrice: l1GasPrice, + } + } + + // Apply factor to calculate l2 gasPrice + factor := big.NewFloat(0).SetFloat64(api.GasPriceFactor) + res := new(big.Float).Mul(factor, big.NewFloat(0).SetInt(api.L1GasPrice.gasPrice)) + + // Store l2 gasPrice calculated + result := new(big.Int) + res.Int(result) + minGasPrice := big.NewInt(0).SetUint64(api.DefaultGasPrice) + if minGasPrice.Cmp(result) == 1 { // minGasPrice > result + result = minGasPrice + } + maxGasPrice := new(big.Int).SetUint64(api.MaxGasPrice) + if api.MaxGasPrice > 0 && result.Cmp(maxGasPrice) == 1 { // result > maxGasPrice + result = maxGasPrice + } + + var truncateValue *big.Int + log.Debug("Full L2 gas price value: ", result, ". Length: ", len(result.String())) + numLength := len(result.String()) + if numLength > 3 { //nolint:gomnd + aux := "%0" + strconv.Itoa(numLength-3) + "d" //nolint:gomnd + var ok bool + value := result.String()[:3] + fmt.Sprintf(aux, 0) + truncateValue, ok = new(big.Int).SetString(value, encoding.Base10) + if !ok { + return nil, fmt.Errorf("failed to convert result to big.Int") + } + } else { + truncateValue = result + } + + if truncateValue == nil { + return nil, fmt.Errorf("truncateValue nil value detected") + } + + return (*hexutil.Big)(truncateValue), nil } func (api *APIImpl) l1GasPrice() (*big.Int, error) { From a5fd5ef164ad8486adca327696765a2705c702b0 Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Thu, 27 Jun 2024 11:23:24 +0800 Subject: [PATCH 19/21] reduce conflict --- cmd/rpcdaemon/commands/eth_system_xlayer.go | 6 ++++++ cmd/rpcdaemon/commands/eth_system_zk.go | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_system_xlayer.go b/cmd/rpcdaemon/commands/eth_system_xlayer.go index 4008a41b5db..a06bf4b30fa 100644 --- a/cmd/rpcdaemon/commands/eth_system_xlayer.go +++ b/cmd/rpcdaemon/commands/eth_system_xlayer.go @@ -149,3 +149,9 @@ func (api *APIImpl) runL2GasPriceSuggester() { } } } + +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 + return avg +} diff --git a/cmd/rpcdaemon/commands/eth_system_zk.go b/cmd/rpcdaemon/commands/eth_system_zk.go index 58b017ee51e..3f4f75a194a 100644 --- a/cmd/rpcdaemon/commands/eth_system_zk.go +++ b/cmd/rpcdaemon/commands/eth_system_zk.go @@ -146,9 +146,3 @@ func (api *APIImpl) l1GasPrice() (*big.Int, error) { return price, nil } - -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 - return avg -} From b233ac3b5f7d7c2b7e6eeaf1c9569dd565fba81e Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Thu, 27 Jun 2024 11:36:55 +0800 Subject: [PATCH 20/21] reduce conflicts --- cmd/rpcdaemon/commands/eth_system_xlayer.go | 6 +++--- cmd/rpcdaemon/commands/eth_system_zk.go | 6 +++++- eth/gasprice/gasprice.go | 1 + 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_system_xlayer.go b/cmd/rpcdaemon/commands/eth_system_xlayer.go index a06bf4b30fa..bf318b5fe28 100644 --- a/cmd/rpcdaemon/commands/eth_system_xlayer.go +++ b/cmd/rpcdaemon/commands/eth_system_xlayer.go @@ -17,7 +17,7 @@ import ( "github.com/ledgerwatch/log/v3" ) -func (api *APIImpl) GasPrice_xlayer(ctx context.Context) (*hexutil.Big, error) { +func (api *APIImpl) gasPriceXL(ctx context.Context) (*hexutil.Big, error) { tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err @@ -29,7 +29,7 @@ func (api *APIImpl) GasPrice_xlayer(ctx context.Context) (*hexutil.Big, error) { } chainId := cc.ChainID if !api.isZkNonSequencer(chainId) { - return api.GasPrice_nonRedirectedXL(ctx) + return api.gasPriceNonRedirectedXL(ctx) } price, err := api.getGPFromTrustedNode() @@ -41,7 +41,7 @@ func (api *APIImpl) GasPrice_xlayer(ctx context.Context) (*hexutil.Big, error) { return (*hexutil.Big)(price), nil } -func (api *APIImpl) GasPrice_nonRedirectedXL(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 diff --git a/cmd/rpcdaemon/commands/eth_system_zk.go b/cmd/rpcdaemon/commands/eth_system_zk.go index 3f4f75a194a..fc982ffb79b 100644 --- a/cmd/rpcdaemon/commands/eth_system_zk.go +++ b/cmd/rpcdaemon/commands/eth_system_zk.go @@ -20,7 +20,11 @@ type L1GasPrice struct { } func (api *APIImpl) GasPrice(ctx context.Context) (*hexutil.Big, error) { - return api.GasPrice_xlayer(ctx) + // xlayer handler + if api.L2GasPircer.GetConfig().Type != "" { + return api.gasPriceXL(ctx) + } + tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index bb4bac3f2f8..d79858e78e4 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -259,6 +259,7 @@ func (oracle *Oracle) getBlockPrices(ctx context.Context, blockNum uint64, limit } } + // xlayer if count == 0 { defaultGP := uint256.NewInt(oracle.lastPrice.Uint64()) heap.Push(s, defaultGP) From c9208967b6c2a2671400d3fa6b783fc667fe7954 Mon Sep 17 00:00:00 2001 From: LeoGuo621 <335209779@qq.com> Date: Fri, 28 Jun 2024 11:06:49 +0800 Subject: [PATCH 21/21] Update eth_api.go --- cmd/rpcdaemon/commands/eth_api.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/eth_api.go b/cmd/rpcdaemon/commands/eth_api.go index c7122815d18..466a7351ec8 100644 --- a/cmd/rpcdaemon/commands/eth_api.go +++ b/cmd/rpcdaemon/commands/eth_api.go @@ -380,7 +380,8 @@ func NewEthAPI(base *BaseAPI, db kv.RoDB, eth rpchelper.ApiBackend, txPool txpoo EnableInnerTx: ethCfg.EnableInnerTx, } - apii.gasCache.latestPrice = apii.L2GasPircer.GetConfig().Default + // set default gas price + apii.gasCache.SetLatest(common.Hash{}, apii.L2GasPircer.GetConfig().Default) go apii.runL2GasPriceSuggester() return apii