From 61433c2172f26cff15710a56fa5a696a51c056a5 Mon Sep 17 00:00:00 2001 From: Igor Crevar Date: Mon, 25 Sep 2023 13:02:23 +0200 Subject: [PATCH] EVM-850 Validator rootchain balance metrics --- command/server/config/config.go | 7 +++++ command/server/params.go | 3 +++ command/server/server.go | 7 +++++ consensus/consensus.go | 2 ++ consensus/polybft/polybft.go | 6 +++++ consensus/polybft/state_stats.go | 45 ++++++++++++++++++++++++++++++++ server/config.go | 1 + server/server.go | 1 + 8 files changed, 72 insertions(+) diff --git a/command/server/config/config.go b/command/server/config/config.go index 1b26e8cd1b..1fb1b303cc 100644 --- a/command/server/config/config.go +++ b/command/server/config/config.go @@ -39,6 +39,8 @@ type Config struct { ConcurrentRequestsDebug uint64 `json:"concurrent_requests_debug" yaml:"concurrent_requests_debug"` WebSocketReadLimit uint64 `json:"web_socket_read_limit" yaml:"web_socket_read_limit"` + + MetricsInterval time.Duration `json:"metrics_interval" yaml:"metrics_interval"` } // Telemetry holds the config details for metric services. @@ -96,6 +98,10 @@ const ( // DefaultRelayerTrackerPollInterval specifies time interval after which relayer node's event tracker // polls child chain to get the latest block DefaultRelayerTrackerPollInterval time.Duration = time.Second + + // DefaultMetricsInterval specifies the time interval after which Prometheus metrics will be generated. + // A value of 0 means the metrics are disabled. + DefaultMetricsInterval time.Duration = time.Second * 8 ) // DefaultConfig returns the default server configuration @@ -136,6 +142,7 @@ func DefaultConfig() *Config { ConcurrentRequestsDebug: DefaultConcurrentRequestsDebug, WebSocketReadLimit: DefaultWebSocketReadLimit, RelayerTrackerPollInterval: DefaultRelayerTrackerPollInterval, + MetricsInterval: DefaultMetricsInterval, } } diff --git a/command/server/params.go b/command/server/params.go index c7752c41f2..3e727ff3f1 100644 --- a/command/server/params.go +++ b/command/server/params.go @@ -45,6 +45,8 @@ const ( webSocketReadLimitFlag = "websocket-read-limit" relayerTrackerPollIntervalFlag = "relayer-poll-interval" + + metricsIntervalFlag = "metrics-interval" ) // Flags that are deprecated, but need to be preserved for @@ -190,5 +192,6 @@ func (p *serverParams) generateConfig() *server.Config { Relayer: p.relayer, NumBlockConfirmations: p.rawConfig.NumBlockConfirmations, RelayerTrackerPollInterval: p.rawConfig.RelayerTrackerPollInterval, + MetricsInterval: p.rawConfig.MetricsInterval, } } diff --git a/command/server/server.go b/command/server/server.go index 135f2ce0ce..6db00adb6e 100644 --- a/command/server/server.go +++ b/command/server/server.go @@ -249,6 +249,13 @@ func setFlags(cmd *cobra.Command) { "interval (number of seconds) at which relayer's tracker polls for latest block at childchain", ) + cmd.Flags().DurationVar( + ¶ms.rawConfig.MetricsInterval, + metricsIntervalFlag, + defaultConfig.MetricsInterval, + "interval (number of seconds) at which special metrics is generated. zero means the metrics is disabled", + ) + setLegacyFlags(cmd) setDevFlags(cmd) diff --git a/consensus/consensus.go b/consensus/consensus.go index 9532d801f4..878ad76655 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -3,6 +3,7 @@ package consensus import ( "context" "log" + "time" "github.com/0xPolygon/polygon-edge/blockchain" "github.com/0xPolygon/polygon-edge/chain" @@ -78,6 +79,7 @@ type Params struct { BlockTime uint64 NumBlockConfirmations uint64 + MetricsInterval time.Duration } // Factory is the factory function to create a discovery consensus diff --git a/consensus/polybft/polybft.go b/consensus/polybft/polybft.go index 4f2b56ce24..cc11d3427e 100644 --- a/consensus/polybft/polybft.go +++ b/consensus/polybft/polybft.go @@ -527,6 +527,12 @@ func (p *Polybft) Start() error { // start state DB process go p.state.startStatsReleasing() + // additional polybft metrics + go polybftMetrics( + p.consensusConfig.Bridge.JSONRPCEndpoint, + p.key.Address(), p.closeCh, + p.logger, p.config.MetricsInterval) + return nil } diff --git a/consensus/polybft/state_stats.go b/consensus/polybft/state_stats.go index 02ae335e0c..a5fca6070b 100644 --- a/consensus/polybft/state_stats.go +++ b/consensus/polybft/state_stats.go @@ -1,10 +1,14 @@ package polybft import ( + "math/big" "time" "github.com/armon/go-metrics" + "github.com/hashicorp/go-hclog" "github.com/prometheus/client_golang/prometheus" + "github.com/umbracle/ethgo" + "github.com/umbracle/ethgo/jsonrpc" ) // startStatsReleasing starts the process that releases BoltDB stats into prometheus periodically. @@ -154,3 +158,44 @@ func (s *State) startStatsReleasing() { prev = stats } } + +func polybftMetrics(rootnodeURL string, + validatorAddress ethgo.Address, + closeCh <-chan struct{}, + logger hclog.Logger, + interval time.Duration) { + // zero means metrics are disabled + if interval <= 0 { + return + } + + gweiPerWei := new(big.Int).Exp(big.NewInt(10), big.NewInt(9), nil) // 10^9 + + ticker := time.NewTicker(interval) + defer ticker.Stop() + + rpcClient, err := jsonrpc.NewClient(rootnodeURL) + if err != nil { + logger.Error("metrics - connection to root node failed", "err", err) + + return + } + + for { + select { + case <-closeCh: + return + case <-ticker.C: + balance, err := rpcClient.Eth().GetBalance(validatorAddress, ethgo.Latest) + if err != nil { + logger.Error("metrics get balance call failed", "err", err) + + continue + } + + balanceInGwei := new(big.Int).Div(balance, gweiPerWei).Uint64() + metrics.SetGauge([]string{"bridge", "validator_balance_gwei", validatorAddress.String()}, + float32(balanceInGwei)) + } + } +} diff --git a/server/config.go b/server/config.go index edfb2980ae..ff725973b0 100644 --- a/server/config.go +++ b/server/config.go @@ -46,6 +46,7 @@ type Config struct { NumBlockConfirmations uint64 RelayerTrackerPollInterval time.Duration + MetricsInterval time.Duration } // Telemetry holds the config details for metric services diff --git a/server/server.go b/server/server.go index 25e40591fb..da981068e4 100644 --- a/server/server.go +++ b/server/server.go @@ -585,6 +585,7 @@ func (s *Server) setupConsensus() error { SecretsManager: s.secretsManager, BlockTime: uint64(blockTime.Seconds()), NumBlockConfirmations: s.config.NumBlockConfirmations, + MetricsInterval: s.config.MetricsInterval, }, )