mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 07:31:02 +00:00
CLI refactoring
* [CLI] Make bridge definitions more complete * [CLI] Refactor relay_headers_and_messages Signed-off-by: Serban Iorga <serban@parity.io>
This commit is contained in:
committed by
Bastian Köcher
parent
ceefd1b05d
commit
e1fd877b80
@@ -0,0 +1,694 @@
|
||||
// Copyright 2019-2022 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity Bridges Common.
|
||||
|
||||
// Parity Bridges Common is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity Bridges Common is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Complex 2-ways headers+messages relays support.
|
||||
//!
|
||||
//! To add new complex relay between `ChainA` and `ChainB`, you must:
|
||||
//!
|
||||
//! 1) ensure that there's a `declare_chain_cli_schema!(...)` for both chains.
|
||||
//! 2) add `declare_chain_to_chain_bridge_schema!(...)` or
|
||||
//! `declare_chain_to_parachain_bridge_schema` for the bridge.
|
||||
//! 3) declare a new struct for the added bridge and implement the `Full2WayBridge` trait for it.
|
||||
|
||||
#[macro_use]
|
||||
mod relay_to_relay;
|
||||
#[macro_use]
|
||||
mod relay_to_parachain;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use std::sync::Arc;
|
||||
use structopt::StructOpt;
|
||||
use strum::VariantNames;
|
||||
|
||||
use futures::{FutureExt, TryFutureExt};
|
||||
use relay_to_parachain::*;
|
||||
use relay_to_relay::*;
|
||||
|
||||
use crate::{
|
||||
cli::{
|
||||
bridge::{
|
||||
CliBridgeBase, MessagesCliBridge, MillauToRialtoCliBridge,
|
||||
MillauToRialtoParachainCliBridge, ParachainToRelayHeadersCliBridge,
|
||||
RelayToRelayHeadersCliBridge, RialtoParachainToMillauCliBridge,
|
||||
RialtoToMillauCliBridge,
|
||||
},
|
||||
chain_schema::*,
|
||||
relay_messages::RelayerMode,
|
||||
CliChain, HexLaneId, PrometheusParams,
|
||||
},
|
||||
declare_chain_cli_schema,
|
||||
};
|
||||
use bp_runtime::{BalanceOf, BlockNumberOf};
|
||||
use messages_relay::relay_strategy::MixStrategy;
|
||||
use relay_substrate_client::{
|
||||
AccountIdOf, AccountKeyPairOf, Chain, ChainWithBalances, Client, TransactionSignScheme,
|
||||
};
|
||||
use relay_utils::metrics::MetricsParams;
|
||||
use sp_core::Pair;
|
||||
use substrate_relay_helper::{
|
||||
messages_lane::MessagesRelayParams, on_demand::OnDemandRelay, TaggedAccount, TransactionParams,
|
||||
};
|
||||
|
||||
/// Maximal allowed conversion rate error ratio (abs(real - stored) / stored) that we allow.
|
||||
///
|
||||
/// If it is zero, then transaction will be submitted every time we see difference between
|
||||
/// stored and real conversion rates. If it is large enough (e.g. > than 10 percents, which is 0.1),
|
||||
/// then rational relayers may stop relaying messages because they were submitted using
|
||||
/// lesser conversion rate.
|
||||
pub(crate) const CONVERSION_RATE_ALLOWED_DIFFERENCE_RATIO: f64 = 0.05;
|
||||
|
||||
/// Parameters that have the same names across all bridges.
|
||||
#[derive(Debug, PartialEq, StructOpt)]
|
||||
pub struct HeadersAndMessagesSharedParams {
|
||||
/// Hex-encoded lane identifiers that should be served by the complex relay.
|
||||
#[structopt(long, default_value = "00000000")]
|
||||
pub lane: Vec<HexLaneId>,
|
||||
#[structopt(long, possible_values = RelayerMode::VARIANTS, case_insensitive = true, default_value = "rational")]
|
||||
pub relayer_mode: RelayerMode,
|
||||
/// If passed, only mandatory headers (headers that are changing the GRANDPA authorities set)
|
||||
/// are relayed.
|
||||
#[structopt(long)]
|
||||
pub only_mandatory_headers: bool,
|
||||
#[structopt(flatten)]
|
||||
pub prometheus_params: PrometheusParams,
|
||||
}
|
||||
|
||||
pub struct Full2WayBridgeCommonParams<
|
||||
Left: TransactionSignScheme + CliChain,
|
||||
Right: TransactionSignScheme + CliChain,
|
||||
> {
|
||||
pub shared: HeadersAndMessagesSharedParams,
|
||||
|
||||
pub left: Client<Left>,
|
||||
// default signer, which is always used to sign messages relay transactions on the left chain
|
||||
pub left_sign: AccountKeyPairOf<Left>,
|
||||
pub left_transactions_mortality: Option<u32>,
|
||||
pub left_messages_pallet_owner: Option<AccountKeyPairOf<Left>>,
|
||||
pub at_left_accounts: Vec<TaggedAccount<AccountIdOf<Left>>>,
|
||||
|
||||
pub right: Client<Right>,
|
||||
// default signer, which is always used to sign messages relay transactions on the right chain
|
||||
pub right_sign: AccountKeyPairOf<Right>,
|
||||
pub right_transactions_mortality: Option<u32>,
|
||||
pub right_messages_pallet_owner: Option<AccountKeyPairOf<Right>>,
|
||||
pub at_right_accounts: Vec<TaggedAccount<AccountIdOf<Right>>>,
|
||||
}
|
||||
|
||||
// All supported chains.
|
||||
declare_chain_cli_schema!(Millau, millau);
|
||||
declare_chain_cli_schema!(Rialto, rialto);
|
||||
declare_chain_cli_schema!(RialtoParachain, rialto_parachain);
|
||||
// Means to override signers of different layer transactions.
|
||||
declare_chain_cli_schema!(MillauHeadersToRialto, millau_headers_to_rialto);
|
||||
declare_chain_cli_schema!(MillauHeadersToRialtoParachain, millau_headers_to_rialto_parachain);
|
||||
declare_chain_cli_schema!(RialtoHeadersToMillau, rialto_headers_to_millau);
|
||||
declare_chain_cli_schema!(RialtoParachainsToMillau, rialto_parachains_to_millau);
|
||||
// All supported bridges.
|
||||
declare_relay_to_relay_bridge_schema!(Millau, Rialto);
|
||||
declare_relay_to_parachain_bridge_schema!(Millau, RialtoParachain, Rialto);
|
||||
|
||||
#[async_trait]
|
||||
trait Full2WayBridgeBase: Sized + Send + Sync {
|
||||
/// The CLI params for the bridge.
|
||||
type Params;
|
||||
/// The left relay chain.
|
||||
type Left: TransactionSignScheme<Chain = Self::Left>
|
||||
+ CliChain<KeyPair = AccountKeyPairOf<Self::Left>>;
|
||||
/// The right destination chain (it can be a relay or a parachain).
|
||||
type Right: TransactionSignScheme<Chain = Self::Right>
|
||||
+ CliChain<KeyPair = AccountKeyPairOf<Self::Right>>;
|
||||
|
||||
fn common(&self) -> &Full2WayBridgeCommonParams<Self::Left, Self::Right>;
|
||||
|
||||
fn mut_common(&mut self) -> &mut Full2WayBridgeCommonParams<Self::Left, Self::Right>;
|
||||
|
||||
async fn start_on_demand_headers_relayers(
|
||||
&mut self,
|
||||
) -> anyhow::Result<(
|
||||
Arc<dyn OnDemandRelay<BlockNumberOf<Self::Left>>>,
|
||||
Arc<dyn OnDemandRelay<BlockNumberOf<Self::Right>>>,
|
||||
)>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
trait Full2WayBridge: Sized + Sync
|
||||
where
|
||||
AccountIdOf<Self::Left>: From<<AccountKeyPairOf<Self::Left> as Pair>::Public>,
|
||||
AccountIdOf<Self::Right>: From<<AccountKeyPairOf<Self::Right> as Pair>::Public>,
|
||||
BalanceOf<Self::Left>: TryFrom<BalanceOf<Self::Right>> + Into<u128>,
|
||||
BalanceOf<Self::Right>: TryFrom<BalanceOf<Self::Left>> + Into<u128>,
|
||||
{
|
||||
type Base: Full2WayBridgeBase<Left = Self::Left, Right = Self::Right>;
|
||||
|
||||
/// The left relay chain.
|
||||
type Left: Chain
|
||||
+ ChainWithBalances
|
||||
+ TransactionSignScheme<Chain = Self::Left>
|
||||
+ CliChain<KeyPair = AccountKeyPairOf<Self::Left>>;
|
||||
/// The right relay chain.
|
||||
type Right: Chain
|
||||
+ ChainWithBalances
|
||||
+ TransactionSignScheme<Chain = Self::Right>
|
||||
+ CliChain<KeyPair = AccountKeyPairOf<Self::Right>>;
|
||||
|
||||
// Left to Right bridge
|
||||
type L2R: MessagesCliBridge<Source = Self::Left, Target = Self::Right>;
|
||||
// Right to Left bridge
|
||||
type R2L: MessagesCliBridge<Source = Self::Right, Target = Self::Left>;
|
||||
|
||||
fn new(params: <Self::Base as Full2WayBridgeBase>::Params) -> anyhow::Result<Self>;
|
||||
|
||||
fn base(&self) -> &Self::Base;
|
||||
|
||||
fn mut_base(&mut self) -> &mut Self::Base;
|
||||
|
||||
async fn run(&mut self) -> anyhow::Result<()> {
|
||||
let left_client = self.base().common().left.clone();
|
||||
let left_transactions_mortality = self.base().common().left_transactions_mortality;
|
||||
let left_sign = self.base().common().left_sign.clone();
|
||||
let left_messages_pallet_owner = self.base().common().left_messages_pallet_owner.clone();
|
||||
let right_client = self.base().common().right.clone();
|
||||
let right_transactions_mortality = self.base().common().right_transactions_mortality;
|
||||
let right_sign = self.base().common().right_sign.clone();
|
||||
let right_messages_pallet_owner = self.base().common().right_messages_pallet_owner.clone();
|
||||
|
||||
let lanes = self.base().common().shared.lane.clone();
|
||||
let relayer_mode = self.base().common().shared.relayer_mode.into();
|
||||
let relay_strategy = MixStrategy::new(relayer_mode);
|
||||
|
||||
// create metrics registry and register standalone metrics
|
||||
let metrics_params: MetricsParams =
|
||||
self.base().common().shared.prometheus_params.clone().into();
|
||||
let metrics_params = relay_utils::relay_metrics(metrics_params).into_params();
|
||||
let left_to_right_metrics = substrate_relay_helper::messages_metrics::standalone_metrics::<
|
||||
<Self::L2R as MessagesCliBridge>::MessagesLane,
|
||||
>(left_client.clone(), right_client.clone())?;
|
||||
let right_to_left_metrics = left_to_right_metrics.clone().reverse();
|
||||
self.mut_base().mut_common().at_left_accounts.push(TaggedAccount::Messages {
|
||||
id: left_sign.public().into(),
|
||||
bridged_chain: Self::Right::NAME.to_string(),
|
||||
});
|
||||
self.mut_base().mut_common().at_right_accounts.push(TaggedAccount::Messages {
|
||||
id: right_sign.public().into(),
|
||||
bridged_chain: Self::Left::NAME.to_string(),
|
||||
});
|
||||
|
||||
// start conversion rate update loops for left/right chains
|
||||
if let Some(left_messages_pallet_owner) = left_messages_pallet_owner.clone() {
|
||||
let left_client = left_client.clone();
|
||||
let format_err = || {
|
||||
anyhow::format_err!(
|
||||
"Cannon run conversion rate updater: {} -> {}",
|
||||
Self::Right::NAME,
|
||||
Self::Left::NAME
|
||||
)
|
||||
};
|
||||
substrate_relay_helper::conversion_rate_update::run_conversion_rate_update_loop::<
|
||||
<Self::L2R as MessagesCliBridge>::MessagesLane,
|
||||
Self::Left,
|
||||
>(
|
||||
left_client,
|
||||
TransactionParams {
|
||||
signer: left_messages_pallet_owner.clone(),
|
||||
mortality: left_transactions_mortality,
|
||||
},
|
||||
left_to_right_metrics
|
||||
.target_to_source_conversion_rate
|
||||
.as_ref()
|
||||
.ok_or_else(format_err)?
|
||||
.shared_value_ref(),
|
||||
left_to_right_metrics
|
||||
.target_to_base_conversion_rate
|
||||
.as_ref()
|
||||
.ok_or_else(format_err)?
|
||||
.shared_value_ref(),
|
||||
left_to_right_metrics
|
||||
.source_to_base_conversion_rate
|
||||
.as_ref()
|
||||
.ok_or_else(format_err)?
|
||||
.shared_value_ref(),
|
||||
CONVERSION_RATE_ALLOWED_DIFFERENCE_RATIO,
|
||||
);
|
||||
self.mut_base().mut_common().at_left_accounts.push(
|
||||
TaggedAccount::MessagesPalletOwner {
|
||||
id: left_messages_pallet_owner.public().into(),
|
||||
bridged_chain: Self::Right::NAME.to_string(),
|
||||
},
|
||||
);
|
||||
}
|
||||
if let Some(right_messages_pallet_owner) = right_messages_pallet_owner.clone() {
|
||||
let right_client = right_client.clone();
|
||||
let format_err = || {
|
||||
anyhow::format_err!(
|
||||
"Cannon run conversion rate updater: {} -> {}",
|
||||
Self::Left::NAME,
|
||||
Self::Right::NAME
|
||||
)
|
||||
};
|
||||
substrate_relay_helper::conversion_rate_update::run_conversion_rate_update_loop::<
|
||||
<Self::R2L as MessagesCliBridge>::MessagesLane,
|
||||
Self::Right,
|
||||
>(
|
||||
right_client,
|
||||
TransactionParams {
|
||||
signer: right_messages_pallet_owner.clone(),
|
||||
mortality: right_transactions_mortality,
|
||||
},
|
||||
right_to_left_metrics
|
||||
.target_to_source_conversion_rate
|
||||
.as_ref()
|
||||
.ok_or_else(format_err)?
|
||||
.shared_value_ref(),
|
||||
right_to_left_metrics
|
||||
.target_to_base_conversion_rate
|
||||
.as_ref()
|
||||
.ok_or_else(format_err)?
|
||||
.shared_value_ref(),
|
||||
right_to_left_metrics
|
||||
.source_to_base_conversion_rate
|
||||
.as_ref()
|
||||
.ok_or_else(format_err)?
|
||||
.shared_value_ref(),
|
||||
CONVERSION_RATE_ALLOWED_DIFFERENCE_RATIO,
|
||||
);
|
||||
self.mut_base().mut_common().at_right_accounts.push(
|
||||
TaggedAccount::MessagesPalletOwner {
|
||||
id: right_messages_pallet_owner.public().into(),
|
||||
bridged_chain: Self::Left::NAME.to_string(),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// start on-demand header relays
|
||||
let (left_to_right_on_demand_headers, right_to_left_on_demand_headers) =
|
||||
self.mut_base().start_on_demand_headers_relayers().await?;
|
||||
|
||||
// add balance-related metrics
|
||||
let metrics_params = substrate_relay_helper::messages_metrics::add_relay_balances_metrics(
|
||||
left_client.clone(),
|
||||
metrics_params,
|
||||
&self.base().common().at_left_accounts,
|
||||
)
|
||||
.await?;
|
||||
let metrics_params = substrate_relay_helper::messages_metrics::add_relay_balances_metrics(
|
||||
right_client.clone(),
|
||||
metrics_params,
|
||||
&self.base().common().at_right_accounts,
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Need 2x capacity since we consider both directions for each lane
|
||||
let mut message_relays = Vec::with_capacity(lanes.len() * 2);
|
||||
for lane in lanes {
|
||||
let lane = lane.into();
|
||||
let left_to_right_messages = substrate_relay_helper::messages_lane::run::<
|
||||
<Self::L2R as MessagesCliBridge>::MessagesLane,
|
||||
>(MessagesRelayParams {
|
||||
source_client: left_client.clone(),
|
||||
source_transaction_params: TransactionParams {
|
||||
signer: left_sign.clone(),
|
||||
mortality: left_transactions_mortality,
|
||||
},
|
||||
target_client: right_client.clone(),
|
||||
target_transaction_params: TransactionParams {
|
||||
signer: right_sign.clone(),
|
||||
mortality: right_transactions_mortality,
|
||||
},
|
||||
source_to_target_headers_relay: Some(left_to_right_on_demand_headers.clone()),
|
||||
target_to_source_headers_relay: Some(right_to_left_on_demand_headers.clone()),
|
||||
lane_id: lane,
|
||||
metrics_params: metrics_params.clone().disable(),
|
||||
standalone_metrics: Some(left_to_right_metrics.clone()),
|
||||
relay_strategy: relay_strategy.clone(),
|
||||
})
|
||||
.map_err(|e| anyhow::format_err!("{}", e))
|
||||
.boxed();
|
||||
let right_to_left_messages = substrate_relay_helper::messages_lane::run::<
|
||||
<Self::R2L as MessagesCliBridge>::MessagesLane,
|
||||
>(MessagesRelayParams {
|
||||
source_client: right_client.clone(),
|
||||
source_transaction_params: TransactionParams {
|
||||
signer: right_sign.clone(),
|
||||
mortality: right_transactions_mortality,
|
||||
},
|
||||
target_client: left_client.clone(),
|
||||
target_transaction_params: TransactionParams {
|
||||
signer: left_sign.clone(),
|
||||
mortality: left_transactions_mortality,
|
||||
},
|
||||
source_to_target_headers_relay: Some(right_to_left_on_demand_headers.clone()),
|
||||
target_to_source_headers_relay: Some(left_to_right_on_demand_headers.clone()),
|
||||
lane_id: lane,
|
||||
metrics_params: metrics_params.clone().disable(),
|
||||
standalone_metrics: Some(right_to_left_metrics.clone()),
|
||||
relay_strategy: relay_strategy.clone(),
|
||||
})
|
||||
.map_err(|e| anyhow::format_err!("{}", e))
|
||||
.boxed();
|
||||
|
||||
message_relays.push(left_to_right_messages);
|
||||
message_relays.push(right_to_left_messages);
|
||||
}
|
||||
|
||||
relay_utils::relay_metrics(metrics_params)
|
||||
.expose()
|
||||
.await
|
||||
.map_err(|e| anyhow::format_err!("{}", e))?;
|
||||
|
||||
futures::future::select_all(message_relays).await.0
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MillauRialtoFull2WayBridge {
|
||||
base: <Self as Full2WayBridge>::Base,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Full2WayBridge for MillauRialtoFull2WayBridge {
|
||||
type Base = RelayToRelayBridge<Self::L2R, Self::R2L>;
|
||||
type Left = relay_millau_client::Millau;
|
||||
type Right = relay_rialto_client::Rialto;
|
||||
type L2R = MillauToRialtoCliBridge;
|
||||
type R2L = RialtoToMillauCliBridge;
|
||||
|
||||
fn new(base: Self::Base) -> anyhow::Result<Self> {
|
||||
Ok(Self { base })
|
||||
}
|
||||
|
||||
fn base(&self) -> &Self::Base {
|
||||
&self.base
|
||||
}
|
||||
|
||||
fn mut_base(&mut self) -> &mut Self::Base {
|
||||
&mut self.base
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MillauRialtoParachainFull2WayBridge {
|
||||
base: <Self as Full2WayBridge>::Base,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Full2WayBridge for MillauRialtoParachainFull2WayBridge {
|
||||
type Base = RelayToParachainBridge<Self::L2R, Self::R2L>;
|
||||
type Left = relay_millau_client::Millau;
|
||||
type Right = relay_rialto_parachain_client::RialtoParachain;
|
||||
type L2R = MillauToRialtoParachainCliBridge;
|
||||
type R2L = RialtoParachainToMillauCliBridge;
|
||||
|
||||
fn new(base: Self::Base) -> anyhow::Result<Self> {
|
||||
Ok(Self { base })
|
||||
}
|
||||
|
||||
fn base(&self) -> &Self::Base {
|
||||
&self.base
|
||||
}
|
||||
|
||||
fn mut_base(&mut self) -> &mut Self::Base {
|
||||
&mut self.base
|
||||
}
|
||||
}
|
||||
|
||||
/// Start headers+messages relayer process.
|
||||
#[derive(Debug, PartialEq, StructOpt)]
|
||||
pub enum RelayHeadersAndMessages {
|
||||
MillauRialto(MillauRialtoHeadersAndMessages),
|
||||
MillauRialtoParachain(MillauRialtoParachainHeadersAndMessages),
|
||||
}
|
||||
|
||||
impl RelayHeadersAndMessages {
|
||||
/// Run the command.
|
||||
pub async fn run(self) -> anyhow::Result<()> {
|
||||
match self {
|
||||
RelayHeadersAndMessages::MillauRialto(params) =>
|
||||
MillauRialtoFull2WayBridge::new(params.into_bridge().await?)?.run().await,
|
||||
RelayHeadersAndMessages::MillauRialtoParachain(params) =>
|
||||
MillauRialtoParachainFull2WayBridge::new(params.into_bridge().await?)?
|
||||
.run()
|
||||
.await,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn should_parse_relay_to_relay_options() {
|
||||
// when
|
||||
let res = RelayHeadersAndMessages::from_iter(vec![
|
||||
"relay-headers-and-messages",
|
||||
"millau-rialto",
|
||||
"--millau-host",
|
||||
"millau-node-alice",
|
||||
"--millau-port",
|
||||
"9944",
|
||||
"--millau-signer",
|
||||
"//Charlie",
|
||||
"--millau-messages-pallet-owner",
|
||||
"//RialtoMessagesOwner",
|
||||
"--millau-transactions-mortality",
|
||||
"64",
|
||||
"--rialto-host",
|
||||
"rialto-node-alice",
|
||||
"--rialto-port",
|
||||
"9944",
|
||||
"--rialto-signer",
|
||||
"//Charlie",
|
||||
"--rialto-messages-pallet-owner",
|
||||
"//MillauMessagesOwner",
|
||||
"--rialto-transactions-mortality",
|
||||
"64",
|
||||
"--lane",
|
||||
"00000000",
|
||||
"--lane",
|
||||
"73776170",
|
||||
"--prometheus-host",
|
||||
"0.0.0.0",
|
||||
]);
|
||||
|
||||
// then
|
||||
assert_eq!(
|
||||
res,
|
||||
RelayHeadersAndMessages::MillauRialto(MillauRialtoHeadersAndMessages {
|
||||
shared: HeadersAndMessagesSharedParams {
|
||||
lane: vec![
|
||||
HexLaneId([0x00, 0x00, 0x00, 0x00]),
|
||||
HexLaneId([0x73, 0x77, 0x61, 0x70])
|
||||
],
|
||||
relayer_mode: RelayerMode::Rational,
|
||||
only_mandatory_headers: false,
|
||||
prometheus_params: PrometheusParams {
|
||||
no_prometheus: false,
|
||||
prometheus_host: "0.0.0.0".into(),
|
||||
prometheus_port: 9616,
|
||||
},
|
||||
},
|
||||
left: MillauConnectionParams {
|
||||
millau_host: "millau-node-alice".into(),
|
||||
millau_port: 9944,
|
||||
millau_secure: false,
|
||||
millau_runtime_version: MillauRuntimeVersionParams {
|
||||
millau_version_mode: RuntimeVersionType::Bundle,
|
||||
millau_spec_version: None,
|
||||
millau_transaction_version: None,
|
||||
},
|
||||
},
|
||||
left_sign: MillauSigningParams {
|
||||
millau_signer: Some("//Charlie".into()),
|
||||
millau_signer_password: None,
|
||||
millau_signer_file: None,
|
||||
millau_signer_password_file: None,
|
||||
millau_transactions_mortality: Some(64),
|
||||
},
|
||||
left_messages_pallet_owner: MillauMessagesPalletOwnerSigningParams {
|
||||
millau_messages_pallet_owner: Some("//RialtoMessagesOwner".into()),
|
||||
millau_messages_pallet_owner_password: None,
|
||||
},
|
||||
left_headers_to_right_sign_override: MillauHeadersToRialtoSigningParams {
|
||||
millau_headers_to_rialto_signer: None,
|
||||
millau_headers_to_rialto_signer_password: None,
|
||||
millau_headers_to_rialto_signer_file: None,
|
||||
millau_headers_to_rialto_signer_password_file: None,
|
||||
millau_headers_to_rialto_transactions_mortality: None,
|
||||
},
|
||||
right: RialtoConnectionParams {
|
||||
rialto_host: "rialto-node-alice".into(),
|
||||
rialto_port: 9944,
|
||||
rialto_secure: false,
|
||||
rialto_runtime_version: RialtoRuntimeVersionParams {
|
||||
rialto_version_mode: RuntimeVersionType::Bundle,
|
||||
rialto_spec_version: None,
|
||||
rialto_transaction_version: None,
|
||||
},
|
||||
},
|
||||
right_sign: RialtoSigningParams {
|
||||
rialto_signer: Some("//Charlie".into()),
|
||||
rialto_signer_password: None,
|
||||
rialto_signer_file: None,
|
||||
rialto_signer_password_file: None,
|
||||
rialto_transactions_mortality: Some(64),
|
||||
},
|
||||
right_messages_pallet_owner: RialtoMessagesPalletOwnerSigningParams {
|
||||
rialto_messages_pallet_owner: Some("//MillauMessagesOwner".into()),
|
||||
rialto_messages_pallet_owner_password: None,
|
||||
},
|
||||
right_headers_to_left_sign_override: RialtoHeadersToMillauSigningParams {
|
||||
rialto_headers_to_millau_signer: None,
|
||||
rialto_headers_to_millau_signer_password: None,
|
||||
rialto_headers_to_millau_signer_file: None,
|
||||
rialto_headers_to_millau_signer_password_file: None,
|
||||
rialto_headers_to_millau_transactions_mortality: None,
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_parse_relay_to_parachain_options() {
|
||||
// when
|
||||
let res = RelayHeadersAndMessages::from_iter(vec![
|
||||
"relay-headers-and-messages",
|
||||
"millau-rialto-parachain",
|
||||
"--millau-host",
|
||||
"millau-node-alice",
|
||||
"--millau-port",
|
||||
"9944",
|
||||
"--millau-signer",
|
||||
"//Iden",
|
||||
"--rialto-headers-to-millau-signer",
|
||||
"//Ken",
|
||||
"--millau-messages-pallet-owner",
|
||||
"//RialtoParachainMessagesOwner",
|
||||
"--millau-transactions-mortality",
|
||||
"64",
|
||||
"--rialto-parachain-host",
|
||||
"rialto-parachain-collator-charlie",
|
||||
"--rialto-parachain-port",
|
||||
"9944",
|
||||
"--rialto-parachain-signer",
|
||||
"//George",
|
||||
"--rialto-parachain-messages-pallet-owner",
|
||||
"//MillauMessagesOwner",
|
||||
"--rialto-parachain-transactions-mortality",
|
||||
"64",
|
||||
"--rialto-host",
|
||||
"rialto-node-alice",
|
||||
"--rialto-port",
|
||||
"9944",
|
||||
"--lane",
|
||||
"00000000",
|
||||
"--prometheus-host",
|
||||
"0.0.0.0",
|
||||
]);
|
||||
|
||||
// then
|
||||
assert_eq!(
|
||||
res,
|
||||
RelayHeadersAndMessages::MillauRialtoParachain(
|
||||
MillauRialtoParachainHeadersAndMessages {
|
||||
shared: HeadersAndMessagesSharedParams {
|
||||
lane: vec![HexLaneId([0x00, 0x00, 0x00, 0x00])],
|
||||
relayer_mode: RelayerMode::Rational,
|
||||
only_mandatory_headers: false,
|
||||
prometheus_params: PrometheusParams {
|
||||
no_prometheus: false,
|
||||
prometheus_host: "0.0.0.0".into(),
|
||||
prometheus_port: 9616,
|
||||
},
|
||||
},
|
||||
left: MillauConnectionParams {
|
||||
millau_host: "millau-node-alice".into(),
|
||||
millau_port: 9944,
|
||||
millau_secure: false,
|
||||
millau_runtime_version: MillauRuntimeVersionParams {
|
||||
millau_version_mode: RuntimeVersionType::Bundle,
|
||||
millau_spec_version: None,
|
||||
millau_transaction_version: None,
|
||||
},
|
||||
},
|
||||
left_sign: MillauSigningParams {
|
||||
millau_signer: Some("//Iden".into()),
|
||||
millau_signer_password: None,
|
||||
millau_signer_file: None,
|
||||
millau_signer_password_file: None,
|
||||
millau_transactions_mortality: Some(64),
|
||||
},
|
||||
left_messages_pallet_owner: MillauMessagesPalletOwnerSigningParams {
|
||||
millau_messages_pallet_owner: Some("//RialtoParachainMessagesOwner".into()),
|
||||
millau_messages_pallet_owner_password: None,
|
||||
},
|
||||
left_headers_to_right_sign_override:
|
||||
MillauHeadersToRialtoParachainSigningParams {
|
||||
millau_headers_to_rialto_parachain_signer: None,
|
||||
millau_headers_to_rialto_parachain_signer_password: None,
|
||||
millau_headers_to_rialto_parachain_signer_file: None,
|
||||
millau_headers_to_rialto_parachain_signer_password_file: None,
|
||||
millau_headers_to_rialto_parachain_transactions_mortality: None,
|
||||
},
|
||||
right: RialtoParachainConnectionParams {
|
||||
rialto_parachain_host: "rialto-parachain-collator-charlie".into(),
|
||||
rialto_parachain_port: 9944,
|
||||
rialto_parachain_secure: false,
|
||||
rialto_parachain_runtime_version: RialtoParachainRuntimeVersionParams {
|
||||
rialto_parachain_version_mode: RuntimeVersionType::Bundle,
|
||||
rialto_parachain_spec_version: None,
|
||||
rialto_parachain_transaction_version: None,
|
||||
},
|
||||
},
|
||||
right_sign: RialtoParachainSigningParams {
|
||||
rialto_parachain_signer: Some("//George".into()),
|
||||
rialto_parachain_signer_password: None,
|
||||
rialto_parachain_signer_file: None,
|
||||
rialto_parachain_signer_password_file: None,
|
||||
rialto_parachain_transactions_mortality: Some(64),
|
||||
},
|
||||
right_messages_pallet_owner: RialtoParachainMessagesPalletOwnerSigningParams {
|
||||
rialto_parachain_messages_pallet_owner: Some(
|
||||
"//MillauMessagesOwner".into()
|
||||
),
|
||||
rialto_parachain_messages_pallet_owner_password: None,
|
||||
},
|
||||
right_relay_headers_to_left_sign_override: RialtoHeadersToMillauSigningParams {
|
||||
rialto_headers_to_millau_signer: Some("//Ken".into()),
|
||||
rialto_headers_to_millau_signer_password: None,
|
||||
rialto_headers_to_millau_signer_file: None,
|
||||
rialto_headers_to_millau_signer_password_file: None,
|
||||
rialto_headers_to_millau_transactions_mortality: None,
|
||||
},
|
||||
right_parachains_to_left_sign_override: RialtoParachainsToMillauSigningParams {
|
||||
rialto_parachains_to_millau_signer: None,
|
||||
rialto_parachains_to_millau_signer_password: None,
|
||||
rialto_parachains_to_millau_signer_file: None,
|
||||
rialto_parachains_to_millau_signer_password_file: None,
|
||||
rialto_parachains_to_millau_transactions_mortality: None,
|
||||
},
|
||||
right_relay: RialtoConnectionParams {
|
||||
rialto_host: "rialto-node-alice".into(),
|
||||
rialto_port: 9944,
|
||||
rialto_secure: false,
|
||||
rialto_runtime_version: RialtoRuntimeVersionParams {
|
||||
rialto_version_mode: RuntimeVersionType::Bundle,
|
||||
rialto_spec_version: None,
|
||||
rialto_transaction_version: None,
|
||||
},
|
||||
},
|
||||
}
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
+235
@@ -0,0 +1,235 @@
|
||||
// Copyright 2019-2022 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity Bridges Common.
|
||||
|
||||
// Parity Bridges Common is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity Bridges Common is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use async_trait::async_trait;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::cli::{
|
||||
bridge::{
|
||||
CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge,
|
||||
RelayToRelayHeadersCliBridge,
|
||||
},
|
||||
relay_headers_and_messages::{Full2WayBridgeBase, Full2WayBridgeCommonParams},
|
||||
CliChain,
|
||||
};
|
||||
use bp_polkadot_core::parachains::ParaHash;
|
||||
use bp_runtime::BlockNumberOf;
|
||||
use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
|
||||
use relay_substrate_client::{AccountIdOf, AccountKeyPairOf, Chain, Client, TransactionSignScheme};
|
||||
use sp_core::Pair;
|
||||
use substrate_relay_helper::{
|
||||
finality::SubstrateFinalitySyncPipeline,
|
||||
on_demand::{
|
||||
headers::OnDemandHeadersRelay, parachains::OnDemandParachainsRelay, OnDemandRelay,
|
||||
},
|
||||
TaggedAccount, TransactionParams,
|
||||
};
|
||||
|
||||
pub struct RelayToParachainBridge<
|
||||
L2R: MessagesCliBridge + RelayToRelayHeadersCliBridge,
|
||||
R2L: MessagesCliBridge + ParachainToRelayHeadersCliBridge,
|
||||
> {
|
||||
pub common:
|
||||
Full2WayBridgeCommonParams<<R2L as CliBridgeBase>::Target, <L2R as CliBridgeBase>::Target>,
|
||||
pub right_relay: Client<<R2L as ParachainToRelayHeadersCliBridge>::SourceRelay>,
|
||||
|
||||
// override for right_relay->left headers signer
|
||||
pub right_headers_to_left_transaction_params:
|
||||
TransactionParams<AccountKeyPairOf<<R2L as CliBridgeBase>::Target>>,
|
||||
// override for right->left parachains signer
|
||||
pub right_parachains_to_left_transaction_params:
|
||||
TransactionParams<AccountKeyPairOf<<R2L as CliBridgeBase>::Target>>,
|
||||
// override for left->right headers signer
|
||||
pub left_headers_to_right_transaction_params:
|
||||
TransactionParams<AccountKeyPairOf<<L2R as CliBridgeBase>::Target>>,
|
||||
}
|
||||
|
||||
macro_rules! declare_relay_to_parachain_bridge_schema {
|
||||
// chain, parachain, relay-chain-of-parachain
|
||||
($left_chain:ident, $right_parachain:ident, $right_chain:ident) => {
|
||||
paste::item! {
|
||||
#[doc = $left_chain ", " $right_parachain " and " $right_chain " headers+parachains+messages relay params."]
|
||||
#[derive(Debug, PartialEq, StructOpt)]
|
||||
pub struct [<$left_chain $right_parachain HeadersAndMessages>] {
|
||||
#[structopt(flatten)]
|
||||
shared: HeadersAndMessagesSharedParams,
|
||||
#[structopt(flatten)]
|
||||
left: [<$left_chain ConnectionParams>],
|
||||
// default signer, which is always used to sign messages relay transactions on the left chain
|
||||
#[structopt(flatten)]
|
||||
left_sign: [<$left_chain SigningParams>],
|
||||
// override for right_relay->left headers signer
|
||||
#[structopt(flatten)]
|
||||
right_relay_headers_to_left_sign_override: [<$right_chain HeadersTo $left_chain SigningParams>],
|
||||
// override for right->left parachains signer
|
||||
#[structopt(flatten)]
|
||||
right_parachains_to_left_sign_override: [<$right_chain ParachainsTo $left_chain SigningParams>],
|
||||
#[structopt(flatten)]
|
||||
left_messages_pallet_owner: [<$left_chain MessagesPalletOwnerSigningParams>],
|
||||
#[structopt(flatten)]
|
||||
right: [<$right_parachain ConnectionParams>],
|
||||
// default signer, which is always used to sign messages relay transactions on the right chain
|
||||
#[structopt(flatten)]
|
||||
right_sign: [<$right_parachain SigningParams>],
|
||||
// override for left->right headers signer
|
||||
#[structopt(flatten)]
|
||||
left_headers_to_right_sign_override: [<$left_chain HeadersTo $right_parachain SigningParams>],
|
||||
#[structopt(flatten)]
|
||||
right_messages_pallet_owner: [<$right_parachain MessagesPalletOwnerSigningParams>],
|
||||
#[structopt(flatten)]
|
||||
right_relay: [<$right_chain ConnectionParams>],
|
||||
}
|
||||
|
||||
impl [<$left_chain $right_parachain HeadersAndMessages>] {
|
||||
async fn into_bridge<
|
||||
Left: TransactionSignScheme + CliChain<KeyPair = AccountKeyPairOf<Left>>,
|
||||
Right: TransactionSignScheme + CliChain<KeyPair = AccountKeyPairOf<Right>>,
|
||||
RightRelay: TransactionSignScheme + CliChain,
|
||||
L2R: CliBridgeBase<Source = Left, Target = Right> + MessagesCliBridge + RelayToRelayHeadersCliBridge,
|
||||
R2L: CliBridgeBase<Source = Right, Target = Left>
|
||||
+ MessagesCliBridge
|
||||
+ ParachainToRelayHeadersCliBridge<SourceRelay = RightRelay>,
|
||||
>(
|
||||
self,
|
||||
) -> anyhow::Result<RelayToParachainBridge<L2R, R2L>> {
|
||||
Ok(RelayToParachainBridge {
|
||||
common: Full2WayBridgeCommonParams {
|
||||
shared: self.shared,
|
||||
left: self.left.into_client::<Left>().await?,
|
||||
left_sign: self.left_sign.to_keypair::<Left>()?,
|
||||
left_transactions_mortality: self.left_sign.transactions_mortality()?,
|
||||
left_messages_pallet_owner: self.left_messages_pallet_owner.to_keypair::<Left>()?,
|
||||
at_left_accounts: vec![],
|
||||
right: self.right.into_client::<Right>().await?,
|
||||
right_sign: self.right_sign.to_keypair::<Right>()?,
|
||||
right_transactions_mortality: self.right_sign.transactions_mortality()?,
|
||||
right_messages_pallet_owner: self.right_messages_pallet_owner.to_keypair::<Right>()?,
|
||||
at_right_accounts: vec![],
|
||||
},
|
||||
right_relay: self.right_relay.into_client::<RightRelay>().await?,
|
||||
right_headers_to_left_transaction_params: self
|
||||
.right_relay_headers_to_left_sign_override
|
||||
.transaction_params_or::<Left, _>(
|
||||
&self.left_sign,
|
||||
)?,
|
||||
right_parachains_to_left_transaction_params: self
|
||||
.right_parachains_to_left_sign_override
|
||||
.transaction_params_or::<Left, _>(
|
||||
&self.left_sign,
|
||||
)?,
|
||||
left_headers_to_right_transaction_params: self
|
||||
.left_headers_to_right_sign_override
|
||||
.transaction_params_or::<Right, _>(&self.right_sign)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<
|
||||
Left: Chain + TransactionSignScheme<Chain = Left> + CliChain<KeyPair = AccountKeyPairOf<Left>>,
|
||||
Right: Chain<Hash = ParaHash>
|
||||
+ TransactionSignScheme<Chain = Right>
|
||||
+ CliChain<KeyPair = AccountKeyPairOf<Right>>,
|
||||
RightRelay: Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>
|
||||
+ TransactionSignScheme
|
||||
+ CliChain,
|
||||
L2R: CliBridgeBase<Source = Left, Target = Right>
|
||||
+ MessagesCliBridge
|
||||
+ RelayToRelayHeadersCliBridge,
|
||||
R2L: CliBridgeBase<Source = Right, Target = Left>
|
||||
+ MessagesCliBridge
|
||||
+ ParachainToRelayHeadersCliBridge<SourceRelay = RightRelay>,
|
||||
> Full2WayBridgeBase for RelayToParachainBridge<L2R, R2L>
|
||||
where
|
||||
AccountIdOf<Left>: From<<AccountKeyPairOf<Left> as Pair>::Public>,
|
||||
AccountIdOf<Right>: From<<AccountKeyPairOf<Right> as Pair>::Public>,
|
||||
{
|
||||
type Params = RelayToParachainBridge<L2R, R2L>;
|
||||
type Left = Left;
|
||||
type Right = Right;
|
||||
|
||||
fn common(&self) -> &Full2WayBridgeCommonParams<Left, Right> {
|
||||
&self.common
|
||||
}
|
||||
|
||||
fn mut_common(&mut self) -> &mut Full2WayBridgeCommonParams<Self::Left, Self::Right> {
|
||||
&mut self.common
|
||||
}
|
||||
|
||||
async fn start_on_demand_headers_relayers(
|
||||
&mut self,
|
||||
) -> anyhow::Result<(
|
||||
Arc<dyn OnDemandRelay<BlockNumberOf<Self::Left>>>,
|
||||
Arc<dyn OnDemandRelay<BlockNumberOf<Self::Right>>>,
|
||||
)> {
|
||||
self.common.at_left_accounts.push(TaggedAccount::Headers {
|
||||
id: self.right_headers_to_left_transaction_params.signer.public().into(),
|
||||
bridged_chain: RightRelay::NAME.to_string(),
|
||||
});
|
||||
self.common.at_left_accounts.push(TaggedAccount::Parachains {
|
||||
id: self.right_parachains_to_left_transaction_params.signer.public().into(),
|
||||
bridged_chain: RightRelay::NAME.to_string(),
|
||||
});
|
||||
self.common.at_right_accounts.push(TaggedAccount::Headers {
|
||||
id: self.left_headers_to_right_transaction_params.signer.public().into(),
|
||||
bridged_chain: Left::NAME.to_string(),
|
||||
});
|
||||
|
||||
<L2R as RelayToRelayHeadersCliBridge>::Finality::start_relay_guards(
|
||||
&self.common.right,
|
||||
&self.left_headers_to_right_transaction_params,
|
||||
self.common.right.can_start_version_guard(),
|
||||
)
|
||||
.await?;
|
||||
<R2L as ParachainToRelayHeadersCliBridge>::RelayFinality::start_relay_guards(
|
||||
&self.common.left,
|
||||
&self.right_headers_to_left_transaction_params,
|
||||
self.common.left.can_start_version_guard(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let left_to_right_on_demand_headers =
|
||||
OnDemandHeadersRelay::new::<<L2R as RelayToRelayHeadersCliBridge>::Finality>(
|
||||
self.common.left.clone(),
|
||||
self.common.right.clone(),
|
||||
self.left_headers_to_right_transaction_params.clone(),
|
||||
self.common.shared.only_mandatory_headers,
|
||||
);
|
||||
let right_relay_to_left_on_demand_headers =
|
||||
OnDemandHeadersRelay::new::<<R2L as ParachainToRelayHeadersCliBridge>::RelayFinality>(
|
||||
self.right_relay.clone(),
|
||||
self.common.left.clone(),
|
||||
self.right_headers_to_left_transaction_params.clone(),
|
||||
self.common.shared.only_mandatory_headers,
|
||||
);
|
||||
let right_to_left_on_demand_parachains = OnDemandParachainsRelay::new::<
|
||||
<R2L as ParachainToRelayHeadersCliBridge>::ParachainFinality,
|
||||
>(
|
||||
self.right_relay.clone(),
|
||||
self.common.left.clone(),
|
||||
self.right_parachains_to_left_transaction_params.clone(),
|
||||
Arc::new(right_relay_to_left_on_demand_headers),
|
||||
);
|
||||
|
||||
Ok((
|
||||
Arc::new(left_to_right_on_demand_headers),
|
||||
Arc::new(right_to_left_on_demand_parachains),
|
||||
))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
// Copyright 2019-2022 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity Bridges Common.
|
||||
|
||||
// Parity Bridges Common is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity Bridges Common is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use async_trait::async_trait;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::cli::{
|
||||
bridge::{CliBridgeBase, MessagesCliBridge, RelayToRelayHeadersCliBridge},
|
||||
relay_headers_and_messages::{Full2WayBridgeBase, Full2WayBridgeCommonParams},
|
||||
CliChain,
|
||||
};
|
||||
use bp_runtime::BlockNumberOf;
|
||||
use relay_substrate_client::{AccountIdOf, AccountKeyPairOf, Chain, TransactionSignScheme};
|
||||
use sp_core::Pair;
|
||||
use substrate_relay_helper::{
|
||||
finality::SubstrateFinalitySyncPipeline,
|
||||
on_demand::{headers::OnDemandHeadersRelay, OnDemandRelay},
|
||||
TaggedAccount, TransactionParams,
|
||||
};
|
||||
|
||||
pub struct RelayToRelayBridge<
|
||||
L2R: MessagesCliBridge + RelayToRelayHeadersCliBridge,
|
||||
R2L: MessagesCliBridge + RelayToRelayHeadersCliBridge,
|
||||
> {
|
||||
pub common:
|
||||
Full2WayBridgeCommonParams<<R2L as CliBridgeBase>::Target, <L2R as CliBridgeBase>::Target>,
|
||||
// override for right->left headers signer
|
||||
pub right_to_left_transaction_params:
|
||||
TransactionParams<AccountKeyPairOf<<R2L as CliBridgeBase>::Target>>,
|
||||
// override for left->right headers signer
|
||||
pub left_to_right_transaction_params:
|
||||
TransactionParams<AccountKeyPairOf<<L2R as CliBridgeBase>::Target>>,
|
||||
}
|
||||
|
||||
macro_rules! declare_relay_to_relay_bridge_schema {
|
||||
($left_chain:ident, $right_chain:ident) => {
|
||||
paste::item! {
|
||||
#[doc = $left_chain " and " $right_chain " headers+messages relay params."]
|
||||
#[derive(Debug, PartialEq, StructOpt)]
|
||||
pub struct [<$left_chain $right_chain HeadersAndMessages>] {
|
||||
#[structopt(flatten)]
|
||||
shared: HeadersAndMessagesSharedParams,
|
||||
// default signer, which is always used to sign messages relay transactions on the left chain
|
||||
#[structopt(flatten)]
|
||||
left: [<$left_chain ConnectionParams>],
|
||||
// override for right->left headers signer
|
||||
#[structopt(flatten)]
|
||||
right_headers_to_left_sign_override: [<$right_chain HeadersTo $left_chain SigningParams>],
|
||||
#[structopt(flatten)]
|
||||
left_sign: [<$left_chain SigningParams>],
|
||||
#[structopt(flatten)]
|
||||
left_messages_pallet_owner: [<$left_chain MessagesPalletOwnerSigningParams>],
|
||||
// default signer, which is always used to sign messages relay transactions on the right chain
|
||||
#[structopt(flatten)]
|
||||
right: [<$right_chain ConnectionParams>],
|
||||
// override for left->right headers signer
|
||||
#[structopt(flatten)]
|
||||
left_headers_to_right_sign_override: [<$left_chain HeadersTo $right_chain SigningParams>],
|
||||
#[structopt(flatten)]
|
||||
right_sign: [<$right_chain SigningParams>],
|
||||
#[structopt(flatten)]
|
||||
right_messages_pallet_owner: [<$right_chain MessagesPalletOwnerSigningParams>],
|
||||
}
|
||||
|
||||
impl [<$left_chain $right_chain HeadersAndMessages>] {
|
||||
async fn into_bridge<
|
||||
Left: TransactionSignScheme + CliChain<KeyPair = AccountKeyPairOf<Left>>,
|
||||
Right: TransactionSignScheme + CliChain<KeyPair = AccountKeyPairOf<Right>>,
|
||||
L2R: CliBridgeBase<Source = Left, Target = Right> + MessagesCliBridge + RelayToRelayHeadersCliBridge,
|
||||
R2L: CliBridgeBase<Source = Right, Target = Left> + MessagesCliBridge + RelayToRelayHeadersCliBridge,
|
||||
>(
|
||||
self,
|
||||
) -> anyhow::Result<RelayToRelayBridge<L2R, R2L>> {
|
||||
Ok(RelayToRelayBridge {
|
||||
common: Full2WayBridgeCommonParams {
|
||||
shared: self.shared,
|
||||
left: self.left.into_client::<Left>().await?,
|
||||
left_sign: self.left_sign.to_keypair::<Left>()?,
|
||||
left_transactions_mortality: self.left_sign.transactions_mortality()?,
|
||||
left_messages_pallet_owner: self.left_messages_pallet_owner.to_keypair::<Left>()?,
|
||||
at_left_accounts: vec![],
|
||||
right: self.right.into_client::<Right>().await?,
|
||||
right_sign: self.right_sign.to_keypair::<Right>()?,
|
||||
right_transactions_mortality: self.right_sign.transactions_mortality()?,
|
||||
right_messages_pallet_owner: self.right_messages_pallet_owner.to_keypair::<Right>()?,
|
||||
at_right_accounts: vec![],
|
||||
},
|
||||
|
||||
right_to_left_transaction_params: self
|
||||
.right_headers_to_left_sign_override
|
||||
.transaction_params_or::<Left, _>(&self.left_sign)?,
|
||||
left_to_right_transaction_params: self
|
||||
.left_headers_to_right_sign_override
|
||||
.transaction_params_or::<Right, _>(&self.right_sign)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<
|
||||
Left: Chain + TransactionSignScheme<Chain = Left> + CliChain<KeyPair = AccountKeyPairOf<Left>>,
|
||||
Right: Chain + TransactionSignScheme<Chain = Right> + CliChain<KeyPair = AccountKeyPairOf<Right>>,
|
||||
L2R: CliBridgeBase<Source = Left, Target = Right>
|
||||
+ MessagesCliBridge
|
||||
+ RelayToRelayHeadersCliBridge,
|
||||
R2L: CliBridgeBase<Source = Right, Target = Left>
|
||||
+ MessagesCliBridge
|
||||
+ RelayToRelayHeadersCliBridge,
|
||||
> Full2WayBridgeBase for RelayToRelayBridge<L2R, R2L>
|
||||
where
|
||||
AccountIdOf<Left>: From<<AccountKeyPairOf<Left> as Pair>::Public>,
|
||||
AccountIdOf<Right>: From<<AccountKeyPairOf<Right> as Pair>::Public>,
|
||||
{
|
||||
type Params = RelayToRelayBridge<L2R, R2L>;
|
||||
type Left = Left;
|
||||
type Right = Right;
|
||||
|
||||
fn common(&self) -> &Full2WayBridgeCommonParams<Left, Right> {
|
||||
&self.common
|
||||
}
|
||||
|
||||
fn mut_common(&mut self) -> &mut Full2WayBridgeCommonParams<Self::Left, Self::Right> {
|
||||
&mut self.common
|
||||
}
|
||||
|
||||
async fn start_on_demand_headers_relayers(
|
||||
&mut self,
|
||||
) -> anyhow::Result<(
|
||||
Arc<dyn OnDemandRelay<BlockNumberOf<Self::Left>>>,
|
||||
Arc<dyn OnDemandRelay<BlockNumberOf<Self::Right>>>,
|
||||
)> {
|
||||
self.common.at_right_accounts.push(TaggedAccount::Headers {
|
||||
id: self.left_to_right_transaction_params.signer.public().into(),
|
||||
bridged_chain: Self::Left::NAME.to_string(),
|
||||
});
|
||||
self.common.at_left_accounts.push(TaggedAccount::Headers {
|
||||
id: self.right_to_left_transaction_params.signer.public().into(),
|
||||
bridged_chain: Self::Right::NAME.to_string(),
|
||||
});
|
||||
|
||||
<L2R as RelayToRelayHeadersCliBridge>::Finality::start_relay_guards(
|
||||
&self.common.right,
|
||||
&self.left_to_right_transaction_params,
|
||||
self.common.right.can_start_version_guard(),
|
||||
)
|
||||
.await?;
|
||||
<R2L as RelayToRelayHeadersCliBridge>::Finality::start_relay_guards(
|
||||
&self.common.left,
|
||||
&self.right_to_left_transaction_params,
|
||||
self.common.left.can_start_version_guard(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let left_to_right_on_demand_headers =
|
||||
OnDemandHeadersRelay::new::<<L2R as RelayToRelayHeadersCliBridge>::Finality>(
|
||||
self.common.left.clone(),
|
||||
self.common.right.clone(),
|
||||
self.left_to_right_transaction_params.clone(),
|
||||
self.common.shared.only_mandatory_headers,
|
||||
);
|
||||
let right_to_left_on_demand_headers =
|
||||
OnDemandHeadersRelay::new::<<R2L as RelayToRelayHeadersCliBridge>::Finality>(
|
||||
self.common.right.clone(),
|
||||
self.common.left.clone(),
|
||||
self.right_to_left_transaction_params.clone(),
|
||||
self.common.shared.only_mandatory_headers,
|
||||
);
|
||||
|
||||
Ok((Arc::new(left_to_right_on_demand_headers), Arc::new(right_to_left_on_demand_headers)))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user