substrate_relay_helper/cli/
relay_parachains.rs1use async_std::sync::Mutex;
20use async_trait::async_trait;
21use bp_polkadot_core::BlockNumber as RelayBlockNumber;
22use bp_runtime::HeaderIdProvider;
23use clap::Parser;
24use parachains_relay::parachains_loop::{AvailableHeader, SourceClient, TargetClient};
25use relay_substrate_client::{Client, Parachain};
26use relay_utils::metrics::{GlobalMetrics, StandaloneMetric};
27use std::sync::Arc;
28
29use crate::{
30 cli::{
31 bridge::{CliBridgeBase, ParachainToRelayHeadersCliBridge},
32 chain_schema::*,
33 DefaultClient, PrometheusParams,
34 },
35 finality::SubstrateFinalitySyncPipeline,
36 parachains::{source::ParachainsSource, target::ParachainsTarget, ParachainsPipelineAdapter},
37 TransactionParams,
38};
39
40#[derive(Parser)]
42pub struct RelayParachainsParams {
43 #[command(flatten)]
44 source: SourceConnectionParams,
45 #[command(flatten)]
46 target: TargetConnectionParams,
47 #[command(flatten)]
48 target_sign: TargetSigningParams,
49 #[arg(long)]
52 only_free_headers: bool,
53 #[command(flatten)]
54 prometheus_params: PrometheusParams,
55}
56
57#[derive(Parser)]
59pub struct RelayParachainHeadParams {
60 #[command(flatten)]
61 source: SourceConnectionParams,
62 #[command(flatten)]
63 target: TargetConnectionParams,
64 #[command(flatten)]
65 target_sign: TargetSigningParams,
66 #[arg(long)]
69 at_relay_block: RelayBlockNumber,
70}
71
72#[async_trait]
74pub trait ParachainsRelayer: ParachainToRelayHeadersCliBridge
75where
76 ParachainsSource<Self::ParachainFinality, DefaultClient<Self::SourceRelay>>:
77 SourceClient<ParachainsPipelineAdapter<Self::ParachainFinality>>,
78 ParachainsTarget<
79 Self::ParachainFinality,
80 DefaultClient<Self::SourceRelay>,
81 DefaultClient<Self::Target>,
82 >: TargetClient<ParachainsPipelineAdapter<Self::ParachainFinality>>,
83 <Self as CliBridgeBase>::Source: Parachain,
84{
85 async fn relay_parachains(data: RelayParachainsParams) -> anyhow::Result<()> {
87 let source_chain_client = data.source.into_client::<Self::SourceRelay>().await?;
88 let source_client = ParachainsSource::<Self::ParachainFinality, _>::new(
89 source_chain_client.clone(),
90 Arc::new(Mutex::new(AvailableHeader::Missing)),
91 );
92
93 let target_transaction_params = TransactionParams {
94 signer: data.target_sign.to_keypair::<Self::Target>()?,
95 mortality: data.target_sign.target_transactions_mortality,
96 };
97 let target_chain_client = data.target.into_client::<Self::Target>().await?;
98 let target_client = ParachainsTarget::<Self::ParachainFinality, _, _>::new(
99 source_chain_client,
100 target_chain_client,
101 target_transaction_params,
102 );
103
104 let metrics_params: relay_utils::metrics::MetricsParams =
105 data.prometheus_params.into_metrics_params()?;
106 GlobalMetrics::new()?.register_and_spawn(&metrics_params.registry)?;
107
108 Self::RelayFinality::start_relay_guards(
109 target_client.target_client(),
110 target_client.target_client().can_start_version_guard(),
111 )
112 .await?;
113
114 parachains_relay::parachains_loop::run(
115 source_client,
116 target_client,
117 metrics_params,
118 data.only_free_headers,
119 futures::future::pending(),
120 )
121 .await
122 .map_err(|e| anyhow::format_err!("{}", e))
123 }
124
125 async fn relay_parachain_head(data: RelayParachainHeadParams) -> anyhow::Result<()> {
127 let source_chain_client = data.source.into_client::<Self::SourceRelay>().await?;
128 let at_relay_block = source_chain_client
129 .header_by_number(data.at_relay_block)
130 .await
131 .map_err(|e| anyhow::format_err!("{}", e))?
132 .id();
133
134 let source_client = ParachainsSource::<Self::ParachainFinality, _>::new(
135 source_chain_client.clone(),
136 Arc::new(Mutex::new(AvailableHeader::Missing)),
137 );
138
139 let target_transaction_params = TransactionParams {
140 signer: data.target_sign.to_keypair::<Self::Target>()?,
141 mortality: data.target_sign.target_transactions_mortality,
142 };
143 let target_chain_client = data.target.into_client::<Self::Target>().await?;
144 let target_client = ParachainsTarget::<Self::ParachainFinality, _, _>::new(
145 source_chain_client,
146 target_chain_client,
147 target_transaction_params,
148 );
149
150 parachains_relay::parachains_loop::relay_single_head(
151 source_client,
152 target_client,
153 at_relay_block,
154 )
155 .await
156 .map_err(|_| anyhow::format_err!("The command has failed"))
157 }
158}