referrerpolicy=no-referrer-when-downgrade

messages_relay/
metrics.rs

1// Copyright 2019-2021 Parity Technologies (UK) Ltd.
2// This file is part of Parity Bridges Common.
3
4// Parity Bridges Common is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Parity Bridges Common is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Parity Bridges Common.  If not, see <http://www.gnu.org/licenses/>.
16
17//! Metrics for message lane relay loop.
18
19use crate::{
20	message_lane::MessageLane,
21	message_lane_loop::{SourceClientState, TargetClientState},
22};
23
24use bp_messages::{HashedLaneId, LegacyLaneId, MessageNonce};
25use finality_relay::SyncLoopMetrics;
26use relay_utils::metrics::{
27	metric_name, register, GaugeVec, Metric, Opts, PrometheusError, Registry, U64,
28};
29
30/// Message lane relay metrics.
31///
32/// Cloning only clones references.
33#[derive(Clone)]
34pub struct MessageLaneLoopMetrics {
35	/// Best finalized block numbers - "source", "source_at_target", "target_at_source".
36	source_to_target_finality_metrics: SyncLoopMetrics,
37	/// Best finalized block numbers - "source", "target", "source_at_target", "target_at_source".
38	target_to_source_finality_metrics: SyncLoopMetrics,
39	/// Lane state nonces: "source_latest_generated", "source_latest_confirmed",
40	/// "target_latest_received", "target_latest_confirmed".
41	lane_state_nonces: GaugeVec<U64>,
42}
43
44impl MessageLaneLoopMetrics {
45	/// Create and register messages loop metrics.
46	pub fn new(prefix: Option<&str>) -> Result<Self, PrometheusError> {
47		Ok(MessageLaneLoopMetrics {
48			source_to_target_finality_metrics: SyncLoopMetrics::new(
49				prefix,
50				"source",
51				"source_at_target",
52			)?,
53			target_to_source_finality_metrics: SyncLoopMetrics::new(
54				prefix,
55				"target",
56				"target_at_source",
57			)?,
58			lane_state_nonces: GaugeVec::new(
59				Opts::new(metric_name(prefix, "lane_state_nonces"), "Nonces of the lane state"),
60				&["type"],
61			)?,
62		})
63	}
64
65	/// Update source client state metrics.
66	pub fn update_source_state<P: MessageLane>(&self, source_client_state: SourceClientState<P>) {
67		self.source_to_target_finality_metrics
68			.update_best_block_at_source(source_client_state.best_self.0);
69		if let Some(best_finalized_peer_at_best_self) =
70			source_client_state.best_finalized_peer_at_best_self
71		{
72			self.target_to_source_finality_metrics
73				.update_best_block_at_target(best_finalized_peer_at_best_self.0);
74			if let Some(actual_best_finalized_peer_at_best_self) =
75				source_client_state.actual_best_finalized_peer_at_best_self
76			{
77				self.target_to_source_finality_metrics.update_using_same_fork(
78					best_finalized_peer_at_best_self.1 == actual_best_finalized_peer_at_best_self.1,
79				);
80			}
81		}
82	}
83
84	/// Update target client state metrics.
85	pub fn update_target_state<P: MessageLane>(&self, target_client_state: TargetClientState<P>) {
86		self.target_to_source_finality_metrics
87			.update_best_block_at_source(target_client_state.best_self.0);
88		if let Some(best_finalized_peer_at_best_self) =
89			target_client_state.best_finalized_peer_at_best_self
90		{
91			self.source_to_target_finality_metrics
92				.update_best_block_at_target(best_finalized_peer_at_best_self.0);
93			if let Some(actual_best_finalized_peer_at_best_self) =
94				target_client_state.actual_best_finalized_peer_at_best_self
95			{
96				self.source_to_target_finality_metrics.update_using_same_fork(
97					best_finalized_peer_at_best_self.1 == actual_best_finalized_peer_at_best_self.1,
98				);
99			}
100		}
101	}
102
103	/// Update latest generated nonce at source.
104	pub fn update_source_latest_generated_nonce(
105		&self,
106		source_latest_generated_nonce: MessageNonce,
107	) {
108		self.lane_state_nonces
109			.with_label_values(&["source_latest_generated"])
110			.set(source_latest_generated_nonce);
111	}
112
113	/// Update the latest confirmed nonce at source.
114	pub fn update_source_latest_confirmed_nonce(
115		&self,
116		source_latest_confirmed_nonce: MessageNonce,
117	) {
118		self.lane_state_nonces
119			.with_label_values(&["source_latest_confirmed"])
120			.set(source_latest_confirmed_nonce);
121	}
122
123	/// Update the latest received nonce at target.
124	pub fn update_target_latest_received_nonce(&self, target_latest_generated_nonce: MessageNonce) {
125		self.lane_state_nonces
126			.with_label_values(&["target_latest_received"])
127			.set(target_latest_generated_nonce);
128	}
129
130	/// Update the latest confirmed nonce at target.
131	pub fn update_target_latest_confirmed_nonce(
132		&self,
133		target_latest_confirmed_nonce: MessageNonce,
134	) {
135		self.lane_state_nonces
136			.with_label_values(&["target_latest_confirmed"])
137			.set(target_latest_confirmed_nonce);
138	}
139}
140
141impl Metric for MessageLaneLoopMetrics {
142	fn register(&self, registry: &Registry) -> Result<(), PrometheusError> {
143		self.source_to_target_finality_metrics.register(registry)?;
144		self.target_to_source_finality_metrics.register(registry)?;
145		register(self.lane_state_nonces.clone(), registry)?;
146		Ok(())
147	}
148}
149
150/// Provides a label for metrics.
151pub trait Labeled {
152	/// Returns a label.
153	fn label(&self) -> String;
154}
155
156/// `Labeled` implementation for `LegacyLaneId`.
157impl Labeled for LegacyLaneId {
158	fn label(&self) -> String {
159		hex::encode(self.0)
160	}
161}
162
163/// `Labeled` implementation for `HashedLaneId`.
164impl Labeled for HashedLaneId {
165	fn label(&self) -> String {
166		format!("{:?}", self.inner())
167	}
168}
169
170#[test]
171fn lane_to_label_works() {
172	assert_eq!(
173		"0x0101010101010101010101010101010101010101010101010101010101010101",
174		HashedLaneId::from_inner(sp_core::H256::from([1u8; 32])).label(),
175	);
176	assert_eq!("00000001", LegacyLaneId([0, 0, 0, 1]).label());
177}