Parachain loop metrics (#1484)

* parachain loop metrics

* some fixes

* mini refactoring

* add tests
This commit is contained in:
Svyatoslav Nikolsky
2022-06-29 15:58:19 +03:00
committed by Bastian Köcher
parent f8ff3c9142
commit d11d9fd0b7
7 changed files with 228 additions and 22 deletions
@@ -23,7 +23,10 @@ use async_trait::async_trait;
use bp_parachains::parachain_head_storage_key_at_source;
use bp_polkadot_core::parachains::{ParaHash, ParaHead, ParaHeadsProof, ParaId};
use codec::Decode;
use parachains_relay::parachains_loop::{ParaHashAtSource, SourceClient};
use parachains_relay::{
parachains_loop::{ParaHashAtSource, SourceClient},
parachains_loop_metrics::ParachainsLoopMetrics,
};
use relay_substrate_client::{
Chain, Client, Error as SubstrateError, HeaderIdOf, HeaderOf, RelayChain,
};
@@ -100,6 +103,7 @@ where
async fn parachain_head(
&self,
at_block: HeaderIdOf<P::SourceRelayChain>,
metrics: Option<&ParachainsLoopMetrics>,
para_id: ParaId,
) -> Result<ParaHashAtSource, Self::Error> {
// we don't need to support many parachains now
@@ -111,9 +115,11 @@ where
)))
}
Ok(match self.on_chain_parachain_header(at_block, para_id).await? {
let mut para_header_number_at_source = None;
let para_hash_at_source = match self.on_chain_parachain_header(at_block, para_id).await? {
Some(parachain_header) => {
let mut parachain_head = ParaHashAtSource::Some(parachain_header.hash());
para_header_number_at_source = Some(*parachain_header.number());
// never return head that is larger than requested. This way we'll never sync
// headers past `maximal_header_id`
if let Some(ref maximal_header_id) = self.maximal_header_id {
@@ -125,11 +131,13 @@ where
// we don't want this header yet => let's report previously requested
// header
parachain_head = ParaHashAtSource::Some(maximal_header_id.1);
para_header_number_at_source = Some(maximal_header_id.0);
},
Some(_) => (),
None => {
// on-demand relay has not yet asked us to sync anything let's do that
parachain_head = ParaHashAtSource::Unavailable;
para_header_number_at_source = None;
},
}
}
@@ -137,7 +145,15 @@ where
parachain_head
},
None => ParaHashAtSource::None,
})
};
if let (Some(metrics), Some(para_header_number_at_source)) =
(metrics, para_header_number_at_source)
{
metrics.update_best_parachain_block_at_source(para_id, para_header_number_at_source);
}
Ok(para_hash_at_source)
}
async fn prove_parachain_heads(
@@ -24,13 +24,19 @@ use crate::{
};
use async_trait::async_trait;
use bp_parachains::{parachain_head_storage_key_at_target, BestParaHeadHash};
use bp_polkadot_core::parachains::{ParaHeadsProof, ParaId};
use bp_parachains::{
best_parachain_head_hash_storage_key_at_target, imported_parachain_head_storage_key_at_target,
BestParaHeadHash,
};
use bp_polkadot_core::parachains::{ParaHead, ParaHeadsProof, ParaId};
use codec::{Decode, Encode};
use parachains_relay::parachains_loop::TargetClient;
use parachains_relay::{
parachains_loop::TargetClient, parachains_loop_metrics::ParachainsLoopMetrics,
};
use relay_substrate_client::{
AccountIdOf, AccountKeyPairOf, BlockNumberOf, Chain, Client, Error as SubstrateError, HashOf,
HeaderIdOf, RelayChain, SignParam, TransactionEra, TransactionSignScheme, UnsignedTransaction,
HeaderIdOf, HeaderOf, RelayChain, SignParam, TransactionEra, TransactionSignScheme,
UnsignedTransaction,
};
use relay_utils::{relay_loop::Client as RelayClient, HeaderId};
use sp_core::{Bytes, Pair};
@@ -115,15 +121,46 @@ where
async fn parachain_head(
&self,
at_block: HeaderIdOf<P::TargetChain>,
metrics: Option<&ParachainsLoopMetrics>,
para_id: ParaId,
) -> Result<Option<BestParaHeadHash>, Self::Error> {
let storage_key = parachain_head_storage_key_at_target(
let best_para_head_hash_key = best_parachain_head_hash_storage_key_at_target(
P::SourceRelayChain::PARACHAINS_FINALITY_PALLET_NAME,
para_id,
);
let para_head = self.client.storage_value(storage_key, Some(at_block.1)).await?;
let best_para_head_hash: Option<BestParaHeadHash> =
self.client.storage_value(best_para_head_hash_key, Some(at_block.1)).await?;
if let (Some(metrics), &Some(ref best_para_head_hash)) = (metrics, &best_para_head_hash) {
let imported_para_head_key = imported_parachain_head_storage_key_at_target(
P::SourceRelayChain::PARACHAINS_FINALITY_PALLET_NAME,
para_id,
best_para_head_hash.head_hash,
);
let imported_para_header = self
.client
.storage_value::<ParaHead>(imported_para_head_key, Some(at_block.1))
.await?
.and_then(|h| match HeaderOf::<P::SourceParachain>::decode(&mut &h.0[..]) {
Ok(header) => Some(header),
Err(e) => {
log::error!(
target: "bridge-metrics",
"Failed to decode {} parachain header at {}: {:?}. Metric will have obsolete value",
P::SourceParachain::NAME,
P::TargetChain::NAME,
e,
);
Ok(para_head)
None
},
});
if let Some(imported_para_header) = imported_para_header {
metrics
.update_best_parachain_block_at_target(para_id, *imported_para_header.number());
}
}
Ok(best_para_head_hash)
}
async fn submit_parachain_heads_proof(