Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
* gasPricer as a component with the follower

follower sets the l2gasprice depending on the l1 gas price

* make command

* Unit test + mocks

* linter

* fix

* suggestions

* suggestions

* log message

* suggesto to suggester + fix merge

* file name fixed
  • Loading branch information
ARR552 authored Jan 24, 2023
1 parent 9aaa4b6 commit cb5a457
Show file tree
Hide file tree
Showing 35 changed files with 464 additions and 312 deletions.
4 changes: 3 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ const (
BROADCAST = "broadcast-trusted-state"
// ETHTXMANAGER is the service that manages the tx sent to L1
ETHTXMANAGER = "eth-tx-manager"
// L2GASPRICER is the l2 gas pricer component identifier.
L2GASPRICER = "l2gaspricer"
)

var (
Expand All @@ -52,7 +54,7 @@ var (
Aliases: []string{"co"},
Usage: "List of components to run",
Required: false,
Value: cli.NewStringSlice(AGGREGATOR, SEQUENCER, RPC, SYNCHRONIZER, ETHTXMANAGER),
Value: cli.NewStringSlice(AGGREGATOR, SEQUENCER, RPC, SYNCHRONIZER, ETHTXMANAGER, L2GASPRICER),
}
httpAPIFlag = cli.StringSliceFlag{
Name: config.FlagHTTPAPI,
Expand Down
40 changes: 14 additions & 26 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package main
import (
"context"
"fmt"
"math/big"
"net"
"net/http"
"os"
Expand Down Expand Up @@ -101,18 +100,16 @@ func start(cliCtx *cli.Context) error {
case SEQUENCER:
log.Info("Running sequencer")
poolInstance := createPool(c.Pool, c.NetworkConfig.L2BridgeAddr, l2ChainID, st)
gpe := createGasPriceEstimator(c.GasPriceEstimator, st, poolInstance)
seq := createSequencer(*c, poolInstance, ethTxManagerStorage, st, gpe)
seq := createSequencer(*c, poolInstance, ethTxManagerStorage, st)
go seq.Start(ctx)
case RPC:
log.Info("Running JSON-RPC server")
poolInstance := createPool(c.Pool, c.NetworkConfig.L2BridgeAddr, l2ChainID, st)
gpe := createGasPriceEstimator(c.GasPriceEstimator, st, poolInstance)
apis := map[string]bool{}
for _, a := range cliCtx.StringSlice(config.FlagHTTPAPI) {
apis[a] = true
}
go runJSONRPCServer(*c, poolInstance, st, gpe, apis)
go runJSONRPCServer(*c, poolInstance, st, apis)
case SYNCHRONIZER:
log.Info("Running synchronizer")
go runSynchronizer(*c, etherman, etm, st)
Expand All @@ -123,6 +120,10 @@ func start(cliCtx *cli.Context) error {
log.Info("Running eth tx manager service")
etm := createEthTxManager(*c, ethTxManagerStorage, st)
go etm.Start()
case L2GASPRICER:
log.Info("Running L2 gasPricer")
poolInstance := createPool(c.Pool, c.NetworkConfig.L2BridgeAddr, l2ChainID, st)
go runL2GasPriceSuggester(c.L2GasPriceSuggester, st, poolInstance, etherman)
}
}

Expand Down Expand Up @@ -180,16 +181,16 @@ func runSynchronizer(cfg config.Config, etherman *etherman.Client, ethTxManager
}
}

func runJSONRPCServer(c config.Config, pool *pool.Pool, st *state.State, gpe gasPriceEstimator, apis map[string]bool) {
func runJSONRPCServer(c config.Config, pool *pool.Pool, st *state.State, apis map[string]bool) {
storage := jsonrpc.NewStorage()
c.RPC.MaxCumulativeGasUsed = c.Sequencer.MaxCumulativeGasUsed

if err := jsonrpc.NewServer(c.RPC, pool, st, gpe, storage, apis).Start(); err != nil {
if err := jsonrpc.NewServer(c.RPC, pool, st, storage, apis).Start(); err != nil {
log.Fatal(err)
}
}

func createSequencer(cfg config.Config, pool *pool.Pool, etmStorage *ethtxmanager.PostgresStorage, st *state.State, gpe gasPriceEstimator) *sequencer.Sequencer {
func createSequencer(cfg config.Config, pool *pool.Pool, etmStorage *ethtxmanager.PostgresStorage, st *state.State) *sequencer.Sequencer {
pg, err := pricegetter.NewClient(cfg.PriceGetter)
if err != nil {
log.Fatal(err)
Expand All @@ -209,7 +210,7 @@ func createSequencer(cfg config.Config, pool *pool.Pool, etmStorage *ethtxmanage

ethTxManager := ethtxmanager.New(cfg.EthTxManager, etherman, etmStorage, st)

seq, err := sequencer.New(cfg.Sequencer, pool, st, etherman, pg, ethTxManager, gpe)
seq, err := sequencer.New(cfg.Sequencer, pool, st, etherman, pg, ethTxManager)
if err != nil {
log.Fatal(err)
}
Expand All @@ -236,23 +237,10 @@ func runBroadcastServer(c broadcast.ServerConfig, st *state.State) {
broadcastSrv.Start()
}

// gasPriceEstimator interface for gas price estimator.
type gasPriceEstimator interface {
GetAvgGasPrice(ctx context.Context) (*big.Int, error)
UpdateGasPriceAvg(newValue *big.Int)
}

// createGasPriceEstimator init gas price gasPriceEstimator based on type in config.
func createGasPriceEstimator(cfg gasprice.Config, st *state.State, pool *pool.Pool) gasPriceEstimator {
switch cfg.Type {
case gasprice.AllBatchesType:
return gasprice.NewEstimatorAllBatches()
case gasprice.LastNBatchesType:
return gasprice.NewEstimatorLastNL2Blocks(cfg, st)
case gasprice.DefaultType:
return gasprice.NewDefaultEstimator(cfg, pool)
}
return nil
// runL2GasPriceSuggester init gas price gasPriceEstimator based on type in config.
func runL2GasPriceSuggester(cfg gasprice.Config, state *state.State, pool *pool.Pool, etherman *etherman.Client) {
ctx := context.Background()
gasprice.NewL2GasPriceSuggester(ctx, cfg, pool, etherman, state)
}

func waitSignal(cancelFuncs []context.CancelFunc) {
Expand Down
34 changes: 17 additions & 17 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,23 +50,23 @@ const (

// Config represents the configuration of the entire Hermez Node
type Config struct {
IsTrustedSequencer bool `mapstructure:"IsTrustedSequencer"`
Log log.Config
Etherman etherman.Config
EthTxManager ethtxmanager.Config
Pool pool.Config
RPC jsonrpc.Config
Synchronizer synchronizer.Config
Sequencer sequencer.Config
PriceGetter pricegetter.Config
Aggregator aggregator.Config
NetworkConfig NetworkConfig
GasPriceEstimator gasprice.Config
Executor executor.Config
BroadcastServer broadcast.ServerConfig
MTClient merkletree.Config
StateDB db.Config
Metrics metrics.Config
IsTrustedSequencer bool `mapstructure:"IsTrustedSequencer"`
Log log.Config
Etherman etherman.Config
EthTxManager ethtxmanager.Config
Pool pool.Config
RPC jsonrpc.Config
Synchronizer synchronizer.Config
Sequencer sequencer.Config
PriceGetter pricegetter.Config
Aggregator aggregator.Config
NetworkConfig NetworkConfig
L2GasPriceSuggester gasprice.Config
Executor executor.Config
BroadcastServer broadcast.ServerConfig
MTClient merkletree.Config
StateDB db.Config
Metrics metrics.Config
}

// Default parses the default configuration values.
Expand Down
2 changes: 1 addition & 1 deletion config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ func Test_Defaults(t *testing.T) {
expectedValue: pricegetter.TokenPrice{Float: new(big.Float).SetInt64(2000)},
},
{
path: "GasPriceEstimator.DefaultGasPriceWei",
path: "L2GasPriceSuggester.DefaultGasPriceWei",
expectedValue: uint64(1000000000),
},
{
Expand Down
2 changes: 1 addition & 1 deletion config/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ TxProfitabilityCheckerType = "acceptall"
TxProfitabilityMinReward = "1.1"
ProofStatePollingInterval = "5s"
[GasPriceEstimator]
[L2GasPriceSuggester]
Type = "default"
DefaultGasPriceWei = 1000000000
Expand Down
2 changes: 1 addition & 1 deletion config/environments/public/public.node.config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ SyncChunkSize = 10000
TrustedSequencerURI = ""
GenBlockNumber = 8168980

[GasPriceEstimator]
[L2GasPriceSuggester]
Type = "default"
DefaultGasPriceWei = 1000000000

Expand Down
7 changes: 4 additions & 3 deletions etherman/etherman.go
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,7 @@ func (etherMan *Client) ApproveMatic(ctx context.Context, account common.Address
return nil, errors.New("can't find account private key to sign tx")
}
if etherMan.GasProviders.MultiGasProvider {
opts.GasPrice = etherMan.getGasPrice(ctx)
opts.GasPrice = etherMan.GetL1GasPrice(ctx)
}
tx, err := etherMan.Matic.Approve(&opts, etherMan.cfg.PoEAddr, maticAmount)
if err != nil {
Expand All @@ -838,7 +838,8 @@ func (etherMan *Client) GetL2ChainID() (uint64, error) {
return etherMan.PoE.ChainID(&bind.CallOpts{Pending: false})
}

func (etherMan *Client) getGasPrice(ctx context.Context) *big.Int {
// GetL1GasPrice gets the l1 gas price
func (etherMan *Client) GetL1GasPrice(ctx context.Context) *big.Int {
// Get gasPrice from providers
gasPrice := big.NewInt(0)
for i, prov := range etherMan.GasProviders.Providers {
Expand All @@ -865,7 +866,7 @@ func (etherMan *Client) CurrentNonce(ctx context.Context, account common.Address

// SuggestedGasPrice returns the suggest nonce for the network at the moment
func (etherMan *Client) SuggestedGasPrice(ctx context.Context) (*big.Int, error) {
suggestedGasPrice := etherMan.getGasPrice(ctx)
suggestedGasPrice := etherMan.GetL1GasPrice(ctx)
if suggestedGasPrice.Cmp(big.NewInt(0)) == 0 {
return nil, errors.New("failed to get the suggested gas price")
}
Expand Down
10 changes: 5 additions & 5 deletions etherman/etherman_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,12 +343,12 @@ func TestGasPrice(t *testing.T) {

etherscanM.On("SuggestGasPrice", ctx).Return(big.NewInt(765625003), nil)
ethGasStationM.On("SuggestGasPrice", ctx).Return(big.NewInt(765625002), nil)
gp := etherman.getGasPrice(ctx)
gp := etherman.GetL1GasPrice(ctx)
assert.Equal(t, big.NewInt(765625003), gp)

etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, ethGasStationM}

gp = etherman.getGasPrice(ctx)
gp = etherman.GetL1GasPrice(ctx)
assert.Equal(t, big.NewInt(765625002), gp)
}

Expand All @@ -360,14 +360,14 @@ func TestErrorEthGasStationPrice(t *testing.T) {
ctx := context.Background()

ethGasStationM.On("SuggestGasPrice", ctx).Return(big.NewInt(0), fmt.Errorf("error getting gasPrice from ethGasStation"))
gp := etherman.getGasPrice(ctx)
gp := etherman.GetL1GasPrice(ctx)
assert.Equal(t, big.NewInt(765625001), gp)

etherscanM := new(etherscanMock)
etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, etherscanM, ethGasStationM}

etherscanM.On("SuggestGasPrice", ctx).Return(big.NewInt(765625003), nil)
gp = etherman.getGasPrice(ctx)
gp = etherman.GetL1GasPrice(ctx)
assert.Equal(t, big.NewInt(765625003), gp)
}

Expand All @@ -381,6 +381,6 @@ func TestErrorEtherScanPrice(t *testing.T) {

etherscanM.On("SuggestGasPrice", ctx).Return(big.NewInt(0), fmt.Errorf("error getting gasPrice from etherscan"))
ethGasStationM.On("SuggestGasPrice", ctx).Return(big.NewInt(765625002), nil)
gp := etherman.getGasPrice(ctx)
gp := etherman.GetL1GasPrice(ctx)
assert.Equal(t, big.NewInt(765625002), gp)
}
43 changes: 0 additions & 43 deletions gasprice/allbatches.go

This file was deleted.

18 changes: 11 additions & 7 deletions gasprice/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package gasprice

import (
"math/big"

"github.com/0xPolygonHermez/zkevm-node/config/types"
)

// EstimatorType different gas estimator types.
Expand All @@ -10,19 +12,21 @@ type EstimatorType string
const (
// DefaultType default gas price from config is set.
DefaultType EstimatorType = "default"
// AllBatchesType calculate average gas used from all batches.
AllBatchesType EstimatorType = "allbatches"
// LastNBatchesType calculate average gas tip from last n batches.
LastNBatchesType EstimatorType = "lastnbatches"
// FollowerType calculate the gas price basing on the L1 gasPrice.
FollowerType EstimatorType = "follower"
)

// Config for gas price estimator.
type Config struct {
Type EstimatorType `mapstructure:"Type"`

DefaultGasPriceWei uint64 `mapstructure:"DefaultGasPriceWei"`
MaxPrice *big.Int `mapstructure:"MaxPrice"`
IgnorePrice *big.Int `mapstructure:"IgnorePrice"`
CheckBlocks int `mapstructure:"CheckBlocks"`
Percentile int `mapstructure:"Percentile"`
DefaultGasPriceWei uint64 `mapstructure:"DefaultGasPriceWei"`
MaxPrice *big.Int `mapstructure:"MaxPrice"`
IgnorePrice *big.Int `mapstructure:"IgnorePrice"`
CheckBlocks int `mapstructure:"CheckBlocks"`
Percentile int `mapstructure:"Percentile"`
UpdatePeriod types.Duration `mapstructure:"UpdatePeriod"`
Factor float64 `mapstructure:"Factor"`
}
37 changes: 11 additions & 26 deletions gasprice/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,29 @@ package gasprice

import (
"context"
"errors"
"fmt"
"math/big"

"github.com/0xPolygonHermez/zkevm-node/state"
)

// Default gas price from config is set.
type Default struct {
// DefaultGasPricer gas price from config is set.
type DefaultGasPricer struct {
cfg Config
pool pool
ctx context.Context
}

// GetAvgGasPrice get default gas price from the pool.
func (d *Default) GetAvgGasPrice(ctx context.Context) (*big.Int, error) {
gasPrice, err := d.pool.GetGasPrice(ctx)
if errors.Is(err, state.ErrNotFound) {
return big.NewInt(0), nil
} else if err != nil {
return nil, err
}
return new(big.Int).SetUint64(gasPrice), nil
// newDefaultGasPriceSuggester init default gas price suggester.
func newDefaultGasPriceSuggester(ctx context.Context, cfg Config, pool pool) *DefaultGasPricer {
gpe := &DefaultGasPricer{ctx: ctx, cfg: cfg, pool: pool}
gpe.setDefaultGasPrice()
return gpe
}

// UpdateGasPriceAvg not needed for default strategy.
func (d *Default) UpdateGasPriceAvg(newValue *big.Int) {}
func (d *DefaultGasPricer) UpdateGasPriceAvg() {}

func (d *Default) setDefaultGasPrice() {
ctx := context.Background()
err := d.pool.SetGasPrice(ctx, d.cfg.DefaultGasPriceWei)
func (d *DefaultGasPricer) setDefaultGasPrice() {
err := d.pool.SetGasPrice(d.ctx, d.cfg.DefaultGasPriceWei)
if err != nil {
panic(fmt.Errorf("failed to set default gas price, err: %v", err))
}
}

// NewDefaultEstimator init default gas price estimator.
func NewDefaultEstimator(cfg Config, pool pool) *Default {
gpe := &Default{cfg: cfg, pool: pool}
gpe.setDefaultGasPrice()
return gpe
}
Loading

0 comments on commit cb5a457

Please sign in to comment.