Unify metric names (#1209)

* unify metric names

* refactor standalone metrics

* headers sync metrics

* post-merge fix

* fix compilation

* fmt

* fix dashboards

* fix local dashboards

* update Rococo/Wococo runtime version

* remove commented code

* fixed grumbles

* fmt

* fixed widget names
This commit is contained in:
Svyatoslav Nikolsky
2021-11-22 15:38:42 +03:00
committed by Bastian Köcher
parent 940d7e463b
commit bbf8b51f9c
33 changed files with 509 additions and 515 deletions
+1 -1
View File
@@ -44,7 +44,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: sp_version::create_runtime_str!("rococo"), spec_name: sp_version::create_runtime_str!("rococo"),
impl_name: sp_version::create_runtime_str!("parity-rococo-v1.6"), impl_name: sp_version::create_runtime_str!("parity-rococo-v1.6"),
authoring_version: 0, authoring_version: 0,
spec_version: 9004, spec_version: 9100,
impl_version: 0, impl_version: 0,
apis: sp_version::create_apis_vec![[]], apis: sp_version::create_apis_vec![[]],
transaction_version: 0, transaction_version: 0,
@@ -17,6 +17,8 @@
use codec::Decode; use codec::Decode;
use frame_support::weights::{DispatchClass, DispatchInfo, Pays, Weight}; use frame_support::weights::{DispatchClass, DispatchInfo, Pays, Weight};
use relay_kusama_client::Kusama; use relay_kusama_client::Kusama;
use sp_core::storage::StorageKey;
use sp_runtime::{FixedPointNumber, FixedU128};
use sp_version::RuntimeVersion; use sp_version::RuntimeVersion;
use crate::cli::{ use crate::cli::{
@@ -101,3 +103,14 @@ impl CliChain for Kusama {
anyhow::bail!("Sending messages from Kusama is not yet supported.") anyhow::bail!("Sending messages from Kusama is not yet supported.")
} }
} }
/// Storage key and initial value of Polkadot -> Kusama conversion rate.
pub(crate) fn polkadot_to_kusama_conversion_rate_params() -> (StorageKey, FixedU128) {
(
bp_runtime::storage_parameter_key(
bp_kusama::POLKADOT_TO_KUSAMA_CONVERSION_RATE_PARAMETER_NAME,
),
// starting relay before this parameter will be set to some value may cause troubles
FixedU128::from_inner(FixedU128::DIV),
)
}
@@ -64,10 +64,7 @@ impl SubstrateFinalitySyncPipeline for KusamaFinalityToPolkadot {
type TargetChain = Polkadot; type TargetChain = Polkadot;
fn customize_metrics(params: MetricsParams) -> anyhow::Result<MetricsParams> { fn customize_metrics(params: MetricsParams) -> anyhow::Result<MetricsParams> {
crate::chains::add_polkadot_kusama_price_metrics::<Self::FinalitySyncPipeline>( crate::chains::add_polkadot_kusama_price_metrics::<Self::FinalitySyncPipeline>(params)
Some(finality_relay::metrics_prefix::<Self::FinalitySyncPipeline>()),
params,
)
} }
fn start_relay_guards(&self) { fn start_relay_guards(&self) {
@@ -21,7 +21,6 @@ use std::ops::RangeInclusive;
use codec::Encode; use codec::Encode;
use frame_support::weights::Weight; use frame_support::weights::Weight;
use sp_core::{Bytes, Pair}; use sp_core::{Bytes, Pair};
use sp_runtime::{FixedPointNumber, FixedU128};
use bp_messages::MessageNonce; use bp_messages::MessageNonce;
use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof; use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof;
@@ -33,7 +32,6 @@ use relay_polkadot_client::{
HeaderId as PolkadotHeaderId, Polkadot, SigningParams as PolkadotSigningParams, HeaderId as PolkadotHeaderId, Polkadot, SigningParams as PolkadotSigningParams,
}; };
use relay_substrate_client::{Chain, Client, TransactionSignScheme, UnsignedTransaction}; use relay_substrate_client::{Chain, Client, TransactionSignScheme, UnsignedTransaction};
use relay_utils::metrics::MetricsParams;
use substrate_relay_helper::{ use substrate_relay_helper::{
messages_lane::{ messages_lane::{
select_delivery_transaction_limits, MessagesRelayParams, StandaloneMessagesMetrics, select_delivery_transaction_limits, MessagesRelayParams, StandaloneMessagesMetrics,
@@ -196,12 +194,13 @@ pub async fn run(
let lane_id = params.lane_id; let lane_id = params.lane_id;
let source_client = params.source_client; let source_client = params.source_client;
let target_client = params.target_client;
let lane = KusamaMessagesToPolkadot { let lane = KusamaMessagesToPolkadot {
message_lane: SubstrateMessageLaneToSubstrate { message_lane: SubstrateMessageLaneToSubstrate {
source_client: source_client.clone(), source_client: source_client.clone(),
source_sign: params.source_sign, source_sign: params.source_sign,
source_transactions_mortality: params.source_transactions_mortality, source_transactions_mortality: params.source_transactions_mortality,
target_client: params.target_client.clone(), target_client: target_client.clone(),
target_sign: params.target_sign, target_sign: params.target_sign,
target_transactions_mortality: params.target_transactions_mortality, target_transactions_mortality: params.target_transactions_mortality,
relayer_id_at_source: relayer_id_at_kusama, relayer_id_at_source: relayer_id_at_kusama,
@@ -240,13 +239,10 @@ pub async fn run(
stall_timeout, stall_timeout,
); );
let (metrics_params, metrics_values) = add_standalone_metrics( let standalone_metrics = params
Some(messages_relay::message_lane_loop::metrics_prefix::< .standalone_metrics
<KusamaMessagesToPolkadot as SubstrateMessageLane>::MessageLane, .map(Ok)
>(&lane_id)), .unwrap_or_else(|| standalone_metrics(source_client.clone(), target_client.clone()))?;
params.metrics_params,
source_client.clone(),
)?;
messages_relay::message_lane_loop::run( messages_relay::message_lane_loop::run(
messages_relay::message_lane_loop::Params { messages_relay::message_lane_loop::Params {
lane: lane_id, lane: lane_id,
@@ -272,41 +268,31 @@ pub async fn run(
params.target_to_source_headers_relay, params.target_to_source_headers_relay,
), ),
PolkadotTargetClient::new( PolkadotTargetClient::new(
params.target_client, target_client,
lane, lane,
lane_id, lane_id,
metrics_values, standalone_metrics.clone(),
params.source_to_target_headers_relay, params.source_to_target_headers_relay,
), ),
metrics_params, standalone_metrics.register_and_spawn(params.metrics_params)?,
futures::future::pending(), futures::future::pending(),
) )
.await .await
.map_err(Into::into) .map_err(Into::into)
} }
/// Add standalone metrics for the Kusama -> Polkadot messages loop. /// Create standalone metrics for the Kusama -> Polkadot messages loop.
pub(crate) fn add_standalone_metrics( pub(crate) fn standalone_metrics(
metrics_prefix: Option<String>,
metrics_params: MetricsParams,
source_client: Client<Kusama>, source_client: Client<Kusama>,
) -> anyhow::Result<(MetricsParams, StandaloneMessagesMetrics)> { target_client: Client<Polkadot>,
let polkadot_to_kusama_conversion_rate_key = bp_runtime::storage_parameter_key( ) -> anyhow::Result<StandaloneMessagesMetrics<Kusama, Polkadot>> {
bp_kusama::POLKADOT_TO_KUSAMA_CONVERSION_RATE_PARAMETER_NAME, substrate_relay_helper::messages_lane::standalone_metrics(
)
.0;
substrate_relay_helper::messages_lane::add_standalone_metrics::<KusamaMessagesToPolkadot>(
metrics_prefix,
metrics_params,
source_client, source_client,
Some(crate::chains::polkadot::TOKEN_ID), target_client,
Some(crate::chains::kusama::TOKEN_ID), Some(crate::chains::kusama::TOKEN_ID),
Some(( Some(crate::chains::polkadot::TOKEN_ID),
sp_core::storage::StorageKey(polkadot_to_kusama_conversion_rate_key), Some(crate::chains::polkadot::kusama_to_polkadot_conversion_rate_params()),
// starting relay before this parameter will be set to some value may cause troubles Some(crate::chains::kusama::polkadot_to_kusama_conversion_rate_params()),
FixedU128::from_inner(FixedU128::DIV),
)),
) )
} }
@@ -28,8 +28,17 @@ use bp_message_dispatch::{CallOrigin, MessagePayload};
use codec::Decode; use codec::Decode;
use frame_support::weights::{DispatchInfo, GetDispatchInfo, Weight}; use frame_support::weights::{DispatchInfo, GetDispatchInfo, Weight};
use relay_millau_client::Millau; use relay_millau_client::Millau;
use sp_core::storage::StorageKey;
use sp_runtime::FixedU128;
use sp_version::RuntimeVersion; use sp_version::RuntimeVersion;
// Millau/Rialto tokens have no any real value, so the conversion rate we use is always 1:1. But we
// want to test our code that is intended to work with real-value chains. So to keep it close to
// 1:1, we'll be treating Rialto as BTC and Millau as wBTC (only in relayer).
/// The identifier of token, which value is associated with Millau token value by relayer.
pub(crate) const ASSOCIATED_TOKEN_ID: &str = crate::chains::kusama::TOKEN_ID;
impl CliEncodeCall for Millau { impl CliEncodeCall for Millau {
fn max_extrinsic_size() -> u32 { fn max_extrinsic_size() -> u32 {
bp_millau::max_extrinsic_size() bp_millau::max_extrinsic_size()
@@ -123,3 +132,11 @@ impl CliChain for Millau {
} }
} }
} }
/// Storage key and initial value of Rialto -> Millau conversion rate.
pub(crate) fn rialto_to_millau_conversion_rate_params() -> (StorageKey, FixedU128) {
(
StorageKey(millau_runtime::rialto_messages::RialtoToMillauConversionRate::key().to_vec()),
millau_runtime::rialto_messages::INITIAL_RIALTO_TO_MILLAU_CONVERSION_RATE,
)
}
@@ -33,7 +33,6 @@ use relay_rialto_client::{
HeaderId as RialtoHeaderId, Rialto, SigningParams as RialtoSigningParams, HeaderId as RialtoHeaderId, Rialto, SigningParams as RialtoSigningParams,
}; };
use relay_substrate_client::{Chain, Client, IndexOf, TransactionSignScheme, UnsignedTransaction}; use relay_substrate_client::{Chain, Client, IndexOf, TransactionSignScheme, UnsignedTransaction};
use relay_utils::metrics::MetricsParams;
use substrate_relay_helper::{ use substrate_relay_helper::{
messages_lane::{ messages_lane::{
select_delivery_transaction_limits, MessagesRelayParams, StandaloneMessagesMetrics, select_delivery_transaction_limits, MessagesRelayParams, StandaloneMessagesMetrics,
@@ -193,12 +192,13 @@ pub async fn run(
let lane_id = params.lane_id; let lane_id = params.lane_id;
let source_client = params.source_client; let source_client = params.source_client;
let target_client = params.target_client;
let lane = MillauMessagesToRialto { let lane = MillauMessagesToRialto {
message_lane: SubstrateMessageLaneToSubstrate { message_lane: SubstrateMessageLaneToSubstrate {
source_client: source_client.clone(), source_client: source_client.clone(),
source_sign: params.source_sign, source_sign: params.source_sign,
source_transactions_mortality: params.source_transactions_mortality, source_transactions_mortality: params.source_transactions_mortality,
target_client: params.target_client.clone(), target_client: target_client.clone(),
target_sign: params.target_sign, target_sign: params.target_sign,
target_transactions_mortality: params.target_transactions_mortality, target_transactions_mortality: params.target_transactions_mortality,
relayer_id_at_source: relayer_id_at_millau, relayer_id_at_source: relayer_id_at_millau,
@@ -234,13 +234,10 @@ pub async fn run(
stall_timeout, stall_timeout,
); );
let (metrics_params, metrics_values) = add_standalone_metrics( let standalone_metrics = params
Some(messages_relay::message_lane_loop::metrics_prefix::< .standalone_metrics
<MillauMessagesToRialto as SubstrateMessageLane>::MessageLane, .map(Ok)
>(&lane_id)), .unwrap_or_else(|| standalone_metrics(source_client.clone(), target_client.clone()))?;
params.metrics_params,
source_client.clone(),
)?;
messages_relay::message_lane_loop::run( messages_relay::message_lane_loop::run(
messages_relay::message_lane_loop::Params { messages_relay::message_lane_loop::Params {
lane: lane_id, lane: lane_id,
@@ -266,37 +263,31 @@ pub async fn run(
params.target_to_source_headers_relay, params.target_to_source_headers_relay,
), ),
RialtoTargetClient::new( RialtoTargetClient::new(
params.target_client, target_client,
lane, lane,
lane_id, lane_id,
metrics_values, standalone_metrics.clone(),
params.source_to_target_headers_relay, params.source_to_target_headers_relay,
), ),
metrics_params, standalone_metrics.register_and_spawn(params.metrics_params)?,
futures::future::pending(), futures::future::pending(),
) )
.await .await
.map_err(Into::into) .map_err(Into::into)
} }
/// Add standalone metrics for the Millau -> Rialto messages loop. /// Create standalone metrics for the Millau -> Rialto messages loop.
pub(crate) fn add_standalone_metrics( pub(crate) fn standalone_metrics(
metrics_prefix: Option<String>,
metrics_params: MetricsParams,
source_client: Client<Millau>, source_client: Client<Millau>,
) -> anyhow::Result<(MetricsParams, StandaloneMessagesMetrics)> { target_client: Client<Rialto>,
substrate_relay_helper::messages_lane::add_standalone_metrics::<MillauMessagesToRialto>( ) -> anyhow::Result<StandaloneMessagesMetrics<Millau, Rialto>> {
metrics_prefix, substrate_relay_helper::messages_lane::standalone_metrics(
metrics_params,
source_client, source_client,
Some(crate::chains::MILLAU_ASSOCIATED_TOKEN_ID), target_client,
Some(crate::chains::RIALTO_ASSOCIATED_TOKEN_ID), Some(crate::chains::millau::ASSOCIATED_TOKEN_ID),
Some(( Some(crate::chains::rialto::ASSOCIATED_TOKEN_ID),
sp_core::storage::StorageKey( Some(crate::chains::rialto::millau_to_rialto_conversion_rate_params()),
millau_runtime::rialto_messages::RialtoToMillauConversionRate::key().to_vec(), Some(crate::chains::millau::rialto_to_millau_conversion_rate_params()),
),
millau_runtime::rialto_messages::INITIAL_RIALTO_TO_MILLAU_CONVERSION_RATE,
)),
) )
} }
+6 -21
View File
@@ -39,31 +39,16 @@ mod rococo;
mod westend; mod westend;
mod wococo; mod wococo;
// Millau/Rialto tokens have no any real value, so the conversion rate we use is always 1:1. But we use relay_utils::metrics::{MetricsParams, StandaloneMetric};
// want to test our code that is intended to work with real-value chains. So to keep it close to
// 1:1, we'll be treating Rialto as BTC and Millau as wBTC (only in relayer).
/// The identifier of token, which value is associated with Rialto token value by relayer.
pub(crate) const RIALTO_ASSOCIATED_TOKEN_ID: &str = polkadot::TOKEN_ID;
/// The identifier of token, which value is associated with Millau token value by relayer.
pub(crate) const MILLAU_ASSOCIATED_TOKEN_ID: &str = kusama::TOKEN_ID;
use relay_utils::metrics::MetricsParams;
pub(crate) fn add_polkadot_kusama_price_metrics<T: finality_relay::FinalitySyncPipeline>( pub(crate) fn add_polkadot_kusama_price_metrics<T: finality_relay::FinalitySyncPipeline>(
prefix: Option<String>,
params: MetricsParams, params: MetricsParams,
) -> anyhow::Result<MetricsParams> { ) -> anyhow::Result<MetricsParams> {
// Polkadot/Kusama prices are added as metrics here, because atm we don't have Polkadot <-> substrate_relay_helper::helpers::token_price_metric(polkadot::TOKEN_ID)?
// Kusama relays, but we want to test metrics/dashboards in advance .register_and_spawn(&params.registry)?;
Ok(relay_utils::relay_metrics(prefix, params) substrate_relay_helper::helpers::token_price_metric(kusama::TOKEN_ID)?
.standalone_metric(|registry, prefix| { .register_and_spawn(&params.registry)?;
substrate_relay_helper::helpers::token_price_metric(registry, prefix, "polkadot") Ok(params)
})?
.standalone_metric(|registry, prefix| {
substrate_relay_helper::helpers::token_price_metric(registry, prefix, "kusama")
})?
.into_params())
} }
#[cfg(test)] #[cfg(test)]
@@ -17,6 +17,8 @@
use codec::Decode; use codec::Decode;
use frame_support::weights::{DispatchClass, DispatchInfo, Pays, Weight}; use frame_support::weights::{DispatchClass, DispatchInfo, Pays, Weight};
use relay_polkadot_client::Polkadot; use relay_polkadot_client::Polkadot;
use sp_core::storage::StorageKey;
use sp_runtime::{FixedPointNumber, FixedU128};
use sp_version::RuntimeVersion; use sp_version::RuntimeVersion;
use crate::cli::{ use crate::cli::{
@@ -101,3 +103,14 @@ impl CliChain for Polkadot {
anyhow::bail!("Sending messages from Polkadot is not yet supported.") anyhow::bail!("Sending messages from Polkadot is not yet supported.")
} }
} }
/// Storage key and initial value of Kusama -> Polkadot conversion rate.
pub(crate) fn kusama_to_polkadot_conversion_rate_params() -> (StorageKey, FixedU128) {
(
bp_runtime::storage_parameter_key(
bp_polkadot::KUSAMA_TO_POLKADOT_CONVERSION_RATE_PARAMETER_NAME,
),
// starting relay before this parameter will be set to some value may cause troubles
FixedU128::from_inner(FixedU128::DIV),
)
}
@@ -64,10 +64,7 @@ impl SubstrateFinalitySyncPipeline for PolkadotFinalityToKusama {
type TargetChain = Kusama; type TargetChain = Kusama;
fn customize_metrics(params: MetricsParams) -> anyhow::Result<MetricsParams> { fn customize_metrics(params: MetricsParams) -> anyhow::Result<MetricsParams> {
crate::chains::add_polkadot_kusama_price_metrics::<Self::FinalitySyncPipeline>( crate::chains::add_polkadot_kusama_price_metrics::<Self::FinalitySyncPipeline>(params)
Some(finality_relay::metrics_prefix::<Self::FinalitySyncPipeline>()),
params,
)
} }
fn start_relay_guards(&self) { fn start_relay_guards(&self) {
@@ -32,8 +32,6 @@ use relay_polkadot_client::{
HeaderId as PolkadotHeaderId, Polkadot, SigningParams as PolkadotSigningParams, HeaderId as PolkadotHeaderId, Polkadot, SigningParams as PolkadotSigningParams,
}; };
use relay_substrate_client::{Chain, Client, TransactionSignScheme, UnsignedTransaction}; use relay_substrate_client::{Chain, Client, TransactionSignScheme, UnsignedTransaction};
use relay_utils::metrics::MetricsParams;
use sp_runtime::{FixedPointNumber, FixedU128};
use substrate_relay_helper::{ use substrate_relay_helper::{
messages_lane::{ messages_lane::{
select_delivery_transaction_limits, MessagesRelayParams, StandaloneMessagesMetrics, select_delivery_transaction_limits, MessagesRelayParams, StandaloneMessagesMetrics,
@@ -195,12 +193,13 @@ pub async fn run(
let lane_id = params.lane_id; let lane_id = params.lane_id;
let source_client = params.source_client; let source_client = params.source_client;
let target_client = params.target_client;
let lane = PolkadotMessagesToKusama { let lane = PolkadotMessagesToKusama {
message_lane: SubstrateMessageLaneToSubstrate { message_lane: SubstrateMessageLaneToSubstrate {
source_client: source_client.clone(), source_client: source_client.clone(),
source_sign: params.source_sign, source_sign: params.source_sign,
source_transactions_mortality: params.source_transactions_mortality, source_transactions_mortality: params.source_transactions_mortality,
target_client: params.target_client.clone(), target_client: target_client.clone(),
target_sign: params.target_sign, target_sign: params.target_sign,
target_transactions_mortality: params.target_transactions_mortality, target_transactions_mortality: params.target_transactions_mortality,
relayer_id_at_source: relayer_id_at_polkadot, relayer_id_at_source: relayer_id_at_polkadot,
@@ -239,13 +238,10 @@ pub async fn run(
stall_timeout, stall_timeout,
); );
let (metrics_params, metrics_values) = add_standalone_metrics( let standalone_metrics = params
Some(messages_relay::message_lane_loop::metrics_prefix::< .standalone_metrics
<PolkadotMessagesToKusama as SubstrateMessageLane>::MessageLane, .map(Ok)
>(&lane_id)), .unwrap_or_else(|| standalone_metrics(source_client.clone(), target_client.clone()))?;
params.metrics_params,
source_client.clone(),
)?;
messages_relay::message_lane_loop::run( messages_relay::message_lane_loop::run(
messages_relay::message_lane_loop::Params { messages_relay::message_lane_loop::Params {
lane: lane_id, lane: lane_id,
@@ -271,41 +267,31 @@ pub async fn run(
params.target_to_source_headers_relay, params.target_to_source_headers_relay,
), ),
KusamaTargetClient::new( KusamaTargetClient::new(
params.target_client, target_client,
lane, lane,
lane_id, lane_id,
metrics_values, standalone_metrics.clone(),
params.source_to_target_headers_relay, params.source_to_target_headers_relay,
), ),
metrics_params, standalone_metrics.register_and_spawn(params.metrics_params)?,
futures::future::pending(), futures::future::pending(),
) )
.await .await
.map_err(Into::into) .map_err(Into::into)
} }
/// Add standalone metrics for the Polkadot -> Kusama messages loop. /// Create standalone metrics for the Polkadot -> Kusama messages loop.
pub(crate) fn add_standalone_metrics( pub(crate) fn standalone_metrics(
metrics_prefix: Option<String>,
metrics_params: MetricsParams,
source_client: Client<Polkadot>, source_client: Client<Polkadot>,
) -> anyhow::Result<(MetricsParams, StandaloneMessagesMetrics)> { target_client: Client<Kusama>,
let kusama_to_polkadot_conversion_rate_key = bp_runtime::storage_parameter_key( ) -> anyhow::Result<StandaloneMessagesMetrics<Polkadot, Kusama>> {
bp_polkadot::KUSAMA_TO_POLKADOT_CONVERSION_RATE_PARAMETER_NAME, substrate_relay_helper::messages_lane::standalone_metrics(
)
.0;
substrate_relay_helper::messages_lane::add_standalone_metrics::<PolkadotMessagesToKusama>(
metrics_prefix,
metrics_params,
source_client, source_client,
Some(crate::chains::kusama::TOKEN_ID), target_client,
Some(crate::chains::polkadot::TOKEN_ID), Some(crate::chains::polkadot::TOKEN_ID),
Some(( Some(crate::chains::kusama::TOKEN_ID),
sp_core::storage::StorageKey(kusama_to_polkadot_conversion_rate_key), Some(crate::chains::kusama::polkadot_to_kusama_conversion_rate_params()),
// starting relay before this parameter will be set to some value may cause troubles Some(crate::chains::polkadot::kusama_to_polkadot_conversion_rate_params()),
FixedU128::from_inner(FixedU128::DIV),
)),
) )
} }
@@ -28,8 +28,17 @@ use bp_message_dispatch::{CallOrigin, MessagePayload};
use codec::Decode; use codec::Decode;
use frame_support::weights::{DispatchInfo, GetDispatchInfo, Weight}; use frame_support::weights::{DispatchInfo, GetDispatchInfo, Weight};
use relay_rialto_client::Rialto; use relay_rialto_client::Rialto;
use sp_core::storage::StorageKey;
use sp_runtime::FixedU128;
use sp_version::RuntimeVersion; use sp_version::RuntimeVersion;
// Millau/Rialto tokens have no any real value, so the conversion rate we use is always 1:1. But we
// want to test our code that is intended to work with real-value chains. So to keep it close to
// 1:1, we'll be treating Rialto as BTC and Millau as wBTC (only in relayer).
/// The identifier of token, which value is associated with Rialto token value by relayer.
pub(crate) const ASSOCIATED_TOKEN_ID: &str = crate::chains::polkadot::TOKEN_ID;
impl CliEncodeCall for Rialto { impl CliEncodeCall for Rialto {
fn max_extrinsic_size() -> u32 { fn max_extrinsic_size() -> u32 {
bp_rialto::max_extrinsic_size() bp_rialto::max_extrinsic_size()
@@ -122,3 +131,11 @@ impl CliChain for Rialto {
} }
} }
} }
/// Storage key and initial value of Millau -> Rialto conversion rate.
pub(crate) fn millau_to_rialto_conversion_rate_params() -> (StorageKey, FixedU128) {
(
StorageKey(rialto_runtime::millau_messages::MillauToRialtoConversionRate::key().to_vec()),
rialto_runtime::millau_messages::INITIAL_MILLAU_TO_RIALTO_CONVERSION_RATE,
)
}
@@ -33,7 +33,6 @@ use relay_rialto_client::{
HeaderId as RialtoHeaderId, Rialto, SigningParams as RialtoSigningParams, HeaderId as RialtoHeaderId, Rialto, SigningParams as RialtoSigningParams,
}; };
use relay_substrate_client::{Chain, Client, IndexOf, TransactionSignScheme, UnsignedTransaction}; use relay_substrate_client::{Chain, Client, IndexOf, TransactionSignScheme, UnsignedTransaction};
use relay_utils::metrics::MetricsParams;
use substrate_relay_helper::{ use substrate_relay_helper::{
messages_lane::{ messages_lane::{
select_delivery_transaction_limits, MessagesRelayParams, StandaloneMessagesMetrics, select_delivery_transaction_limits, MessagesRelayParams, StandaloneMessagesMetrics,
@@ -193,12 +192,13 @@ pub async fn run(
let lane_id = params.lane_id; let lane_id = params.lane_id;
let source_client = params.source_client; let source_client = params.source_client;
let target_client = params.target_client;
let lane = RialtoMessagesToMillau { let lane = RialtoMessagesToMillau {
message_lane: SubstrateMessageLaneToSubstrate { message_lane: SubstrateMessageLaneToSubstrate {
source_client: source_client.clone(), source_client: source_client.clone(),
source_sign: params.source_sign, source_sign: params.source_sign,
source_transactions_mortality: params.source_transactions_mortality, source_transactions_mortality: params.source_transactions_mortality,
target_client: params.target_client.clone(), target_client: target_client.clone(),
target_sign: params.target_sign, target_sign: params.target_sign,
target_transactions_mortality: params.target_transactions_mortality, target_transactions_mortality: params.target_transactions_mortality,
relayer_id_at_source: relayer_id_at_rialto, relayer_id_at_source: relayer_id_at_rialto,
@@ -233,13 +233,10 @@ pub async fn run(
stall_timeout, stall_timeout,
); );
let (metrics_params, metrics_values) = add_standalone_metrics( let standalone_metrics = params
Some(messages_relay::message_lane_loop::metrics_prefix::< .standalone_metrics
<RialtoMessagesToMillau as SubstrateMessageLane>::MessageLane, .map(Ok)
>(&lane_id)), .unwrap_or_else(|| standalone_metrics(source_client.clone(), target_client.clone()))?;
params.metrics_params,
source_client.clone(),
)?;
messages_relay::message_lane_loop::run( messages_relay::message_lane_loop::run(
messages_relay::message_lane_loop::Params { messages_relay::message_lane_loop::Params {
lane: lane_id, lane: lane_id,
@@ -265,37 +262,31 @@ pub async fn run(
params.target_to_source_headers_relay, params.target_to_source_headers_relay,
), ),
MillauTargetClient::new( MillauTargetClient::new(
params.target_client, target_client,
lane, lane,
lane_id, lane_id,
metrics_values, standalone_metrics.clone(),
params.source_to_target_headers_relay, params.source_to_target_headers_relay,
), ),
metrics_params, standalone_metrics.register_and_spawn(params.metrics_params)?,
futures::future::pending(), futures::future::pending(),
) )
.await .await
.map_err(Into::into) .map_err(Into::into)
} }
/// Add standalone metrics for the Rialto -> Millau messages loop. /// Create standalone metrics for the Rialto -> Millau messages loop.
pub(crate) fn add_standalone_metrics( pub(crate) fn standalone_metrics(
metrics_prefix: Option<String>,
metrics_params: MetricsParams,
source_client: Client<Rialto>, source_client: Client<Rialto>,
) -> anyhow::Result<(MetricsParams, StandaloneMessagesMetrics)> { target_client: Client<Millau>,
substrate_relay_helper::messages_lane::add_standalone_metrics::<RialtoMessagesToMillau>( ) -> anyhow::Result<StandaloneMessagesMetrics<Rialto, Millau>> {
metrics_prefix, substrate_relay_helper::messages_lane::standalone_metrics(
metrics_params,
source_client, source_client,
Some(crate::chains::RIALTO_ASSOCIATED_TOKEN_ID), target_client,
Some(crate::chains::MILLAU_ASSOCIATED_TOKEN_ID), Some(crate::chains::rialto::ASSOCIATED_TOKEN_ID),
Some(( Some(crate::chains::millau::ASSOCIATED_TOKEN_ID),
sp_core::storage::StorageKey( Some(crate::chains::millau::rialto_to_millau_conversion_rate_params()),
rialto_runtime::millau_messages::MillauToRialtoConversionRate::key().to_vec(), Some(crate::chains::rialto::millau_to_rialto_conversion_rate_params()),
),
rialto_runtime::millau_messages::INITIAL_MILLAU_TO_RIALTO_CONVERSION_RATE,
)),
) )
} }
@@ -59,10 +59,7 @@ impl SubstrateFinalitySyncPipeline for RococoFinalityToWococo {
type TargetChain = Wococo; type TargetChain = Wococo;
fn customize_metrics(params: MetricsParams) -> anyhow::Result<MetricsParams> { fn customize_metrics(params: MetricsParams) -> anyhow::Result<MetricsParams> {
crate::chains::add_polkadot_kusama_price_metrics::<Self::FinalitySyncPipeline>( crate::chains::add_polkadot_kusama_price_metrics::<Self::FinalitySyncPipeline>(params)
Some(finality_relay::metrics_prefix::<Self::FinalitySyncPipeline>()),
params,
)
} }
fn start_relay_guards(&self) { fn start_relay_guards(&self) {
@@ -29,7 +29,6 @@ use relay_rococo_client::{
HeaderId as RococoHeaderId, Rococo, SigningParams as RococoSigningParams, HeaderId as RococoHeaderId, Rococo, SigningParams as RococoSigningParams,
}; };
use relay_substrate_client::{Chain, Client, IndexOf, TransactionSignScheme, UnsignedTransaction}; use relay_substrate_client::{Chain, Client, IndexOf, TransactionSignScheme, UnsignedTransaction};
use relay_utils::metrics::MetricsParams;
use relay_wococo_client::{ use relay_wococo_client::{
HeaderId as WococoHeaderId, SigningParams as WococoSigningParams, Wococo, HeaderId as WococoHeaderId, SigningParams as WococoSigningParams, Wococo,
}; };
@@ -193,12 +192,13 @@ pub async fn run(
let lane_id = params.lane_id; let lane_id = params.lane_id;
let source_client = params.source_client; let source_client = params.source_client;
let target_client = params.target_client;
let lane = RococoMessagesToWococo { let lane = RococoMessagesToWococo {
message_lane: SubstrateMessageLaneToSubstrate { message_lane: SubstrateMessageLaneToSubstrate {
source_client: source_client.clone(), source_client: source_client.clone(),
source_sign: params.source_sign, source_sign: params.source_sign,
source_transactions_mortality: params.source_transactions_mortality, source_transactions_mortality: params.source_transactions_mortality,
target_client: params.target_client.clone(), target_client: target_client.clone(),
target_sign: params.target_sign, target_sign: params.target_sign,
target_transactions_mortality: params.target_transactions_mortality, target_transactions_mortality: params.target_transactions_mortality,
relayer_id_at_source: relayer_id_at_rococo, relayer_id_at_source: relayer_id_at_rococo,
@@ -237,13 +237,10 @@ pub async fn run(
stall_timeout, stall_timeout,
); );
let (metrics_params, metrics_values) = add_standalone_metrics( let standalone_metrics = params
Some(messages_relay::message_lane_loop::metrics_prefix::< .standalone_metrics
<RococoMessagesToWococo as SubstrateMessageLane>::MessageLane, .map(Ok)
>(&lane_id)), .unwrap_or_else(|| standalone_metrics(source_client.clone(), target_client.clone()))?;
params.metrics_params,
source_client.clone(),
)?;
messages_relay::message_lane_loop::run( messages_relay::message_lane_loop::run(
messages_relay::message_lane_loop::Params { messages_relay::message_lane_loop::Params {
lane: lane_id, lane: lane_id,
@@ -269,29 +266,28 @@ pub async fn run(
params.target_to_source_headers_relay, params.target_to_source_headers_relay,
), ),
WococoTargetClient::new( WococoTargetClient::new(
params.target_client, target_client,
lane, lane,
lane_id, lane_id,
metrics_values, standalone_metrics.clone(),
params.source_to_target_headers_relay, params.source_to_target_headers_relay,
), ),
metrics_params, standalone_metrics.register_and_spawn(params.metrics_params)?,
futures::future::pending(), futures::future::pending(),
) )
.await .await
.map_err(Into::into) .map_err(Into::into)
} }
/// Add standalone metrics for the Rococo -> Wococo messages loop. /// Create standalone metrics for the Rococo -> Wococo messages loop.
pub(crate) fn add_standalone_metrics( pub(crate) fn standalone_metrics(
metrics_prefix: Option<String>,
metrics_params: MetricsParams,
source_client: Client<Rococo>, source_client: Client<Rococo>,
) -> anyhow::Result<(MetricsParams, StandaloneMessagesMetrics)> { target_client: Client<Wococo>,
substrate_relay_helper::messages_lane::add_standalone_metrics::<RococoMessagesToWococo>( ) -> anyhow::Result<StandaloneMessagesMetrics<Rococo, Wococo>> {
metrics_prefix, substrate_relay_helper::messages_lane::standalone_metrics(
metrics_params,
source_client, source_client,
target_client,
None,
None, None,
None, None,
None, None,
@@ -57,10 +57,7 @@ impl SubstrateFinalitySyncPipeline for WestendFinalityToMillau {
type TargetChain = Millau; type TargetChain = Millau;
fn customize_metrics(params: MetricsParams) -> anyhow::Result<MetricsParams> { fn customize_metrics(params: MetricsParams) -> anyhow::Result<MetricsParams> {
crate::chains::add_polkadot_kusama_price_metrics::<Self::FinalitySyncPipeline>( crate::chains::add_polkadot_kusama_price_metrics::<Self::FinalitySyncPipeline>(params)
Some(finality_relay::metrics_prefix::<Self::FinalitySyncPipeline>()),
params,
)
} }
fn transactions_author(&self) -> bp_millau::AccountId { fn transactions_author(&self) -> bp_millau::AccountId {
@@ -64,10 +64,7 @@ impl SubstrateFinalitySyncPipeline for WococoFinalityToRococo {
type TargetChain = Rococo; type TargetChain = Rococo;
fn customize_metrics(params: MetricsParams) -> anyhow::Result<MetricsParams> { fn customize_metrics(params: MetricsParams) -> anyhow::Result<MetricsParams> {
crate::chains::add_polkadot_kusama_price_metrics::<Self::FinalitySyncPipeline>( crate::chains::add_polkadot_kusama_price_metrics::<Self::FinalitySyncPipeline>(params)
Some(finality_relay::metrics_prefix::<Self::FinalitySyncPipeline>()),
params,
)
} }
fn start_relay_guards(&self) { fn start_relay_guards(&self) {
@@ -29,7 +29,6 @@ use relay_rococo_client::{
HeaderId as RococoHeaderId, Rococo, SigningParams as RococoSigningParams, HeaderId as RococoHeaderId, Rococo, SigningParams as RococoSigningParams,
}; };
use relay_substrate_client::{Chain, Client, IndexOf, TransactionSignScheme, UnsignedTransaction}; use relay_substrate_client::{Chain, Client, IndexOf, TransactionSignScheme, UnsignedTransaction};
use relay_utils::metrics::MetricsParams;
use relay_wococo_client::{ use relay_wococo_client::{
HeaderId as WococoHeaderId, SigningParams as WococoSigningParams, Wococo, HeaderId as WococoHeaderId, SigningParams as WococoSigningParams, Wococo,
}; };
@@ -192,12 +191,13 @@ pub async fn run(
let lane_id = params.lane_id; let lane_id = params.lane_id;
let source_client = params.source_client; let source_client = params.source_client;
let target_client = params.target_client;
let lane = WococoMessagesToRococo { let lane = WococoMessagesToRococo {
message_lane: SubstrateMessageLaneToSubstrate { message_lane: SubstrateMessageLaneToSubstrate {
source_client: source_client.clone(), source_client: source_client.clone(),
source_sign: params.source_sign, source_sign: params.source_sign,
source_transactions_mortality: params.source_transactions_mortality, source_transactions_mortality: params.source_transactions_mortality,
target_client: params.target_client.clone(), target_client: target_client.clone(),
target_sign: params.target_sign, target_sign: params.target_sign,
target_transactions_mortality: params.target_transactions_mortality, target_transactions_mortality: params.target_transactions_mortality,
relayer_id_at_source: relayer_id_at_wococo, relayer_id_at_source: relayer_id_at_wococo,
@@ -236,13 +236,10 @@ pub async fn run(
stall_timeout, stall_timeout,
); );
let (metrics_params, metrics_values) = add_standalone_metrics( let standalone_metrics = params
Some(messages_relay::message_lane_loop::metrics_prefix::< .standalone_metrics
<WococoMessagesToRococo as SubstrateMessageLane>::MessageLane, .map(Ok)
>(&lane_id)), .unwrap_or_else(|| standalone_metrics(source_client.clone(), target_client.clone()))?;
params.metrics_params,
source_client.clone(),
)?;
messages_relay::message_lane_loop::run( messages_relay::message_lane_loop::run(
messages_relay::message_lane_loop::Params { messages_relay::message_lane_loop::Params {
lane: lane_id, lane: lane_id,
@@ -268,29 +265,28 @@ pub async fn run(
params.target_to_source_headers_relay, params.target_to_source_headers_relay,
), ),
RococoTargetClient::new( RococoTargetClient::new(
params.target_client, target_client,
lane, lane,
lane_id, lane_id,
metrics_values, standalone_metrics.clone(),
params.source_to_target_headers_relay, params.source_to_target_headers_relay,
), ),
metrics_params, standalone_metrics.register_and_spawn(params.metrics_params)?,
futures::future::pending(), futures::future::pending(),
) )
.await .await
.map_err(Into::into) .map_err(Into::into)
} }
/// Add standalone metrics for the Wococo -> Rococo messages loop. /// Create standalone metrics for the Wococo -> Rococo messages loop.
pub(crate) fn add_standalone_metrics( pub(crate) fn standalone_metrics(
metrics_prefix: Option<String>,
metrics_params: MetricsParams,
source_client: Client<Wococo>, source_client: Client<Wococo>,
) -> anyhow::Result<(MetricsParams, StandaloneMessagesMetrics)> { target_client: Client<Rococo>,
substrate_relay_helper::messages_lane::add_standalone_metrics::<WococoMessagesToRococo>( ) -> anyhow::Result<StandaloneMessagesMetrics<Wococo, Rococo>> {
metrics_prefix, substrate_relay_helper::messages_lane::standalone_metrics(
metrics_params,
source_client, source_client,
target_client,
None,
None, None,
None, None,
None, None,
@@ -17,6 +17,7 @@
use structopt::StructOpt; use structopt::StructOpt;
use strum::{EnumString, EnumVariantNames, VariantNames}; use strum::{EnumString, EnumVariantNames, VariantNames};
use relay_utils::metrics::{GlobalMetrics, StandaloneMetric};
use substrate_relay_helper::finality_pipeline::SubstrateFinalitySyncPipeline; use substrate_relay_helper::finality_pipeline::SubstrateFinalitySyncPipeline;
use crate::cli::{ use crate::cli::{
@@ -121,6 +122,8 @@ impl RelayHeaders {
let target_transactions_mortality = self.target_sign.target_transactions_mortality; let target_transactions_mortality = self.target_sign.target_transactions_mortality;
let target_sign = self.target_sign.to_keypair::<Target>()?; let target_sign = self.target_sign.to_keypair::<Target>()?;
let metrics_params = Finality::customize_metrics(self.prometheus_params.into())?; let metrics_params = Finality::customize_metrics(self.prometheus_params.into())?;
GlobalMetrics::new()?.register_and_spawn(&metrics_params.registry)?;
let finality = Finality::new(target_client.clone(), target_sign); let finality = Finality::new(target_client.clone(), target_sign);
finality.start_relay_guards(); finality.start_relay_guards();
@@ -34,8 +34,7 @@ use relay_substrate_client::{
use relay_utils::metrics::MetricsParams; use relay_utils::metrics::MetricsParams;
use sp_core::{Bytes, Pair}; use sp_core::{Bytes, Pair};
use substrate_relay_helper::{ use substrate_relay_helper::{
messages_lane::{MessagesRelayParams, SubstrateMessageLane}, messages_lane::MessagesRelayParams, on_demand_headers::OnDemandHeadersRelay,
on_demand_headers::OnDemandHeadersRelay,
}; };
use crate::{ use crate::{
@@ -129,11 +128,6 @@ macro_rules! select_bridge {
type RightToLeftFinality = type RightToLeftFinality =
crate::chains::rialto_headers_to_millau::RialtoFinalityToMillau; crate::chains::rialto_headers_to_millau::RialtoFinalityToMillau;
type LeftToRightMessages =
crate::chains::millau_messages_to_rialto::MillauMessagesToRialto;
type RightToLeftMessages =
crate::chains::rialto_messages_to_millau::RialtoMessagesToMillau;
type LeftAccountIdConverter = bp_millau::AccountIdConverter; type LeftAccountIdConverter = bp_millau::AccountIdConverter;
type RightAccountIdConverter = bp_rialto::AccountIdConverter; type RightAccountIdConverter = bp_rialto::AccountIdConverter;
@@ -144,12 +138,11 @@ macro_rules! select_bridge {
use crate::chains::{ use crate::chains::{
millau_messages_to_rialto::{ millau_messages_to_rialto::{
add_standalone_metrics as add_left_to_right_standalone_metrics, standalone_metrics as left_to_right_standalone_metrics,
run as left_to_right_messages, run as left_to_right_messages,
update_rialto_to_millau_conversion_rate as update_right_to_left_conversion_rate, update_rialto_to_millau_conversion_rate as update_right_to_left_conversion_rate,
}, },
rialto_messages_to_millau::{ rialto_messages_to_millau::{
add_standalone_metrics as add_right_to_left_standalone_metrics,
run as right_to_left_messages, run as right_to_left_messages,
update_millau_to_rialto_conversion_rate as update_left_to_right_conversion_rate, update_millau_to_rialto_conversion_rate as update_left_to_right_conversion_rate,
}, },
@@ -184,11 +177,6 @@ macro_rules! select_bridge {
type RightToLeftFinality = type RightToLeftFinality =
crate::chains::wococo_headers_to_rococo::WococoFinalityToRococo; crate::chains::wococo_headers_to_rococo::WococoFinalityToRococo;
type LeftToRightMessages =
crate::chains::rococo_messages_to_wococo::RococoMessagesToWococo;
type RightToLeftMessages =
crate::chains::wococo_messages_to_rococo::WococoMessagesToRococo;
type LeftAccountIdConverter = bp_rococo::AccountIdConverter; type LeftAccountIdConverter = bp_rococo::AccountIdConverter;
type RightAccountIdConverter = bp_wococo::AccountIdConverter; type RightAccountIdConverter = bp_wococo::AccountIdConverter;
@@ -199,11 +187,10 @@ macro_rules! select_bridge {
use crate::chains::{ use crate::chains::{
rococo_messages_to_wococo::{ rococo_messages_to_wococo::{
add_standalone_metrics as add_left_to_right_standalone_metrics, standalone_metrics as left_to_right_standalone_metrics,
run as left_to_right_messages, run as left_to_right_messages,
}, },
wococo_messages_to_rococo::{ wococo_messages_to_rococo::{
add_standalone_metrics as add_right_to_left_standalone_metrics,
run as right_to_left_messages, run as right_to_left_messages,
}, },
}; };
@@ -253,11 +240,6 @@ macro_rules! select_bridge {
type RightToLeftFinality = type RightToLeftFinality =
crate::chains::polkadot_headers_to_kusama::PolkadotFinalityToKusama; crate::chains::polkadot_headers_to_kusama::PolkadotFinalityToKusama;
type LeftToRightMessages =
crate::chains::kusama_messages_to_polkadot::KusamaMessagesToPolkadot;
type RightToLeftMessages =
crate::chains::polkadot_messages_to_kusama::PolkadotMessagesToKusama;
type LeftAccountIdConverter = bp_kusama::AccountIdConverter; type LeftAccountIdConverter = bp_kusama::AccountIdConverter;
type RightAccountIdConverter = bp_polkadot::AccountIdConverter; type RightAccountIdConverter = bp_polkadot::AccountIdConverter;
@@ -268,12 +250,11 @@ macro_rules! select_bridge {
use crate::chains::{ use crate::chains::{
kusama_messages_to_polkadot::{ kusama_messages_to_polkadot::{
add_standalone_metrics as add_left_to_right_standalone_metrics, standalone_metrics as left_to_right_standalone_metrics,
run as left_to_right_messages, run as left_to_right_messages,
update_polkadot_to_kusama_conversion_rate as update_right_to_left_conversion_rate, update_polkadot_to_kusama_conversion_rate as update_right_to_left_conversion_rate,
}, },
polkadot_messages_to_kusama::{ polkadot_messages_to_kusama::{
add_standalone_metrics as add_right_to_left_standalone_metrics,
run as right_to_left_messages, run as right_to_left_messages,
update_kusama_to_polkadot_conversion_rate as update_left_to_right_conversion_rate, update_kusama_to_polkadot_conversion_rate as update_left_to_right_conversion_rate,
}, },
@@ -378,31 +359,39 @@ impl RelayHeadersAndMessages {
let relayer_mode = params.shared.relayer_mode.into(); let relayer_mode = params.shared.relayer_mode.into();
let relay_strategy = MixStrategy::new(relayer_mode); let relay_strategy = MixStrategy::new(relayer_mode);
const METRIC_IS_SOME_PROOF: &str = // create metrics registry and register standalone metrics
"it is `None` when metric has been already registered; \
this is the command entrypoint, so nothing has been registered yet; \
qed";
let metrics_params: MetricsParams = params.shared.prometheus_params.into(); let metrics_params: MetricsParams = params.shared.prometheus_params.into();
let metrics_params = relay_utils::relay_metrics(None, metrics_params).into_params(); let metrics_params = relay_utils::relay_metrics(metrics_params).into_params();
let (metrics_params, left_to_right_metrics) = let left_to_right_metrics =
add_left_to_right_standalone_metrics(None, metrics_params, left_client.clone())?; left_to_right_standalone_metrics(left_client.clone(), right_client.clone())?;
let (metrics_params, right_to_left_metrics) = let right_to_left_metrics = left_to_right_metrics.clone().reverse();
add_right_to_left_standalone_metrics(None, metrics_params, right_client.clone())?;
// start conversion rate update loops for left/right chains
if let Some(left_messages_pallet_owner) = left_messages_pallet_owner { if let Some(left_messages_pallet_owner) = left_messages_pallet_owner {
let left_client = left_client.clone(); let left_client = left_client.clone();
let format_err = || {
anyhow::format_err!(
"Cannon run conversion rate updater: {} -> {}",
Right::NAME,
Left::NAME
)
};
substrate_relay_helper::conversion_rate_update::run_conversion_rate_update_loop( substrate_relay_helper::conversion_rate_update::run_conversion_rate_update_loop(
left_to_right_metrics left_to_right_metrics
.target_to_source_conversion_rate .target_to_source_conversion_rate
.expect(METRIC_IS_SOME_PROOF), .as_ref()
.ok_or_else(format_err)?
.shared_value_ref(),
left_to_right_metrics left_to_right_metrics
.target_to_base_conversion_rate .target_to_base_conversion_rate
.clone() .as_ref()
.expect(METRIC_IS_SOME_PROOF), .ok_or_else(format_err)?
.shared_value_ref(),
left_to_right_metrics left_to_right_metrics
.source_to_base_conversion_rate .source_to_base_conversion_rate
.clone() .as_ref()
.expect(METRIC_IS_SOME_PROOF), .ok_or_else(format_err)?
.shared_value_ref(),
CONVERSION_RATE_ALLOWED_DIFFERENCE_RATIO, CONVERSION_RATE_ALLOWED_DIFFERENCE_RATIO,
move |new_rate| { move |new_rate| {
log::info!( log::info!(
@@ -423,16 +412,29 @@ impl RelayHeadersAndMessages {
} }
if let Some(right_messages_pallet_owner) = right_messages_pallet_owner { if let Some(right_messages_pallet_owner) = right_messages_pallet_owner {
let right_client = right_client.clone(); let right_client = right_client.clone();
let format_err = || {
anyhow::format_err!(
"Cannon run conversion rate updater: {} -> {}",
Left::NAME,
Right::NAME
)
};
substrate_relay_helper::conversion_rate_update::run_conversion_rate_update_loop( substrate_relay_helper::conversion_rate_update::run_conversion_rate_update_loop(
right_to_left_metrics right_to_left_metrics
.target_to_source_conversion_rate .target_to_source_conversion_rate
.expect(METRIC_IS_SOME_PROOF), .as_ref()
.ok_or_else(format_err)?
.shared_value_ref(),
left_to_right_metrics left_to_right_metrics
.source_to_base_conversion_rate .source_to_base_conversion_rate
.expect(METRIC_IS_SOME_PROOF), .as_ref()
.ok_or_else(format_err)?
.shared_value_ref(),
left_to_right_metrics left_to_right_metrics
.target_to_base_conversion_rate .target_to_base_conversion_rate
.expect(METRIC_IS_SOME_PROOF), .as_ref()
.ok_or_else(format_err)?
.shared_value_ref(),
CONVERSION_RATE_ALLOWED_DIFFERENCE_RATIO, CONVERSION_RATE_ALLOWED_DIFFERENCE_RATIO,
move |new_rate| { move |new_rate| {
log::info!( log::info!(
@@ -452,6 +454,7 @@ impl RelayHeadersAndMessages {
); );
} }
// optionally, create relayers fund account
if params.shared.create_relayers_fund_accounts { if params.shared.create_relayers_fund_accounts {
let relayer_fund_acount_id = pallet_bridge_messages::relayer_fund_account_id::< let relayer_fund_acount_id = pallet_bridge_messages::relayer_fund_account_id::<
AccountIdOf<Left>, AccountIdOf<Left>,
@@ -490,6 +493,7 @@ impl RelayHeadersAndMessages {
} }
} }
// start on-demand header relays
let left_to_right_on_demand_headers = OnDemandHeadersRelay::new( let left_to_right_on_demand_headers = OnDemandHeadersRelay::new(
left_client.clone(), left_client.clone(),
right_client.clone(), right_client.clone(),
@@ -521,11 +525,8 @@ impl RelayHeadersAndMessages {
source_to_target_headers_relay: Some(left_to_right_on_demand_headers.clone()), source_to_target_headers_relay: Some(left_to_right_on_demand_headers.clone()),
target_to_source_headers_relay: Some(right_to_left_on_demand_headers.clone()), target_to_source_headers_relay: Some(right_to_left_on_demand_headers.clone()),
lane_id: lane, lane_id: lane,
metrics_params: metrics_params.clone().disable().metrics_prefix( metrics_params: metrics_params.clone().disable(),
messages_relay::message_lane_loop::metrics_prefix::< standalone_metrics: Some(left_to_right_metrics.clone()),
<LeftToRightMessages as SubstrateMessageLane>::MessageLane,
>(&lane),
),
relay_strategy: relay_strategy.clone(), relay_strategy: relay_strategy.clone(),
}) })
.map_err(|e| anyhow::format_err!("{}", e)) .map_err(|e| anyhow::format_err!("{}", e))
@@ -540,11 +541,8 @@ impl RelayHeadersAndMessages {
source_to_target_headers_relay: Some(right_to_left_on_demand_headers.clone()), source_to_target_headers_relay: Some(right_to_left_on_demand_headers.clone()),
target_to_source_headers_relay: Some(left_to_right_on_demand_headers.clone()), target_to_source_headers_relay: Some(left_to_right_on_demand_headers.clone()),
lane_id: lane, lane_id: lane,
metrics_params: metrics_params.clone().disable().metrics_prefix( metrics_params: metrics_params.clone().disable(),
messages_relay::message_lane_loop::metrics_prefix::< standalone_metrics: Some(right_to_left_metrics.clone()),
<RightToLeftMessages as SubstrateMessageLane>::MessageLane,
>(&lane),
),
relay_strategy: relay_strategy.clone(), relay_strategy: relay_strategy.clone(),
}) })
.map_err(|e| anyhow::format_err!("{}", e)) .map_err(|e| anyhow::format_err!("{}", e))
@@ -554,7 +552,7 @@ impl RelayHeadersAndMessages {
message_relays.push(right_to_left_messages); message_relays.push(right_to_left_messages);
} }
relay_utils::relay_metrics(None, metrics_params) relay_utils::relay_metrics(metrics_params)
.expose() .expose()
.await .await
.map_err(|e| anyhow::format_err!("{}", e))?; .map_err(|e| anyhow::format_err!("{}", e))?;
@@ -95,6 +95,7 @@ impl RelayMessages {
target_to_source_headers_relay: None, target_to_source_headers_relay: None,
lane_id: self.lane.into(), lane_id: self.lane.into(),
metrics_params: self.prometheus_params.into(), metrics_params: self.prometheus_params.into(),
standalone_metrics: None,
relay_strategy, relay_strategy,
}) })
.await .await
@@ -20,7 +20,8 @@ use async_std::sync::{Arc, RwLock};
use async_trait::async_trait; use async_trait::async_trait;
use codec::Decode; use codec::Decode;
use relay_utils::metrics::{ use relay_utils::metrics::{
metric_name, register, F64SharedRef, Gauge, PrometheusError, Registry, StandaloneMetrics, F64, metric_name, register, F64SharedRef, Gauge, Metric, PrometheusError, Registry,
StandaloneMetric, F64,
}; };
use sp_core::storage::StorageKey; use sp_core::storage::StorageKey;
use sp_runtime::{traits::UniqueSaturatedInto, FixedPointNumber}; use sp_runtime::{traits::UniqueSaturatedInto, FixedPointNumber};
@@ -42,8 +43,6 @@ pub struct FloatStorageValueMetric<C: Chain, T: Clone> {
impl<C: Chain, T: Decode + FixedPointNumber> FloatStorageValueMetric<C, T> { impl<C: Chain, T: Decode + FixedPointNumber> FloatStorageValueMetric<C, T> {
/// Create new metric. /// Create new metric.
pub fn new( pub fn new(
registry: &Registry,
prefix: Option<&str>,
client: Client<C>, client: Client<C>,
storage_key: StorageKey, storage_key: StorageKey,
maybe_default_value: Option<T>, maybe_default_value: Option<T>,
@@ -55,7 +54,7 @@ impl<C: Chain, T: Decode + FixedPointNumber> FloatStorageValueMetric<C, T> {
client, client,
storage_key, storage_key,
maybe_default_value, maybe_default_value,
metric: register(Gauge::new(metric_name(prefix, &name), help)?, registry)?, metric: Gauge::new(metric_name(None, &name), help)?,
shared_value_ref, shared_value_ref,
}) })
} }
@@ -66,8 +65,17 @@ impl<C: Chain, T: Decode + FixedPointNumber> FloatStorageValueMetric<C, T> {
} }
} }
impl<C: Chain, T> Metric for FloatStorageValueMetric<C, T>
where
T: 'static + Decode + Send + Sync + FixedPointNumber,
{
fn register(&self, registry: &Registry) -> Result<(), PrometheusError> {
register(self.metric.clone(), registry).map(drop)
}
}
#[async_trait] #[async_trait]
impl<C: Chain, T> StandaloneMetrics for FloatStorageValueMetric<C, T> impl<C: Chain, T> StandaloneMetric for FloatStorageValueMetric<C, T>
where where
T: 'static + Decode + Send + Sync + FixedPointNumber, T: 'static + Decode + Send + Sync + FixedPointNumber,
{ {
@@ -18,7 +18,7 @@ use crate::{chain::Chain, client::Client, error::Error};
use async_trait::async_trait; use async_trait::async_trait;
use relay_utils::metrics::{ use relay_utils::metrics::{
metric_name, register, Gauge, PrometheusError, Registry, StandaloneMetrics, U64, metric_name, register, Gauge, Metric, PrometheusError, Registry, StandaloneMetric, U64,
}; };
use sp_core::storage::StorageKey; use sp_core::storage::StorageKey;
use sp_runtime::traits::Header as HeaderT; use sp_runtime::traits::Header as HeaderT;
@@ -46,16 +46,10 @@ impl<C: Chain> Clone for StorageProofOverheadMetric<C> {
impl<C: Chain> StorageProofOverheadMetric<C> { impl<C: Chain> StorageProofOverheadMetric<C> {
/// Create new metric instance with given name and help. /// Create new metric instance with given name and help.
pub fn new( pub fn new(client: Client<C>, name: String, help: String) -> Result<Self, PrometheusError> {
registry: &Registry,
prefix: Option<&str>,
client: Client<C>,
name: String,
help: String,
) -> Result<Self, PrometheusError> {
Ok(StorageProofOverheadMetric { Ok(StorageProofOverheadMetric {
client, client,
metric: register(Gauge::new(metric_name(prefix, &name), help)?, registry)?, metric: Gauge::new(metric_name(None, &name), help)?,
}) })
} }
@@ -84,8 +78,14 @@ impl<C: Chain> StorageProofOverheadMetric<C> {
} }
} }
impl<C: Chain> Metric for StorageProofOverheadMetric<C> {
fn register(&self, registry: &Registry) -> Result<(), PrometheusError> {
register(self.metric.clone(), registry).map(drop)
}
}
#[async_trait] #[async_trait]
impl<C: Chain> StandaloneMetrics for StorageProofOverheadMetric<C> { impl<C: Chain> StandaloneMetric for StorageProofOverheadMetric<C> {
fn update_interval(&self) -> Duration { fn update_interval(&self) -> Duration {
C::AVERAGE_BLOCK_INTERVAL * UPDATE_INTERVAL_IN_BLOCKS C::AVERAGE_BLOCK_INTERVAL * UPDATE_INTERVAL_IN_BLOCKS
} }
+4 -6
View File
@@ -28,9 +28,8 @@ use backoff::backoff::Backoff;
use futures::{select, Future, FutureExt, Stream, StreamExt}; use futures::{select, Future, FutureExt, Stream, StreamExt};
use num_traits::{One, Saturating}; use num_traits::{One, Saturating};
use relay_utils::{ use relay_utils::{
metrics::{GlobalMetrics, MetricsParams}, metrics::MetricsParams, relay_loop::Client as RelayClient, retry_backoff, FailedClient,
relay_loop::Client as RelayClient, MaybeConnectionError,
retry_backoff, FailedClient, MaybeConnectionError,
}; };
use std::{ use std::{
pin::Pin, pin::Pin,
@@ -114,9 +113,8 @@ pub async fn run<P: FinalitySyncPipeline>(
) -> Result<(), relay_utils::Error> { ) -> Result<(), relay_utils::Error> {
let exit_signal = exit_signal.shared(); let exit_signal = exit_signal.shared();
relay_utils::relay_loop(source_client, target_client) relay_utils::relay_loop(source_client, target_client)
.with_metrics(Some(metrics_prefix::<P>()), metrics_params) .with_metrics(metrics_params)
.loop_metric(SyncLoopMetrics::new)? .loop_metric(SyncLoopMetrics::new(Some(&metrics_prefix::<P>()))?)?
.standalone_metric(GlobalMetrics::new)?
.expose() .expose()
.await? .await?
.run(metrics_prefix::<P>(), move |source_client, target_client, metrics| { .run(metrics_prefix::<P>(), move |source_client, target_client, metrics| {
@@ -16,7 +16,9 @@
//! Metrics for headers synchronization relay loop. //! Metrics for headers synchronization relay loop.
use relay_utils::metrics::{metric_name, register, GaugeVec, Opts, PrometheusError, Registry, U64}; use relay_utils::metrics::{
metric_name, register, GaugeVec, Metric, Opts, PrometheusError, Registry, U64,
};
/// Headers sync metrics. /// Headers sync metrics.
#[derive(Clone)] #[derive(Clone)]
@@ -27,23 +29,18 @@ pub struct SyncLoopMetrics {
impl SyncLoopMetrics { impl SyncLoopMetrics {
/// Create and register headers loop metrics. /// Create and register headers loop metrics.
pub fn new(registry: &Registry, prefix: Option<&str>) -> Result<Self, PrometheusError> { pub fn new(prefix: Option<&str>) -> Result<Self, PrometheusError> {
Ok(SyncLoopMetrics { Ok(SyncLoopMetrics {
best_block_numbers: register( best_block_numbers: GaugeVec::new(
GaugeVec::new( Opts::new(
Opts::new( metric_name(prefix, "best_block_numbers"),
metric_name(prefix, "best_block_numbers"), "Best block numbers on source and target nodes",
"Best block numbers on source and target nodes", ),
), &["node"],
&["node"],
)?,
registry,
)?, )?,
}) })
} }
}
impl SyncLoopMetrics {
/// Update best block number at source. /// Update best block number at source.
pub fn update_best_block_at_source<Number: Into<u64>>(&self, source_best_number: Number) { pub fn update_best_block_at_source<Number: Into<u64>>(&self, source_best_number: Number) {
self.best_block_numbers self.best_block_numbers
@@ -58,3 +55,10 @@ impl SyncLoopMetrics {
.set(target_best_number.into()); .set(target_best_number.into());
} }
} }
impl Metric for SyncLoopMetrics {
fn register(&self, registry: &Registry) -> Result<(), PrometheusError> {
register(self.best_block_numbers.clone(), registry)?;
Ok(())
}
}
@@ -16,17 +16,11 @@
//! Substrate relay helpers //! Substrate relay helpers
use relay_utils::metrics::{FloatJsonValueMetric, PrometheusError, Registry}; use relay_utils::metrics::{FloatJsonValueMetric, PrometheusError};
/// Creates standalone token price metric. /// Creates standalone token price metric.
pub fn token_price_metric( pub fn token_price_metric(token_id: &str) -> Result<FloatJsonValueMetric, PrometheusError> {
registry: &Registry,
prefix: Option<&str>,
token_id: &str,
) -> Result<FloatJsonValueMetric, PrometheusError> {
FloatJsonValueMetric::new( FloatJsonValueMetric::new(
registry,
prefix,
format!("https://api.coingecko.com/api/v3/simple/price?ids={}&vs_currencies=btc", token_id), format!("https://api.coingecko.com/api/v3/simple/price?ids={}&vs_currencies=btc", token_id),
format!("$.{}.btc", token_id), format!("$.{}.btc", token_id),
format!("{}_to_base_conversion_rate", token_id.replace("-", "_")), format!("{}_to_base_conversion_rate", token_id.replace("-", "_")),
@@ -34,7 +34,9 @@ use relay_substrate_client::{
BlockNumberOf, Chain, Client, HashOf, BlockNumberOf, Chain, Client, HashOf,
}; };
use relay_utils::{ use relay_utils::{
metrics::{F64SharedRef, MetricsParams}, metrics::{
FloatJsonValueMetric, GlobalMetrics, MetricsParams, PrometheusError, StandaloneMetric,
},
BlockNumberBase, BlockNumberBase,
}; };
use sp_core::{storage::StorageKey, Bytes}; use sp_core::{storage::StorageKey, Bytes};
@@ -63,6 +65,8 @@ pub struct MessagesRelayParams<SC: Chain, SS, TC: Chain, TS, Strategy: RelayStra
pub lane_id: LaneId, pub lane_id: LaneId,
/// Metrics parameters. /// Metrics parameters.
pub metrics_params: MetricsParams, pub metrics_params: MetricsParams,
/// Pre-registered standalone metrics.
pub standalone_metrics: Option<StandaloneMessagesMetrics<SC, TC>>,
/// Relay strategy /// Relay strategy
pub relay_strategy: Strategy, pub relay_strategy: Strategy,
} }
@@ -241,110 +245,155 @@ pub fn select_delivery_transaction_limits<W: pallet_bridge_messages::WeightInfoE
(max_number_of_messages, weight_for_messages_dispatch) (max_number_of_messages, weight_for_messages_dispatch)
} }
/// Shared references to the values of standalone metrics of the message lane relay loop. /// Shared references to the standalone metrics of the message lane relay loop.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct StandaloneMessagesMetrics { pub struct StandaloneMessagesMetrics<SC: Chain, TC: Chain> {
/// Shared reference to the actual target -> <base> chain token conversion rate. /// Global metrics.
pub target_to_base_conversion_rate: Option<F64SharedRef>, pub global: GlobalMetrics,
/// Shared reference to the actual source -> <base> chain token conversion rate. /// Storage chain proof overhead metric.
pub source_to_base_conversion_rate: Option<F64SharedRef>, pub source_storage_proof_overhead: StorageProofOverheadMetric<SC>,
/// Shared reference to the stored (in the source chain runtime storage) target -> source chain /// Target chain proof overhead metric.
/// conversion rate. pub target_storage_proof_overhead: StorageProofOverheadMetric<TC>,
pub target_to_source_conversion_rate: Option<F64SharedRef>, /// Source tokens to base conversion rate metric.
pub source_to_base_conversion_rate: Option<FloatJsonValueMetric>,
/// Target tokens to base conversion rate metric.
pub target_to_base_conversion_rate: Option<FloatJsonValueMetric>,
/// Source tokens to target tokens conversion rate metric. This rate is stored by the target
/// chain.
pub source_to_target_conversion_rate:
Option<FloatStorageValueMetric<TC, sp_runtime::FixedU128>>,
/// Target tokens to source tokens conversion rate metric. This rate is stored by the source
/// chain.
pub target_to_source_conversion_rate:
Option<FloatStorageValueMetric<SC, sp_runtime::FixedU128>>,
} }
impl StandaloneMessagesMetrics { impl<SC: Chain, TC: Chain> StandaloneMessagesMetrics<SC, TC> {
/// Swap source and target sides.
pub fn reverse(self) -> StandaloneMessagesMetrics<TC, SC> {
StandaloneMessagesMetrics {
global: self.global,
source_storage_proof_overhead: self.target_storage_proof_overhead,
target_storage_proof_overhead: self.source_storage_proof_overhead,
source_to_base_conversion_rate: self.target_to_base_conversion_rate,
target_to_base_conversion_rate: self.source_to_base_conversion_rate,
source_to_target_conversion_rate: self.target_to_source_conversion_rate,
target_to_source_conversion_rate: self.source_to_target_conversion_rate,
}
}
/// Register all metrics in the registry.
pub fn register_and_spawn(
self,
metrics: MetricsParams,
) -> Result<MetricsParams, PrometheusError> {
self.global.register_and_spawn(&metrics.registry)?;
self.source_storage_proof_overhead.register_and_spawn(&metrics.registry)?;
self.target_storage_proof_overhead.register_and_spawn(&metrics.registry)?;
if let Some(m) = self.source_to_base_conversion_rate {
m.register_and_spawn(&metrics.registry)?;
}
if let Some(m) = self.target_to_base_conversion_rate {
m.register_and_spawn(&metrics.registry)?;
}
if let Some(m) = self.target_to_source_conversion_rate {
m.register_and_spawn(&metrics.registry)?;
}
Ok(metrics)
}
/// Return conversion rate from target to source tokens. /// Return conversion rate from target to source tokens.
pub async fn target_to_source_conversion_rate(&self) -> Option<f64> { pub async fn target_to_source_conversion_rate(&self) -> Option<f64> {
let target_to_base_conversion_rate = Self::compute_target_to_source_conversion_rate(
(*self.target_to_base_conversion_rate.as_ref()?.read().await)?; *self.target_to_base_conversion_rate.as_ref()?.shared_value_ref().read().await,
let source_to_base_conversion_rate = *self.source_to_base_conversion_rate.as_ref()?.shared_value_ref().read().await,
(*self.source_to_base_conversion_rate.as_ref()?.read().await)?; )
Some(source_to_base_conversion_rate / target_to_base_conversion_rate) }
/// Return conversion rate from target to source tokens, given conversion rates from
/// target/source tokens to some base token.
fn compute_target_to_source_conversion_rate(
target_to_base_conversion_rate: Option<f64>,
source_to_base_conversion_rate: Option<f64>,
) -> Option<f64> {
Some(source_to_base_conversion_rate? / target_to_base_conversion_rate?)
} }
} }
/// Add general standalone metrics for the message lane relay loop. /// Create standalone metrics for the message lane relay loop.
pub fn add_standalone_metrics<P: SubstrateMessageLane>( ///
metrics_prefix: Option<String>, /// All metrics returned by this function are exposed by loops that are serving given lane (`P`)
metrics_params: MetricsParams, /// and by loops that are serving reverse lane (`P` with swapped `TargetChain` and `SourceChain`).
source_client: Client<P::SourceChain>, pub fn standalone_metrics<SC: Chain, TC: Chain>(
source_client: Client<SC>,
target_client: Client<TC>,
source_chain_token_id: Option<&str>, source_chain_token_id: Option<&str>,
target_chain_token_id: Option<&str>, target_chain_token_id: Option<&str>,
source_to_target_conversion_rate_params: Option<(StorageKey, FixedU128)>,
target_to_source_conversion_rate_params: Option<(StorageKey, FixedU128)>, target_to_source_conversion_rate_params: Option<(StorageKey, FixedU128)>,
) -> anyhow::Result<(MetricsParams, StandaloneMessagesMetrics)> { ) -> anyhow::Result<StandaloneMessagesMetrics<SC, TC>> {
let mut target_to_source_conversion_rate = None; Ok(StandaloneMessagesMetrics {
let mut source_to_base_conversion_rate = None; global: GlobalMetrics::new()?,
let mut target_to_base_conversion_rate = None; source_storage_proof_overhead: StorageProofOverheadMetric::new(
let mut metrics_params = relay_utils::relay_metrics(metrics_prefix, metrics_params) source_client.clone(),
.standalone_metric(|registry, prefix| { format!("{}_storage_proof_overhead", SC::NAME.to_lowercase()),
StorageProofOverheadMetric::new( format!("{} storage proof overhead", SC::NAME),
registry, )?,
prefix, target_storage_proof_overhead: StorageProofOverheadMetric::new(
source_client.clone(), target_client.clone(),
format!("{}_storage_proof_overhead", P::SourceChain::NAME.to_lowercase()), format!("{}_storage_proof_overhead", TC::NAME.to_lowercase()),
format!("{} storage proof overhead", P::SourceChain::NAME), format!("{} storage proof overhead", TC::NAME),
) )?,
})?; source_to_base_conversion_rate: source_chain_token_id
if let Some(( .map(|source_chain_token_id| {
target_to_source_conversion_rate_storage_key, crate::helpers::token_price_metric(source_chain_token_id).map(Some)
initial_target_to_source_conversion_rate, })
)) = target_to_source_conversion_rate_params .unwrap_or(Ok(None))?,
{ target_to_base_conversion_rate: target_chain_token_id
metrics_params = metrics_params.standalone_metric(|registry, prefix| { .map(|target_chain_token_id| {
let metric = FloatStorageValueMetric::<_, sp_runtime::FixedU128>::new( crate::helpers::token_price_metric(target_chain_token_id).map(Some)
registry, })
prefix, .unwrap_or(Ok(None))?,
source_client, source_to_target_conversion_rate: source_to_target_conversion_rate_params
target_to_source_conversion_rate_storage_key, .map(|(key, rate)| {
Some(initial_target_to_source_conversion_rate), FloatStorageValueMetric::<_, sp_runtime::FixedU128>::new(
format!( target_client,
"{}_{}_to_{}_conversion_rate", key,
P::SourceChain::NAME, Some(rate),
P::TargetChain::NAME, format!("{}_{}_to_{}_conversion_rate", TC::NAME, SC::NAME, TC::NAME),
P::SourceChain::NAME format!(
), "{} to {} tokens conversion rate (used by {})",
format!( SC::NAME,
"{} to {} tokens conversion rate (used by {})", TC::NAME,
P::TargetChain::NAME, TC::NAME
P::SourceChain::NAME, ),
P::SourceChain::NAME )
), .map(Some)
)?; })
target_to_source_conversion_rate = Some(metric.shared_value_ref()); .unwrap_or(Ok(None))?,
Ok(metric) target_to_source_conversion_rate: target_to_source_conversion_rate_params
})?; .map(|(key, rate)| {
} FloatStorageValueMetric::<_, sp_runtime::FixedU128>::new(
if let Some(source_chain_token_id) = source_chain_token_id { source_client,
metrics_params = metrics_params.standalone_metric(|registry, prefix| { key,
let metric = Some(rate),
crate::helpers::token_price_metric(registry, prefix, source_chain_token_id)?; format!("{}_{}_to_{}_conversion_rate", SC::NAME, TC::NAME, SC::NAME),
source_to_base_conversion_rate = Some(metric.shared_value_ref()); format!(
Ok(metric) "{} to {} tokens conversion rate (used by {})",
})?; TC::NAME,
} SC::NAME,
if let Some(target_chain_token_id) = target_chain_token_id { SC::NAME
metrics_params = metrics_params.standalone_metric(|registry, prefix| { ),
let metric = )
crate::helpers::token_price_metric(registry, prefix, target_chain_token_id)?; .map(Some)
target_to_base_conversion_rate = Some(metric.shared_value_ref()); })
Ok(metric) .unwrap_or(Ok(None))?,
})?; })
}
Ok((
metrics_params.into_params(),
StandaloneMessagesMetrics {
target_to_base_conversion_rate,
source_to_base_conversion_rate,
target_to_source_conversion_rate,
},
))
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use async_std::sync::{Arc, RwLock};
type RialtoToMillauMessagesWeights = type RialtoToMillauMessagesWeights =
pallet_bridge_messages::weights::RialtoWeight<rialto_runtime::Runtime>; pallet_bridge_messages::weights::RialtoWeight<rialto_runtime::Runtime>;
@@ -369,12 +418,9 @@ mod tests {
#[async_std::test] #[async_std::test]
async fn target_to_source_conversion_rate_works() { async fn target_to_source_conversion_rate_works() {
let metrics = StandaloneMessagesMetrics { assert_eq!(
target_to_base_conversion_rate: Some(Arc::new(RwLock::new(Some(183.15)))), StandaloneMessagesMetrics::<relay_rococo_client::Rococo, relay_wococo_client::Wococo>::compute_target_to_source_conversion_rate(Some(183.15), Some(12.32)),
source_to_base_conversion_rate: Some(Arc::new(RwLock::new(Some(12.32)))), Some(12.32 / 183.15),
target_to_source_conversion_rate: None, // we don't care );
};
assert_eq!(metrics.target_to_source_conversion_rate().await, Some(12.32 / 183.15),);
} }
} }
@@ -55,7 +55,7 @@ pub struct SubstrateMessagesTarget<P: SubstrateMessageLane> {
client: Client<P::TargetChain>, client: Client<P::TargetChain>,
lane: P, lane: P,
lane_id: LaneId, lane_id: LaneId,
metric_values: StandaloneMessagesMetrics, metric_values: StandaloneMessagesMetrics<P::SourceChain, P::TargetChain>,
source_to_target_headers_relay: Option<OnDemandHeadersRelay<P::SourceChain>>, source_to_target_headers_relay: Option<OnDemandHeadersRelay<P::SourceChain>>,
} }
@@ -65,7 +65,7 @@ impl<P: SubstrateMessageLane> SubstrateMessagesTarget<P> {
client: Client<P::TargetChain>, client: Client<P::TargetChain>,
lane: P, lane: P,
lane_id: LaneId, lane_id: LaneId,
metric_values: StandaloneMessagesMetrics, metric_values: StandaloneMessagesMetrics<P::SourceChain, P::TargetChain>,
source_to_target_headers_relay: Option<OnDemandHeadersRelay<P::SourceChain>>, source_to_target_headers_relay: Option<OnDemandHeadersRelay<P::SourceChain>>,
) -> Self { ) -> Self {
SubstrateMessagesTarget { SubstrateMessagesTarget {
@@ -32,10 +32,7 @@ use futures::{channel::mpsc::unbounded, future::FutureExt, stream::StreamExt};
use bp_messages::{LaneId, MessageNonce, UnrewardedRelayersState, Weight}; use bp_messages::{LaneId, MessageNonce, UnrewardedRelayersState, Weight};
use bp_runtime::messages::DispatchFeePayment; use bp_runtime::messages::DispatchFeePayment;
use relay_utils::{ use relay_utils::{
interval, interval, metrics::MetricsParams, process_future_result, relay_loop::Client as RelayClient,
metrics::{GlobalMetrics, MetricsParams},
process_future_result,
relay_loop::Client as RelayClient,
retry_backoff, FailedClient, retry_backoff, FailedClient,
}; };
@@ -270,9 +267,8 @@ pub async fn run<P: MessageLane, Strategy: RelayStrategy>(
let exit_signal = exit_signal.shared(); let exit_signal = exit_signal.shared();
relay_utils::relay_loop(source_client, target_client) relay_utils::relay_loop(source_client, target_client)
.reconnect_delay(params.reconnect_delay) .reconnect_delay(params.reconnect_delay)
.with_metrics(Some(metrics_prefix::<P>(&params.lane)), metrics_params) .with_metrics(metrics_params)
.loop_metric(MessageLaneLoopMetrics::new)? .loop_metric(MessageLaneLoopMetrics::new(Some(&metrics_prefix::<P>(&params.lane)))?)?
.standalone_metric(GlobalMetrics::new)?
.expose() .expose()
.await? .await?
.run(metrics_prefix::<P>(&params.lane), move |source_client, target_client, metrics| { .run(metrics_prefix::<P>(&params.lane), move |source_client, target_client, metrics| {
+21 -19
View File
@@ -22,7 +22,9 @@ use crate::{
}; };
use bp_messages::MessageNonce; use bp_messages::MessageNonce;
use relay_utils::metrics::{metric_name, register, GaugeVec, Opts, PrometheusError, Registry, U64}; use relay_utils::metrics::{
metric_name, register, GaugeVec, Metric, Opts, PrometheusError, Registry, U64,
};
/// Message lane relay metrics. /// Message lane relay metrics.
/// ///
@@ -38,30 +40,22 @@ pub struct MessageLaneLoopMetrics {
impl MessageLaneLoopMetrics { impl MessageLaneLoopMetrics {
/// Create and register messages loop metrics. /// Create and register messages loop metrics.
pub fn new(registry: &Registry, prefix: Option<&str>) -> Result<Self, PrometheusError> { pub fn new(prefix: Option<&str>) -> Result<Self, PrometheusError> {
Ok(MessageLaneLoopMetrics { Ok(MessageLaneLoopMetrics {
best_block_numbers: register( best_block_numbers: GaugeVec::new(
GaugeVec::new( Opts::new(
Opts::new( metric_name(prefix, "best_block_numbers"),
metric_name(prefix, "best_block_numbers"), "Best finalized block numbers",
"Best finalized block numbers", ),
), &["type"],
&["type"],
)?,
registry,
)?, )?,
lane_state_nonces: register( lane_state_nonces: GaugeVec::new(
GaugeVec::new( Opts::new(metric_name(prefix, "lane_state_nonces"), "Nonces of the lane state"),
Opts::new(metric_name(prefix, "lane_state_nonces"), "Nonces of the lane state"), &["type"],
&["type"],
)?,
registry,
)?, )?,
}) })
} }
}
impl MessageLaneLoopMetrics {
/// Update source client state metrics. /// Update source client state metrics.
pub fn update_source_state<P: MessageLane>(&self, source_client_state: SourceClientState<P>) { pub fn update_source_state<P: MessageLane>(&self, source_client_state: SourceClientState<P>) {
self.best_block_numbers self.best_block_numbers
@@ -122,3 +116,11 @@ impl MessageLaneLoopMetrics {
.set(target_latest_confirmed_nonce); .set(target_latest_confirmed_nonce);
} }
} }
impl Metric for MessageLaneLoopMetrics {
fn register(&self, registry: &Registry) -> Result<(), PrometheusError> {
register(self.best_block_numbers.clone(), registry)?;
register(self.lane_state_nonces.clone(), registry)?;
Ok(())
}
}
+21 -17
View File
@@ -46,28 +46,38 @@ pub struct MetricsParams {
/// Interface and TCP port to be used when exposing Prometheus metrics. /// Interface and TCP port to be used when exposing Prometheus metrics.
pub address: Option<MetricsAddress>, pub address: Option<MetricsAddress>,
/// Metrics registry. May be `Some(_)` if several components share the same endpoint. /// Metrics registry. May be `Some(_)` if several components share the same endpoint.
pub registry: Option<Registry>, pub registry: Registry,
/// Prefix that must be used in metric names.
pub metrics_prefix: Option<String>,
} }
/// Metrics API. /// Metric API.
pub trait Metrics: Clone + Send + Sync + 'static {} pub trait Metric: Clone + Send + Sync + 'static {
fn register(&self, registry: &Registry) -> Result<(), PrometheusError>;
}
impl<T: Clone + Send + Sync + 'static> Metrics for T {} /// Standalone metric API.
/// Standalone metrics API.
/// ///
/// Metrics of this kind know how to update themselves, so we may just spawn and forget the /// Metrics of this kind know how to update themselves, so we may just spawn and forget the
/// asynchronous self-update task. /// asynchronous self-update task.
#[async_trait] #[async_trait]
pub trait StandaloneMetrics: Metrics { pub trait StandaloneMetric: Metric {
/// Update metric values. /// Update metric values.
async fn update(&self); async fn update(&self);
/// Metrics update interval. /// Metrics update interval.
fn update_interval(&self) -> Duration; fn update_interval(&self) -> Duration;
/// Register and spawn metric. Metric is only spawned if it is registered for the first time.
fn register_and_spawn(self, registry: &Registry) -> Result<(), PrometheusError> {
match self.register(registry) {
Ok(()) => {
self.spawn();
Ok(())
},
Err(PrometheusError::AlreadyReg) => Ok(()),
Err(e) => Err(e),
}
}
/// Spawn the self update task that will keep update metric value at given intervals. /// Spawn the self update task that will keep update metric value at given intervals.
fn spawn(self) { fn spawn(self) {
async_std::task::spawn(async move { async_std::task::spawn(async move {
@@ -89,7 +99,7 @@ impl Default for MetricsAddress {
impl MetricsParams { impl MetricsParams {
/// Creates metrics params so that metrics are not exposed. /// Creates metrics params so that metrics are not exposed.
pub fn disabled() -> Self { pub fn disabled() -> Self {
MetricsParams { address: None, registry: None, metrics_prefix: None } MetricsParams { address: None, registry: Registry::new() }
} }
/// Do not expose metrics. /// Do not expose metrics.
@@ -97,17 +107,11 @@ impl MetricsParams {
self.address = None; self.address = None;
self self
} }
/// Set prefix to use in metric names.
pub fn metrics_prefix(mut self, prefix: String) -> Self {
self.metrics_prefix = Some(prefix);
self
}
} }
impl From<Option<MetricsAddress>> for MetricsParams { impl From<Option<MetricsAddress>> for MetricsParams {
fn from(address: Option<MetricsAddress>) -> Self { fn from(address: Option<MetricsAddress>) -> Self {
MetricsParams { address, registry: None, metrics_prefix: None } MetricsParams { address, registry: Registry::new() }
} }
} }
@@ -17,8 +17,8 @@
use crate::{ use crate::{
error::{self, Error}, error::{self, Error},
metrics::{ metrics::{
metric_name, register, F64SharedRef, Gauge, PrometheusError, Registry, StandaloneMetrics, metric_name, register, F64SharedRef, Gauge, Metric, PrometheusError, Registry,
F64, StandaloneMetric, F64,
}, },
}; };
@@ -44,8 +44,6 @@ pub struct FloatJsonValueMetric {
impl FloatJsonValueMetric { impl FloatJsonValueMetric {
/// Create new metric instance with given name and help. /// Create new metric instance with given name and help.
pub fn new( pub fn new(
registry: &Registry,
prefix: Option<&str>,
url: String, url: String,
json_path: String, json_path: String,
name: String, name: String,
@@ -55,7 +53,7 @@ impl FloatJsonValueMetric {
Ok(FloatJsonValueMetric { Ok(FloatJsonValueMetric {
url, url,
json_path, json_path,
metric: register(Gauge::new(metric_name(prefix, &name), help)?, registry)?, metric: Gauge::new(metric_name(None, &name), help)?,
shared_value_ref, shared_value_ref,
}) })
} }
@@ -81,8 +79,14 @@ impl FloatJsonValueMetric {
} }
} }
impl Metric for FloatJsonValueMetric {
fn register(&self, registry: &Registry) -> Result<(), PrometheusError> {
register(self.metric.clone(), registry).map(drop)
}
}
#[async_trait] #[async_trait]
impl StandaloneMetrics for FloatJsonValueMetric { impl StandaloneMetric for FloatJsonValueMetric {
fn update_interval(&self) -> Duration { fn update_interval(&self) -> Duration {
UPDATE_INTERVAL UPDATE_INTERVAL
} }
+22 -22
View File
@@ -17,8 +17,8 @@
//! Global system-wide Prometheus metrics exposed by relays. //! Global system-wide Prometheus metrics exposed by relays.
use crate::metrics::{ use crate::metrics::{
metric_name, register, Gauge, GaugeVec, Opts, PrometheusError, Registry, StandaloneMetrics, metric_name, register, Gauge, GaugeVec, Metric, Opts, PrometheusError, Registry,
F64, U64, StandaloneMetric, F64, U64,
}; };
use async_std::sync::{Arc, Mutex}; use async_std::sync::{Arc, Mutex};
@@ -40,36 +40,36 @@ pub struct GlobalMetrics {
impl GlobalMetrics { impl GlobalMetrics {
/// Create and register global metrics. /// Create and register global metrics.
pub fn new(registry: &Registry, prefix: Option<&str>) -> Result<Self, PrometheusError> { pub fn new() -> Result<Self, PrometheusError> {
Ok(GlobalMetrics { Ok(GlobalMetrics {
system: Arc::new(Mutex::new(System::new_with_specifics(RefreshKind::everything()))), system: Arc::new(Mutex::new(System::new_with_specifics(RefreshKind::everything()))),
system_average_load: register( system_average_load: GaugeVec::new(
GaugeVec::new( Opts::new(metric_name(None, "system_average_load"), "System load average"),
Opts::new(metric_name(prefix, "system_average_load"), "System load average"), &["over"],
&["over"],
)?,
registry,
)?, )?,
process_cpu_usage_percentage: register( process_cpu_usage_percentage: Gauge::new(
Gauge::new( metric_name(None, "process_cpu_usage_percentage"),
metric_name(prefix, "process_cpu_usage_percentage"), "Process CPU usage",
"Process CPU usage",
)?,
registry,
)?, )?,
process_memory_usage_bytes: register( process_memory_usage_bytes: Gauge::new(
Gauge::new( metric_name(None, "process_memory_usage_bytes"),
metric_name(prefix, "process_memory_usage_bytes"), "Process memory (resident set size) usage",
"Process memory (resident set size) usage",
)?,
registry,
)?, )?,
}) })
} }
} }
impl Metric for GlobalMetrics {
fn register(&self, registry: &Registry) -> Result<(), PrometheusError> {
register(self.system_average_load.clone(), registry)?;
register(self.process_cpu_usage_percentage.clone(), registry)?;
register(self.process_memory_usage_bytes.clone(), registry)?;
Ok(())
}
}
#[async_trait] #[async_trait]
impl StandaloneMetrics for GlobalMetrics { impl StandaloneMetric for GlobalMetrics {
async fn update(&self) { async fn update(&self) {
// update system-wide metrics // update system-wide metrics
let mut system = self.system.lock().await; let mut system = self.system.lock().await;
+10 -50
View File
@@ -16,7 +16,7 @@
use crate::{ use crate::{
error::Error, error::Error,
metrics::{Metrics, MetricsAddress, MetricsParams, PrometheusError, StandaloneMetrics}, metrics::{Metric, MetricsAddress, MetricsParams},
FailedClient, MaybeConnectionError, FailedClient, MaybeConnectionError,
}; };
@@ -53,7 +53,7 @@ pub fn relay_loop<SC, TC>(source_client: SC, target_client: TC) -> Loop<SC, TC,
/// Returns generic relay loop metrics that may be customized and used in one or several relay /// Returns generic relay loop metrics that may be customized and used in one or several relay
/// loops. /// loops.
pub fn relay_metrics(prefix: Option<String>, params: MetricsParams) -> LoopMetrics<(), (), ()> { pub fn relay_metrics(params: MetricsParams) -> LoopMetrics<(), (), ()> {
LoopMetrics { LoopMetrics {
relay_loop: Loop { relay_loop: Loop {
reconnect_delay: RECONNECT_DELAY, reconnect_delay: RECONNECT_DELAY,
@@ -62,8 +62,7 @@ pub fn relay_metrics(prefix: Option<String>, params: MetricsParams) -> LoopMetri
loop_metric: None, loop_metric: None,
}, },
address: params.address, address: params.address,
registry: params.registry.unwrap_or_else(|| create_metrics_registry(prefix)), registry: params.registry,
metrics_prefix: params.metrics_prefix,
loop_metric: None, loop_metric: None,
} }
} }
@@ -81,7 +80,6 @@ pub struct LoopMetrics<SC, TC, LM> {
relay_loop: Loop<SC, TC, ()>, relay_loop: Loop<SC, TC, ()>,
address: Option<MetricsAddress>, address: Option<MetricsAddress>,
registry: Registry, registry: Registry,
metrics_prefix: Option<String>,
loop_metric: Option<LM>, loop_metric: Option<LM>,
} }
@@ -93,11 +91,7 @@ impl<SC, TC, LM> Loop<SC, TC, LM> {
} }
/// Start building loop metrics using given prefix. /// Start building loop metrics using given prefix.
pub fn with_metrics( pub fn with_metrics(self, params: MetricsParams) -> LoopMetrics<SC, TC, ()> {
self,
prefix: Option<String>,
params: MetricsParams,
) -> LoopMetrics<SC, TC, ()> {
LoopMetrics { LoopMetrics {
relay_loop: Loop { relay_loop: Loop {
reconnect_delay: self.reconnect_delay, reconnect_delay: self.reconnect_delay,
@@ -106,8 +100,7 @@ impl<SC, TC, LM> Loop<SC, TC, LM> {
loop_metric: None, loop_metric: None,
}, },
address: params.address, address: params.address,
registry: params.registry.unwrap_or_else(|| create_metrics_registry(prefix)), registry: params.registry,
metrics_prefix: params.metrics_prefix,
loop_metric: None, loop_metric: None,
} }
} }
@@ -160,44 +153,23 @@ impl<SC, TC, LM> LoopMetrics<SC, TC, LM> {
/// Add relay loop metrics. /// Add relay loop metrics.
/// ///
/// Loop metrics will be passed to the loop callback. /// Loop metrics will be passed to the loop callback.
pub fn loop_metric<NewLM: Metrics>( pub fn loop_metric<NewLM: Metric>(
self, self,
create_metric: impl FnOnce(&Registry, Option<&str>) -> Result<NewLM, PrometheusError>, metric: NewLM,
) -> Result<LoopMetrics<SC, TC, NewLM>, Error> { ) -> Result<LoopMetrics<SC, TC, NewLM>, Error> {
let loop_metric = create_metric(&self.registry, self.metrics_prefix.as_deref())?; metric.register(&self.registry)?;
Ok(LoopMetrics { Ok(LoopMetrics {
relay_loop: self.relay_loop, relay_loop: self.relay_loop,
address: self.address, address: self.address,
registry: self.registry, registry: self.registry,
metrics_prefix: self.metrics_prefix, loop_metric: Some(metric),
loop_metric: Some(loop_metric),
}) })
} }
/// Add standalone metrics.
pub fn standalone_metric<M: StandaloneMetrics>(
self,
create_metric: impl FnOnce(&Registry, Option<&str>) -> Result<M, PrometheusError>,
) -> Result<Self, Error> {
// since standalone metrics are updating themselves, we may just ignore the fact that the
// same standalone metric is exposed by several loops && only spawn single metric
match create_metric(&self.registry, self.metrics_prefix.as_deref()) {
Ok(standalone_metrics) => standalone_metrics.spawn(),
Err(PrometheusError::AlreadyReg) => (),
Err(e) => return Err(e.into()),
}
Ok(self)
}
/// Convert into `MetricsParams` structure so that metrics registry may be extended later. /// Convert into `MetricsParams` structure so that metrics registry may be extended later.
pub fn into_params(self) -> MetricsParams { pub fn into_params(self) -> MetricsParams {
MetricsParams { MetricsParams { address: self.address, registry: self.registry }
address: self.address,
registry: Some(self.registry),
metrics_prefix: self.metrics_prefix,
}
} }
/// Expose metrics using address passed at creation. /// Expose metrics using address passed at creation.
@@ -274,15 +246,3 @@ pub async fn reconnect_failed_client(
break break
} }
} }
/// Create new registry with global metrics.
fn create_metrics_registry(prefix: Option<String>) -> Registry {
match prefix {
Some(prefix) => {
assert!(!prefix.is_empty(), "Metrics prefix can not be empty");
Registry::new_custom(Some(prefix), None)
.expect("only fails if prefix is empty; prefix is not empty; qed")
},
None => Registry::new(),
}
}