substrate_relay_helper/cli/relay_headers_and_messages/
relay_to_parachain.rs1use async_trait::async_trait;
20use std::sync::Arc;
21
22use crate::{
23 cli::{
24 bridge::{
25 CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge,
26 RelayToRelayHeadersCliBridge,
27 },
28 relay_headers_and_messages::{Full2WayBridgeBase, Full2WayBridgeCommonParams},
29 DefaultClient,
30 },
31 finality::SubstrateFinalitySyncPipeline,
32 on_demand::{
33 headers::OnDemandHeadersRelay, parachains::OnDemandParachainsRelay, OnDemandRelay,
34 },
35};
36use bp_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
37use bp_polkadot_core::parachains::ParaHash;
38use relay_substrate_client::{
39 AccountIdOf, AccountKeyPairOf, Chain, ChainWithRuntimeVersion, ChainWithTransactions, Client,
40 Parachain,
41};
42use sp_core::Pair;
43
44pub struct RelayToParachainBridge<
49 L2R: MessagesCliBridge + RelayToRelayHeadersCliBridge,
50 R2L: MessagesCliBridge + ParachainToRelayHeadersCliBridge,
51> where
52 <R2L as CliBridgeBase>::Source: Parachain,
53{
54 pub common:
56 Full2WayBridgeCommonParams<<R2L as CliBridgeBase>::Target, <L2R as CliBridgeBase>::Target>,
57 pub right_relay: DefaultClient<<R2L as ParachainToRelayHeadersCliBridge>::SourceRelay>,
59}
60
61#[macro_export]
63macro_rules! declare_relay_to_parachain_bridge_schema {
64 ($left_chain:ident, $right_parachain:ident, $right_chain:ident) => {
66 bp_runtime::paste::item! {
67 #[doc = $left_chain ", " $right_parachain " and " $right_chain " headers+parachains+messages relay params."]
68 #[derive(Debug, PartialEq, Parser)]
69 pub struct [<$left_chain $right_parachain HeadersAndMessages>] {
70 #[command(flatten)]
72 shared: HeadersAndMessagesSharedParams,
73
74 #[command(flatten)]
75 left: [<$left_chain ConnectionParams>],
76 #[command(flatten)]
78 left_sign: [<$left_chain SigningParams>],
79
80 #[command(flatten)]
81 right: [<$right_parachain ConnectionParams>],
82 #[command(flatten)]
84 right_sign: [<$right_parachain SigningParams>],
85
86 #[command(flatten)]
87 right_relay: [<$right_chain ConnectionParams>],
88 }
89
90 impl [<$left_chain $right_parachain HeadersAndMessages>] {
91 async fn into_bridge<
92 Left: ChainWithTransactions + ChainWithRuntimeVersion,
93 Right: ChainWithTransactions + ChainWithRuntimeVersion + Parachain,
94 RightRelay: ChainWithRuntimeVersion,
95 L2R: CliBridgeBase<Source = Left, Target = Right> + MessagesCliBridge + RelayToRelayHeadersCliBridge,
96 R2L: CliBridgeBase<Source = Right, Target = Left>
97 + MessagesCliBridge
98 + ParachainToRelayHeadersCliBridge<SourceRelay = RightRelay>,
99 >(
100 self,
101 ) -> anyhow::Result<RelayToParachainBridge<L2R, R2L>> {
102 Ok(RelayToParachainBridge {
103 common: Full2WayBridgeCommonParams::new::<L2R>(
104 self.shared,
105 BridgeEndCommonParams {
106 client: self.left.into_client::<Left>().await?,
107 tx_params: self.left_sign.transaction_params::<Left>()?,
108 accounts: vec![],
109 },
110 BridgeEndCommonParams {
111 client: self.right.into_client::<Right>().await?,
112 tx_params: self.right_sign.transaction_params::<Right>()?,
113 accounts: vec![],
114 },
115 )?,
116 right_relay: self.right_relay.into_client::<RightRelay>().await?,
117 })
118 }
119 }
120 }
121 };
122}
123
124#[async_trait]
125impl<
126 Left: ChainWithTransactions + ChainWithRuntimeVersion,
127 Right: Chain<Hash = ParaHash> + ChainWithTransactions + ChainWithRuntimeVersion + Parachain,
128 RightRelay: Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>
129 + ChainWithRuntimeVersion,
130 L2R: CliBridgeBase<Source = Left, Target = Right>
131 + MessagesCliBridge
132 + RelayToRelayHeadersCliBridge,
133 R2L: CliBridgeBase<Source = Right, Target = Left>
134 + MessagesCliBridge
135 + ParachainToRelayHeadersCliBridge<SourceRelay = RightRelay>,
136 > Full2WayBridgeBase for RelayToParachainBridge<L2R, R2L>
137where
138 AccountIdOf<Left>: From<<AccountKeyPairOf<Left> as Pair>::Public>,
139 AccountIdOf<Right>: From<<AccountKeyPairOf<Right> as Pair>::Public>,
140{
141 type Params = RelayToParachainBridge<L2R, R2L>;
142 type Left = Left;
143 type Right = Right;
144
145 fn common(&self) -> &Full2WayBridgeCommonParams<Left, Right> {
146 &self.common
147 }
148
149 fn mut_common(&mut self) -> &mut Full2WayBridgeCommonParams<Self::Left, Self::Right> {
150 &mut self.common
151 }
152
153 async fn start_on_demand_headers_relayers(
154 &mut self,
155 ) -> anyhow::Result<(
156 Arc<dyn OnDemandRelay<Self::Left, Self::Right>>,
157 Arc<dyn OnDemandRelay<Self::Right, Self::Left>>,
158 )> {
159 <L2R as RelayToRelayHeadersCliBridge>::Finality::start_relay_guards(
160 &self.common.right.client,
161 self.common.right.client.can_start_version_guard(),
162 )
163 .await?;
164 <R2L as ParachainToRelayHeadersCliBridge>::RelayFinality::start_relay_guards(
165 &self.common.left.client,
166 self.common.left.client.can_start_version_guard(),
167 )
168 .await?;
169
170 let left_to_right_on_demand_headers =
171 OnDemandHeadersRelay::<<L2R as RelayToRelayHeadersCliBridge>::Finality, _, _>::new(
172 self.common.left.client.clone(),
173 self.common.right.client.clone(),
174 self.common.right.tx_params.clone(),
175 self.common.shared.headers_to_relay(),
176 None,
177 );
178 let right_relay_to_left_on_demand_headers = OnDemandHeadersRelay::<
179 <R2L as ParachainToRelayHeadersCliBridge>::RelayFinality,
180 _,
181 _,
182 >::new(
183 self.right_relay.clone(),
184 self.common.left.client.clone(),
185 self.common.left.tx_params.clone(),
186 self.common.shared.headers_to_relay(),
187 Some(self.common.metrics_params.clone()),
188 );
189 let right_to_left_on_demand_parachains = OnDemandParachainsRelay::<
190 <R2L as ParachainToRelayHeadersCliBridge>::ParachainFinality,
191 _,
192 _,
193 >::new(
194 self.right_relay.clone(),
195 self.common.left.client.clone(),
196 self.common.left.tx_params.clone(),
197 Arc::new(right_relay_to_left_on_demand_headers),
198 );
199
200 Ok((
201 Arc::new(left_to_right_on_demand_headers),
202 Arc::new(right_to_left_on_demand_parachains),
203 ))
204 }
205}