referrerpolicy=no-referrer-when-downgrade

substrate_relay_helper/cli/relay_headers_and_messages/
relay_to_relay.rs

1// Copyright 2019-2022 Parity Technologies (UK) Ltd.
2// This file is part of Parity Bridges Common.
3
4// Parity Bridges Common is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Parity Bridges Common is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Parity Bridges Common.  If not, see <http://www.gnu.org/licenses/>.
16
17// we don't have any relay/standalone <> relay/standalone chain bridges, but we may need it in a
18// future
19#![allow(unused_macros)]
20
21//! Relay chain to Relay chain relayer CLI primitives.
22
23use async_trait::async_trait;
24use std::sync::Arc;
25
26use crate::{
27	cli::{
28		bridge::{CliBridgeBase, MessagesCliBridge, RelayToRelayHeadersCliBridge},
29		relay_headers_and_messages::{Full2WayBridgeBase, Full2WayBridgeCommonParams},
30	},
31	finality::SubstrateFinalitySyncPipeline,
32	on_demand::{headers::OnDemandHeadersRelay, OnDemandRelay},
33};
34use relay_substrate_client::{
35	AccountIdOf, AccountKeyPairOf, ChainWithRuntimeVersion, ChainWithTransactions, Client,
36};
37use sp_core::Pair;
38
39/// A base relay between two standalone (relay) chains.
40///
41/// Such relay starts 2 messages relay and 2 on-demand header relays.
42pub struct RelayToRelayBridge<
43	L2R: MessagesCliBridge + RelayToRelayHeadersCliBridge,
44	R2L: MessagesCliBridge + RelayToRelayHeadersCliBridge,
45> {
46	/// Parameters that are shared by all bridge types.
47	pub common:
48		Full2WayBridgeCommonParams<<R2L as CliBridgeBase>::Target, <L2R as CliBridgeBase>::Target>,
49}
50
51/// Create set of configuration objects specific to relay-to-relay relayer.
52macro_rules! declare_relay_to_relay_bridge_schema {
53	($left_chain:ident, $right_chain:ident) => {
54		bp_runtime::paste::item! {
55			#[doc = $left_chain " and " $right_chain " headers+messages relay params."]
56			#[derive(Debug, PartialEq, Parser)]
57			pub struct [<$left_chain $right_chain HeadersAndMessages>] {
58				#[command(flatten)]
59				shared: HeadersAndMessagesSharedParams,
60
61				#[command(flatten)]
62				left: [<$left_chain ConnectionParams>],
63				// default signer, which is always used to sign messages relay transactions on the left chain
64				#[command(flatten)]
65				left_sign: [<$left_chain SigningParams>],
66
67				#[command(flatten)]
68				right: [<$right_chain ConnectionParams>],
69				#[command(flatten)]
70				// default signer, which is always used to sign messages relay transactions on the right chain
71				right_sign: [<$right_chain SigningParams>],
72			}
73
74			impl [<$left_chain $right_chain HeadersAndMessages>] {
75				async fn into_bridge<
76					Left: ChainWithTransactions + CliChain,
77					Right: ChainWithTransactions + CliChain,
78					L2R: CliBridgeBase<Source = Left, Target = Right> + MessagesCliBridge + RelayToRelayHeadersCliBridge,
79					R2L: CliBridgeBase<Source = Right, Target = Left> + MessagesCliBridge + RelayToRelayHeadersCliBridge,
80				>(
81					self,
82				) -> anyhow::Result<RelayToRelayBridge<L2R, R2L>> {
83					Ok(RelayToRelayBridge {
84						common: Full2WayBridgeCommonParams::new::<L2R>(
85							self.shared,
86							BridgeEndCommonParams {
87								client: self.left.into_client::<Left>().await?,
88								tx_params: self.left_sign.transaction_params::<Left>()?,
89								accounts: vec![],
90							},
91							BridgeEndCommonParams {
92								client: self.right.into_client::<Right>().await?,
93								tx_params: self.right_sign.transaction_params::<Right>()?,
94								accounts: vec![],
95							},
96						)?,
97						right_to_left_transaction_params: self.left_sign.transaction_params::<Left>(),
98						left_to_right_transaction_params: self.right_sign.transaction_params::<Right>(),
99					})
100				}
101			}
102		}
103	};
104}
105
106#[async_trait]
107impl<
108		Left: ChainWithTransactions + ChainWithRuntimeVersion,
109		Right: ChainWithTransactions + ChainWithRuntimeVersion,
110		L2R: CliBridgeBase<Source = Left, Target = Right>
111			+ MessagesCliBridge
112			+ RelayToRelayHeadersCliBridge,
113		R2L: CliBridgeBase<Source = Right, Target = Left>
114			+ MessagesCliBridge
115			+ RelayToRelayHeadersCliBridge,
116	> Full2WayBridgeBase for RelayToRelayBridge<L2R, R2L>
117where
118	AccountIdOf<Left>: From<<AccountKeyPairOf<Left> as Pair>::Public>,
119	AccountIdOf<Right>: From<<AccountKeyPairOf<Right> as Pair>::Public>,
120{
121	type Params = RelayToRelayBridge<L2R, R2L>;
122	type Left = Left;
123	type Right = Right;
124
125	fn common(&self) -> &Full2WayBridgeCommonParams<Left, Right> {
126		&self.common
127	}
128
129	fn mut_common(&mut self) -> &mut Full2WayBridgeCommonParams<Self::Left, Self::Right> {
130		&mut self.common
131	}
132
133	async fn start_on_demand_headers_relayers(
134		&mut self,
135	) -> anyhow::Result<(
136		Arc<dyn OnDemandRelay<Self::Left, Self::Right>>,
137		Arc<dyn OnDemandRelay<Self::Right, Self::Left>>,
138	)> {
139		<L2R as RelayToRelayHeadersCliBridge>::Finality::start_relay_guards(
140			&self.common.right.client,
141			self.common.right.client.can_start_version_guard(),
142		)
143		.await?;
144		<R2L as RelayToRelayHeadersCliBridge>::Finality::start_relay_guards(
145			&self.common.left.client,
146			self.common.left.client.can_start_version_guard(),
147		)
148		.await?;
149
150		let left_to_right_on_demand_headers =
151			OnDemandHeadersRelay::<<L2R as RelayToRelayHeadersCliBridge>::Finality, _, _>::new(
152				self.common.left.client.clone(),
153				self.common.right.client.clone(),
154				self.common.right.tx_params.clone(),
155				self.common.shared.headers_to_relay(),
156				None,
157			);
158		let right_to_left_on_demand_headers =
159			OnDemandHeadersRelay::<<R2L as RelayToRelayHeadersCliBridge>::Finality, _, _>::new(
160				self.common.right.client.clone(),
161				self.common.left.client.clone(),
162				self.common.left.tx_params.clone(),
163				self.common.shared.headers_to_relay(),
164				None,
165			);
166
167		Ok((Arc::new(left_to_right_on_demand_headers), Arc::new(right_to_left_on_demand_headers)))
168	}
169}