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