Skip to content

Commit

Permalink
recurring gas price check from the L1 (erigontech#1543)
Browse files Browse the repository at this point in the history
Co-authored-by: Valentin Staykov <79150443+V-Staykov@users.noreply.github.com>
  • Loading branch information
hexoscott and V-Staykov authored Dec 10, 2024
1 parent b48c204 commit 14d24c7
Show file tree
Hide file tree
Showing 17 changed files with 558 additions and 174 deletions.
6 changes: 5 additions & 1 deletion cmd/rpcdaemon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ func main() {
ethConfig := ethconfig.Defaults
ethConfig.L2RpcUrl = cfg.L2RpcUrl

apiList := jsonrpc.APIList(db, backend, txPool, nil, mining, ff, stateCache, blockReader, agg, cfg, engine, &ethConfig, nil, logger, nil)
gasTracker := jsonrpc.NewRecurringL1GasPriceTracker(ethConfig.AllowFreeTransactions, ethConfig.GasPriceFactor, ethConfig.DefaultGasPrice, ethConfig.MaxGasPrice, ethConfig.L1RpcUrl, ethConfig.GasPriceCheckFrequency, ethConfig.GasPriceHistoryCount)
gasTracker.Start()
defer gasTracker.Stop()

apiList := jsonrpc.APIList(db, backend, txPool, nil, mining, ff, stateCache, blockReader, agg, cfg, engine, &ethConfig, nil, logger, nil, gasTracker)
rpc.PreAllocateRPCMetricLabels(apiList)
if err := cli.StartRpcServer(ctx, cfg, apiList, logger); err != nil {
logger.Error(err.Error())
Expand Down
20 changes: 20 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,16 @@ var (
Usage: "Allow the sequencer to proceed transactions with 0 gas price",
Value: false,
}
RejectLowGasPriceTransactions = cli.BoolFlag{
Name: "zkevm.reject-low-gas-price-transactions",
Usage: "Reject the sequencer to proceed transactions with low gas price",
Value: false,
}
RejectLowGasPriceTolerance = cli.Float64Flag{
Name: "zkevm.reject-low-gas-price-tolerance",
Usage: "Value between 0 and 1 that defines the tolerance for low gas price transactions, this percentage will be removed from the lowest price to determine rejection",
Value: 0,
}
AllowPreEIP155Transactions = cli.BoolFlag{
Name: "zkevm.allow-pre-eip155-transactions",
Usage: "Allow the sequencer to proceed pre-EIP155 transactions",
Expand Down Expand Up @@ -713,6 +723,16 @@ var (
Usage: "Apply factor to L1 gas price to calculate l2 gasPrice",
Value: 1,
}
GasPriceCheckFrequency = cli.DurationFlag{
Name: "zkevm.gas-price-check-frequency",
Usage: "The frequency at which to check the L1 for the latest gas price",
Value: 0,
}
GasPriceHistoryCount = cli.Uint64Flag{
Name: "zkevm.gas-price-history-count",
Usage: "The number of historical gas prices to keep",
Value: 1,
}
WitnessFullFlag = cli.BoolFlag{
Name: "zkevm.witness-full",
Usage: "Enable/Diable witness full",
Expand Down
20 changes: 18 additions & 2 deletions eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ type Ethereum struct {

polygonSyncService polygonsync.Service
stopNode func() error
gasTracker *jsonrpc.RecurringL1GasPriceTracker
}

func splitAddrIntoHostAndPort(addr string) (host string, port int, err error) {
Expand Down Expand Up @@ -970,6 +971,17 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger
}

if backend.config.Zk != nil {
// setup the gas tracker and start it
backend.gasTracker = jsonrpc.NewRecurringL1GasPriceTracker(
backend.config.AllowFreeTransactions,
backend.config.GasPriceFactor,
backend.config.DefaultGasPrice,
backend.config.MaxGasPrice,
backend.config.L1RpcUrl,
backend.config.GasPriceCheckFrequency,
backend.config.GasPriceHistoryCount,
)

// zkevm: create a data stream server if we have the appropriate config for one. This will be started on the call to Init
// alongside the http server
httpCfg := stack.Config().Http
Expand Down Expand Up @@ -1343,7 +1355,7 @@ func (s *Ethereum) Init(stack *node.Node, config *ethconfig.Config, chainConfig
if s.streamServer != nil {
dataStreamServer = dataStreamServerFactory.CreateDataStreamServer(s.streamServer, config.Zk.L2ChainId)
}
s.apiList = jsonrpc.APIList(chainKv, ethRpcClient, txPoolRpcClient, s.txPool2, miningRpcClient, ff, stateCache, blockReader, s.agg, &httpRpcCfg, s.engine, config, s.l1Syncer, s.logger, dataStreamServer)
s.apiList = jsonrpc.APIList(chainKv, ethRpcClient, txPoolRpcClient, s.txPool2, miningRpcClient, ff, stateCache, blockReader, s.agg, &httpRpcCfg, s.engine, config, s.l1Syncer, s.logger, dataStreamServer, s.gasTracker)

if config.SilkwormRpcDaemon && httpRpcCfg.Enabled {
interface_log_settings := silkworm.RpcInterfaceLogSettings{
Expand Down Expand Up @@ -1377,7 +1389,7 @@ func (s *Ethereum) Init(stack *node.Node, config *ethconfig.Config, chainConfig
}

if chainConfig.Bor == nil {
go s.engineBackendRPC.Start(ctx, &httpRpcCfg, s.chainDB, s.blockReader, ff, stateCache, s.agg, s.engine, ethRpcClient, txPoolRpcClient, miningRpcClient)
go s.engineBackendRPC.Start(ctx, &httpRpcCfg, s.chainDB, s.blockReader, ff, stateCache, s.agg, s.engine, ethRpcClient, txPoolRpcClient, miningRpcClient, s.gasTracker)
}

go func() {
Expand Down Expand Up @@ -1904,6 +1916,8 @@ func (s *Ethereum) Start() error {
s.engine.(*bor.Bor).Start(s.chainDB)
}

s.gasTracker.Start()

// if s.silkwormRPCDaemonService != nil {
// if err := s.silkwormRPCDaemonService.Start(); err != nil {
// s.logger.Error("silkworm.StartRpcDaemon error", "err", err)
Expand Down Expand Up @@ -1960,6 +1974,8 @@ func (s *Ethereum) Stop() error {
}
s.chainDB.Close()

s.gasTracker.Stop()

if s.silkwormRPCDaemonService != nil {
if err := s.silkwormRPCDaemonService.Stop(); err != nil {
s.logger.Error("silkworm.StopRpcDaemon error", "err", err)
Expand Down
4 changes: 4 additions & 0 deletions eth/ethconfig/config_zkevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ type Zk struct {
DefaultGasPrice uint64
MaxGasPrice uint64
GasPriceFactor float64
GasPriceCheckFrequency time.Duration
GasPriceHistoryCount uint64
DAUrl string
DataStreamHost string
DataStreamPort uint
Expand Down Expand Up @@ -99,6 +101,8 @@ type Zk struct {
WitnessCacheEnabled bool
WitnessCacheLimit uint64
WitnessContractInclusion []common.Address
RejectLowGasPriceTransactions bool
RejectLowGasPriceTolerance float64
LogLevel utils.LogLevel
}

Expand Down
4 changes: 4 additions & 0 deletions turbo/cli/default_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,4 +295,8 @@ var DefaultFlags = []cli.Flag{
&utils.WitnessCacheEnable,
&utils.WitnessCacheLimit,
&utils.WitnessContractInclusion,
&utils.GasPriceCheckFrequency,
&utils.GasPriceHistoryCount,
&utils.RejectLowGasPriceTransactions,
&utils.RejectLowGasPriceTolerance,
}
4 changes: 4 additions & 0 deletions turbo/cli/flags_zkevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,10 @@ func ApplyFlagsForZkConfig(ctx *cli.Context, cfg *ethconfig.Config) {
MockWitnessGeneration: ctx.Bool(utils.MockWitnessGeneration.Name),
WitnessCacheLimit: witnessCacheLimit,
WitnessContractInclusion: witnessInclusion,
GasPriceCheckFrequency: ctx.Duration(utils.GasPriceCheckFrequency.Name),
GasPriceHistoryCount: ctx.Uint64(utils.GasPriceHistoryCount.Name),
RejectLowGasPriceTransactions: ctx.Bool(utils.RejectLowGasPriceTransactions.Name),
RejectLowGasPriceTolerance: ctx.Float64(utils.RejectLowGasPriceTolerance.Name),
LogLevel: utils2.LogLevel(logLevel),
}

Expand Down
3 changes: 2 additions & 1 deletion turbo/engineapi/engine_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,11 @@ func (e *EngineServer) Start(
eth rpchelper.ApiBackend,
txPool txpool.TxpoolClient,
mining txpool.MiningClient,
gasTracker *jsonrpc.RecurringL1GasPriceTracker,
) {
base := jsonrpc.NewBaseApi(filters, stateCache, blockReader, agg, httpConfig.WithDatadir, httpConfig.EvmCallTimeout, engineReader, httpConfig.Dirs)

ethImpl := jsonrpc.NewEthAPI(base, db, eth, txPool, mining, httpConfig.Gascap, httpConfig.Feecap, httpConfig.ReturnDataLimit, &ethconfig.Defaults, httpConfig.AllowUnprotectedTxs, httpConfig.MaxGetProofRewindBlockCount, httpConfig.WebsocketSubscribeLogsChannelSize, e.logger)
ethImpl := jsonrpc.NewEthAPI(base, db, eth, txPool, mining, httpConfig.Gascap, httpConfig.Feecap, httpConfig.ReturnDataLimit, &ethconfig.Defaults, httpConfig.AllowUnprotectedTxs, httpConfig.MaxGetProofRewindBlockCount, httpConfig.WebsocketSubscribeLogsChannelSize, e.logger, gasTracker)

// engineImpl := NewEngineAPI(base, db, engineBackend)
// e.startEngineMessageHandler()
Expand Down
3 changes: 2 additions & 1 deletion turbo/jsonrpc/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func APIList(db kv.RoDB, eth rpchelper.ApiBackend, txPool txpool.TxpoolClient, r
filters *rpchelper.Filters, stateCache kvcache.Cache,
blockReader services.FullBlockReader, agg *libstate.Aggregator, cfg *httpcfg.HttpCfg, engine consensus.EngineReader,
ethCfg *ethconfig.Config, l1Syncer *syncer.L1Syncer, logger log.Logger, dataStreamServer server.DataStreamServer,
gasTracker *RecurringL1GasPriceTracker,
) (list []rpc.API) {
// non-sequencer nodes should forward on requests to the sequencer
rpcUrl := ""
Expand All @@ -38,7 +39,7 @@ func APIList(db kv.RoDB, eth rpchelper.ApiBackend, txPool txpool.TxpoolClient, r
base := NewBaseApi(filters, stateCache, blockReader, agg, cfg.WithDatadir, cfg.EvmCallTimeout, engine, cfg.Dirs)
base.SetL2RpcUrl(ethCfg.Zk.L2RpcUrl)
base.SetGasless(ethCfg.AllowFreeTransactions)
ethImpl := NewEthAPI(base, db, eth, txPool, mining, cfg.Gascap, cfg.Feecap, cfg.ReturnDataLimit, ethCfg, cfg.AllowUnprotectedTxs, cfg.MaxGetProofRewindBlockCount, cfg.WebsocketSubscribeLogsChannelSize, logger)
ethImpl := NewEthAPI(base, db, eth, txPool, mining, cfg.Gascap, cfg.Feecap, cfg.ReturnDataLimit, ethCfg, cfg.AllowUnprotectedTxs, cfg.MaxGetProofRewindBlockCount, cfg.WebsocketSubscribeLogsChannelSize, logger, gasTracker)
erigonImpl := NewErigonAPI(base, db, eth)
txpoolImpl := NewTxPoolAPI(base, db, txPool, rawPool, rpcUrl)
netImpl := NewNetAPIImpl(eth)
Expand Down
99 changes: 53 additions & 46 deletions turbo/jsonrpc/eth_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,63 +354,70 @@ func (api *BaseAPI) pruneMode(tx kv.Tx) (*prune.Mode, error) {
// APIImpl is implementation of the EthAPI interface based on remote Db access
type APIImpl struct {
*BaseAPI
ethBackend rpchelper.ApiBackend
txPool txpool.TxpoolClient
mining txpool.MiningClient
gasCache *GasPriceCache
db kv.RoDB
GasCap uint64
FeeCap float64
ReturnDataLimit int
ZkRpcUrl string
PoolManagerUrl string
AllowFreeTransactions bool
AllowPreEIP155Transactions bool
AllowUnprotectedTxs bool
MaxGetProofRewindBlockCount int
L1RpcUrl string
DefaultGasPrice uint64
MaxGasPrice uint64
GasPriceFactor float64
L1GasPrice L1GasPrice
SubscribeLogsChannelSize int
logger log.Logger
VirtualCountersSmtReduction float64
ethBackend rpchelper.ApiBackend
txPool txpool.TxpoolClient
mining txpool.MiningClient
gasCache *GasPriceCache
db kv.RoDB
GasCap uint64
FeeCap float64
ReturnDataLimit int
ZkRpcUrl string
PoolManagerUrl string
AllowFreeTransactions bool
AllowPreEIP155Transactions bool
AllowUnprotectedTxs bool
MaxGetProofRewindBlockCount int
L1RpcUrl string
DefaultGasPrice uint64
MaxGasPrice uint64
GasPriceFactor float64
L1GasPrice L1GasPrice
SubscribeLogsChannelSize int
logger log.Logger
VirtualCountersSmtReduction float64
gasTracker RpcL1GasPriceTracker
RejectLowGasPriceTransactions bool
RejectLowGasPriceTolerance float64

logLevel utils.LogLevel
}

// NewEthAPI returns APIImpl instance
func NewEthAPI(base *BaseAPI, db kv.RoDB, eth rpchelper.ApiBackend, txPool txpool.TxpoolClient, mining txpool.MiningClient, gascap uint64, feecap float64, returnDataLimit int, ethCfg *ethconfig.Config, allowUnprotectedTxs bool, maxGetProofRewindBlockCount int, subscribeLogsChannelSize int, logger log.Logger) *APIImpl {
func NewEthAPI(base *BaseAPI, db kv.RoDB, eth rpchelper.ApiBackend, txPool txpool.TxpoolClient, mining txpool.MiningClient, gascap uint64, feecap float64, returnDataLimit int, ethCfg *ethconfig.Config, allowUnprotectedTxs bool, maxGetProofRewindBlockCount int, subscribeLogsChannelSize int, logger log.Logger, gasTracker RpcL1GasPriceTracker) *APIImpl {
if gascap == 0 {
gascap = uint64(math.MaxUint64 / 2)
}

base.logLevel = ethCfg.LogLevel

return &APIImpl{
BaseAPI: base,
db: db,
ethBackend: eth,
txPool: txPool,
mining: mining,
gasCache: NewGasPriceCache(),
GasCap: gascap,
FeeCap: feecap,
AllowUnprotectedTxs: allowUnprotectedTxs,
ReturnDataLimit: returnDataLimit,
ZkRpcUrl: ethCfg.L2RpcUrl,
PoolManagerUrl: ethCfg.PoolManagerUrl,
AllowFreeTransactions: ethCfg.AllowFreeTransactions,
AllowPreEIP155Transactions: ethCfg.AllowPreEIP155Transactions,
MaxGetProofRewindBlockCount: maxGetProofRewindBlockCount,
L1RpcUrl: ethCfg.L1RpcUrl,
DefaultGasPrice: ethCfg.DefaultGasPrice,
MaxGasPrice: ethCfg.MaxGasPrice,
GasPriceFactor: ethCfg.GasPriceFactor,
L1GasPrice: L1GasPrice{},
SubscribeLogsChannelSize: subscribeLogsChannelSize,
logger: logger,
VirtualCountersSmtReduction: ethCfg.VirtualCountersSmtReduction,
BaseAPI: base,
db: db,
ethBackend: eth,
txPool: txPool,
mining: mining,
gasCache: NewGasPriceCache(),
GasCap: gascap,
FeeCap: feecap,
AllowUnprotectedTxs: allowUnprotectedTxs,
ReturnDataLimit: returnDataLimit,
ZkRpcUrl: ethCfg.L2RpcUrl,
PoolManagerUrl: ethCfg.PoolManagerUrl,
AllowFreeTransactions: ethCfg.AllowFreeTransactions,
AllowPreEIP155Transactions: ethCfg.AllowPreEIP155Transactions,
MaxGetProofRewindBlockCount: maxGetProofRewindBlockCount,
L1RpcUrl: ethCfg.L1RpcUrl,
DefaultGasPrice: ethCfg.DefaultGasPrice,
MaxGasPrice: ethCfg.MaxGasPrice,
GasPriceFactor: ethCfg.GasPriceFactor,
L1GasPrice: L1GasPrice{},
SubscribeLogsChannelSize: subscribeLogsChannelSize,
logger: logger,
VirtualCountersSmtReduction: ethCfg.VirtualCountersSmtReduction,
gasTracker: gasTracker,
RejectLowGasPriceTransactions: ethCfg.RejectLowGasPriceTransactions,
RejectLowGasPriceTolerance: ethCfg.RejectLowGasPriceTolerance,
}
}

Expand Down
2 changes: 1 addition & 1 deletion turbo/jsonrpc/eth_callMany_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func TestCallMany(t *testing.T) {
db := contractBackend.DB()
engine := contractBackend.Engine()
api := NewEthAPI(NewBaseApi(nil, stateCache, contractBackend.BlockReader(), contractBackend.Agg(), false, rpccfg.DefaultEvmCallTimeout, engine,
datadir.New(t.TempDir())), db, nil, nil, nil, 5000000, 1e18, 100_000, &ethconfig.Defaults, false, 100_000, 128, log.New())
datadir.New(t.TempDir())), db, nil, nil, nil, 5000000, 1e18, 100_000, &ethconfig.Defaults, false, 100_000, 128, log.New(), nil)

callArgAddr1 := ethapi.CallArgs{From: &address, To: &tokenAddr, Nonce: &nonce,
MaxPriorityFeePerGas: (*hexutil.Big)(big.NewInt(1e9)),
Expand Down
2 changes: 1 addition & 1 deletion turbo/jsonrpc/eth_mining_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestPendingBlock(t *testing.T) {
stateCache := kvcache.New(kvcache.DefaultCoherentConfig)
engine := ethash.NewFaker()
api := NewEthAPI(NewBaseApi(ff, stateCache, m.BlockReader, nil, false, rpccfg.DefaultEvmCallTimeout, engine,
m.Dirs), nil, nil, nil, mining, 5000000, 1e18, 100_000, &ethconfig.Defaults, false, 100_000, 128, log.New())
m.Dirs), nil, nil, nil, mining, 5000000, 1e18, 100_000, &ethconfig.Defaults, false, 100_000, 128, log.New(), nil)
expect := uint64(12345)
b, err := rlp.EncodeToBytes(types.NewBlockWithHeader(&types.Header{Number: big.NewInt(int64(expect))}))
require.NoError(t, err)
Expand Down
Loading

0 comments on commit 14d24c7

Please sign in to comment.