mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 01:41:03 +00:00
Move generic CLI logic to different crate (#2885)
* Move generic CLI logic to separate crate * Move and rename `CliChain` trait definition Move it to `relay-substrate-client` * Move generic cli logic to substrate-relay-helper * Fix docs warnings
This commit is contained in:
committed by
Bastian Köcher
parent
bfce7a250f
commit
3643f721d4
+5
-2
@@ -16,10 +16,13 @@
|
||||
|
||||
//! BridgeHubKusama-to-BridgeHubPolkadot messages sync entrypoint.
|
||||
|
||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge};
|
||||
use relay_bridge_hub_kusama_client::BridgeHubKusama;
|
||||
use relay_bridge_hub_polkadot_client::BridgeHubPolkadot;
|
||||
use substrate_relay_helper::{messages_lane::SubstrateMessageLane, UtilityPalletBatchCallBuilder};
|
||||
use substrate_relay_helper::{
|
||||
cli::bridge::{CliBridgeBase, MessagesCliBridge},
|
||||
messages_lane::SubstrateMessageLane,
|
||||
UtilityPalletBatchCallBuilder,
|
||||
};
|
||||
|
||||
/// BridgeHubKusama-to-BridgeHubPolkadot messages bridge.
|
||||
pub struct BridgeHubKusamaToBridgeHubPolkadotMessagesCliBridge {}
|
||||
|
||||
+5
-2
@@ -16,10 +16,13 @@
|
||||
|
||||
//! BridgeHubPolkadot-to-BridgeHubKusama messages sync entrypoint.
|
||||
|
||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge};
|
||||
use relay_bridge_hub_kusama_client::BridgeHubKusama;
|
||||
use relay_bridge_hub_polkadot_client::BridgeHubPolkadot;
|
||||
use substrate_relay_helper::{messages_lane::SubstrateMessageLane, UtilityPalletBatchCallBuilder};
|
||||
use substrate_relay_helper::{
|
||||
cli::bridge::{CliBridgeBase, MessagesCliBridge},
|
||||
messages_lane::SubstrateMessageLane,
|
||||
UtilityPalletBatchCallBuilder,
|
||||
};
|
||||
|
||||
/// BridgeHubPolkadot-to-BridgeHubKusama messages bridge.
|
||||
pub struct BridgeHubPolkadotToBridgeHubKusamaMessagesCliBridge {}
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
|
||||
//! Kusama-to-BridgeHubPolkadot headers sync entrypoint.
|
||||
|
||||
use crate::cli::bridge::{
|
||||
use substrate_relay_helper::cli::bridge::{
|
||||
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
||||
};
|
||||
|
||||
|
||||
+3
-3
@@ -16,11 +16,11 @@
|
||||
|
||||
//! Kusama-to-BridgeHubPolkadot parachains sync entrypoint.
|
||||
|
||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge};
|
||||
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
|
||||
use relay_substrate_client::{CallOf, HeaderIdOf};
|
||||
use substrate_relay_helper::parachains::{
|
||||
SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline,
|
||||
use substrate_relay_helper::{
|
||||
cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge},
|
||||
parachains::{SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline},
|
||||
};
|
||||
|
||||
/// Kusama-to-BridgeHubPolkadot parachain sync description.
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
|
||||
//! Polkadot-to-KusamaBridgeHub headers sync entrypoint.
|
||||
|
||||
use crate::cli::bridge::{
|
||||
use substrate_relay_helper::cli::bridge::{
|
||||
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
||||
};
|
||||
|
||||
|
||||
+3
-3
@@ -16,11 +16,11 @@
|
||||
|
||||
//! Polkadot-to-BridgeHubKusama parachains sync entrypoint.
|
||||
|
||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge};
|
||||
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
|
||||
use relay_substrate_client::{CallOf, HeaderIdOf};
|
||||
use substrate_relay_helper::parachains::{
|
||||
SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline,
|
||||
use substrate_relay_helper::{
|
||||
cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge},
|
||||
parachains::{SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline},
|
||||
};
|
||||
|
||||
/// Polkadot-to-BridgeHubKusama parachain sync description.
|
||||
|
||||
+5
-2
@@ -16,10 +16,13 @@
|
||||
|
||||
//! BridgeHubPolkadot-to-PolkadotBulletin messages sync entrypoint.
|
||||
|
||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge};
|
||||
use relay_bridge_hub_polkadot_client::BridgeHubPolkadot;
|
||||
use relay_polkadot_bulletin_client::PolkadotBulletin;
|
||||
use substrate_relay_helper::{messages_lane::SubstrateMessageLane, UtilityPalletBatchCallBuilder};
|
||||
use substrate_relay_helper::{
|
||||
cli::bridge::{CliBridgeBase, MessagesCliBridge},
|
||||
messages_lane::SubstrateMessageLane,
|
||||
UtilityPalletBatchCallBuilder,
|
||||
};
|
||||
|
||||
/// BridgeHubPolkadot-to-PolkadotBulletin messages bridge.
|
||||
pub struct BridgeHubPolkadotToPolkadotBulletinMessagesCliBridge {}
|
||||
|
||||
+5
-5
@@ -16,11 +16,6 @@
|
||||
|
||||
//! PolkadotBulletin-to-BridgeHubPolkadot headers sync entrypoint.
|
||||
|
||||
use crate::cli::bridge::{
|
||||
CliBridgeBase, MessagesCliBridge, RelayToRelayEquivocationDetectionCliBridge,
|
||||
RelayToRelayHeadersCliBridge,
|
||||
};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use substrate_relay_helper::{
|
||||
equivocation::SubstrateEquivocationDetectionPipeline,
|
||||
@@ -28,6 +23,11 @@ use substrate_relay_helper::{
|
||||
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
|
||||
};
|
||||
|
||||
use substrate_relay_helper::cli::bridge::{
|
||||
CliBridgeBase, MessagesCliBridge, RelayToRelayEquivocationDetectionCliBridge,
|
||||
RelayToRelayHeadersCliBridge,
|
||||
};
|
||||
|
||||
/// Description of `PolkadotBulletin` -> `PolkadotBridgeHub` finalized headers bridge.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PolkadotBulletinFinalityToBridgeHubPolkadot;
|
||||
|
||||
+5
-2
@@ -16,10 +16,13 @@
|
||||
|
||||
//! PolkadotBulletin-to-BridgeHubPolkadot messages sync entrypoint.
|
||||
|
||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge};
|
||||
use relay_bridge_hub_polkadot_client::BridgeHubPolkadot;
|
||||
use relay_polkadot_bulletin_client::PolkadotBulletin;
|
||||
use substrate_relay_helper::{messages_lane::SubstrateMessageLane, UtilityPalletBatchCallBuilder};
|
||||
use substrate_relay_helper::{
|
||||
cli::bridge::{CliBridgeBase, MessagesCliBridge},
|
||||
messages_lane::SubstrateMessageLane,
|
||||
UtilityPalletBatchCallBuilder,
|
||||
};
|
||||
|
||||
/// PolkadotBulletin-to-BridgeHubPolkadot messages bridge.
|
||||
pub struct PolkadotBulletinToBridgeHubPolkadotMessagesCliBridge {}
|
||||
|
||||
+4
-4
@@ -16,10 +16,6 @@
|
||||
|
||||
//! Polkadot-to-PolkadotBulletin headers sync entrypoint.
|
||||
|
||||
use crate::cli::bridge::{
|
||||
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
||||
};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use substrate_relay_helper::{
|
||||
equivocation::SubstrateEquivocationDetectionPipeline,
|
||||
@@ -27,6 +23,10 @@ use substrate_relay_helper::{
|
||||
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
|
||||
};
|
||||
|
||||
use substrate_relay_helper::cli::bridge::{
|
||||
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
||||
};
|
||||
|
||||
/// Description of Polkadot -> `PolkadotBulletin` finalized headers bridge.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PolkadotFinalityToPolkadotBulletin;
|
||||
|
||||
+3
-1
@@ -16,7 +16,9 @@
|
||||
|
||||
//! Polkadot-to-PolkadotBulletin parachains sync entrypoint.
|
||||
|
||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge};
|
||||
use substrate_relay_helper::cli::bridge::{
|
||||
CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge,
|
||||
};
|
||||
|
||||
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
|
||||
use bp_runtime::Chain;
|
||||
|
||||
+5
-2
@@ -17,9 +17,12 @@
|
||||
//! BridgeHubRococo-to-RococoBulletin messages sync entrypoint.
|
||||
|
||||
use super::BridgeHubRococoAsBridgeHubPolkadot;
|
||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge};
|
||||
use relay_polkadot_bulletin_client::PolkadotBulletin as RococoBulletin;
|
||||
use substrate_relay_helper::{messages_lane::SubstrateMessageLane, UtilityPalletBatchCallBuilder};
|
||||
use substrate_relay_helper::{
|
||||
cli::bridge::{CliBridgeBase, MessagesCliBridge},
|
||||
messages_lane::SubstrateMessageLane,
|
||||
UtilityPalletBatchCallBuilder,
|
||||
};
|
||||
|
||||
/// BridgeHubRococo-to-RococoBulletin messages bridge.
|
||||
pub struct BridgeHubRococoToRococoBulletinMessagesCliBridge {}
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
//! Declaration of all bridges between Rococo Bulletin Chain and Rococo Bridge Hub.
|
||||
|
||||
use crate::cli::CliChain;
|
||||
|
||||
use bp_messages::MessageNonce;
|
||||
use bp_runtime::{
|
||||
AccountIdOf, BalanceOf, BlockNumberOf, ChainId, HashOf, HasherOf, HeaderOf, NonceOf,
|
||||
@@ -25,7 +23,8 @@ use bp_runtime::{
|
||||
};
|
||||
use frame_support::pallet_prelude::Weight;
|
||||
use relay_substrate_client::{
|
||||
Error as SubstrateError, SignParam, SimpleRuntimeVersion, UnsignedTransaction,
|
||||
ChainWithRuntimeVersion, Error as SubstrateError, SignParam, SimpleRuntimeVersion,
|
||||
UnsignedTransaction,
|
||||
};
|
||||
use sp_core::storage::StorageKey;
|
||||
use std::time::Duration;
|
||||
@@ -127,7 +126,7 @@ impl relay_substrate_client::ChainWithTransactions for RococoAsPolkadot {
|
||||
}
|
||||
}
|
||||
|
||||
impl CliChain for RococoAsPolkadot {
|
||||
impl ChainWithRuntimeVersion for RococoAsPolkadot {
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> = None;
|
||||
}
|
||||
|
||||
@@ -232,7 +231,7 @@ impl relay_substrate_client::ChainWithMessages for BridgeHubRococoAsBridgeHubPol
|
||||
relay_bridge_hub_polkadot_client::BridgeHubPolkadot::FROM_CHAIN_MESSAGE_DETAILS_METHOD;
|
||||
}
|
||||
|
||||
impl CliChain for BridgeHubRococoAsBridgeHubPolkadot {
|
||||
impl ChainWithRuntimeVersion for BridgeHubRococoAsBridgeHubPolkadot {
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
||||
Some(SimpleRuntimeVersion { spec_version: 1_003_000, transaction_version: 3 });
|
||||
}
|
||||
|
||||
+5
-4
@@ -17,10 +17,6 @@
|
||||
//! RococoBulletin-to-BridgeHubRococo headers sync entrypoint.
|
||||
|
||||
use super::BridgeHubRococoAsBridgeHubPolkadot;
|
||||
use crate::cli::bridge::{
|
||||
CliBridgeBase, MessagesCliBridge, RelayToRelayEquivocationDetectionCliBridge,
|
||||
RelayToRelayHeadersCliBridge,
|
||||
};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use substrate_relay_helper::{
|
||||
@@ -29,6 +25,11 @@ use substrate_relay_helper::{
|
||||
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
|
||||
};
|
||||
|
||||
use substrate_relay_helper::cli::bridge::{
|
||||
CliBridgeBase, MessagesCliBridge, RelayToRelayEquivocationDetectionCliBridge,
|
||||
RelayToRelayHeadersCliBridge,
|
||||
};
|
||||
|
||||
/// Description of `RococoBulletin` -> `RococoBridgeHub` finalized headers bridge.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RococoBulletinFinalityToBridgeHubRococo;
|
||||
|
||||
+5
-2
@@ -17,9 +17,12 @@
|
||||
//! RococoBulletin-to-BridgeHubRococo messages sync entrypoint.
|
||||
|
||||
use super::BridgeHubRococoAsBridgeHubPolkadot;
|
||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge};
|
||||
use relay_polkadot_bulletin_client::PolkadotBulletin as RococoBulletin;
|
||||
use substrate_relay_helper::{messages_lane::SubstrateMessageLane, UtilityPalletBatchCallBuilder};
|
||||
use substrate_relay_helper::{
|
||||
cli::bridge::{CliBridgeBase, MessagesCliBridge},
|
||||
messages_lane::SubstrateMessageLane,
|
||||
UtilityPalletBatchCallBuilder,
|
||||
};
|
||||
|
||||
/// RococoBulletin-to-BridgeHubRococo messages bridge.
|
||||
pub struct RococoBulletinToBridgeHubRococoMessagesCliBridge {}
|
||||
|
||||
+4
-3
@@ -17,9 +17,6 @@
|
||||
//! Rococo-to-RococoBulletin headers sync entrypoint.
|
||||
|
||||
use super::RococoAsPolkadot;
|
||||
use crate::cli::bridge::{
|
||||
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
||||
};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use substrate_relay_helper::{
|
||||
@@ -28,6 +25,10 @@ use substrate_relay_helper::{
|
||||
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
|
||||
};
|
||||
|
||||
use substrate_relay_helper::cli::bridge::{
|
||||
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
||||
};
|
||||
|
||||
/// Description of Rococo -> `RococoBulletin` finalized headers bridge.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RococoFinalityToRococoBulletin;
|
||||
|
||||
+1
-1
@@ -17,12 +17,12 @@
|
||||
//! Rococo-to-RococoBulletin parachains sync entrypoint.
|
||||
|
||||
use super::{BridgeHubRococoAsBridgeHubPolkadot, RococoAsPolkadot};
|
||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge};
|
||||
|
||||
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
|
||||
use bp_runtime::Chain;
|
||||
use relay_substrate_client::{CallOf, HeaderIdOf};
|
||||
use substrate_relay_helper::{
|
||||
cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge},
|
||||
messages_lane::MessagesRelayLimits,
|
||||
parachains::{SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline},
|
||||
};
|
||||
|
||||
+5
-2
@@ -16,10 +16,13 @@
|
||||
|
||||
//! BridgeHubRococo-to-BridgeHubWestend messages sync entrypoint.
|
||||
|
||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge};
|
||||
use relay_bridge_hub_rococo_client::BridgeHubRococo;
|
||||
use relay_bridge_hub_westend_client::BridgeHubWestend;
|
||||
use substrate_relay_helper::{messages_lane::SubstrateMessageLane, UtilityPalletBatchCallBuilder};
|
||||
use substrate_relay_helper::{
|
||||
cli::bridge::{CliBridgeBase, MessagesCliBridge},
|
||||
messages_lane::SubstrateMessageLane,
|
||||
UtilityPalletBatchCallBuilder,
|
||||
};
|
||||
|
||||
pub struct BridgeHubRococoToBridgeHubWestendMessagesCliBridge {}
|
||||
|
||||
|
||||
+5
-2
@@ -16,10 +16,13 @@
|
||||
|
||||
//! BridgeHubWestend-to-BridgeHubRococo messages sync entrypoint.
|
||||
|
||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge};
|
||||
use relay_bridge_hub_rococo_client::BridgeHubRococo;
|
||||
use relay_bridge_hub_westend_client::BridgeHubWestend;
|
||||
use substrate_relay_helper::{messages_lane::SubstrateMessageLane, UtilityPalletBatchCallBuilder};
|
||||
use substrate_relay_helper::{
|
||||
cli::bridge::{CliBridgeBase, MessagesCliBridge},
|
||||
messages_lane::SubstrateMessageLane,
|
||||
UtilityPalletBatchCallBuilder,
|
||||
};
|
||||
|
||||
pub struct BridgeHubWestendToBridgeHubRococoMessagesCliBridge {}
|
||||
|
||||
|
||||
+4
-4
@@ -16,10 +16,6 @@
|
||||
|
||||
//! Rococo-to-Westend bridge hubs headers sync entrypoint.
|
||||
|
||||
use crate::cli::bridge::{
|
||||
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
||||
};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use substrate_relay_helper::{
|
||||
equivocation::SubstrateEquivocationDetectionPipeline,
|
||||
@@ -27,6 +23,10 @@ use substrate_relay_helper::{
|
||||
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
|
||||
};
|
||||
|
||||
use substrate_relay_helper::cli::bridge::{
|
||||
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
||||
};
|
||||
|
||||
/// Description of Rococo -> Westend finalized headers bridge.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RococoFinalityToBridgeHubWestend;
|
||||
|
||||
+3
-3
@@ -16,11 +16,11 @@
|
||||
|
||||
//! Westend-to-Rococo parachains sync entrypoint.
|
||||
|
||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge};
|
||||
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
|
||||
use relay_substrate_client::{CallOf, HeaderIdOf};
|
||||
use substrate_relay_helper::parachains::{
|
||||
SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline,
|
||||
use substrate_relay_helper::{
|
||||
cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge},
|
||||
parachains::{SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline},
|
||||
};
|
||||
|
||||
/// BridgeHub-to-BridgeHub parachain sync description.
|
||||
|
||||
+4
-4
@@ -16,10 +16,6 @@
|
||||
|
||||
//! Westend-to-Rococo bridge hubs headers sync entrypoint.
|
||||
|
||||
use crate::cli::bridge::{
|
||||
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
||||
};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use substrate_relay_helper::{
|
||||
equivocation::SubstrateEquivocationDetectionPipeline,
|
||||
@@ -27,6 +23,10 @@ use substrate_relay_helper::{
|
||||
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
|
||||
};
|
||||
|
||||
use substrate_relay_helper::cli::bridge::{
|
||||
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
||||
};
|
||||
|
||||
/// Description of Westend -> Rococo finalized headers bridge.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct WestendFinalityToBridgeHubRococo;
|
||||
|
||||
+3
-3
@@ -16,11 +16,11 @@
|
||||
|
||||
//! Rococo-to-Westend parachains sync entrypoint.
|
||||
|
||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge};
|
||||
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
|
||||
use relay_substrate_client::{CallOf, HeaderIdOf};
|
||||
use substrate_relay_helper::parachains::{
|
||||
SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline,
|
||||
use substrate_relay_helper::{
|
||||
cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge},
|
||||
parachains::{SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline},
|
||||
};
|
||||
|
||||
/// BridgeHub-to-BridgeHub parachain sync description.
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
// Copyright 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/>.
|
||||
|
||||
//! Kusama + Kusama parachains specification for CLI.
|
||||
|
||||
use crate::cli::CliChain;
|
||||
use relay_bridge_hub_kusama_client::BridgeHubKusama;
|
||||
use relay_kusama_client::Kusama;
|
||||
use relay_substrate_client::SimpleRuntimeVersion;
|
||||
|
||||
impl CliChain for Kusama {
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
||||
Some(SimpleRuntimeVersion { spec_version: 1_001_002, transaction_version: 25 });
|
||||
}
|
||||
|
||||
impl CliChain for BridgeHubKusama {
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
||||
Some(SimpleRuntimeVersion { spec_version: 1_001_000, transaction_version: 4 });
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
// Copyright 2019-2021 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/>.
|
||||
|
||||
//! Chain-specific relayer configuration.
|
||||
|
||||
mod kusama;
|
||||
mod polkadot;
|
||||
mod polkadot_bulletin;
|
||||
mod rococo;
|
||||
mod westend;
|
||||
@@ -1,32 +0,0 @@
|
||||
// Copyright 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/>.
|
||||
|
||||
//! Polkadot + Polkadot parachains specification for CLI.
|
||||
|
||||
use crate::cli::CliChain;
|
||||
use relay_bridge_hub_polkadot_client::BridgeHubPolkadot;
|
||||
use relay_polkadot_client::Polkadot;
|
||||
use relay_substrate_client::SimpleRuntimeVersion;
|
||||
|
||||
impl CliChain for Polkadot {
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
||||
Some(SimpleRuntimeVersion { spec_version: 1_001_002, transaction_version: 25 });
|
||||
}
|
||||
|
||||
impl CliChain for BridgeHubPolkadot {
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
||||
Some(SimpleRuntimeVersion { spec_version: 1_001_000, transaction_version: 3 });
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
// Copyright 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/>.
|
||||
|
||||
//! Polkadot + Polkadot parachains specification for CLI.
|
||||
|
||||
use crate::cli::CliChain;
|
||||
use relay_polkadot_bulletin_client::PolkadotBulletin;
|
||||
use relay_substrate_client::SimpleRuntimeVersion;
|
||||
|
||||
impl CliChain for PolkadotBulletin {
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
||||
Some(SimpleRuntimeVersion { spec_version: 100, transaction_version: 1 });
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
// Copyright 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/>.
|
||||
|
||||
//! Rococo + Rococo parachains specification for CLI.
|
||||
|
||||
use crate::cli::CliChain;
|
||||
use relay_bridge_hub_rococo_client::BridgeHubRococo;
|
||||
use relay_rococo_client::Rococo;
|
||||
use relay_substrate_client::SimpleRuntimeVersion;
|
||||
|
||||
impl CliChain for Rococo {
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
||||
Some(SimpleRuntimeVersion { spec_version: 1_008_000, transaction_version: 24 });
|
||||
}
|
||||
|
||||
impl CliChain for BridgeHubRococo {
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
||||
Some(SimpleRuntimeVersion { spec_version: 1_008_000, transaction_version: 4 });
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
// Copyright 2019-2021 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/>.
|
||||
|
||||
//! Westend chain specification for CLI.
|
||||
|
||||
use crate::cli::CliChain;
|
||||
use relay_bridge_hub_westend_client::BridgeHubWestend;
|
||||
use relay_substrate_client::SimpleRuntimeVersion;
|
||||
use relay_westend_client::Westend;
|
||||
|
||||
impl CliChain for Westend {
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
||||
Some(SimpleRuntimeVersion { spec_version: 1_008_000, transaction_version: 24 });
|
||||
}
|
||||
|
||||
impl CliChain for BridgeHubWestend {
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
||||
Some(SimpleRuntimeVersion { spec_version: 1_008_000, transaction_version: 4 });
|
||||
}
|
||||
@@ -12,248 +12,12 @@
|
||||
// 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 relay_substrate_client::{AccountKeyPairOf, ChainWithTransactions};
|
||||
use structopt::StructOpt;
|
||||
use strum::{EnumString, VariantNames};
|
||||
|
||||
use crate::cli::CliChain;
|
||||
pub use relay_substrate_client::{ChainRuntimeVersion, SimpleRuntimeVersion};
|
||||
use substrate_relay_helper::TransactionParams;
|
||||
|
||||
#[doc = "Runtime version params."]
|
||||
#[derive(StructOpt, Debug, PartialEq, Eq, Clone, Copy, EnumString, VariantNames)]
|
||||
pub enum RuntimeVersionType {
|
||||
/// Auto query version from chain
|
||||
Auto,
|
||||
/// Custom `spec_version` and `transaction_version`
|
||||
Custom,
|
||||
/// Read version from bundle dependencies directly.
|
||||
Bundle,
|
||||
}
|
||||
|
||||
/// Create chain-specific set of runtime version parameters.
|
||||
#[macro_export]
|
||||
macro_rules! declare_chain_runtime_version_params_cli_schema {
|
||||
($chain:ident, $chain_prefix:ident) => {
|
||||
bp_runtime::paste::item! {
|
||||
#[doc = $chain " runtime version params."]
|
||||
#[derive(StructOpt, Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub struct [<$chain RuntimeVersionParams>] {
|
||||
#[doc = "The type of runtime version for chain " $chain]
|
||||
#[structopt(long, default_value = "Bundle")]
|
||||
pub [<$chain_prefix _version_mode>]: RuntimeVersionType,
|
||||
#[doc = "The custom sepc_version for chain " $chain]
|
||||
#[structopt(long)]
|
||||
pub [<$chain_prefix _spec_version>]: Option<u32>,
|
||||
#[doc = "The custom transaction_version for chain " $chain]
|
||||
#[structopt(long)]
|
||||
pub [<$chain_prefix _transaction_version>]: Option<u32>,
|
||||
}
|
||||
|
||||
impl [<$chain RuntimeVersionParams>] {
|
||||
/// Converts self into `ChainRuntimeVersion`.
|
||||
pub fn into_runtime_version(
|
||||
self,
|
||||
bundle_runtime_version: Option<SimpleRuntimeVersion>,
|
||||
) -> anyhow::Result<ChainRuntimeVersion> {
|
||||
Ok(match self.[<$chain_prefix _version_mode>] {
|
||||
RuntimeVersionType::Auto => ChainRuntimeVersion::Auto,
|
||||
RuntimeVersionType::Custom => {
|
||||
let custom_spec_version = self.[<$chain_prefix _spec_version>]
|
||||
.ok_or_else(|| anyhow::Error::msg(format!("The {}-spec-version is required when choose custom mode", stringify!($chain_prefix))))?;
|
||||
let custom_transaction_version = self.[<$chain_prefix _transaction_version>]
|
||||
.ok_or_else(|| anyhow::Error::msg(format!("The {}-transaction-version is required when choose custom mode", stringify!($chain_prefix))))?;
|
||||
ChainRuntimeVersion::Custom(
|
||||
SimpleRuntimeVersion {
|
||||
spec_version: custom_spec_version,
|
||||
transaction_version: custom_transaction_version
|
||||
}
|
||||
)
|
||||
},
|
||||
RuntimeVersionType::Bundle => match bundle_runtime_version {
|
||||
Some(runtime_version) => ChainRuntimeVersion::Custom(runtime_version),
|
||||
None => {
|
||||
return Err(anyhow::format_err!("Cannot use bundled runtime version of {}: it is not known to the relay", stringify!($chain_prefix)));
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Create chain-specific set of runtime version parameters.
|
||||
#[macro_export]
|
||||
macro_rules! declare_chain_connection_params_cli_schema {
|
||||
($chain:ident, $chain_prefix:ident) => {
|
||||
bp_runtime::paste::item! {
|
||||
#[doc = $chain " connection params."]
|
||||
#[derive(StructOpt, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct [<$chain ConnectionParams>] {
|
||||
#[doc = "Connect to " $chain " node at given host."]
|
||||
#[structopt(long, default_value = "127.0.0.1")]
|
||||
pub [<$chain_prefix _host>]: String,
|
||||
#[doc = "Connect to " $chain " node websocket server at given port."]
|
||||
#[structopt(long, default_value = "9944")]
|
||||
pub [<$chain_prefix _port>]: u16,
|
||||
#[doc = "Use secure websocket connection."]
|
||||
#[structopt(long)]
|
||||
pub [<$chain_prefix _secure>]: bool,
|
||||
#[doc = "Custom runtime version"]
|
||||
#[structopt(flatten)]
|
||||
pub [<$chain_prefix _runtime_version>]: [<$chain RuntimeVersionParams>],
|
||||
}
|
||||
|
||||
impl [<$chain ConnectionParams>] {
|
||||
/// Convert connection params into Substrate client.
|
||||
#[allow(dead_code)]
|
||||
pub async fn into_client<Chain: CliChain>(
|
||||
self,
|
||||
) -> anyhow::Result<relay_substrate_client::Client<Chain>> {
|
||||
let chain_runtime_version = self
|
||||
.[<$chain_prefix _runtime_version>]
|
||||
.into_runtime_version(Chain::RUNTIME_VERSION)?;
|
||||
Ok(relay_substrate_client::Client::new(relay_substrate_client::ConnectionParams {
|
||||
host: self.[<$chain_prefix _host>],
|
||||
port: self.[<$chain_prefix _port>],
|
||||
secure: self.[<$chain_prefix _secure>],
|
||||
chain_runtime_version,
|
||||
})
|
||||
.await
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Create chain-specific set of signing parameters.
|
||||
#[macro_export]
|
||||
macro_rules! declare_chain_signing_params_cli_schema {
|
||||
($chain:ident, $chain_prefix:ident) => {
|
||||
bp_runtime::paste::item! {
|
||||
#[doc = $chain " signing params."]
|
||||
#[derive(StructOpt, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct [<$chain SigningParams>] {
|
||||
#[doc = "The SURI of secret key to use when transactions are submitted to the " $chain " node."]
|
||||
#[structopt(long)]
|
||||
pub [<$chain_prefix _signer>]: Option<String>,
|
||||
#[doc = "The password for the SURI of secret key to use when transactions are submitted to the " $chain " node."]
|
||||
#[structopt(long)]
|
||||
pub [<$chain_prefix _signer_password>]: Option<String>,
|
||||
|
||||
#[doc = "Path to the file, that contains SURI of secret key to use when transactions are submitted to the " $chain " node. Can be overridden with " $chain_prefix "_signer option."]
|
||||
#[structopt(long)]
|
||||
pub [<$chain_prefix _signer_file>]: Option<std::path::PathBuf>,
|
||||
#[doc = "Path to the file, that password for the SURI of secret key to use when transactions are submitted to the " $chain " node. Can be overridden with " $chain_prefix "_signer_password option."]
|
||||
#[structopt(long)]
|
||||
pub [<$chain_prefix _signer_password_file>]: Option<std::path::PathBuf>,
|
||||
|
||||
#[doc = "Transactions mortality period, in blocks. MUST be a power of two in [4; 65536] range. MAY NOT be larger than `BlockHashCount` parameter of the chain system module."]
|
||||
#[structopt(long)]
|
||||
pub [<$chain_prefix _transactions_mortality>]: Option<u32>,
|
||||
}
|
||||
|
||||
impl [<$chain SigningParams>] {
|
||||
/// Return transactions mortality.
|
||||
#[allow(dead_code)]
|
||||
pub fn transactions_mortality(&self) -> anyhow::Result<Option<u32>> {
|
||||
self.[<$chain_prefix _transactions_mortality>]
|
||||
.map(|transactions_mortality| {
|
||||
if !(4..=65536).contains(&transactions_mortality)
|
||||
|| !transactions_mortality.is_power_of_two()
|
||||
{
|
||||
Err(anyhow::format_err!(
|
||||
"Transactions mortality {} is not a power of two in a [4; 65536] range",
|
||||
transactions_mortality,
|
||||
))
|
||||
} else {
|
||||
Ok(transactions_mortality)
|
||||
}
|
||||
})
|
||||
.transpose()
|
||||
}
|
||||
|
||||
/// Parse signing params into chain-specific KeyPair.
|
||||
#[allow(dead_code)]
|
||||
pub fn to_keypair<Chain: ChainWithTransactions>(&self) -> anyhow::Result<AccountKeyPairOf<Chain>> {
|
||||
let suri = match (self.[<$chain_prefix _signer>].as_ref(), self.[<$chain_prefix _signer_file>].as_ref()) {
|
||||
(Some(suri), _) => suri.to_owned(),
|
||||
(None, Some(suri_file)) => std::fs::read_to_string(suri_file)
|
||||
.map_err(|err| anyhow::format_err!(
|
||||
"Failed to read SURI from file {:?}: {}",
|
||||
suri_file,
|
||||
err,
|
||||
))?,
|
||||
(None, None) => return Err(anyhow::format_err!(
|
||||
"One of options must be specified: '{}' or '{}'",
|
||||
stringify!([<$chain_prefix _signer>]),
|
||||
stringify!([<$chain_prefix _signer_file>]),
|
||||
)),
|
||||
};
|
||||
|
||||
let suri_password = match (
|
||||
self.[<$chain_prefix _signer_password>].as_ref(),
|
||||
self.[<$chain_prefix _signer_password_file>].as_ref(),
|
||||
) {
|
||||
(Some(suri_password), _) => Some(suri_password.to_owned()),
|
||||
(None, Some(suri_password_file)) => std::fs::read_to_string(suri_password_file)
|
||||
.map(Some)
|
||||
.map_err(|err| anyhow::format_err!(
|
||||
"Failed to read SURI password from file {:?}: {}",
|
||||
suri_password_file,
|
||||
err,
|
||||
))?,
|
||||
_ => None,
|
||||
};
|
||||
|
||||
use sp_core::crypto::Pair;
|
||||
|
||||
AccountKeyPairOf::<Chain>::from_string(
|
||||
&suri,
|
||||
suri_password.as_deref()
|
||||
).map_err(|e| anyhow::format_err!("{:?}", e))
|
||||
}
|
||||
|
||||
/// Return transaction parameters.
|
||||
#[allow(dead_code)]
|
||||
pub fn transaction_params<Chain: ChainWithTransactions>(
|
||||
&self,
|
||||
) -> anyhow::Result<TransactionParams<AccountKeyPairOf<Chain>>> {
|
||||
Ok(TransactionParams {
|
||||
mortality: self.transactions_mortality()?,
|
||||
signer: self.to_keypair::<Chain>()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Create chain-specific set of configuration objects: connection parameters,
|
||||
/// signing parameters and bridge initialization parameters.
|
||||
#[macro_export]
|
||||
macro_rules! declare_chain_cli_schema {
|
||||
($chain:ident, $chain_prefix:ident) => {
|
||||
$crate::declare_chain_runtime_version_params_cli_schema!($chain, $chain_prefix);
|
||||
$crate::declare_chain_connection_params_cli_schema!($chain, $chain_prefix);
|
||||
$crate::declare_chain_signing_params_cli_schema!($chain, $chain_prefix);
|
||||
};
|
||||
}
|
||||
|
||||
declare_chain_cli_schema!(Source, source);
|
||||
declare_chain_cli_schema!(Target, target);
|
||||
declare_chain_cli_schema!(Relaychain, relaychain);
|
||||
declare_chain_cli_schema!(Parachain, parachain);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use sp_core::Pair;
|
||||
use substrate_relay_helper::cli::chain_schema::TargetSigningParams;
|
||||
|
||||
#[test]
|
||||
fn reads_suri_from_file() {
|
||||
|
||||
@@ -14,25 +14,23 @@
|
||||
// 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 crate::{
|
||||
bridges::{
|
||||
kusama_polkadot::{
|
||||
kusama_headers_to_bridge_hub_polkadot::KusamaToBridgeHubPolkadotCliBridge,
|
||||
polkadot_headers_to_bridge_hub_kusama::PolkadotToBridgeHubKusamaCliBridge,
|
||||
},
|
||||
rococo_westend::{
|
||||
rococo_headers_to_bridge_hub_westend::RococoToBridgeHubWestendCliBridge,
|
||||
westend_headers_to_bridge_hub_rococo::WestendToBridgeHubRococoCliBridge,
|
||||
},
|
||||
use crate::bridges::{
|
||||
kusama_polkadot::{
|
||||
kusama_headers_to_bridge_hub_polkadot::KusamaToBridgeHubPolkadotCliBridge,
|
||||
polkadot_headers_to_bridge_hub_kusama::PolkadotToBridgeHubKusamaCliBridge,
|
||||
},
|
||||
rococo_westend::{
|
||||
rococo_headers_to_bridge_hub_westend::RococoToBridgeHubWestendCliBridge,
|
||||
westend_headers_to_bridge_hub_rococo::WestendToBridgeHubRococoCliBridge,
|
||||
},
|
||||
cli::{bridge::*, chain_schema::*, PrometheusParams},
|
||||
};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use relay_substrate_client::ChainWithTransactions;
|
||||
use structopt::StructOpt;
|
||||
use strum::{EnumString, VariantNames};
|
||||
use substrate_relay_helper::{equivocation, equivocation::SubstrateEquivocationDetectionPipeline};
|
||||
|
||||
use substrate_relay_helper::cli::detect_equivocations::{
|
||||
DetectEquivocationsParams, EquivocationsDetector,
|
||||
};
|
||||
|
||||
/// Start equivocation detection loop.
|
||||
#[derive(StructOpt)]
|
||||
@@ -40,13 +38,7 @@ pub struct DetectEquivocations {
|
||||
#[structopt(possible_values = DetectEquivocationsBridge::VARIANTS, case_insensitive = true)]
|
||||
bridge: DetectEquivocationsBridge,
|
||||
#[structopt(flatten)]
|
||||
source: SourceConnectionParams,
|
||||
#[structopt(flatten)]
|
||||
source_sign: SourceSigningParams,
|
||||
#[structopt(flatten)]
|
||||
target: TargetConnectionParams,
|
||||
#[structopt(flatten)]
|
||||
prometheus_params: PrometheusParams,
|
||||
params: DetectEquivocationsParams,
|
||||
}
|
||||
|
||||
#[derive(Debug, EnumString, VariantNames)]
|
||||
@@ -59,29 +51,6 @@ pub enum DetectEquivocationsBridge {
|
||||
WestendToBridgeHubRococo,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
trait EquivocationsDetector: RelayToRelayEquivocationDetectionCliBridge
|
||||
where
|
||||
Self::Source: ChainWithTransactions,
|
||||
{
|
||||
async fn start(data: DetectEquivocations) -> anyhow::Result<()> {
|
||||
let source_client = data.source.into_client::<Self::Source>().await?;
|
||||
Self::Equivocation::start_relay_guards(
|
||||
&source_client,
|
||||
source_client.can_start_version_guard(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
equivocation::run::<Self::Equivocation>(
|
||||
source_client,
|
||||
data.target.into_client::<Self::Target>().await?,
|
||||
data.source_sign.transaction_params::<Self::Source>()?,
|
||||
data.prometheus_params.into_metrics_params()?,
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
impl EquivocationsDetector for KusamaToBridgeHubPolkadotCliBridge {}
|
||||
impl EquivocationsDetector for PolkadotToBridgeHubKusamaCliBridge {}
|
||||
impl EquivocationsDetector for RococoToBridgeHubWestendCliBridge {}
|
||||
@@ -92,13 +61,13 @@ impl DetectEquivocations {
|
||||
pub async fn run(self) -> anyhow::Result<()> {
|
||||
match self.bridge {
|
||||
DetectEquivocationsBridge::KusamaToBridgeHubPolkadot =>
|
||||
KusamaToBridgeHubPolkadotCliBridge::start(self),
|
||||
KusamaToBridgeHubPolkadotCliBridge::start(self.params),
|
||||
DetectEquivocationsBridge::PolkadotToBridgeHubKusama =>
|
||||
PolkadotToBridgeHubKusamaCliBridge::start(self),
|
||||
PolkadotToBridgeHubKusamaCliBridge::start(self.params),
|
||||
DetectEquivocationsBridge::RococoToBridgeHubWestend =>
|
||||
RococoToBridgeHubWestendCliBridge::start(self),
|
||||
RococoToBridgeHubWestendCliBridge::start(self.params),
|
||||
DetectEquivocationsBridge::WestendToBridgeHubRococo =>
|
||||
WestendToBridgeHubRococoCliBridge::start(self),
|
||||
WestendToBridgeHubRococoCliBridge::start(self.params),
|
||||
}
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -14,107 +14,31 @@
|
||||
// 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 codec::Encode;
|
||||
|
||||
use crate::{
|
||||
bridges::{
|
||||
kusama_polkadot::{
|
||||
kusama_headers_to_bridge_hub_polkadot::KusamaToBridgeHubPolkadotCliBridge,
|
||||
polkadot_headers_to_bridge_hub_kusama::PolkadotToBridgeHubKusamaCliBridge,
|
||||
},
|
||||
polkadot_bulletin::{
|
||||
polkadot_bulletin_headers_to_bridge_hub_polkadot::PolkadotBulletinToBridgeHubPolkadotCliBridge,
|
||||
polkadot_headers_to_polkadot_bulletin::PolkadotToPolkadotBulletinCliBridge,
|
||||
},
|
||||
rococo_bulletin::{
|
||||
rococo_bulletin_headers_to_bridge_hub_rococo::RococoBulletinToBridgeHubRococoCliBridge,
|
||||
rococo_headers_to_rococo_bulletin::RococoToRococoBulletinCliBridge,
|
||||
},
|
||||
rococo_westend::{
|
||||
rococo_headers_to_bridge_hub_westend::RococoToBridgeHubWestendCliBridge,
|
||||
westend_headers_to_bridge_hub_rococo::WestendToBridgeHubRococoCliBridge,
|
||||
},
|
||||
use crate::bridges::{
|
||||
kusama_polkadot::{
|
||||
kusama_headers_to_bridge_hub_polkadot::KusamaToBridgeHubPolkadotCliBridge,
|
||||
polkadot_headers_to_bridge_hub_kusama::PolkadotToBridgeHubKusamaCliBridge,
|
||||
},
|
||||
polkadot_bulletin::{
|
||||
polkadot_bulletin_headers_to_bridge_hub_polkadot::PolkadotBulletinToBridgeHubPolkadotCliBridge,
|
||||
polkadot_headers_to_polkadot_bulletin::PolkadotToPolkadotBulletinCliBridge,
|
||||
},
|
||||
rococo_bulletin::{
|
||||
rococo_bulletin_headers_to_bridge_hub_rococo::RococoBulletinToBridgeHubRococoCliBridge,
|
||||
rococo_headers_to_rococo_bulletin::RococoToRococoBulletinCliBridge,
|
||||
},
|
||||
rococo_westend::{
|
||||
rococo_headers_to_bridge_hub_westend::RococoToBridgeHubWestendCliBridge,
|
||||
westend_headers_to_bridge_hub_rococo::WestendToBridgeHubRococoCliBridge,
|
||||
},
|
||||
cli::{bridge::CliBridgeBase, chain_schema::*},
|
||||
};
|
||||
use bp_runtime::Chain as ChainBase;
|
||||
use relay_substrate_client::{AccountKeyPairOf, Chain, UnsignedTransaction};
|
||||
use sp_core::Pair;
|
||||
use relay_substrate_client::Chain;
|
||||
use structopt::StructOpt;
|
||||
use strum::{EnumString, VariantNames};
|
||||
use substrate_relay_helper::finality_base::engine::{Engine, Grandpa as GrandpaFinalityEngine};
|
||||
|
||||
/// Initialize bridge pallet.
|
||||
#[derive(StructOpt)]
|
||||
pub struct InitBridge {
|
||||
/// A bridge instance to initialize.
|
||||
#[structopt(possible_values = InitBridgeName::VARIANTS, case_insensitive = true)]
|
||||
bridge: InitBridgeName,
|
||||
#[structopt(flatten)]
|
||||
source: SourceConnectionParams,
|
||||
#[structopt(flatten)]
|
||||
target: TargetConnectionParams,
|
||||
#[structopt(flatten)]
|
||||
target_sign: TargetSigningParams,
|
||||
/// Generates all required data, but does not submit extrinsic
|
||||
#[structopt(long)]
|
||||
dry_run: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, EnumString, VariantNames)]
|
||||
#[strum(serialize_all = "kebab_case")]
|
||||
/// Bridge to initialize.
|
||||
pub enum InitBridgeName {
|
||||
KusamaToBridgeHubPolkadot,
|
||||
PolkadotToBridgeHubKusama,
|
||||
PolkadotToPolkadotBulletin,
|
||||
PolkadotBulletinToBridgeHubPolkadot,
|
||||
RococoToRococoBulletin,
|
||||
RococoBulletinToBridgeHubRococo,
|
||||
RococoToBridgeHubWestend,
|
||||
WestendToBridgeHubRococo,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
trait BridgeInitializer: CliBridgeBase
|
||||
where
|
||||
<Self::Target as ChainBase>::AccountId: From<<AccountKeyPairOf<Self::Target> as Pair>::Public>,
|
||||
{
|
||||
type Engine: Engine<Self::Source>;
|
||||
|
||||
/// Get the encoded call to init the bridge.
|
||||
fn encode_init_bridge(
|
||||
init_data: <Self::Engine as Engine<Self::Source>>::InitializationData,
|
||||
) -> <Self::Target as Chain>::Call;
|
||||
|
||||
/// Initialize the bridge.
|
||||
async fn init_bridge(data: InitBridge) -> anyhow::Result<()> {
|
||||
let source_client = data.source.into_client::<Self::Source>().await?;
|
||||
let target_client = data.target.into_client::<Self::Target>().await?;
|
||||
let target_sign = data.target_sign.to_keypair::<Self::Target>()?;
|
||||
let dry_run = data.dry_run;
|
||||
|
||||
substrate_relay_helper::finality::initialize::initialize::<Self::Engine, _, _, _>(
|
||||
source_client,
|
||||
target_client.clone(),
|
||||
target_sign,
|
||||
move |transaction_nonce, initialization_data| {
|
||||
let call = Self::encode_init_bridge(initialization_data);
|
||||
log::info!(
|
||||
target: "bridge",
|
||||
"Initialize bridge call encoded as hex string: {:?}",
|
||||
format!("0x{}", hex::encode(call.encode()))
|
||||
);
|
||||
Ok(UnsignedTransaction::new(call.into(), transaction_nonce))
|
||||
},
|
||||
dry_run,
|
||||
)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
use substrate_relay_helper::{
|
||||
cli::init_bridge::{BridgeInitializer, InitBridgeParams},
|
||||
finality_base::engine::{Engine, Grandpa as GrandpaFinalityEngine},
|
||||
};
|
||||
|
||||
impl BridgeInitializer for RococoToBridgeHubWestendCliBridge {
|
||||
type Engine = GrandpaFinalityEngine<Self::Source>;
|
||||
@@ -225,26 +149,50 @@ impl BridgeInitializer for RococoBulletinToBridgeHubRococoCliBridge {
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize bridge pallet.
|
||||
#[derive(StructOpt)]
|
||||
pub struct InitBridge {
|
||||
/// A bridge instance to initialize.
|
||||
#[structopt(possible_values = InitBridgeName::VARIANTS, case_insensitive = true)]
|
||||
bridge: InitBridgeName,
|
||||
#[structopt(flatten)]
|
||||
params: InitBridgeParams,
|
||||
}
|
||||
|
||||
#[derive(Debug, EnumString, VariantNames)]
|
||||
#[strum(serialize_all = "kebab_case")]
|
||||
/// Bridge to initialize.
|
||||
pub enum InitBridgeName {
|
||||
KusamaToBridgeHubPolkadot,
|
||||
PolkadotToBridgeHubKusama,
|
||||
PolkadotToPolkadotBulletin,
|
||||
PolkadotBulletinToBridgeHubPolkadot,
|
||||
RococoToRococoBulletin,
|
||||
RococoBulletinToBridgeHubRococo,
|
||||
RococoToBridgeHubWestend,
|
||||
WestendToBridgeHubRococo,
|
||||
}
|
||||
|
||||
impl InitBridge {
|
||||
/// Run the command.
|
||||
pub async fn run(self) -> anyhow::Result<()> {
|
||||
match self.bridge {
|
||||
InitBridgeName::KusamaToBridgeHubPolkadot =>
|
||||
KusamaToBridgeHubPolkadotCliBridge::init_bridge(self),
|
||||
KusamaToBridgeHubPolkadotCliBridge::init_bridge(self.params),
|
||||
InitBridgeName::PolkadotToBridgeHubKusama =>
|
||||
PolkadotToBridgeHubKusamaCliBridge::init_bridge(self),
|
||||
PolkadotToBridgeHubKusamaCliBridge::init_bridge(self.params),
|
||||
InitBridgeName::PolkadotToPolkadotBulletin =>
|
||||
PolkadotToPolkadotBulletinCliBridge::init_bridge(self),
|
||||
PolkadotToPolkadotBulletinCliBridge::init_bridge(self.params),
|
||||
InitBridgeName::PolkadotBulletinToBridgeHubPolkadot =>
|
||||
PolkadotBulletinToBridgeHubPolkadotCliBridge::init_bridge(self),
|
||||
PolkadotBulletinToBridgeHubPolkadotCliBridge::init_bridge(self.params),
|
||||
InitBridgeName::RococoToRococoBulletin =>
|
||||
RococoToRococoBulletinCliBridge::init_bridge(self),
|
||||
RococoToRococoBulletinCliBridge::init_bridge(self.params),
|
||||
InitBridgeName::RococoBulletinToBridgeHubRococo =>
|
||||
RococoBulletinToBridgeHubRococoCliBridge::init_bridge(self),
|
||||
RococoBulletinToBridgeHubRococoCliBridge::init_bridge(self.params),
|
||||
InitBridgeName::RococoToBridgeHubWestend =>
|
||||
RococoToBridgeHubWestendCliBridge::init_bridge(self),
|
||||
RococoToBridgeHubWestendCliBridge::init_bridge(self.params),
|
||||
InitBridgeName::WestendToBridgeHubRococo =>
|
||||
WestendToBridgeHubRococoCliBridge::init_bridge(self),
|
||||
WestendToBridgeHubRococoCliBridge::init_bridge(self.params),
|
||||
}
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -17,18 +17,10 @@
|
||||
//! Deal with CLI args of substrate-to-substrate relay.
|
||||
|
||||
use async_std::prelude::*;
|
||||
use codec::{Decode, Encode};
|
||||
use futures::{select, FutureExt};
|
||||
use rbtag::BuildInfo;
|
||||
use signal_hook::consts::*;
|
||||
use signal_hook_async_std::Signals;
|
||||
use structopt::{clap::arg_enum, StructOpt};
|
||||
use strum::{EnumString, VariantNames};
|
||||
|
||||
use bp_messages::LaneId;
|
||||
use relay_substrate_client::SimpleRuntimeVersion;
|
||||
|
||||
pub(crate) mod bridge;
|
||||
use structopt::StructOpt;
|
||||
|
||||
mod chain_schema;
|
||||
mod detect_equivocations;
|
||||
@@ -50,11 +42,17 @@ pub fn parse_args() -> Command {
|
||||
#[derive(StructOpt)]
|
||||
#[structopt(about = "Substrate-to-Substrate relay")]
|
||||
pub enum Command {
|
||||
/// Initialize on-chain bridge pallet with current header data.
|
||||
///
|
||||
/// Sends initialization transaction to bootstrap the bridge with current finalized block data.
|
||||
InitBridge(init_bridge::InitBridge),
|
||||
/// Start headers relay between two chains.
|
||||
///
|
||||
/// The on-chain bridge component should have been already initialized with
|
||||
/// `init-bridge` sub-command.
|
||||
RelayHeaders(relay_headers::RelayHeaders),
|
||||
/// Relay parachain heads.
|
||||
RelayParachains(relay_parachains::RelayParachains),
|
||||
/// Start messages relay between two chains.
|
||||
///
|
||||
/// Ties up to `Messages` pallets on both chains and starts relaying messages.
|
||||
@@ -67,12 +65,6 @@ pub enum Command {
|
||||
/// the message relays - i.e. when there are messages or confirmations that needs to be
|
||||
/// relayed between chains.
|
||||
RelayHeadersAndMessages(Box<relay_headers_and_messages::RelayHeadersAndMessages>),
|
||||
/// Initialize on-chain bridge pallet with current header data.
|
||||
///
|
||||
/// Sends initialization transaction to bootstrap the bridge with current finalized block data.
|
||||
InitBridge(init_bridge::InitBridge),
|
||||
/// Relay parachain heads.
|
||||
RelayParachains(relay_parachains::RelayParachains),
|
||||
/// Detect and report equivocations.
|
||||
///
|
||||
/// Parses the source chain headers that were synchronized with the target chain looking for
|
||||
@@ -86,10 +78,10 @@ impl Command {
|
||||
use relay_utils::initialize::{initialize_logger, initialize_relay};
|
||||
|
||||
match self {
|
||||
Self::InitBridge(_) |
|
||||
Self::RelayHeaders(_) |
|
||||
Self::RelayMessages(_) |
|
||||
Self::RelayHeadersAndMessages(_) |
|
||||
Self::InitBridge(_) => {
|
||||
Self::RelayHeadersAndMessages(_) => {
|
||||
initialize_relay();
|
||||
},
|
||||
_ => {
|
||||
@@ -101,11 +93,11 @@ impl Command {
|
||||
/// Run the command.
|
||||
async fn do_run(self) -> anyhow::Result<()> {
|
||||
match self {
|
||||
Self::InitBridge(arg) => arg.run().await?,
|
||||
Self::RelayHeaders(arg) => arg.run().await?,
|
||||
Self::RelayParachains(arg) => arg.run().await?,
|
||||
Self::RelayMessages(arg) => arg.run().await?,
|
||||
Self::RelayHeadersAndMessages(arg) => arg.run().await?,
|
||||
Self::InitBridge(arg) => arg.run().await?,
|
||||
Self::RelayParachains(arg) => arg.run().await?,
|
||||
Self::DetectEquivocations(arg) => arg.run().await?,
|
||||
}
|
||||
Ok(())
|
||||
@@ -137,181 +129,3 @@ impl Command {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
arg_enum! {
|
||||
#[derive(Debug)]
|
||||
/// The origin to use when dispatching the message on the target chain.
|
||||
///
|
||||
/// - `Target` uses account existing on the target chain (requires target private key).
|
||||
/// - `Origin` uses account derived from the source-chain account.
|
||||
pub enum Origins {
|
||||
Target,
|
||||
Source,
|
||||
}
|
||||
}
|
||||
|
||||
/// Bridge-supported network definition.
|
||||
///
|
||||
/// Used to abstract away CLI commands.
|
||||
pub trait CliChain: relay_substrate_client::Chain {
|
||||
/// Current version of the chain runtime, known to relay.
|
||||
///
|
||||
/// can be `None` if relay is not going to submit transactions to that chain.
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion>;
|
||||
}
|
||||
|
||||
/// Lane id.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct HexLaneId(pub [u8; 4]);
|
||||
|
||||
impl From<HexLaneId> for LaneId {
|
||||
fn from(lane_id: HexLaneId) -> LaneId {
|
||||
LaneId(lane_id.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::str::FromStr for HexLaneId {
|
||||
type Err = hex::FromHexError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut lane_id = [0u8; 4];
|
||||
hex::decode_to_slice(s, &mut lane_id)?;
|
||||
Ok(HexLaneId(lane_id))
|
||||
}
|
||||
}
|
||||
|
||||
/// Nicer formatting for raw bytes vectors.
|
||||
#[derive(Default, Encode, Decode, PartialEq, Eq)]
|
||||
pub struct HexBytes(pub Vec<u8>);
|
||||
|
||||
impl std::str::FromStr for HexBytes {
|
||||
type Err = hex::FromHexError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(Self(hex::decode(s)?))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for HexBytes {
|
||||
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(fmt, "0x{self}")
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for HexBytes {
|
||||
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(fmt, "{}", hex::encode(&self.0))
|
||||
}
|
||||
}
|
||||
|
||||
/// Prometheus metrics params.
|
||||
#[derive(Clone, Debug, PartialEq, StructOpt)]
|
||||
pub struct PrometheusParams {
|
||||
/// Do not expose a Prometheus metric endpoint.
|
||||
#[structopt(long)]
|
||||
pub no_prometheus: bool,
|
||||
/// Expose Prometheus endpoint at given interface.
|
||||
#[structopt(long, default_value = "127.0.0.1")]
|
||||
pub prometheus_host: String,
|
||||
/// Expose Prometheus endpoint at given port.
|
||||
#[structopt(long, default_value = "9616")]
|
||||
pub prometheus_port: u16,
|
||||
}
|
||||
|
||||
/// Struct to get git commit info and build time.
|
||||
#[derive(BuildInfo)]
|
||||
struct SubstrateRelayBuildInfo;
|
||||
|
||||
impl SubstrateRelayBuildInfo {
|
||||
/// Get git commit in form `<short-sha-(clean|dirty)>`.
|
||||
pub fn get_git_commit() -> String {
|
||||
// on gitlab we use images without git installed, so we can't use `rbtag` there
|
||||
// locally we don't have `CI_*` env variables, so we can't rely on them
|
||||
// => we are using `CI_*` env variables or else `rbtag`
|
||||
let maybe_sha_from_ci = option_env!("CI_COMMIT_SHORT_SHA");
|
||||
maybe_sha_from_ci
|
||||
.map(|short_sha| {
|
||||
// we assume that on CI the copy is always clean
|
||||
format!("{short_sha}-clean")
|
||||
})
|
||||
.unwrap_or_else(|| SubstrateRelayBuildInfo.get_build_commit().into())
|
||||
}
|
||||
}
|
||||
|
||||
impl PrometheusParams {
|
||||
/// Tries to convert CLI metrics params into metrics params, used by the relay.
|
||||
pub fn into_metrics_params(self) -> anyhow::Result<relay_utils::metrics::MetricsParams> {
|
||||
let metrics_address = if !self.no_prometheus {
|
||||
Some(relay_utils::metrics::MetricsAddress {
|
||||
host: self.prometheus_host,
|
||||
port: self.prometheus_port,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let relay_version = option_env!("CARGO_PKG_VERSION").unwrap_or("unknown");
|
||||
let relay_commit = SubstrateRelayBuildInfo::get_git_commit();
|
||||
relay_utils::metrics::MetricsParams::new(
|
||||
metrics_address,
|
||||
relay_version.into(),
|
||||
relay_commit,
|
||||
)
|
||||
.map_err(|e| anyhow::format_err!("{:?}", e))
|
||||
}
|
||||
}
|
||||
|
||||
/// Either explicit or maximal allowed value.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ExplicitOrMaximal<V> {
|
||||
/// User has explicitly specified argument value.
|
||||
Explicit(V),
|
||||
/// Maximal allowed value for this argument.
|
||||
Maximal,
|
||||
}
|
||||
|
||||
impl<V: std::str::FromStr> std::str::FromStr for ExplicitOrMaximal<V>
|
||||
where
|
||||
V::Err: std::fmt::Debug,
|
||||
{
|
||||
type Err = String;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
if s.to_lowercase() == "max" {
|
||||
return Ok(ExplicitOrMaximal::Maximal)
|
||||
}
|
||||
|
||||
V::from_str(s)
|
||||
.map(ExplicitOrMaximal::Explicit)
|
||||
.map_err(|e| format!("Failed to parse '{e:?}'. Expected 'max' or explicit value"))
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "Runtime version params."]
|
||||
#[derive(StructOpt, Debug, PartialEq, Eq, Clone, Copy, EnumString, VariantNames)]
|
||||
pub enum RuntimeVersionType {
|
||||
/// Auto query version from chain
|
||||
Auto,
|
||||
/// Custom `spec_version` and `transaction_version`
|
||||
Custom,
|
||||
/// Read version from bundle dependencies directly.
|
||||
Bundle,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn hex_bytes_display_matches_from_str_for_clap() {
|
||||
// given
|
||||
let hex = HexBytes(vec![1, 2, 3, 4]);
|
||||
let display = format!("{hex}");
|
||||
|
||||
// when
|
||||
let hex2: HexBytes = display.parse().unwrap();
|
||||
|
||||
// then
|
||||
assert_eq!(hex.0, hex2.0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
// 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 structopt::StructOpt;
|
||||
use strum::{EnumString, VariantNames};
|
||||
|
||||
@@ -32,10 +31,8 @@ use crate::bridges::{
|
||||
rococo_headers_to_rococo_bulletin::RococoToRococoBulletinCliBridge,
|
||||
},
|
||||
};
|
||||
use relay_utils::metrics::{GlobalMetrics, StandaloneMetric};
|
||||
use substrate_relay_helper::finality::SubstrateFinalitySyncPipeline;
|
||||
|
||||
use crate::cli::{bridge::*, chain_schema::*, PrometheusParams};
|
||||
use substrate_relay_helper::cli::relay_headers::{HeadersRelayer, RelayHeadersParams};
|
||||
|
||||
/// Start headers relayer process.
|
||||
#[derive(StructOpt)]
|
||||
@@ -43,18 +40,8 @@ pub struct RelayHeaders {
|
||||
/// A bridge instance to relay headers for.
|
||||
#[structopt(possible_values = RelayHeadersBridge::VARIANTS, case_insensitive = true)]
|
||||
bridge: RelayHeadersBridge,
|
||||
/// If passed, only mandatory headers (headers that are changing the GRANDPA authorities set)
|
||||
/// are relayed.
|
||||
#[structopt(long)]
|
||||
only_mandatory_headers: bool,
|
||||
#[structopt(flatten)]
|
||||
source: SourceConnectionParams,
|
||||
#[structopt(flatten)]
|
||||
target: TargetConnectionParams,
|
||||
#[structopt(flatten)]
|
||||
target_sign: TargetSigningParams,
|
||||
#[structopt(flatten)]
|
||||
prometheus_params: PrometheusParams,
|
||||
params: RelayHeadersParams,
|
||||
}
|
||||
|
||||
#[derive(Debug, EnumString, VariantNames)]
|
||||
@@ -69,37 +56,6 @@ pub enum RelayHeadersBridge {
|
||||
RococoBulletinToBridgeHubRococo,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
trait HeadersRelayer: RelayToRelayHeadersCliBridge {
|
||||
/// Relay headers.
|
||||
async fn relay_headers(data: RelayHeaders) -> anyhow::Result<()> {
|
||||
let source_client = data.source.into_client::<Self::Source>().await?;
|
||||
let target_client = data.target.into_client::<Self::Target>().await?;
|
||||
let target_transactions_mortality = data.target_sign.target_transactions_mortality;
|
||||
let target_sign = data.target_sign.to_keypair::<Self::Target>()?;
|
||||
|
||||
let metrics_params: relay_utils::metrics::MetricsParams =
|
||||
data.prometheus_params.into_metrics_params()?;
|
||||
GlobalMetrics::new()?.register_and_spawn(&metrics_params.registry)?;
|
||||
|
||||
let target_transactions_params = substrate_relay_helper::TransactionParams {
|
||||
signer: target_sign,
|
||||
mortality: target_transactions_mortality,
|
||||
};
|
||||
Self::Finality::start_relay_guards(&target_client, target_client.can_start_version_guard())
|
||||
.await?;
|
||||
|
||||
substrate_relay_helper::finality::run::<Self::Finality>(
|
||||
source_client,
|
||||
target_client,
|
||||
data.only_mandatory_headers,
|
||||
target_transactions_params,
|
||||
metrics_params,
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
impl HeadersRelayer for KusamaToBridgeHubPolkadotCliBridge {}
|
||||
impl HeadersRelayer for PolkadotToBridgeHubKusamaCliBridge {}
|
||||
impl HeadersRelayer for PolkadotToPolkadotBulletinCliBridge {}
|
||||
@@ -112,17 +68,17 @@ impl RelayHeaders {
|
||||
pub async fn run(self) -> anyhow::Result<()> {
|
||||
match self.bridge {
|
||||
RelayHeadersBridge::KusamaToBridgeHubPolkadot =>
|
||||
KusamaToBridgeHubPolkadotCliBridge::relay_headers(self),
|
||||
KusamaToBridgeHubPolkadotCliBridge::relay_headers(self.params),
|
||||
RelayHeadersBridge::PolkadotToBridgeHubKusama =>
|
||||
PolkadotToBridgeHubKusamaCliBridge::relay_headers(self),
|
||||
PolkadotToBridgeHubKusamaCliBridge::relay_headers(self.params),
|
||||
RelayHeadersBridge::PolkadotToPolkadotBulletin =>
|
||||
PolkadotToPolkadotBulletinCliBridge::relay_headers(self),
|
||||
PolkadotToPolkadotBulletinCliBridge::relay_headers(self.params),
|
||||
RelayHeadersBridge::PolkadotBulletinToBridgeHubPolkadot =>
|
||||
PolkadotBulletinToBridgeHubPolkadotCliBridge::relay_headers(self),
|
||||
PolkadotBulletinToBridgeHubPolkadotCliBridge::relay_headers(self.params),
|
||||
RelayHeadersBridge::RococoToRococoBulletin =>
|
||||
RococoToRococoBulletinCliBridge::relay_headers(self),
|
||||
RococoToRococoBulletinCliBridge::relay_headers(self.params),
|
||||
RelayHeadersBridge::RococoBulletinToBridgeHubRococo =>
|
||||
RococoBulletinToBridgeHubRococoCliBridge::relay_headers(self),
|
||||
RococoBulletinToBridgeHubRococoCliBridge::relay_headers(self.params),
|
||||
}
|
||||
.await
|
||||
}
|
||||
|
||||
+31
-323
@@ -23,176 +23,48 @@
|
||||
//! `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 parachain_to_parachain;
|
||||
#[macro_use]
|
||||
mod relay_to_relay;
|
||||
#[macro_use]
|
||||
mod relay_to_parachain;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use std::{marker::PhantomData, sync::Arc};
|
||||
use structopt::StructOpt;
|
||||
|
||||
use futures::{FutureExt, TryFutureExt};
|
||||
use relay_to_parachain::*;
|
||||
|
||||
use crate::{
|
||||
bridges::{
|
||||
kusama_polkadot::{
|
||||
kusama_parachains_to_bridge_hub_polkadot::BridgeHubKusamaToBridgeHubPolkadotCliBridge,
|
||||
polkadot_parachains_to_bridge_hub_kusama::BridgeHubPolkadotToBridgeHubKusamaCliBridge,
|
||||
},
|
||||
polkadot_bulletin::{
|
||||
polkadot_bulletin_headers_to_bridge_hub_polkadot::PolkadotBulletinToBridgeHubPolkadotCliBridge,
|
||||
polkadot_parachains_to_polkadot_bulletin::PolkadotToPolkadotBulletinCliBridge,
|
||||
},
|
||||
rococo_bulletin::{
|
||||
rococo_bulletin_headers_to_bridge_hub_rococo::RococoBulletinToBridgeHubRococoCliBridge,
|
||||
rococo_parachains_to_rococo_bulletin::RococoToRococoBulletinCliBridge,
|
||||
BridgeHubRococoAsBridgeHubPolkadot,
|
||||
},
|
||||
rococo_westend::{
|
||||
rococo_parachains_to_bridge_hub_westend::BridgeHubRococoToBridgeHubWestendCliBridge,
|
||||
westend_parachains_to_bridge_hub_rococo::BridgeHubWestendToBridgeHubRococoCliBridge,
|
||||
},
|
||||
use crate::bridges::{
|
||||
kusama_polkadot::{
|
||||
kusama_parachains_to_bridge_hub_polkadot::BridgeHubKusamaToBridgeHubPolkadotCliBridge,
|
||||
polkadot_parachains_to_bridge_hub_kusama::BridgeHubPolkadotToBridgeHubKusamaCliBridge,
|
||||
},
|
||||
polkadot_bulletin::{
|
||||
polkadot_bulletin_headers_to_bridge_hub_polkadot::PolkadotBulletinToBridgeHubPolkadotCliBridge,
|
||||
polkadot_parachains_to_polkadot_bulletin::PolkadotToPolkadotBulletinCliBridge,
|
||||
},
|
||||
rococo_bulletin::{
|
||||
rococo_bulletin_headers_to_bridge_hub_rococo::RococoBulletinToBridgeHubRococoCliBridge,
|
||||
rococo_parachains_to_rococo_bulletin::RococoToRococoBulletinCliBridge,
|
||||
BridgeHubRococoAsBridgeHubPolkadot,
|
||||
},
|
||||
rococo_westend::{
|
||||
rococo_parachains_to_bridge_hub_westend::BridgeHubRococoToBridgeHubWestendCliBridge,
|
||||
westend_parachains_to_bridge_hub_rococo::BridgeHubWestendToBridgeHubRococoCliBridge,
|
||||
},
|
||||
};
|
||||
use relay_substrate_client::{
|
||||
AccountKeyPairOf, ChainRuntimeVersion, ChainWithRuntimeVersion, ChainWithTransactions,
|
||||
Parachain, SimpleRuntimeVersion,
|
||||
};
|
||||
use substrate_relay_helper::{
|
||||
cli::{
|
||||
bridge::{
|
||||
CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge,
|
||||
RelayToRelayHeadersCliBridge,
|
||||
},
|
||||
chain_schema::*,
|
||||
relay_headers_and_messages::parachain_to_parachain::ParachainToParachainBridge,
|
||||
CliChain, HexLaneId, PrometheusParams,
|
||||
relay_headers_and_messages::{
|
||||
parachain_to_parachain::ParachainToParachainBridge, relay_to_parachain::*,
|
||||
BridgeEndCommonParams, Full2WayBridge, Full2WayBridgeCommonParams,
|
||||
HeadersAndMessagesSharedParams,
|
||||
},
|
||||
},
|
||||
declare_chain_cli_schema,
|
||||
declare_chain_cli_schema, declare_parachain_to_parachain_bridge_schema,
|
||||
declare_relay_to_parachain_bridge_schema, TransactionParams,
|
||||
};
|
||||
use bp_messages::LaneId;
|
||||
use bp_runtime::BalanceOf;
|
||||
use relay_substrate_client::{
|
||||
AccountIdOf, AccountKeyPairOf, Chain, ChainWithBalances, ChainWithMessages,
|
||||
ChainWithTransactions, Client, Parachain,
|
||||
};
|
||||
use relay_utils::metrics::MetricsParams;
|
||||
use sp_core::Pair;
|
||||
use substrate_relay_helper::{
|
||||
messages_lane::{MessagesRelayLimits, MessagesRelayParams},
|
||||
on_demand::OnDemandRelay,
|
||||
TaggedAccount, TransactionParams,
|
||||
};
|
||||
|
||||
/// 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>,
|
||||
/// 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,
|
||||
}
|
||||
|
||||
/// Bridge parameters, shared by all bridge types.
|
||||
pub struct Full2WayBridgeCommonParams<
|
||||
Left: ChainWithTransactions + CliChain,
|
||||
Right: ChainWithTransactions + CliChain,
|
||||
> {
|
||||
/// Shared parameters.
|
||||
pub shared: HeadersAndMessagesSharedParams,
|
||||
/// Parameters of the left chain.
|
||||
pub left: BridgeEndCommonParams<Left>,
|
||||
/// Parameters of the right chain.
|
||||
pub right: BridgeEndCommonParams<Right>,
|
||||
|
||||
/// Common metric parameters.
|
||||
pub metrics_params: MetricsParams,
|
||||
}
|
||||
|
||||
impl<Left: ChainWithTransactions + CliChain, Right: ChainWithTransactions + CliChain>
|
||||
Full2WayBridgeCommonParams<Left, Right>
|
||||
{
|
||||
/// Creates new bridge parameters from its components.
|
||||
pub fn new<L2R: MessagesCliBridge<Source = Left, Target = Right>>(
|
||||
shared: HeadersAndMessagesSharedParams,
|
||||
left: BridgeEndCommonParams<Left>,
|
||||
right: BridgeEndCommonParams<Right>,
|
||||
) -> anyhow::Result<Self> {
|
||||
// Create metrics registry.
|
||||
let metrics_params = shared.prometheus_params.clone().into_metrics_params()?;
|
||||
let metrics_params = relay_utils::relay_metrics(metrics_params).into_params();
|
||||
|
||||
Ok(Self { shared, left, right, metrics_params })
|
||||
}
|
||||
}
|
||||
|
||||
/// Parameters that are associated with one side of the bridge.
|
||||
pub struct BridgeEndCommonParams<Chain: ChainWithTransactions + CliChain> {
|
||||
/// Chain client.
|
||||
pub client: Client<Chain>,
|
||||
/// Params used for sending transactions to the chain.
|
||||
pub tx_params: TransactionParams<AccountKeyPairOf<Chain>>,
|
||||
/// Accounts, which balances are exposed as metrics by the relay process.
|
||||
pub accounts: Vec<TaggedAccount<AccountIdOf<Chain>>>,
|
||||
}
|
||||
|
||||
/// All data of the bidirectional complex relay.
|
||||
struct FullBridge<
|
||||
'a,
|
||||
Source: ChainWithTransactions + CliChain,
|
||||
Target: ChainWithTransactions + CliChain,
|
||||
Bridge: MessagesCliBridge<Source = Source, Target = Target>,
|
||||
> {
|
||||
source: &'a mut BridgeEndCommonParams<Source>,
|
||||
target: &'a mut BridgeEndCommonParams<Target>,
|
||||
metrics_params: &'a MetricsParams,
|
||||
_phantom_data: PhantomData<Bridge>,
|
||||
}
|
||||
|
||||
impl<
|
||||
'a,
|
||||
Source: ChainWithTransactions + CliChain,
|
||||
Target: ChainWithTransactions + CliChain,
|
||||
Bridge: MessagesCliBridge<Source = Source, Target = Target>,
|
||||
> FullBridge<'a, Source, Target, Bridge>
|
||||
where
|
||||
AccountIdOf<Source>: From<<AccountKeyPairOf<Source> as Pair>::Public>,
|
||||
AccountIdOf<Target>: From<<AccountKeyPairOf<Target> as Pair>::Public>,
|
||||
BalanceOf<Source>: TryFrom<BalanceOf<Target>> + Into<u128>,
|
||||
{
|
||||
/// Construct complex relay given it components.
|
||||
fn new(
|
||||
source: &'a mut BridgeEndCommonParams<Source>,
|
||||
target: &'a mut BridgeEndCommonParams<Target>,
|
||||
metrics_params: &'a MetricsParams,
|
||||
) -> Self {
|
||||
Self { source, target, metrics_params, _phantom_data: Default::default() }
|
||||
}
|
||||
|
||||
/// Returns message relay parameters.
|
||||
fn messages_relay_params(
|
||||
&self,
|
||||
source_to_target_headers_relay: Arc<dyn OnDemandRelay<Source, Target>>,
|
||||
target_to_source_headers_relay: Arc<dyn OnDemandRelay<Target, Source>>,
|
||||
lane_id: LaneId,
|
||||
maybe_limits: Option<MessagesRelayLimits>,
|
||||
) -> MessagesRelayParams<Bridge::MessagesLane> {
|
||||
MessagesRelayParams {
|
||||
source_client: self.source.client.clone(),
|
||||
source_transaction_params: self.source.tx_params.clone(),
|
||||
target_client: self.target.client.clone(),
|
||||
target_transaction_params: self.target.tx_params.clone(),
|
||||
source_to_target_headers_relay: Some(source_to_target_headers_relay),
|
||||
target_to_source_headers_relay: Some(target_to_source_headers_relay),
|
||||
lane_id,
|
||||
limits: maybe_limits,
|
||||
metrics_params: self.metrics_params.clone().disable(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// All supported chains.
|
||||
declare_chain_cli_schema!(Rococo, rococo);
|
||||
@@ -247,171 +119,6 @@ declare_parachain_to_parachain_bridge_schema!(BridgeHubKusama, Kusama, BridgeHub
|
||||
declare_relay_to_parachain_bridge_schema!(PolkadotBulletin, BridgeHubPolkadot, Polkadot);
|
||||
declare_relay_to_parachain_bridge_schema!(RococoBulletin, BridgeHubRococo, Rococo);
|
||||
|
||||
/// Base portion of the bidirectional complex relay.
|
||||
///
|
||||
/// This main purpose of extracting this trait is that in different relays the implementation
|
||||
/// of `start_on_demand_headers_relayers` method will be different. But the number of
|
||||
/// implementations is limited to relay <> relay, parachain <> relay and parachain <> parachain.
|
||||
/// This trait allows us to reuse these implementations in different bridges.
|
||||
#[async_trait]
|
||||
trait Full2WayBridgeBase: Sized + Send + Sync {
|
||||
/// The CLI params for the bridge.
|
||||
type Params;
|
||||
/// The left relay chain.
|
||||
type Left: ChainWithTransactions + CliChain;
|
||||
/// The right destination chain (it can be a relay or a parachain).
|
||||
type Right: ChainWithTransactions + CliChain;
|
||||
|
||||
/// Reference to common relay parameters.
|
||||
fn common(&self) -> &Full2WayBridgeCommonParams<Self::Left, Self::Right>;
|
||||
|
||||
/// Mutable reference to common relay parameters.
|
||||
fn mut_common(&mut self) -> &mut Full2WayBridgeCommonParams<Self::Left, Self::Right>;
|
||||
|
||||
/// Start on-demand headers relays.
|
||||
async fn start_on_demand_headers_relayers(
|
||||
&mut self,
|
||||
) -> anyhow::Result<(
|
||||
Arc<dyn OnDemandRelay<Self::Left, Self::Right>>,
|
||||
Arc<dyn OnDemandRelay<Self::Right, Self::Left>>,
|
||||
)>;
|
||||
}
|
||||
|
||||
/// Bidirectional complex relay.
|
||||
#[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>,
|
||||
{
|
||||
/// Base portion of the bidirectional complex relay.
|
||||
type Base: Full2WayBridgeBase<Left = Self::Left, Right = Self::Right>;
|
||||
|
||||
/// The left relay chain.
|
||||
type Left: ChainWithTransactions + ChainWithBalances + ChainWithMessages + CliChain;
|
||||
/// The right relay chain.
|
||||
type Right: ChainWithTransactions + ChainWithBalances + ChainWithMessages + CliChain;
|
||||
|
||||
/// 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>;
|
||||
|
||||
/// Construct new bridge.
|
||||
fn new(params: <Self::Base as Full2WayBridgeBase>::Params) -> anyhow::Result<Self>;
|
||||
|
||||
/// Reference to the base relay portion.
|
||||
fn base(&self) -> &Self::Base;
|
||||
|
||||
/// Mutable reference to the base relay portion.
|
||||
fn mut_base(&mut self) -> &mut Self::Base;
|
||||
|
||||
/// Creates and returns Left to Right complex relay.
|
||||
fn left_to_right(&mut self) -> FullBridge<Self::Left, Self::Right, Self::L2R> {
|
||||
let common = self.mut_base().mut_common();
|
||||
FullBridge::<_, _, Self::L2R>::new(
|
||||
&mut common.left,
|
||||
&mut common.right,
|
||||
&common.metrics_params,
|
||||
)
|
||||
}
|
||||
|
||||
/// Creates and returns Right to Left complex relay.
|
||||
fn right_to_left(&mut self) -> FullBridge<Self::Right, Self::Left, Self::R2L> {
|
||||
let common = self.mut_base().mut_common();
|
||||
FullBridge::<_, _, Self::R2L>::new(
|
||||
&mut common.right,
|
||||
&mut common.left,
|
||||
&common.metrics_params,
|
||||
)
|
||||
}
|
||||
|
||||
/// Start complex relay.
|
||||
async fn run(&mut self) -> anyhow::Result<()> {
|
||||
// Register standalone metrics.
|
||||
{
|
||||
let common = self.mut_base().mut_common();
|
||||
common.left.accounts.push(TaggedAccount::Messages {
|
||||
id: common.left.tx_params.signer.public().into(),
|
||||
bridged_chain: Self::Right::NAME.to_string(),
|
||||
});
|
||||
common.right.accounts.push(TaggedAccount::Messages {
|
||||
id: common.right.tx_params.signer.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 lanes = self
|
||||
.base()
|
||||
.common()
|
||||
.shared
|
||||
.lane
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(Into::into)
|
||||
.collect::<Vec<_>>();
|
||||
{
|
||||
let common = self.mut_base().mut_common();
|
||||
substrate_relay_helper::messages_metrics::add_relay_balances_metrics::<_, Self::Right>(
|
||||
common.left.client.clone(),
|
||||
&common.metrics_params,
|
||||
&common.left.accounts,
|
||||
&lanes,
|
||||
)
|
||||
.await?;
|
||||
substrate_relay_helper::messages_metrics::add_relay_balances_metrics::<_, Self::Left>(
|
||||
common.right.client.clone(),
|
||||
&common.metrics_params,
|
||||
&common.right.accounts,
|
||||
&lanes,
|
||||
)
|
||||
.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 left_to_right_messages = substrate_relay_helper::messages_lane::run::<
|
||||
<Self::L2R as MessagesCliBridge>::MessagesLane,
|
||||
>(self.left_to_right().messages_relay_params(
|
||||
left_to_right_on_demand_headers.clone(),
|
||||
right_to_left_on_demand_headers.clone(),
|
||||
lane,
|
||||
Self::L2R::maybe_messages_limits(),
|
||||
))
|
||||
.map_err(|e| anyhow::format_err!("{}", e))
|
||||
.boxed();
|
||||
message_relays.push(left_to_right_messages);
|
||||
|
||||
let right_to_left_messages = substrate_relay_helper::messages_lane::run::<
|
||||
<Self::R2L as MessagesCliBridge>::MessagesLane,
|
||||
>(self.right_to_left().messages_relay_params(
|
||||
right_to_left_on_demand_headers.clone(),
|
||||
left_to_right_on_demand_headers.clone(),
|
||||
lane,
|
||||
Self::R2L::maybe_messages_limits(),
|
||||
))
|
||||
.map_err(|e| anyhow::format_err!("{}", e))
|
||||
.boxed();
|
||||
message_relays.push(right_to_left_messages);
|
||||
}
|
||||
|
||||
relay_utils::relay_metrics(self.base().common().metrics_params.clone())
|
||||
.expose()
|
||||
.await
|
||||
.map_err(|e| anyhow::format_err!("{}", e))?;
|
||||
|
||||
futures::future::select_all(message_relays).await.0
|
||||
}
|
||||
}
|
||||
|
||||
/// BridgeHubRococo <> BridgeHubWestend complex relay.
|
||||
pub struct BridgeHubRococoBridgeHubWestendFull2WayBridge {
|
||||
base: <Self as Full2WayBridge>::Base,
|
||||
@@ -556,6 +263,7 @@ impl RelayHeadersAndMessages {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use substrate_relay_helper::cli::{HexLaneId, PrometheusParams};
|
||||
|
||||
#[test]
|
||||
fn should_parse_parachain_to_parachain_options() {
|
||||
@@ -14,10 +14,8 @@
|
||||
// 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 sp_core::Pair;
|
||||
use structopt::StructOpt;
|
||||
use strum::VariantNames;
|
||||
use strum::{EnumString, VariantNames};
|
||||
|
||||
use crate::bridges::{
|
||||
kusama_polkadot::{
|
||||
@@ -37,10 +35,21 @@ use crate::bridges::{
|
||||
bridge_hub_westend_messages_to_bridge_hub_rococo::BridgeHubWestendToBridgeHubRococoMessagesCliBridge,
|
||||
},
|
||||
};
|
||||
use relay_substrate_client::{AccountIdOf, AccountKeyPairOf, BalanceOf, ChainWithTransactions};
|
||||
use substrate_relay_helper::{messages_lane::MessagesRelayParams, TransactionParams};
|
||||
use substrate_relay_helper::cli::relay_messages::{MessagesRelayer, RelayMessagesParams};
|
||||
|
||||
use crate::cli::{bridge::*, chain_schema::*, CliChain, HexLaneId, PrometheusParams};
|
||||
#[derive(Debug, PartialEq, Eq, EnumString, VariantNames)]
|
||||
#[strum(serialize_all = "kebab_case")]
|
||||
/// Supported full bridges (headers + messages).
|
||||
pub enum FullBridge {
|
||||
BridgeHubRococoToBridgeHubWestend,
|
||||
BridgeHubWestendToBridgeHubRococo,
|
||||
BridgeHubKusamaToBridgeHubPolkadot,
|
||||
BridgeHubPolkadotToBridgeHubKusama,
|
||||
PolkadotBulletinToBridgeHubPolkadot,
|
||||
BridgeHubPolkadotToPolkadotBulletin,
|
||||
RococoBulletinToBridgeHubRococo,
|
||||
BridgeHubRococoToRococoBulletin,
|
||||
}
|
||||
|
||||
/// Start messages relayer process.
|
||||
#[derive(StructOpt)]
|
||||
@@ -48,57 +57,8 @@ pub struct RelayMessages {
|
||||
/// A bridge instance to relay messages for.
|
||||
#[structopt(possible_values = FullBridge::VARIANTS, case_insensitive = true)]
|
||||
bridge: FullBridge,
|
||||
/// Hex-encoded lane id that should be served by the relay. Defaults to `00000000`.
|
||||
#[structopt(long, default_value = "00000000")]
|
||||
lane: HexLaneId,
|
||||
#[structopt(flatten)]
|
||||
source: SourceConnectionParams,
|
||||
#[structopt(flatten)]
|
||||
source_sign: SourceSigningParams,
|
||||
#[structopt(flatten)]
|
||||
target: TargetConnectionParams,
|
||||
#[structopt(flatten)]
|
||||
target_sign: TargetSigningParams,
|
||||
#[structopt(flatten)]
|
||||
prometheus_params: PrometheusParams,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
trait MessagesRelayer: MessagesCliBridge
|
||||
where
|
||||
Self::Source: ChainWithTransactions + CliChain,
|
||||
AccountIdOf<Self::Source>: From<<AccountKeyPairOf<Self::Source> as Pair>::Public>,
|
||||
AccountIdOf<Self::Target>: From<<AccountKeyPairOf<Self::Target> as Pair>::Public>,
|
||||
BalanceOf<Self::Source>: TryFrom<BalanceOf<Self::Target>>,
|
||||
{
|
||||
async fn relay_messages(data: RelayMessages) -> anyhow::Result<()> {
|
||||
let source_client = data.source.into_client::<Self::Source>().await?;
|
||||
let source_sign = data.source_sign.to_keypair::<Self::Source>()?;
|
||||
let source_transactions_mortality = data.source_sign.transactions_mortality()?;
|
||||
let target_client = data.target.into_client::<Self::Target>().await?;
|
||||
let target_sign = data.target_sign.to_keypair::<Self::Target>()?;
|
||||
let target_transactions_mortality = data.target_sign.transactions_mortality()?;
|
||||
|
||||
substrate_relay_helper::messages_lane::run::<Self::MessagesLane>(MessagesRelayParams {
|
||||
source_client,
|
||||
source_transaction_params: TransactionParams {
|
||||
signer: source_sign,
|
||||
mortality: source_transactions_mortality,
|
||||
},
|
||||
target_client,
|
||||
target_transaction_params: TransactionParams {
|
||||
signer: target_sign,
|
||||
mortality: target_transactions_mortality,
|
||||
},
|
||||
source_to_target_headers_relay: None,
|
||||
target_to_source_headers_relay: None,
|
||||
lane_id: data.lane.into(),
|
||||
limits: Self::maybe_messages_limits(),
|
||||
metrics_params: data.prometheus_params.into_metrics_params()?,
|
||||
})
|
||||
.await
|
||||
.map_err(|e| anyhow::format_err!("{}", e))
|
||||
}
|
||||
params: RelayMessagesParams,
|
||||
}
|
||||
|
||||
impl MessagesRelayer for BridgeHubRococoToBridgeHubWestendMessagesCliBridge {}
|
||||
@@ -115,21 +75,21 @@ impl RelayMessages {
|
||||
pub async fn run(self) -> anyhow::Result<()> {
|
||||
match self.bridge {
|
||||
FullBridge::BridgeHubRococoToBridgeHubWestend =>
|
||||
BridgeHubRococoToBridgeHubWestendMessagesCliBridge::relay_messages(self),
|
||||
BridgeHubRococoToBridgeHubWestendMessagesCliBridge::relay_messages(self.params),
|
||||
FullBridge::BridgeHubWestendToBridgeHubRococo =>
|
||||
BridgeHubWestendToBridgeHubRococoMessagesCliBridge::relay_messages(self),
|
||||
BridgeHubWestendToBridgeHubRococoMessagesCliBridge::relay_messages(self.params),
|
||||
FullBridge::BridgeHubKusamaToBridgeHubPolkadot =>
|
||||
BridgeHubKusamaToBridgeHubPolkadotMessagesCliBridge::relay_messages(self),
|
||||
BridgeHubKusamaToBridgeHubPolkadotMessagesCliBridge::relay_messages(self.params),
|
||||
FullBridge::BridgeHubPolkadotToBridgeHubKusama =>
|
||||
BridgeHubPolkadotToBridgeHubKusamaMessagesCliBridge::relay_messages(self),
|
||||
BridgeHubPolkadotToBridgeHubKusamaMessagesCliBridge::relay_messages(self.params),
|
||||
FullBridge::PolkadotBulletinToBridgeHubPolkadot =>
|
||||
PolkadotBulletinToBridgeHubPolkadotMessagesCliBridge::relay_messages(self),
|
||||
PolkadotBulletinToBridgeHubPolkadotMessagesCliBridge::relay_messages(self.params),
|
||||
FullBridge::BridgeHubPolkadotToPolkadotBulletin =>
|
||||
BridgeHubPolkadotToPolkadotBulletinMessagesCliBridge::relay_messages(self),
|
||||
BridgeHubPolkadotToPolkadotBulletinMessagesCliBridge::relay_messages(self.params),
|
||||
FullBridge::RococoBulletinToBridgeHubRococo =>
|
||||
RococoBulletinToBridgeHubRococoMessagesCliBridge::relay_messages(self),
|
||||
RococoBulletinToBridgeHubRococoMessagesCliBridge::relay_messages(self.params),
|
||||
FullBridge::BridgeHubRococoToRococoBulletin =>
|
||||
BridgeHubRococoToRococoBulletinMessagesCliBridge::relay_messages(self),
|
||||
BridgeHubRococoToRococoBulletinMessagesCliBridge::relay_messages(self.params),
|
||||
}
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -26,24 +26,9 @@ use crate::bridges::{
|
||||
westend_parachains_to_bridge_hub_rococo::BridgeHubWestendToBridgeHubRococoCliBridge,
|
||||
},
|
||||
};
|
||||
use async_std::sync::Mutex;
|
||||
use async_trait::async_trait;
|
||||
use parachains_relay::parachains_loop::{AvailableHeader, SourceClient, TargetClient};
|
||||
use relay_substrate_client::Parachain;
|
||||
use relay_utils::metrics::{GlobalMetrics, StandaloneMetric};
|
||||
use std::sync::Arc;
|
||||
use structopt::StructOpt;
|
||||
use strum::{EnumString, VariantNames};
|
||||
use substrate_relay_helper::{
|
||||
parachains::{source::ParachainsSource, target::ParachainsTarget, ParachainsPipelineAdapter},
|
||||
TransactionParams,
|
||||
};
|
||||
|
||||
use crate::cli::{
|
||||
bridge::{CliBridgeBase, ParachainToRelayHeadersCliBridge},
|
||||
chain_schema::*,
|
||||
PrometheusParams,
|
||||
};
|
||||
use substrate_relay_helper::cli::relay_parachains::{ParachainsRelayer, RelayParachainsParams};
|
||||
|
||||
/// Start parachain heads relayer process.
|
||||
#[derive(StructOpt)]
|
||||
@@ -52,13 +37,7 @@ pub struct RelayParachains {
|
||||
#[structopt(possible_values = RelayParachainsBridge::VARIANTS, case_insensitive = true)]
|
||||
bridge: RelayParachainsBridge,
|
||||
#[structopt(flatten)]
|
||||
source: SourceConnectionParams,
|
||||
#[structopt(flatten)]
|
||||
target: TargetConnectionParams,
|
||||
#[structopt(flatten)]
|
||||
target_sign: TargetSigningParams,
|
||||
#[structopt(flatten)]
|
||||
prometheus_params: PrometheusParams,
|
||||
params: RelayParachainsParams,
|
||||
}
|
||||
|
||||
/// Parachain heads relay bridge.
|
||||
@@ -73,47 +52,6 @@ pub enum RelayParachainsBridge {
|
||||
WestendToBridgeHubRococo,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
trait ParachainsRelayer: ParachainToRelayHeadersCliBridge
|
||||
where
|
||||
ParachainsSource<Self::ParachainFinality>:
|
||||
SourceClient<ParachainsPipelineAdapter<Self::ParachainFinality>>,
|
||||
ParachainsTarget<Self::ParachainFinality>:
|
||||
TargetClient<ParachainsPipelineAdapter<Self::ParachainFinality>>,
|
||||
<Self as CliBridgeBase>::Source: Parachain,
|
||||
{
|
||||
async fn relay_parachains(data: RelayParachains) -> anyhow::Result<()> {
|
||||
let source_client = data.source.into_client::<Self::SourceRelay>().await?;
|
||||
let source_client = ParachainsSource::<Self::ParachainFinality>::new(
|
||||
source_client,
|
||||
Arc::new(Mutex::new(AvailableHeader::Missing)),
|
||||
);
|
||||
|
||||
let target_transaction_params = TransactionParams {
|
||||
signer: data.target_sign.to_keypair::<Self::Target>()?,
|
||||
mortality: data.target_sign.target_transactions_mortality,
|
||||
};
|
||||
let target_client = data.target.into_client::<Self::Target>().await?;
|
||||
let target_client = ParachainsTarget::<Self::ParachainFinality>::new(
|
||||
target_client.clone(),
|
||||
target_transaction_params,
|
||||
);
|
||||
|
||||
let metrics_params: relay_utils::metrics::MetricsParams =
|
||||
data.prometheus_params.into_metrics_params()?;
|
||||
GlobalMetrics::new()?.register_and_spawn(&metrics_params.registry)?;
|
||||
|
||||
parachains_relay::parachains_loop::run(
|
||||
source_client,
|
||||
target_client,
|
||||
metrics_params,
|
||||
futures::future::pending(),
|
||||
)
|
||||
.await
|
||||
.map_err(|e| anyhow::format_err!("{}", e))
|
||||
}
|
||||
}
|
||||
|
||||
impl ParachainsRelayer for BridgeHubRococoToBridgeHubWestendCliBridge {}
|
||||
impl ParachainsRelayer for BridgeHubWestendToBridgeHubRococoCliBridge {}
|
||||
impl ParachainsRelayer for BridgeHubKusamaToBridgeHubPolkadotCliBridge {}
|
||||
@@ -126,17 +64,17 @@ impl RelayParachains {
|
||||
pub async fn run(self) -> anyhow::Result<()> {
|
||||
match self.bridge {
|
||||
RelayParachainsBridge::RococoToBridgeHubWestend =>
|
||||
BridgeHubRococoToBridgeHubWestendCliBridge::relay_parachains(self),
|
||||
BridgeHubRococoToBridgeHubWestendCliBridge::relay_parachains(self.params),
|
||||
RelayParachainsBridge::WestendToBridgeHubRococo =>
|
||||
BridgeHubWestendToBridgeHubRococoCliBridge::relay_parachains(self),
|
||||
BridgeHubWestendToBridgeHubRococoCliBridge::relay_parachains(self.params),
|
||||
RelayParachainsBridge::KusamaToBridgeHubPolkadot =>
|
||||
BridgeHubKusamaToBridgeHubPolkadotCliBridge::relay_parachains(self),
|
||||
BridgeHubKusamaToBridgeHubPolkadotCliBridge::relay_parachains(self.params),
|
||||
RelayParachainsBridge::PolkadotToBridgeHubKusama =>
|
||||
BridgeHubPolkadotToBridgeHubKusamaCliBridge::relay_parachains(self),
|
||||
BridgeHubPolkadotToBridgeHubKusamaCliBridge::relay_parachains(self.params),
|
||||
RelayParachainsBridge::PolkadotToPolkadotBulletin =>
|
||||
PolkadotToPolkadotBulletinCliBridge::relay_parachains(self),
|
||||
PolkadotToPolkadotBulletinCliBridge::relay_parachains(self.params),
|
||||
RelayParachainsBridge::RococoToRococoBulletin =>
|
||||
RococoToRococoBulletinCliBridge::relay_parachains(self),
|
||||
RococoToRococoBulletinCliBridge::relay_parachains(self.params),
|
||||
}
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#![warn(missing_docs)]
|
||||
|
||||
mod bridges;
|
||||
mod chains;
|
||||
mod cli;
|
||||
|
||||
fn main() {
|
||||
|
||||
@@ -23,8 +23,9 @@ use bp_polkadot::SuffixedCommonTransactionExtensionExt;
|
||||
use codec::Encode;
|
||||
use relay_substrate_client::{
|
||||
calls::UtilityCall as MockUtilityCall, Chain, ChainWithBalances, ChainWithMessages,
|
||||
ChainWithTransactions, ChainWithUtilityPallet, Error as SubstrateError,
|
||||
MockedRuntimeUtilityPallet, SignParam, UnderlyingChainProvider, UnsignedTransaction,
|
||||
ChainWithRuntimeVersion, ChainWithTransactions, ChainWithUtilityPallet,
|
||||
Error as SubstrateError, MockedRuntimeUtilityPallet, SignParam, SimpleRuntimeVersion,
|
||||
UnderlyingChainProvider, UnsignedTransaction,
|
||||
};
|
||||
use sp_core::{storage::StorageKey, Pair};
|
||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
|
||||
@@ -120,3 +121,8 @@ impl ChainWithMessages for BridgeHubKusama {
|
||||
const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
|
||||
bp_bridge_hub_kusama::FROM_BRIDGE_HUB_KUSAMA_MESSAGE_DETAILS_METHOD;
|
||||
}
|
||||
|
||||
impl ChainWithRuntimeVersion for BridgeHubKusama {
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
||||
Some(SimpleRuntimeVersion { spec_version: 1_001_000, transaction_version: 4 });
|
||||
}
|
||||
|
||||
@@ -23,8 +23,9 @@ use bp_polkadot_core::SuffixedCommonTransactionExtensionExt;
|
||||
use codec::Encode;
|
||||
use relay_substrate_client::{
|
||||
calls::UtilityCall as MockUtilityCall, Chain, ChainWithBalances, ChainWithMessages,
|
||||
ChainWithTransactions, ChainWithUtilityPallet, Error as SubstrateError,
|
||||
MockedRuntimeUtilityPallet, SignParam, UnderlyingChainProvider, UnsignedTransaction,
|
||||
ChainWithRuntimeVersion, ChainWithTransactions, ChainWithUtilityPallet,
|
||||
Error as SubstrateError, MockedRuntimeUtilityPallet, SignParam, SimpleRuntimeVersion,
|
||||
UnderlyingChainProvider, UnsignedTransaction,
|
||||
};
|
||||
use sp_core::{storage::StorageKey, Pair};
|
||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
|
||||
@@ -124,3 +125,8 @@ impl ChainWithMessages for BridgeHubPolkadot {
|
||||
const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
|
||||
bp_bridge_hub_polkadot::FROM_BRIDGE_HUB_POLKADOT_MESSAGE_DETAILS_METHOD;
|
||||
}
|
||||
|
||||
impl ChainWithRuntimeVersion for BridgeHubPolkadot {
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
||||
Some(SimpleRuntimeVersion { spec_version: 1_001_000, transaction_version: 3 });
|
||||
}
|
||||
|
||||
@@ -23,8 +23,9 @@ use bp_polkadot_core::SuffixedCommonTransactionExtensionExt;
|
||||
use codec::Encode;
|
||||
use relay_substrate_client::{
|
||||
calls::UtilityCall as MockUtilityCall, Chain, ChainWithBalances, ChainWithMessages,
|
||||
ChainWithTransactions, ChainWithUtilityPallet, Error as SubstrateError,
|
||||
MockedRuntimeUtilityPallet, SignParam, UnderlyingChainProvider, UnsignedTransaction,
|
||||
ChainWithRuntimeVersion, ChainWithTransactions, ChainWithUtilityPallet,
|
||||
Error as SubstrateError, MockedRuntimeUtilityPallet, SignParam, SimpleRuntimeVersion,
|
||||
UnderlyingChainProvider, UnsignedTransaction,
|
||||
};
|
||||
use sp_core::{storage::StorageKey, Pair};
|
||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
|
||||
@@ -122,3 +123,8 @@ impl ChainWithMessages for BridgeHubRococo {
|
||||
const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
|
||||
bp_bridge_hub_rococo::FROM_BRIDGE_HUB_ROCOCO_MESSAGE_DETAILS_METHOD;
|
||||
}
|
||||
|
||||
impl ChainWithRuntimeVersion for BridgeHubRococo {
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
||||
Some(SimpleRuntimeVersion { spec_version: 1_008_000, transaction_version: 4 });
|
||||
}
|
||||
|
||||
@@ -23,8 +23,9 @@ use bp_polkadot_core::SuffixedCommonTransactionExtensionExt;
|
||||
use codec::Encode;
|
||||
use relay_substrate_client::{
|
||||
calls::UtilityCall as MockUtilityCall, Chain, ChainWithBalances, ChainWithMessages,
|
||||
ChainWithTransactions, ChainWithUtilityPallet, Error as SubstrateError,
|
||||
MockedRuntimeUtilityPallet, SignParam, UnderlyingChainProvider, UnsignedTransaction,
|
||||
ChainWithRuntimeVersion, ChainWithTransactions, ChainWithUtilityPallet,
|
||||
Error as SubstrateError, MockedRuntimeUtilityPallet, SignParam, SimpleRuntimeVersion,
|
||||
UnderlyingChainProvider, UnsignedTransaction,
|
||||
};
|
||||
use sp_core::{storage::StorageKey, Pair};
|
||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
|
||||
@@ -120,3 +121,8 @@ impl ChainWithMessages for BridgeHubWestend {
|
||||
const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
|
||||
bp_bridge_hub_westend::FROM_BRIDGE_HUB_WESTEND_MESSAGE_DETAILS_METHOD;
|
||||
}
|
||||
|
||||
impl ChainWithRuntimeVersion for BridgeHubWestend {
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
||||
Some(SimpleRuntimeVersion { spec_version: 1_008_000, transaction_version: 4 });
|
||||
}
|
||||
|
||||
@@ -22,8 +22,9 @@ use bp_kusama::{AccountInfoStorageMapKeyProvider, KUSAMA_SYNCED_HEADERS_GRANDPA_
|
||||
use bp_polkadot_core::SuffixedCommonTransactionExtensionExt;
|
||||
use codec::Encode;
|
||||
use relay_substrate_client::{
|
||||
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithTransactions, Error as SubstrateError,
|
||||
RelayChain, SignParam, UnderlyingChainProvider, UnsignedTransaction,
|
||||
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithRuntimeVersion, ChainWithTransactions,
|
||||
Error as SubstrateError, RelayChain, SignParam, SimpleRuntimeVersion, UnderlyingChainProvider,
|
||||
UnsignedTransaction,
|
||||
};
|
||||
use sp_core::{storage::StorageKey, Pair};
|
||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount, MultiAddress};
|
||||
@@ -114,3 +115,8 @@ impl ChainWithTransactions for Kusama {
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl ChainWithRuntimeVersion for Kusama {
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
||||
Some(SimpleRuntimeVersion { spec_version: 1_001_002, transaction_version: 25 });
|
||||
}
|
||||
|
||||
@@ -21,8 +21,9 @@ mod codegen_runtime;
|
||||
use bp_polkadot_bulletin::POLKADOT_BULLETIN_SYNCED_HEADERS_GRANDPA_INFO_METHOD;
|
||||
use codec::Encode;
|
||||
use relay_substrate_client::{
|
||||
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithMessages, ChainWithTransactions,
|
||||
Error as SubstrateError, SignParam, UnderlyingChainProvider, UnsignedTransaction,
|
||||
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithMessages, ChainWithRuntimeVersion,
|
||||
ChainWithTransactions, Error as SubstrateError, SignParam, SimpleRuntimeVersion,
|
||||
UnderlyingChainProvider, UnsignedTransaction,
|
||||
};
|
||||
use sp_core::{storage::StorageKey, Pair};
|
||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount, MultiAddress};
|
||||
@@ -131,3 +132,8 @@ impl ChainWithTransactions for PolkadotBulletin {
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl ChainWithRuntimeVersion for PolkadotBulletin {
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
||||
Some(SimpleRuntimeVersion { spec_version: 100, transaction_version: 1 });
|
||||
}
|
||||
|
||||
@@ -22,8 +22,9 @@ use bp_polkadot::{AccountInfoStorageMapKeyProvider, POLKADOT_SYNCED_HEADERS_GRAN
|
||||
use bp_polkadot_core::SuffixedCommonTransactionExtensionExt;
|
||||
use codec::Encode;
|
||||
use relay_substrate_client::{
|
||||
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithTransactions, Error as SubstrateError,
|
||||
RelayChain, SignParam, UnderlyingChainProvider, UnsignedTransaction,
|
||||
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithRuntimeVersion, ChainWithTransactions,
|
||||
Error as SubstrateError, RelayChain, SignParam, SimpleRuntimeVersion, UnderlyingChainProvider,
|
||||
UnsignedTransaction,
|
||||
};
|
||||
use sp_core::{storage::StorageKey, Pair};
|
||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount, MultiAddress};
|
||||
@@ -114,3 +115,8 @@ impl ChainWithTransactions for Polkadot {
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl ChainWithRuntimeVersion for Polkadot {
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
||||
Some(SimpleRuntimeVersion { spec_version: 1_001_002, transaction_version: 25 });
|
||||
}
|
||||
|
||||
@@ -22,8 +22,9 @@ use bp_polkadot_core::SuffixedCommonTransactionExtensionExt;
|
||||
use bp_rococo::ROCOCO_SYNCED_HEADERS_GRANDPA_INFO_METHOD;
|
||||
use codec::Encode;
|
||||
use relay_substrate_client::{
|
||||
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithTransactions, Error as SubstrateError,
|
||||
RelayChain, SignParam, UnderlyingChainProvider, UnsignedTransaction,
|
||||
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithRuntimeVersion, ChainWithTransactions,
|
||||
Error as SubstrateError, RelayChain, SignParam, SimpleRuntimeVersion, UnderlyingChainProvider,
|
||||
UnsignedTransaction,
|
||||
};
|
||||
use sp_core::{storage::StorageKey, Pair};
|
||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount, MultiAddress};
|
||||
@@ -114,3 +115,8 @@ impl ChainWithTransactions for Rococo {
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl ChainWithRuntimeVersion for Rococo {
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
||||
Some(SimpleRuntimeVersion { spec_version: 1_008_000, transaction_version: 24 });
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
use crate::calls::UtilityCall;
|
||||
|
||||
use crate::SimpleRuntimeVersion;
|
||||
use bp_header_chain::ChainWithGrandpa as ChainWithGrandpaBase;
|
||||
use bp_messages::ChainWithMessages as ChainWithMessagesBase;
|
||||
use bp_runtime::{
|
||||
@@ -58,6 +59,16 @@ pub trait Chain: ChainBase + Clone {
|
||||
type Call: Clone + Codec + Debug + Send + Sync;
|
||||
}
|
||||
|
||||
/// Bridge-supported network definition.
|
||||
///
|
||||
/// Used to abstract away CLI commands.
|
||||
pub trait ChainWithRuntimeVersion: Chain {
|
||||
/// Current version of the chain runtime, known to relay.
|
||||
///
|
||||
/// can be `None` if relay is not going to submit transactions to that chain.
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion>;
|
||||
}
|
||||
|
||||
/// Substrate-based relay chain that supports parachains.
|
||||
///
|
||||
/// We assume that the parachains are supported using `runtime_parachains::paras` pallet.
|
||||
|
||||
@@ -35,9 +35,9 @@ use std::time::Duration;
|
||||
pub use crate::{
|
||||
chain::{
|
||||
AccountKeyPairOf, BlockWithJustification, CallOf, Chain, ChainWithBalances,
|
||||
ChainWithGrandpa, ChainWithMessages, ChainWithTransactions, ChainWithUtilityPallet,
|
||||
FullRuntimeUtilityPallet, MockedRuntimeUtilityPallet, Parachain, RelayChain, SignParam,
|
||||
TransactionStatusOf, UnsignedTransaction, UtilityPallet,
|
||||
ChainWithGrandpa, ChainWithMessages, ChainWithRuntimeVersion, ChainWithTransactions,
|
||||
ChainWithUtilityPallet, FullRuntimeUtilityPallet, MockedRuntimeUtilityPallet, Parachain,
|
||||
RelayChain, SignParam, TransactionStatusOf, UnsignedTransaction, UtilityPallet,
|
||||
},
|
||||
client::{
|
||||
is_ancient_block, ChainRuntimeVersion, Client, OpaqueGrandpaAuthoritiesSet,
|
||||
|
||||
@@ -22,8 +22,9 @@ use bp_polkadot_core::SuffixedCommonTransactionExtensionExt;
|
||||
use bp_westend::WESTEND_SYNCED_HEADERS_GRANDPA_INFO_METHOD;
|
||||
use codec::Encode;
|
||||
use relay_substrate_client::{
|
||||
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithTransactions, Error as SubstrateError,
|
||||
RelayChain, SignParam, UnderlyingChainProvider, UnsignedTransaction,
|
||||
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithRuntimeVersion, ChainWithTransactions,
|
||||
Error as SubstrateError, RelayChain, SignParam, SimpleRuntimeVersion, UnderlyingChainProvider,
|
||||
UnsignedTransaction,
|
||||
};
|
||||
use sp_core::{storage::StorageKey, Pair};
|
||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount, MultiAddress};
|
||||
@@ -114,3 +115,8 @@ impl ChainWithTransactions for Westend {
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl ChainWithRuntimeVersion for Westend {
|
||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
||||
Some(SimpleRuntimeVersion { spec_version: 1_008_000, transaction_version: 24 });
|
||||
}
|
||||
|
||||
@@ -10,14 +10,17 @@ workspace = true
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
thiserror = { workspace = true }
|
||||
async-std = "1.9.0"
|
||||
async-trait = "0.1"
|
||||
codec = { package = "parity-scale-codec", version = "3.1.5" }
|
||||
futures = "0.3.30"
|
||||
hex = "0.4"
|
||||
num-traits = "0.2"
|
||||
log = { workspace = true }
|
||||
num-traits = "0.2"
|
||||
rbtag = "0.3"
|
||||
structopt = "0.3"
|
||||
strum = { version = "0.26.2", features = ["derive"] }
|
||||
thiserror = { workspace = true }
|
||||
|
||||
# Bridge dependencies
|
||||
|
||||
|
||||
+13
-24
@@ -14,38 +14,26 @@
|
||||
// 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 crate::cli::CliChain;
|
||||
use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
|
||||
use relay_substrate_client::{Chain, ChainWithTransactions, Parachain, RelayChain};
|
||||
use strum::{EnumString, VariantNames};
|
||||
use substrate_relay_helper::{
|
||||
//! Basic traits for exposing bridges in the CLI.
|
||||
|
||||
use crate::{
|
||||
equivocation::SubstrateEquivocationDetectionPipeline,
|
||||
finality::SubstrateFinalitySyncPipeline,
|
||||
messages_lane::{MessagesRelayLimits, SubstrateMessageLane},
|
||||
parachains::SubstrateParachainsPipeline,
|
||||
};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, EnumString, VariantNames)]
|
||||
#[strum(serialize_all = "kebab_case")]
|
||||
/// Supported full bridges (headers + messages).
|
||||
pub enum FullBridge {
|
||||
BridgeHubRococoToBridgeHubWestend,
|
||||
BridgeHubWestendToBridgeHubRococo,
|
||||
BridgeHubKusamaToBridgeHubPolkadot,
|
||||
BridgeHubPolkadotToBridgeHubKusama,
|
||||
PolkadotBulletinToBridgeHubPolkadot,
|
||||
BridgeHubPolkadotToPolkadotBulletin,
|
||||
RococoBulletinToBridgeHubRococo,
|
||||
BridgeHubRococoToRococoBulletin,
|
||||
}
|
||||
use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
|
||||
use relay_substrate_client::{
|
||||
Chain, ChainWithRuntimeVersion, ChainWithTransactions, Parachain, RelayChain,
|
||||
};
|
||||
|
||||
/// Minimal bridge representation that can be used from the CLI.
|
||||
/// It connects a source chain to a target chain.
|
||||
pub trait CliBridgeBase: Sized {
|
||||
/// The source chain.
|
||||
type Source: Chain + CliChain;
|
||||
type Source: Chain + ChainWithRuntimeVersion;
|
||||
/// The target chain.
|
||||
type Target: ChainWithTransactions + CliChain;
|
||||
type Target: ChainWithTransactions + ChainWithRuntimeVersion;
|
||||
}
|
||||
|
||||
/// Bridge representation that can be used from the CLI for relaying headers
|
||||
@@ -60,6 +48,7 @@ pub trait RelayToRelayHeadersCliBridge: CliBridgeBase {
|
||||
|
||||
/// Convenience trait that adds bounds to `CliBridgeBase`.
|
||||
pub trait RelayToRelayEquivocationDetectionCliBridgeBase: CliBridgeBase {
|
||||
/// The source chain with extra bounds.
|
||||
type BoundedSource: ChainWithTransactions;
|
||||
}
|
||||
|
||||
@@ -89,10 +78,10 @@ pub trait ParachainToRelayHeadersCliBridge: CliBridgeBase
|
||||
where
|
||||
Self::Source: Parachain,
|
||||
{
|
||||
// The `CliBridgeBase` type represents the parachain in this situation.
|
||||
// We need to add an extra type for the relay chain.
|
||||
/// The `CliBridgeBase` type represents the parachain in this situation.
|
||||
/// We need to add an extra type for the relay chain.
|
||||
type SourceRelay: Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>
|
||||
+ CliChain
|
||||
+ ChainWithRuntimeVersion
|
||||
+ RelayChain;
|
||||
/// Finality proofs synchronization pipeline (source parachain -> target).
|
||||
type ParachainFinality: SubstrateParachainsPipeline<
|
||||
@@ -0,0 +1,250 @@
|
||||
// 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/>.
|
||||
|
||||
//! Primitives related to chain CLI options.
|
||||
|
||||
use relay_substrate_client::{AccountKeyPairOf, ChainWithTransactions};
|
||||
use structopt::StructOpt;
|
||||
use strum::{EnumString, VariantNames};
|
||||
|
||||
use relay_substrate_client::{ChainRuntimeVersion, ChainWithRuntimeVersion, SimpleRuntimeVersion};
|
||||
|
||||
use crate::TransactionParams;
|
||||
|
||||
#[doc = "Runtime version params."]
|
||||
#[derive(StructOpt, Debug, PartialEq, Eq, Clone, Copy, EnumString, VariantNames)]
|
||||
pub enum RuntimeVersionType {
|
||||
/// Auto query version from chain
|
||||
Auto,
|
||||
/// Custom `spec_version` and `transaction_version`
|
||||
Custom,
|
||||
/// Read version from bundle dependencies directly.
|
||||
Bundle,
|
||||
}
|
||||
|
||||
/// Create chain-specific set of runtime version parameters.
|
||||
#[macro_export]
|
||||
macro_rules! declare_chain_runtime_version_params_cli_schema {
|
||||
($chain:ident, $chain_prefix:ident) => {
|
||||
bp_runtime::paste::item! {
|
||||
#[doc = $chain " runtime version params."]
|
||||
#[derive(StructOpt, Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub struct [<$chain RuntimeVersionParams>] {
|
||||
#[doc = "The type of runtime version for chain " $chain]
|
||||
#[structopt(long, default_value = "Bundle")]
|
||||
pub [<$chain_prefix _version_mode>]: RuntimeVersionType,
|
||||
#[doc = "The custom sepc_version for chain " $chain]
|
||||
#[structopt(long)]
|
||||
pub [<$chain_prefix _spec_version>]: Option<u32>,
|
||||
#[doc = "The custom transaction_version for chain " $chain]
|
||||
#[structopt(long)]
|
||||
pub [<$chain_prefix _transaction_version>]: Option<u32>,
|
||||
}
|
||||
|
||||
impl [<$chain RuntimeVersionParams>] {
|
||||
/// Converts self into `ChainRuntimeVersion`.
|
||||
pub fn into_runtime_version(
|
||||
self,
|
||||
bundle_runtime_version: Option<SimpleRuntimeVersion>,
|
||||
) -> anyhow::Result<ChainRuntimeVersion> {
|
||||
Ok(match self.[<$chain_prefix _version_mode>] {
|
||||
RuntimeVersionType::Auto => ChainRuntimeVersion::Auto,
|
||||
RuntimeVersionType::Custom => {
|
||||
let custom_spec_version = self.[<$chain_prefix _spec_version>]
|
||||
.ok_or_else(|| anyhow::Error::msg(format!("The {}-spec-version is required when choose custom mode", stringify!($chain_prefix))))?;
|
||||
let custom_transaction_version = self.[<$chain_prefix _transaction_version>]
|
||||
.ok_or_else(|| anyhow::Error::msg(format!("The {}-transaction-version is required when choose custom mode", stringify!($chain_prefix))))?;
|
||||
ChainRuntimeVersion::Custom(
|
||||
SimpleRuntimeVersion {
|
||||
spec_version: custom_spec_version,
|
||||
transaction_version: custom_transaction_version
|
||||
}
|
||||
)
|
||||
},
|
||||
RuntimeVersionType::Bundle => match bundle_runtime_version {
|
||||
Some(runtime_version) => ChainRuntimeVersion::Custom(runtime_version),
|
||||
None => {
|
||||
return Err(anyhow::format_err!("Cannot use bundled runtime version of {}: it is not known to the relay", stringify!($chain_prefix)));
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Create chain-specific set of runtime version parameters.
|
||||
#[macro_export]
|
||||
macro_rules! declare_chain_connection_params_cli_schema {
|
||||
($chain:ident, $chain_prefix:ident) => {
|
||||
bp_runtime::paste::item! {
|
||||
#[doc = $chain " connection params."]
|
||||
#[derive(StructOpt, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct [<$chain ConnectionParams>] {
|
||||
#[doc = "Connect to " $chain " node at given host."]
|
||||
#[structopt(long, default_value = "127.0.0.1")]
|
||||
pub [<$chain_prefix _host>]: String,
|
||||
#[doc = "Connect to " $chain " node websocket server at given port."]
|
||||
#[structopt(long, default_value = "9944")]
|
||||
pub [<$chain_prefix _port>]: u16,
|
||||
#[doc = "Use secure websocket connection."]
|
||||
#[structopt(long)]
|
||||
pub [<$chain_prefix _secure>]: bool,
|
||||
#[doc = "Custom runtime version"]
|
||||
#[structopt(flatten)]
|
||||
pub [<$chain_prefix _runtime_version>]: [<$chain RuntimeVersionParams>],
|
||||
}
|
||||
|
||||
impl [<$chain ConnectionParams>] {
|
||||
/// Convert connection params into Substrate client.
|
||||
#[allow(dead_code)]
|
||||
pub async fn into_client<Chain: ChainWithRuntimeVersion>(
|
||||
self,
|
||||
) -> anyhow::Result<relay_substrate_client::Client<Chain>> {
|
||||
let chain_runtime_version = self
|
||||
.[<$chain_prefix _runtime_version>]
|
||||
.into_runtime_version(Chain::RUNTIME_VERSION)?;
|
||||
Ok(relay_substrate_client::Client::new(relay_substrate_client::ConnectionParams {
|
||||
host: self.[<$chain_prefix _host>],
|
||||
port: self.[<$chain_prefix _port>],
|
||||
secure: self.[<$chain_prefix _secure>],
|
||||
chain_runtime_version,
|
||||
})
|
||||
.await
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Create chain-specific set of signing parameters.
|
||||
#[macro_export]
|
||||
macro_rules! declare_chain_signing_params_cli_schema {
|
||||
($chain:ident, $chain_prefix:ident) => {
|
||||
bp_runtime::paste::item! {
|
||||
#[doc = $chain " signing params."]
|
||||
#[derive(StructOpt, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct [<$chain SigningParams>] {
|
||||
#[doc = "The SURI of secret key to use when transactions are submitted to the " $chain " node."]
|
||||
#[structopt(long)]
|
||||
pub [<$chain_prefix _signer>]: Option<String>,
|
||||
#[doc = "The password for the SURI of secret key to use when transactions are submitted to the " $chain " node."]
|
||||
#[structopt(long)]
|
||||
pub [<$chain_prefix _signer_password>]: Option<String>,
|
||||
|
||||
#[doc = "Path to the file, that contains SURI of secret key to use when transactions are submitted to the " $chain " node. Can be overridden with " $chain_prefix "_signer option."]
|
||||
#[structopt(long)]
|
||||
pub [<$chain_prefix _signer_file>]: Option<std::path::PathBuf>,
|
||||
#[doc = "Path to the file, that password for the SURI of secret key to use when transactions are submitted to the " $chain " node. Can be overridden with " $chain_prefix "_signer_password option."]
|
||||
#[structopt(long)]
|
||||
pub [<$chain_prefix _signer_password_file>]: Option<std::path::PathBuf>,
|
||||
|
||||
#[doc = "Transactions mortality period, in blocks. MUST be a power of two in [4; 65536] range. MAY NOT be larger than `BlockHashCount` parameter of the chain system module."]
|
||||
#[structopt(long)]
|
||||
pub [<$chain_prefix _transactions_mortality>]: Option<u32>,
|
||||
}
|
||||
|
||||
impl [<$chain SigningParams>] {
|
||||
/// Return transactions mortality.
|
||||
#[allow(dead_code)]
|
||||
pub fn transactions_mortality(&self) -> anyhow::Result<Option<u32>> {
|
||||
self.[<$chain_prefix _transactions_mortality>]
|
||||
.map(|transactions_mortality| {
|
||||
if !(4..=65536).contains(&transactions_mortality)
|
||||
|| !transactions_mortality.is_power_of_two()
|
||||
{
|
||||
Err(anyhow::format_err!(
|
||||
"Transactions mortality {} is not a power of two in a [4; 65536] range",
|
||||
transactions_mortality,
|
||||
))
|
||||
} else {
|
||||
Ok(transactions_mortality)
|
||||
}
|
||||
})
|
||||
.transpose()
|
||||
}
|
||||
|
||||
/// Parse signing params into chain-specific KeyPair.
|
||||
#[allow(dead_code)]
|
||||
pub fn to_keypair<Chain: ChainWithTransactions>(&self) -> anyhow::Result<AccountKeyPairOf<Chain>> {
|
||||
let suri = match (self.[<$chain_prefix _signer>].as_ref(), self.[<$chain_prefix _signer_file>].as_ref()) {
|
||||
(Some(suri), _) => suri.to_owned(),
|
||||
(None, Some(suri_file)) => std::fs::read_to_string(suri_file)
|
||||
.map_err(|err| anyhow::format_err!(
|
||||
"Failed to read SURI from file {:?}: {}",
|
||||
suri_file,
|
||||
err,
|
||||
))?,
|
||||
(None, None) => return Err(anyhow::format_err!(
|
||||
"One of options must be specified: '{}' or '{}'",
|
||||
stringify!([<$chain_prefix _signer>]),
|
||||
stringify!([<$chain_prefix _signer_file>]),
|
||||
)),
|
||||
};
|
||||
|
||||
let suri_password = match (
|
||||
self.[<$chain_prefix _signer_password>].as_ref(),
|
||||
self.[<$chain_prefix _signer_password_file>].as_ref(),
|
||||
) {
|
||||
(Some(suri_password), _) => Some(suri_password.to_owned()),
|
||||
(None, Some(suri_password_file)) => std::fs::read_to_string(suri_password_file)
|
||||
.map(Some)
|
||||
.map_err(|err| anyhow::format_err!(
|
||||
"Failed to read SURI password from file {:?}: {}",
|
||||
suri_password_file,
|
||||
err,
|
||||
))?,
|
||||
_ => None,
|
||||
};
|
||||
|
||||
use sp_core::crypto::Pair;
|
||||
|
||||
AccountKeyPairOf::<Chain>::from_string(
|
||||
&suri,
|
||||
suri_password.as_deref()
|
||||
).map_err(|e| anyhow::format_err!("{:?}", e))
|
||||
}
|
||||
|
||||
/// Return transaction parameters.
|
||||
#[allow(dead_code)]
|
||||
pub fn transaction_params<Chain: ChainWithTransactions>(
|
||||
&self,
|
||||
) -> anyhow::Result<TransactionParams<AccountKeyPairOf<Chain>>> {
|
||||
Ok(TransactionParams {
|
||||
mortality: self.transactions_mortality()?,
|
||||
signer: self.to_keypair::<Chain>()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Create chain-specific set of configuration objects: connection parameters,
|
||||
/// signing parameters and bridge initialization parameters.
|
||||
#[macro_export]
|
||||
macro_rules! declare_chain_cli_schema {
|
||||
($chain:ident, $chain_prefix:ident) => {
|
||||
$crate::declare_chain_runtime_version_params_cli_schema!($chain, $chain_prefix);
|
||||
$crate::declare_chain_connection_params_cli_schema!($chain, $chain_prefix);
|
||||
$crate::declare_chain_signing_params_cli_schema!($chain, $chain_prefix);
|
||||
};
|
||||
}
|
||||
|
||||
declare_chain_cli_schema!(Source, source);
|
||||
declare_chain_cli_schema!(Target, target);
|
||||
@@ -0,0 +1,65 @@
|
||||
// Copyright 2019-2023 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/>.
|
||||
|
||||
//! Primitives for exposing the equivocation detection functionality in the CLI.
|
||||
|
||||
use crate::{
|
||||
cli::{bridge::*, chain_schema::*, PrometheusParams},
|
||||
equivocation,
|
||||
equivocation::SubstrateEquivocationDetectionPipeline,
|
||||
};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use relay_substrate_client::ChainWithTransactions;
|
||||
use structopt::StructOpt;
|
||||
|
||||
/// Start equivocation detection loop.
|
||||
#[derive(StructOpt)]
|
||||
pub struct DetectEquivocationsParams {
|
||||
#[structopt(flatten)]
|
||||
source: SourceConnectionParams,
|
||||
#[structopt(flatten)]
|
||||
source_sign: SourceSigningParams,
|
||||
#[structopt(flatten)]
|
||||
target: TargetConnectionParams,
|
||||
#[structopt(flatten)]
|
||||
prometheus_params: PrometheusParams,
|
||||
}
|
||||
|
||||
/// Trait used for starting the equivocation detection loop between 2 chains.
|
||||
#[async_trait]
|
||||
pub trait EquivocationsDetector: RelayToRelayEquivocationDetectionCliBridge
|
||||
where
|
||||
Self::Source: ChainWithTransactions,
|
||||
{
|
||||
/// Start the equivocation detection loop.
|
||||
async fn start(data: DetectEquivocationsParams) -> anyhow::Result<()> {
|
||||
let source_client = data.source.into_client::<Self::Source>().await?;
|
||||
Self::Equivocation::start_relay_guards(
|
||||
&source_client,
|
||||
source_client.can_start_version_guard(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
equivocation::run::<Self::Equivocation>(
|
||||
source_client,
|
||||
data.target.into_client::<Self::Target>().await?,
|
||||
data.source_sign.transaction_params::<Self::Source>()?,
|
||||
data.prometheus_params.into_metrics_params()?,
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
// Copyright 2019-2021 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/>.
|
||||
|
||||
//! Primitives for exposing the bridge initialization functionality in the CLI.
|
||||
|
||||
use async_trait::async_trait;
|
||||
use codec::Encode;
|
||||
|
||||
use crate::{
|
||||
cli::{bridge::CliBridgeBase, chain_schema::*},
|
||||
finality_base::engine::Engine,
|
||||
};
|
||||
use bp_runtime::Chain as ChainBase;
|
||||
use relay_substrate_client::{AccountKeyPairOf, Chain, UnsignedTransaction};
|
||||
use sp_core::Pair;
|
||||
use structopt::StructOpt;
|
||||
|
||||
/// Bridge initialization params.
|
||||
#[derive(StructOpt)]
|
||||
pub struct InitBridgeParams {
|
||||
#[structopt(flatten)]
|
||||
source: SourceConnectionParams,
|
||||
#[structopt(flatten)]
|
||||
target: TargetConnectionParams,
|
||||
#[structopt(flatten)]
|
||||
target_sign: TargetSigningParams,
|
||||
/// Generates all required data, but does not submit extrinsic
|
||||
#[structopt(long)]
|
||||
dry_run: bool,
|
||||
}
|
||||
|
||||
/// Trait used for bridge initializing.
|
||||
#[async_trait]
|
||||
pub trait BridgeInitializer: CliBridgeBase
|
||||
where
|
||||
<Self::Target as ChainBase>::AccountId: From<<AccountKeyPairOf<Self::Target> as Pair>::Public>,
|
||||
{
|
||||
/// The finality engine used by the source chain.
|
||||
type Engine: Engine<Self::Source>;
|
||||
|
||||
/// Get the encoded call to init the bridge.
|
||||
fn encode_init_bridge(
|
||||
init_data: <Self::Engine as Engine<Self::Source>>::InitializationData,
|
||||
) -> <Self::Target as Chain>::Call;
|
||||
|
||||
/// Initialize the bridge.
|
||||
async fn init_bridge(data: InitBridgeParams) -> anyhow::Result<()> {
|
||||
let source_client = data.source.into_client::<Self::Source>().await?;
|
||||
let target_client = data.target.into_client::<Self::Target>().await?;
|
||||
let target_sign = data.target_sign.to_keypair::<Self::Target>()?;
|
||||
let dry_run = data.dry_run;
|
||||
|
||||
crate::finality::initialize::initialize::<Self::Engine, _, _, _>(
|
||||
source_client,
|
||||
target_client.clone(),
|
||||
target_sign,
|
||||
move |transaction_nonce, initialization_data| {
|
||||
let call = Self::encode_init_bridge(initialization_data);
|
||||
log::info!(
|
||||
target: "bridge",
|
||||
"Initialize bridge call encoded as hex string: {:?}",
|
||||
format!("0x{}", hex::encode(call.encode()))
|
||||
);
|
||||
Ok(UnsignedTransaction::new(call.into(), transaction_nonce))
|
||||
},
|
||||
dry_run,
|
||||
)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
// Copyright 2019-2021 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/>.
|
||||
|
||||
//! Deal with CLI args of substrate-to-substrate relay.
|
||||
|
||||
use codec::{Decode, Encode};
|
||||
use rbtag::BuildInfo;
|
||||
use structopt::StructOpt;
|
||||
use strum::{EnumString, VariantNames};
|
||||
|
||||
use bp_messages::LaneId;
|
||||
|
||||
pub mod bridge;
|
||||
pub mod chain_schema;
|
||||
pub mod detect_equivocations;
|
||||
pub mod init_bridge;
|
||||
pub mod relay_headers;
|
||||
pub mod relay_headers_and_messages;
|
||||
pub mod relay_messages;
|
||||
pub mod relay_parachains;
|
||||
|
||||
/// The target that will be used when publishing logs related to this pallet.
|
||||
pub const LOG_TARGET: &str = "bridge";
|
||||
|
||||
/// Lane id.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct HexLaneId(pub [u8; 4]);
|
||||
|
||||
impl From<HexLaneId> for LaneId {
|
||||
fn from(lane_id: HexLaneId) -> LaneId {
|
||||
LaneId(lane_id.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::str::FromStr for HexLaneId {
|
||||
type Err = hex::FromHexError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut lane_id = [0u8; 4];
|
||||
hex::decode_to_slice(s, &mut lane_id)?;
|
||||
Ok(HexLaneId(lane_id))
|
||||
}
|
||||
}
|
||||
|
||||
/// Nicer formatting for raw bytes vectors.
|
||||
#[derive(Default, Encode, Decode, PartialEq, Eq)]
|
||||
pub struct HexBytes(pub Vec<u8>);
|
||||
|
||||
impl std::str::FromStr for HexBytes {
|
||||
type Err = hex::FromHexError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(Self(hex::decode(s)?))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for HexBytes {
|
||||
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(fmt, "0x{self}")
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for HexBytes {
|
||||
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(fmt, "{}", hex::encode(&self.0))
|
||||
}
|
||||
}
|
||||
|
||||
/// Prometheus metrics params.
|
||||
#[derive(Clone, Debug, PartialEq, StructOpt)]
|
||||
pub struct PrometheusParams {
|
||||
/// Do not expose a Prometheus metric endpoint.
|
||||
#[structopt(long)]
|
||||
pub no_prometheus: bool,
|
||||
/// Expose Prometheus endpoint at given interface.
|
||||
#[structopt(long, default_value = "127.0.0.1")]
|
||||
pub prometheus_host: String,
|
||||
/// Expose Prometheus endpoint at given port.
|
||||
#[structopt(long, default_value = "9616")]
|
||||
pub prometheus_port: u16,
|
||||
}
|
||||
|
||||
/// Struct to get git commit info and build time.
|
||||
#[derive(BuildInfo)]
|
||||
struct SubstrateRelayBuildInfo;
|
||||
|
||||
impl SubstrateRelayBuildInfo {
|
||||
/// Get git commit in form `<short-sha-(clean|dirty)>`.
|
||||
pub fn get_git_commit() -> String {
|
||||
// on gitlab we use images without git installed, so we can't use `rbtag` there
|
||||
// locally we don't have `CI_*` env variables, so we can't rely on them
|
||||
// => we are using `CI_*` env variables or else `rbtag`
|
||||
let maybe_sha_from_ci = option_env!("CI_COMMIT_SHORT_SHA");
|
||||
maybe_sha_from_ci
|
||||
.map(|short_sha| {
|
||||
// we assume that on CI the copy is always clean
|
||||
format!("{short_sha}-clean")
|
||||
})
|
||||
.unwrap_or_else(|| SubstrateRelayBuildInfo.get_build_commit().into())
|
||||
}
|
||||
}
|
||||
|
||||
impl PrometheusParams {
|
||||
/// Tries to convert CLI metrics params into metrics params, used by the relay.
|
||||
pub fn into_metrics_params(self) -> anyhow::Result<relay_utils::metrics::MetricsParams> {
|
||||
let metrics_address = if !self.no_prometheus {
|
||||
Some(relay_utils::metrics::MetricsAddress {
|
||||
host: self.prometheus_host,
|
||||
port: self.prometheus_port,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let relay_version = option_env!("CARGO_PKG_VERSION").unwrap_or("unknown");
|
||||
let relay_commit = SubstrateRelayBuildInfo::get_git_commit();
|
||||
relay_utils::metrics::MetricsParams::new(
|
||||
metrics_address,
|
||||
relay_version.into(),
|
||||
relay_commit,
|
||||
)
|
||||
.map_err(|e| anyhow::format_err!("{:?}", e))
|
||||
}
|
||||
}
|
||||
|
||||
/// Either explicit or maximal allowed value.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ExplicitOrMaximal<V> {
|
||||
/// User has explicitly specified argument value.
|
||||
Explicit(V),
|
||||
/// Maximal allowed value for this argument.
|
||||
Maximal,
|
||||
}
|
||||
|
||||
impl<V: std::str::FromStr> std::str::FromStr for ExplicitOrMaximal<V>
|
||||
where
|
||||
V::Err: std::fmt::Debug,
|
||||
{
|
||||
type Err = String;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
if s.to_lowercase() == "max" {
|
||||
return Ok(ExplicitOrMaximal::Maximal)
|
||||
}
|
||||
|
||||
V::from_str(s)
|
||||
.map(ExplicitOrMaximal::Explicit)
|
||||
.map_err(|e| format!("Failed to parse '{e:?}'. Expected 'max' or explicit value"))
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "Runtime version params."]
|
||||
#[derive(StructOpt, Debug, PartialEq, Eq, Clone, Copy, EnumString, VariantNames)]
|
||||
pub enum RuntimeVersionType {
|
||||
/// Auto query version from chain
|
||||
Auto,
|
||||
/// Custom `spec_version` and `transaction_version`
|
||||
Custom,
|
||||
/// Read version from bundle dependencies directly.
|
||||
Bundle,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn hex_bytes_display_matches_from_str_for_clap() {
|
||||
// given
|
||||
let hex = HexBytes(vec![1, 2, 3, 4]);
|
||||
let display = format!("{hex}");
|
||||
|
||||
// when
|
||||
let hex2: HexBytes = display.parse().unwrap();
|
||||
|
||||
// then
|
||||
assert_eq!(hex.0, hex2.0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
// Copyright 2019-2021 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/>.
|
||||
|
||||
//! Primitives for exposing the headers relaying functionality in the CLI.
|
||||
|
||||
use async_trait::async_trait;
|
||||
use structopt::StructOpt;
|
||||
|
||||
use relay_utils::metrics::{GlobalMetrics, StandaloneMetric};
|
||||
|
||||
use crate::{
|
||||
cli::{bridge::*, chain_schema::*, PrometheusParams},
|
||||
finality::SubstrateFinalitySyncPipeline,
|
||||
};
|
||||
|
||||
/// Chain headers relaying params.
|
||||
#[derive(StructOpt)]
|
||||
pub struct RelayHeadersParams {
|
||||
/// If passed, only mandatory headers (headers that are changing the GRANDPA authorities set)
|
||||
/// are relayed.
|
||||
#[structopt(long)]
|
||||
only_mandatory_headers: bool,
|
||||
#[structopt(flatten)]
|
||||
source: SourceConnectionParams,
|
||||
#[structopt(flatten)]
|
||||
target: TargetConnectionParams,
|
||||
#[structopt(flatten)]
|
||||
target_sign: TargetSigningParams,
|
||||
#[structopt(flatten)]
|
||||
prometheus_params: PrometheusParams,
|
||||
}
|
||||
|
||||
/// Trait used for relaying headers between 2 chains.
|
||||
#[async_trait]
|
||||
pub trait HeadersRelayer: RelayToRelayHeadersCliBridge {
|
||||
/// Relay headers.
|
||||
async fn relay_headers(data: RelayHeadersParams) -> anyhow::Result<()> {
|
||||
let source_client = data.source.into_client::<Self::Source>().await?;
|
||||
let target_client = data.target.into_client::<Self::Target>().await?;
|
||||
let target_transactions_mortality = data.target_sign.target_transactions_mortality;
|
||||
let target_sign = data.target_sign.to_keypair::<Self::Target>()?;
|
||||
|
||||
let metrics_params: relay_utils::metrics::MetricsParams =
|
||||
data.prometheus_params.into_metrics_params()?;
|
||||
GlobalMetrics::new()?.register_and_spawn(&metrics_params.registry)?;
|
||||
|
||||
let target_transactions_params = crate::TransactionParams {
|
||||
signer: target_sign,
|
||||
mortality: target_transactions_mortality,
|
||||
};
|
||||
Self::Finality::start_relay_guards(&target_client, target_client.can_start_version_guard())
|
||||
.await?;
|
||||
|
||||
crate::finality::run::<Self::Finality>(
|
||||
source_client,
|
||||
target_client,
|
||||
data.only_mandatory_headers,
|
||||
target_transactions_params,
|
||||
metrics_params,
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,484 @@
|
||||
// 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]
|
||||
pub mod parachain_to_parachain;
|
||||
#[macro_use]
|
||||
pub mod relay_to_relay;
|
||||
#[macro_use]
|
||||
pub mod relay_to_parachain;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use std::{marker::PhantomData, sync::Arc};
|
||||
use structopt::StructOpt;
|
||||
|
||||
use futures::{FutureExt, TryFutureExt};
|
||||
|
||||
use crate::{
|
||||
cli::{bridge::MessagesCliBridge, HexLaneId, PrometheusParams},
|
||||
messages_lane::{MessagesRelayLimits, MessagesRelayParams},
|
||||
on_demand::OnDemandRelay,
|
||||
TaggedAccount, TransactionParams,
|
||||
};
|
||||
use bp_messages::LaneId;
|
||||
use bp_runtime::BalanceOf;
|
||||
use relay_substrate_client::{
|
||||
AccountIdOf, AccountKeyPairOf, Chain, ChainWithBalances, ChainWithMessages,
|
||||
ChainWithRuntimeVersion, ChainWithTransactions, Client,
|
||||
};
|
||||
use relay_utils::metrics::MetricsParams;
|
||||
use sp_core::Pair;
|
||||
|
||||
/// 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>,
|
||||
/// If passed, only mandatory headers (headers that are changing the GRANDPA authorities set)
|
||||
/// are relayed.
|
||||
#[structopt(long)]
|
||||
pub only_mandatory_headers: bool,
|
||||
#[structopt(flatten)]
|
||||
/// Prometheus metrics params.
|
||||
pub prometheus_params: PrometheusParams,
|
||||
}
|
||||
|
||||
/// Bridge parameters, shared by all bridge types.
|
||||
pub struct Full2WayBridgeCommonParams<
|
||||
Left: ChainWithTransactions + ChainWithRuntimeVersion,
|
||||
Right: ChainWithTransactions + ChainWithRuntimeVersion,
|
||||
> {
|
||||
/// Shared parameters.
|
||||
pub shared: HeadersAndMessagesSharedParams,
|
||||
/// Parameters of the left chain.
|
||||
pub left: BridgeEndCommonParams<Left>,
|
||||
/// Parameters of the right chain.
|
||||
pub right: BridgeEndCommonParams<Right>,
|
||||
|
||||
/// Common metric parameters.
|
||||
pub metrics_params: MetricsParams,
|
||||
}
|
||||
|
||||
impl<
|
||||
Left: ChainWithTransactions + ChainWithRuntimeVersion,
|
||||
Right: ChainWithTransactions + ChainWithRuntimeVersion,
|
||||
> Full2WayBridgeCommonParams<Left, Right>
|
||||
{
|
||||
/// Creates new bridge parameters from its components.
|
||||
pub fn new<L2R: MessagesCliBridge<Source = Left, Target = Right>>(
|
||||
shared: HeadersAndMessagesSharedParams,
|
||||
left: BridgeEndCommonParams<Left>,
|
||||
right: BridgeEndCommonParams<Right>,
|
||||
) -> anyhow::Result<Self> {
|
||||
// Create metrics registry.
|
||||
let metrics_params = shared.prometheus_params.clone().into_metrics_params()?;
|
||||
let metrics_params = relay_utils::relay_metrics(metrics_params).into_params();
|
||||
|
||||
Ok(Self { shared, left, right, metrics_params })
|
||||
}
|
||||
}
|
||||
|
||||
/// Parameters that are associated with one side of the bridge.
|
||||
pub struct BridgeEndCommonParams<Chain: ChainWithTransactions + ChainWithRuntimeVersion> {
|
||||
/// Chain client.
|
||||
pub client: Client<Chain>,
|
||||
/// Params used for sending transactions to the chain.
|
||||
pub tx_params: TransactionParams<AccountKeyPairOf<Chain>>,
|
||||
/// Accounts, which balances are exposed as metrics by the relay process.
|
||||
pub accounts: Vec<TaggedAccount<AccountIdOf<Chain>>>,
|
||||
}
|
||||
|
||||
/// All data of the bidirectional complex relay.
|
||||
pub struct FullBridge<
|
||||
'a,
|
||||
Source: ChainWithTransactions + ChainWithRuntimeVersion,
|
||||
Target: ChainWithTransactions + ChainWithRuntimeVersion,
|
||||
Bridge: MessagesCliBridge<Source = Source, Target = Target>,
|
||||
> {
|
||||
source: &'a mut BridgeEndCommonParams<Source>,
|
||||
target: &'a mut BridgeEndCommonParams<Target>,
|
||||
metrics_params: &'a MetricsParams,
|
||||
_phantom_data: PhantomData<Bridge>,
|
||||
}
|
||||
|
||||
impl<
|
||||
'a,
|
||||
Source: ChainWithTransactions + ChainWithRuntimeVersion,
|
||||
Target: ChainWithTransactions + ChainWithRuntimeVersion,
|
||||
Bridge: MessagesCliBridge<Source = Source, Target = Target>,
|
||||
> FullBridge<'a, Source, Target, Bridge>
|
||||
where
|
||||
AccountIdOf<Source>: From<<AccountKeyPairOf<Source> as Pair>::Public>,
|
||||
AccountIdOf<Target>: From<<AccountKeyPairOf<Target> as Pair>::Public>,
|
||||
BalanceOf<Source>: TryFrom<BalanceOf<Target>> + Into<u128>,
|
||||
{
|
||||
/// Construct complex relay given it components.
|
||||
fn new(
|
||||
source: &'a mut BridgeEndCommonParams<Source>,
|
||||
target: &'a mut BridgeEndCommonParams<Target>,
|
||||
metrics_params: &'a MetricsParams,
|
||||
) -> Self {
|
||||
Self { source, target, metrics_params, _phantom_data: Default::default() }
|
||||
}
|
||||
|
||||
/// Returns message relay parameters.
|
||||
fn messages_relay_params(
|
||||
&self,
|
||||
source_to_target_headers_relay: Arc<dyn OnDemandRelay<Source, Target>>,
|
||||
target_to_source_headers_relay: Arc<dyn OnDemandRelay<Target, Source>>,
|
||||
lane_id: LaneId,
|
||||
maybe_limits: Option<MessagesRelayLimits>,
|
||||
) -> MessagesRelayParams<Bridge::MessagesLane> {
|
||||
MessagesRelayParams {
|
||||
source_client: self.source.client.clone(),
|
||||
source_transaction_params: self.source.tx_params.clone(),
|
||||
target_client: self.target.client.clone(),
|
||||
target_transaction_params: self.target.tx_params.clone(),
|
||||
source_to_target_headers_relay: Some(source_to_target_headers_relay),
|
||||
target_to_source_headers_relay: Some(target_to_source_headers_relay),
|
||||
lane_id,
|
||||
limits: maybe_limits,
|
||||
metrics_params: self.metrics_params.clone().disable(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Base portion of the bidirectional complex relay.
|
||||
///
|
||||
/// This main purpose of extracting this trait is that in different relays the implementation
|
||||
/// of `start_on_demand_headers_relayers` method will be different. But the number of
|
||||
/// implementations is limited to relay <> relay, parachain <> relay and parachain <> parachain.
|
||||
/// This trait allows us to reuse these implementations in different bridges.
|
||||
#[async_trait]
|
||||
pub trait Full2WayBridgeBase: Sized + Send + Sync {
|
||||
/// The CLI params for the bridge.
|
||||
type Params;
|
||||
/// The left relay chain.
|
||||
type Left: ChainWithTransactions + ChainWithRuntimeVersion;
|
||||
/// The right destination chain (it can be a relay or a parachain).
|
||||
type Right: ChainWithTransactions + ChainWithRuntimeVersion;
|
||||
|
||||
/// Reference to common relay parameters.
|
||||
fn common(&self) -> &Full2WayBridgeCommonParams<Self::Left, Self::Right>;
|
||||
|
||||
/// Mutable reference to common relay parameters.
|
||||
fn mut_common(&mut self) -> &mut Full2WayBridgeCommonParams<Self::Left, Self::Right>;
|
||||
|
||||
/// Start on-demand headers relays.
|
||||
async fn start_on_demand_headers_relayers(
|
||||
&mut self,
|
||||
) -> anyhow::Result<(
|
||||
Arc<dyn OnDemandRelay<Self::Left, Self::Right>>,
|
||||
Arc<dyn OnDemandRelay<Self::Right, Self::Left>>,
|
||||
)>;
|
||||
}
|
||||
|
||||
/// Bidirectional complex relay.
|
||||
#[async_trait]
|
||||
pub 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>,
|
||||
{
|
||||
/// Base portion of the bidirectional complex relay.
|
||||
type Base: Full2WayBridgeBase<Left = Self::Left, Right = Self::Right>;
|
||||
|
||||
/// The left relay chain.
|
||||
type Left: ChainWithTransactions
|
||||
+ ChainWithBalances
|
||||
+ ChainWithMessages
|
||||
+ ChainWithRuntimeVersion;
|
||||
/// The right relay chain.
|
||||
type Right: ChainWithTransactions
|
||||
+ ChainWithBalances
|
||||
+ ChainWithMessages
|
||||
+ ChainWithRuntimeVersion;
|
||||
|
||||
/// 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>;
|
||||
|
||||
/// Construct new bridge.
|
||||
fn new(params: <Self::Base as Full2WayBridgeBase>::Params) -> anyhow::Result<Self>;
|
||||
|
||||
/// Reference to the base relay portion.
|
||||
fn base(&self) -> &Self::Base;
|
||||
|
||||
/// Mutable reference to the base relay portion.
|
||||
fn mut_base(&mut self) -> &mut Self::Base;
|
||||
|
||||
/// Creates and returns Left to Right complex relay.
|
||||
fn left_to_right(&mut self) -> FullBridge<Self::Left, Self::Right, Self::L2R> {
|
||||
let common = self.mut_base().mut_common();
|
||||
FullBridge::<_, _, Self::L2R>::new(
|
||||
&mut common.left,
|
||||
&mut common.right,
|
||||
&common.metrics_params,
|
||||
)
|
||||
}
|
||||
|
||||
/// Creates and returns Right to Left complex relay.
|
||||
fn right_to_left(&mut self) -> FullBridge<Self::Right, Self::Left, Self::R2L> {
|
||||
let common = self.mut_base().mut_common();
|
||||
FullBridge::<_, _, Self::R2L>::new(
|
||||
&mut common.right,
|
||||
&mut common.left,
|
||||
&common.metrics_params,
|
||||
)
|
||||
}
|
||||
|
||||
/// Start complex relay.
|
||||
async fn run(&mut self) -> anyhow::Result<()> {
|
||||
// Register standalone metrics.
|
||||
{
|
||||
let common = self.mut_base().mut_common();
|
||||
common.left.accounts.push(TaggedAccount::Messages {
|
||||
id: common.left.tx_params.signer.public().into(),
|
||||
bridged_chain: Self::Right::NAME.to_string(),
|
||||
});
|
||||
common.right.accounts.push(TaggedAccount::Messages {
|
||||
id: common.right.tx_params.signer.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 lanes = self
|
||||
.base()
|
||||
.common()
|
||||
.shared
|
||||
.lane
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(Into::into)
|
||||
.collect::<Vec<_>>();
|
||||
{
|
||||
let common = self.mut_base().mut_common();
|
||||
crate::messages_metrics::add_relay_balances_metrics::<_, Self::Right>(
|
||||
common.left.client.clone(),
|
||||
&common.metrics_params,
|
||||
&common.left.accounts,
|
||||
&lanes,
|
||||
)
|
||||
.await?;
|
||||
crate::messages_metrics::add_relay_balances_metrics::<_, Self::Left>(
|
||||
common.right.client.clone(),
|
||||
&common.metrics_params,
|
||||
&common.right.accounts,
|
||||
&lanes,
|
||||
)
|
||||
.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 left_to_right_messages = crate::messages_lane::run::<
|
||||
<Self::L2R as MessagesCliBridge>::MessagesLane,
|
||||
>(self.left_to_right().messages_relay_params(
|
||||
left_to_right_on_demand_headers.clone(),
|
||||
right_to_left_on_demand_headers.clone(),
|
||||
lane,
|
||||
Self::L2R::maybe_messages_limits(),
|
||||
))
|
||||
.map_err(|e| anyhow::format_err!("{}", e))
|
||||
.boxed();
|
||||
message_relays.push(left_to_right_messages);
|
||||
|
||||
let right_to_left_messages = crate::messages_lane::run::<
|
||||
<Self::R2L as MessagesCliBridge>::MessagesLane,
|
||||
>(self.right_to_left().messages_relay_params(
|
||||
right_to_left_on_demand_headers.clone(),
|
||||
left_to_right_on_demand_headers.clone(),
|
||||
lane,
|
||||
Self::R2L::maybe_messages_limits(),
|
||||
))
|
||||
.map_err(|e| anyhow::format_err!("{}", e))
|
||||
.boxed();
|
||||
message_relays.push(right_to_left_messages);
|
||||
}
|
||||
|
||||
relay_utils::relay_metrics(self.base().common().metrics_params.clone())
|
||||
.expose()
|
||||
.await
|
||||
.map_err(|e| anyhow::format_err!("{}", e))?;
|
||||
|
||||
futures::future::select_all(message_relays).await.0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{cli::chain_schema::RuntimeVersionType, declare_chain_cli_schema};
|
||||
|
||||
use relay_substrate_client::{ChainRuntimeVersion, Parachain, SimpleRuntimeVersion};
|
||||
|
||||
#[test]
|
||||
// We need `#[allow(dead_code)]` because some of the methods generated by the macros
|
||||
// are not used.
|
||||
#[allow(dead_code)]
|
||||
fn should_parse_parachain_to_parachain_options() {
|
||||
// Chains.
|
||||
declare_chain_cli_schema!(Kusama, kusama);
|
||||
declare_chain_cli_schema!(BridgeHubKusama, bridge_hub_kusama);
|
||||
declare_chain_cli_schema!(Polkadot, polkadot);
|
||||
declare_chain_cli_schema!(BridgeHubPolkadot, bridge_hub_polkadot);
|
||||
// Means to override signers of different layer transactions.
|
||||
declare_chain_cli_schema!(
|
||||
KusamaHeadersToBridgeHubPolkadot,
|
||||
kusama_headers_to_bridge_hub_polkadot
|
||||
);
|
||||
declare_chain_cli_schema!(
|
||||
KusamaParachainsToBridgeHubPolkadot,
|
||||
kusama_parachains_to_bridge_hub_polkadot
|
||||
);
|
||||
declare_chain_cli_schema!(
|
||||
PolkadotHeadersToBridgeHubKusama,
|
||||
polkadot_headers_to_bridge_hub_kusama
|
||||
);
|
||||
declare_chain_cli_schema!(
|
||||
PolkadotParachainsToBridgeHubKusama,
|
||||
polkadot_parachains_to_bridge_hub_kusama
|
||||
);
|
||||
// Bridges.
|
||||
declare_parachain_to_parachain_bridge_schema!(
|
||||
BridgeHubKusama,
|
||||
Kusama,
|
||||
BridgeHubPolkadot,
|
||||
Polkadot
|
||||
);
|
||||
|
||||
let res = BridgeHubKusamaBridgeHubPolkadotHeadersAndMessages::from_iter(vec![
|
||||
"bridge-hub-kusama-bridge-hub-polkadot-headers-and-messages",
|
||||
"--bridge-hub-kusama-host",
|
||||
"bridge-hub-kusama-node-collator1",
|
||||
"--bridge-hub-kusama-port",
|
||||
"9944",
|
||||
"--bridge-hub-kusama-signer",
|
||||
"//Iden",
|
||||
"--bridge-hub-kusama-transactions-mortality",
|
||||
"64",
|
||||
"--kusama-host",
|
||||
"kusama-alice",
|
||||
"--kusama-port",
|
||||
"9944",
|
||||
"--bridge-hub-polkadot-host",
|
||||
"bridge-hub-polkadot-collator1",
|
||||
"--bridge-hub-polkadot-port",
|
||||
"9944",
|
||||
"--bridge-hub-polkadot-signer",
|
||||
"//George",
|
||||
"--bridge-hub-polkadot-transactions-mortality",
|
||||
"64",
|
||||
"--polkadot-host",
|
||||
"polkadot-alice",
|
||||
"--polkadot-port",
|
||||
"9944",
|
||||
"--lane",
|
||||
"00000000",
|
||||
"--prometheus-host",
|
||||
"0.0.0.0",
|
||||
]);
|
||||
|
||||
// then
|
||||
assert_eq!(
|
||||
res,
|
||||
BridgeHubKusamaBridgeHubPolkadotHeadersAndMessages {
|
||||
shared: HeadersAndMessagesSharedParams {
|
||||
lane: vec![HexLaneId([0x00, 0x00, 0x00, 0x00])],
|
||||
only_mandatory_headers: false,
|
||||
prometheus_params: PrometheusParams {
|
||||
no_prometheus: false,
|
||||
prometheus_host: "0.0.0.0".into(),
|
||||
prometheus_port: 9616,
|
||||
},
|
||||
},
|
||||
left: BridgeHubKusamaConnectionParams {
|
||||
bridge_hub_kusama_host: "bridge-hub-kusama-node-collator1".into(),
|
||||
bridge_hub_kusama_port: 9944,
|
||||
bridge_hub_kusama_secure: false,
|
||||
bridge_hub_kusama_runtime_version: BridgeHubKusamaRuntimeVersionParams {
|
||||
bridge_hub_kusama_version_mode: RuntimeVersionType::Bundle,
|
||||
bridge_hub_kusama_spec_version: None,
|
||||
bridge_hub_kusama_transaction_version: None,
|
||||
},
|
||||
},
|
||||
left_sign: BridgeHubKusamaSigningParams {
|
||||
bridge_hub_kusama_signer: Some("//Iden".into()),
|
||||
bridge_hub_kusama_signer_password: None,
|
||||
bridge_hub_kusama_signer_file: None,
|
||||
bridge_hub_kusama_signer_password_file: None,
|
||||
bridge_hub_kusama_transactions_mortality: Some(64),
|
||||
},
|
||||
left_relay: KusamaConnectionParams {
|
||||
kusama_host: "kusama-alice".into(),
|
||||
kusama_port: 9944,
|
||||
kusama_secure: false,
|
||||
kusama_runtime_version: KusamaRuntimeVersionParams {
|
||||
kusama_version_mode: RuntimeVersionType::Bundle,
|
||||
kusama_spec_version: None,
|
||||
kusama_transaction_version: None,
|
||||
},
|
||||
},
|
||||
right: BridgeHubPolkadotConnectionParams {
|
||||
bridge_hub_polkadot_host: "bridge-hub-polkadot-collator1".into(),
|
||||
bridge_hub_polkadot_port: 9944,
|
||||
bridge_hub_polkadot_secure: false,
|
||||
bridge_hub_polkadot_runtime_version: BridgeHubPolkadotRuntimeVersionParams {
|
||||
bridge_hub_polkadot_version_mode: RuntimeVersionType::Bundle,
|
||||
bridge_hub_polkadot_spec_version: None,
|
||||
bridge_hub_polkadot_transaction_version: None,
|
||||
},
|
||||
},
|
||||
right_sign: BridgeHubPolkadotSigningParams {
|
||||
bridge_hub_polkadot_signer: Some("//George".into()),
|
||||
bridge_hub_polkadot_signer_password: None,
|
||||
bridge_hub_polkadot_signer_file: None,
|
||||
bridge_hub_polkadot_signer_password_file: None,
|
||||
bridge_hub_polkadot_transactions_mortality: Some(64),
|
||||
},
|
||||
right_relay: PolkadotConnectionParams {
|
||||
polkadot_host: "polkadot-alice".into(),
|
||||
polkadot_port: 9944,
|
||||
polkadot_secure: false,
|
||||
polkadot_runtime_version: PolkadotRuntimeVersionParams {
|
||||
polkadot_version_mode: RuntimeVersionType::Bundle,
|
||||
polkadot_spec_version: None,
|
||||
polkadot_transaction_version: None,
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
+30
-26
@@ -14,26 +14,28 @@
|
||||
// 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/>.
|
||||
|
||||
//! Parachain to parachain relayer CLI primitives.
|
||||
|
||||
use async_trait::async_trait;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::cli::{
|
||||
bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge},
|
||||
relay_headers_and_messages::{Full2WayBridgeBase, Full2WayBridgeCommonParams},
|
||||
CliChain,
|
||||
};
|
||||
use bp_polkadot_core::parachains::ParaHash;
|
||||
use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
|
||||
use relay_substrate_client::{
|
||||
AccountIdOf, AccountKeyPairOf, Chain, ChainWithTransactions, Client, Parachain,
|
||||
};
|
||||
use sp_core::Pair;
|
||||
use substrate_relay_helper::{
|
||||
use crate::{
|
||||
cli::{
|
||||
bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge},
|
||||
relay_headers_and_messages::{Full2WayBridgeBase, Full2WayBridgeCommonParams},
|
||||
},
|
||||
finality::SubstrateFinalitySyncPipeline,
|
||||
on_demand::{
|
||||
headers::OnDemandHeadersRelay, parachains::OnDemandParachainsRelay, OnDemandRelay,
|
||||
},
|
||||
};
|
||||
use bp_polkadot_core::parachains::ParaHash;
|
||||
use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
|
||||
use relay_substrate_client::{
|
||||
AccountIdOf, AccountKeyPairOf, Chain, ChainWithRuntimeVersion, ChainWithTransactions, Client,
|
||||
Parachain,
|
||||
};
|
||||
use sp_core::Pair;
|
||||
|
||||
/// A base relay between two parachain from different consensus systems.
|
||||
///
|
||||
@@ -55,6 +57,8 @@ pub struct ParachainToParachainBridge<
|
||||
pub right_relay: Client<<R2L as ParachainToRelayHeadersCliBridge>::SourceRelay>,
|
||||
}
|
||||
|
||||
/// Create set of configuration objects specific to parachain-to-parachain relayer.
|
||||
#[macro_export]
|
||||
macro_rules! declare_parachain_to_parachain_bridge_schema {
|
||||
// left-parachain, relay-chain-of-left-parachain, right-parachain, relay-chain-of-right-parachain
|
||||
($left_parachain:ident, $left_chain:ident, $right_parachain:ident, $right_chain:ident) => {
|
||||
@@ -87,20 +91,20 @@ macro_rules! declare_parachain_to_parachain_bridge_schema {
|
||||
|
||||
impl [<$left_parachain $right_parachain HeadersAndMessages>] {
|
||||
async fn into_bridge<
|
||||
Left: ChainWithTransactions + CliChain + Parachain,
|
||||
LeftRelay: CliChain,
|
||||
Right: ChainWithTransactions + CliChain + Parachain,
|
||||
RightRelay: CliChain,
|
||||
L2R: CliBridgeBase<Source = Left, Target = Right>
|
||||
Left: ChainWithTransactions + ChainWithRuntimeVersion + Parachain,
|
||||
LeftRelay: ChainWithRuntimeVersion,
|
||||
Right: ChainWithTransactions + ChainWithRuntimeVersion + Parachain,
|
||||
RightRelay: ChainWithRuntimeVersion,
|
||||
L2R: $crate::cli::bridge::CliBridgeBase<Source = Left, Target = Right>
|
||||
+ MessagesCliBridge
|
||||
+ ParachainToRelayHeadersCliBridge<SourceRelay = LeftRelay>,
|
||||
R2L: CliBridgeBase<Source = Right, Target = Left>
|
||||
+ $crate::cli::bridge::ParachainToRelayHeadersCliBridge<SourceRelay = LeftRelay>,
|
||||
R2L: $crate::cli::bridge::CliBridgeBase<Source = Right, Target = Left>
|
||||
+ MessagesCliBridge
|
||||
+ ParachainToRelayHeadersCliBridge<SourceRelay = RightRelay>,
|
||||
+ $crate::cli::bridge::ParachainToRelayHeadersCliBridge<SourceRelay = RightRelay>,
|
||||
>(
|
||||
self,
|
||||
) -> anyhow::Result<ParachainToParachainBridge<L2R, R2L>> {
|
||||
Ok(ParachainToParachainBridge {
|
||||
) -> anyhow::Result<$crate::cli::relay_headers_and_messages::parachain_to_parachain::ParachainToParachainBridge<L2R, R2L>> {
|
||||
Ok($crate::cli::relay_headers_and_messages::parachain_to_parachain::ParachainToParachainBridge {
|
||||
common: Full2WayBridgeCommonParams::new::<L2R>(
|
||||
self.shared,
|
||||
BridgeEndCommonParams {
|
||||
@@ -125,12 +129,12 @@ macro_rules! declare_parachain_to_parachain_bridge_schema {
|
||||
|
||||
#[async_trait]
|
||||
impl<
|
||||
Left: Chain<Hash = ParaHash> + ChainWithTransactions + CliChain + Parachain,
|
||||
Right: Chain<Hash = ParaHash> + ChainWithTransactions + CliChain + Parachain,
|
||||
Left: Chain<Hash = ParaHash> + ChainWithTransactions + ChainWithRuntimeVersion + Parachain,
|
||||
Right: Chain<Hash = ParaHash> + ChainWithTransactions + ChainWithRuntimeVersion + Parachain,
|
||||
LeftRelay: Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>
|
||||
+ CliChain,
|
||||
+ ChainWithRuntimeVersion,
|
||||
RightRelay: Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>
|
||||
+ CliChain,
|
||||
+ ChainWithRuntimeVersion,
|
||||
L2R: CliBridgeBase<Source = Left, Target = Right>
|
||||
+ MessagesCliBridge
|
||||
+ ParachainToRelayHeadersCliBridge<SourceRelay = LeftRelay>,
|
||||
+24
-20
@@ -14,29 +14,31 @@
|
||||
// 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/>.
|
||||
|
||||
//! Relay chain to parachain relayer CLI primitives.
|
||||
|
||||
use async_trait::async_trait;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::cli::{
|
||||
bridge::{
|
||||
CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge,
|
||||
RelayToRelayHeadersCliBridge,
|
||||
use crate::{
|
||||
cli::{
|
||||
bridge::{
|
||||
CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge,
|
||||
RelayToRelayHeadersCliBridge,
|
||||
},
|
||||
relay_headers_and_messages::{Full2WayBridgeBase, Full2WayBridgeCommonParams},
|
||||
},
|
||||
relay_headers_and_messages::{Full2WayBridgeBase, Full2WayBridgeCommonParams},
|
||||
CliChain,
|
||||
};
|
||||
use bp_polkadot_core::parachains::ParaHash;
|
||||
use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
|
||||
use relay_substrate_client::{
|
||||
AccountIdOf, AccountKeyPairOf, Chain, ChainWithTransactions, Client, Parachain,
|
||||
};
|
||||
use sp_core::Pair;
|
||||
use substrate_relay_helper::{
|
||||
finality::SubstrateFinalitySyncPipeline,
|
||||
on_demand::{
|
||||
headers::OnDemandHeadersRelay, parachains::OnDemandParachainsRelay, OnDemandRelay,
|
||||
},
|
||||
};
|
||||
use bp_polkadot_core::parachains::ParaHash;
|
||||
use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
|
||||
use relay_substrate_client::{
|
||||
AccountIdOf, AccountKeyPairOf, Chain, ChainWithRuntimeVersion, ChainWithTransactions, Client,
|
||||
Parachain,
|
||||
};
|
||||
use sp_core::Pair;
|
||||
|
||||
/// A base relay between standalone (relay) chain and a parachain from another consensus system.
|
||||
///
|
||||
@@ -55,6 +57,8 @@ pub struct RelayToParachainBridge<
|
||||
pub right_relay: Client<<R2L as ParachainToRelayHeadersCliBridge>::SourceRelay>,
|
||||
}
|
||||
|
||||
/// Create set of configuration objects specific to relay-to-parachain relayer.
|
||||
#[macro_export]
|
||||
macro_rules! declare_relay_to_parachain_bridge_schema {
|
||||
// chain, parachain, relay-chain-of-parachain
|
||||
($left_chain:ident, $right_parachain:ident, $right_chain:ident) => {
|
||||
@@ -84,9 +88,9 @@ macro_rules! declare_relay_to_parachain_bridge_schema {
|
||||
|
||||
impl [<$left_chain $right_parachain HeadersAndMessages>] {
|
||||
async fn into_bridge<
|
||||
Left: ChainWithTransactions + CliChain,
|
||||
Right: ChainWithTransactions + CliChain + Parachain,
|
||||
RightRelay: CliChain,
|
||||
Left: ChainWithTransactions + ChainWithRuntimeVersion,
|
||||
Right: ChainWithTransactions + ChainWithRuntimeVersion + Parachain,
|
||||
RightRelay: ChainWithRuntimeVersion,
|
||||
L2R: CliBridgeBase<Source = Left, Target = Right> + MessagesCliBridge + RelayToRelayHeadersCliBridge,
|
||||
R2L: CliBridgeBase<Source = Right, Target = Left>
|
||||
+ MessagesCliBridge
|
||||
@@ -118,10 +122,10 @@ macro_rules! declare_relay_to_parachain_bridge_schema {
|
||||
|
||||
#[async_trait]
|
||||
impl<
|
||||
Left: ChainWithTransactions + CliChain,
|
||||
Right: Chain<Hash = ParaHash> + ChainWithTransactions + CliChain + Parachain,
|
||||
Left: ChainWithTransactions + ChainWithRuntimeVersion,
|
||||
Right: Chain<Hash = ParaHash> + ChainWithTransactions + ChainWithRuntimeVersion + Parachain,
|
||||
RightRelay: Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>
|
||||
+ CliChain,
|
||||
+ ChainWithRuntimeVersion,
|
||||
L2R: CliBridgeBase<Source = Left, Target = Right>
|
||||
+ MessagesCliBridge
|
||||
+ RelayToRelayHeadersCliBridge,
|
||||
+14
-10
@@ -18,20 +18,23 @@
|
||||
// future
|
||||
#![allow(unused_macros)]
|
||||
|
||||
//! Relay chain to Relay chain relayer CLI primitives.
|
||||
|
||||
use async_trait::async_trait;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::cli::{
|
||||
bridge::{CliBridgeBase, MessagesCliBridge, RelayToRelayHeadersCliBridge},
|
||||
relay_headers_and_messages::{Full2WayBridgeBase, Full2WayBridgeCommonParams},
|
||||
CliChain,
|
||||
};
|
||||
use relay_substrate_client::{AccountIdOf, AccountKeyPairOf, ChainWithTransactions};
|
||||
use sp_core::Pair;
|
||||
use substrate_relay_helper::{
|
||||
use crate::{
|
||||
cli::{
|
||||
bridge::{CliBridgeBase, MessagesCliBridge, RelayToRelayHeadersCliBridge},
|
||||
relay_headers_and_messages::{Full2WayBridgeBase, Full2WayBridgeCommonParams},
|
||||
},
|
||||
finality::SubstrateFinalitySyncPipeline,
|
||||
on_demand::{headers::OnDemandHeadersRelay, OnDemandRelay},
|
||||
};
|
||||
use relay_substrate_client::{
|
||||
AccountIdOf, AccountKeyPairOf, ChainWithRuntimeVersion, ChainWithTransactions,
|
||||
};
|
||||
use sp_core::Pair;
|
||||
|
||||
/// A base relay between two standalone (relay) chains.
|
||||
///
|
||||
@@ -45,6 +48,7 @@ pub struct RelayToRelayBridge<
|
||||
Full2WayBridgeCommonParams<<R2L as CliBridgeBase>::Target, <L2R as CliBridgeBase>::Target>,
|
||||
}
|
||||
|
||||
/// Create set of configuration objects specific to relay-to-relay relayer.
|
||||
macro_rules! declare_relay_to_relay_bridge_schema {
|
||||
($left_chain:ident, $right_chain:ident) => {
|
||||
bp_runtime::paste::item! {
|
||||
@@ -101,8 +105,8 @@ macro_rules! declare_relay_to_relay_bridge_schema {
|
||||
|
||||
#[async_trait]
|
||||
impl<
|
||||
Left: ChainWithTransactions + CliChain,
|
||||
Right: ChainWithTransactions + CliChain,
|
||||
Left: ChainWithTransactions + ChainWithRuntimeVersion,
|
||||
Right: ChainWithTransactions + ChainWithRuntimeVersion,
|
||||
L2R: CliBridgeBase<Source = Left, Target = Right>
|
||||
+ MessagesCliBridge
|
||||
+ RelayToRelayHeadersCliBridge,
|
||||
@@ -0,0 +1,89 @@
|
||||
// Copyright 2019-2021 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/>.
|
||||
|
||||
//! Primitives for exposing the messages relaying functionality in the CLI.
|
||||
|
||||
use crate::{
|
||||
cli::{bridge::*, chain_schema::*, HexLaneId, PrometheusParams},
|
||||
messages_lane::MessagesRelayParams,
|
||||
TransactionParams,
|
||||
};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use sp_core::Pair;
|
||||
use structopt::StructOpt;
|
||||
|
||||
use relay_substrate_client::{
|
||||
AccountIdOf, AccountKeyPairOf, BalanceOf, ChainWithRuntimeVersion, ChainWithTransactions,
|
||||
};
|
||||
|
||||
/// Messages relaying params.
|
||||
#[derive(StructOpt)]
|
||||
pub struct RelayMessagesParams {
|
||||
/// Hex-encoded lane id that should be served by the relay. Defaults to `00000000`.
|
||||
#[structopt(long, default_value = "00000000")]
|
||||
lane: HexLaneId,
|
||||
#[structopt(flatten)]
|
||||
source: SourceConnectionParams,
|
||||
#[structopt(flatten)]
|
||||
source_sign: SourceSigningParams,
|
||||
#[structopt(flatten)]
|
||||
target: TargetConnectionParams,
|
||||
#[structopt(flatten)]
|
||||
target_sign: TargetSigningParams,
|
||||
#[structopt(flatten)]
|
||||
prometheus_params: PrometheusParams,
|
||||
}
|
||||
|
||||
/// Trait used for relaying messages between 2 chains.
|
||||
#[async_trait]
|
||||
pub trait MessagesRelayer: MessagesCliBridge
|
||||
where
|
||||
Self::Source: ChainWithTransactions + ChainWithRuntimeVersion,
|
||||
AccountIdOf<Self::Source>: From<<AccountKeyPairOf<Self::Source> as Pair>::Public>,
|
||||
AccountIdOf<Self::Target>: From<<AccountKeyPairOf<Self::Target> as Pair>::Public>,
|
||||
BalanceOf<Self::Source>: TryFrom<BalanceOf<Self::Target>>,
|
||||
{
|
||||
/// Start relaying messages.
|
||||
async fn relay_messages(data: RelayMessagesParams) -> anyhow::Result<()> {
|
||||
let source_client = data.source.into_client::<Self::Source>().await?;
|
||||
let source_sign = data.source_sign.to_keypair::<Self::Source>()?;
|
||||
let source_transactions_mortality = data.source_sign.transactions_mortality()?;
|
||||
let target_client = data.target.into_client::<Self::Target>().await?;
|
||||
let target_sign = data.target_sign.to_keypair::<Self::Target>()?;
|
||||
let target_transactions_mortality = data.target_sign.transactions_mortality()?;
|
||||
|
||||
crate::messages_lane::run::<Self::MessagesLane>(MessagesRelayParams {
|
||||
source_client,
|
||||
source_transaction_params: TransactionParams {
|
||||
signer: source_sign,
|
||||
mortality: source_transactions_mortality,
|
||||
},
|
||||
target_client,
|
||||
target_transaction_params: TransactionParams {
|
||||
signer: target_sign,
|
||||
mortality: target_transactions_mortality,
|
||||
},
|
||||
source_to_target_headers_relay: None,
|
||||
target_to_source_headers_relay: None,
|
||||
lane_id: data.lane.into(),
|
||||
limits: Self::maybe_messages_limits(),
|
||||
metrics_params: data.prometheus_params.into_metrics_params()?,
|
||||
})
|
||||
.await
|
||||
.map_err(|e| anyhow::format_err!("{}", e))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
// Copyright 2019-2021 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/>.
|
||||
|
||||
//! Primitives for exposing the parachains finality relaying functionality in the CLI.
|
||||
|
||||
use async_std::sync::Mutex;
|
||||
use async_trait::async_trait;
|
||||
use parachains_relay::parachains_loop::{AvailableHeader, SourceClient, TargetClient};
|
||||
use relay_substrate_client::Parachain;
|
||||
use relay_utils::metrics::{GlobalMetrics, StandaloneMetric};
|
||||
use std::sync::Arc;
|
||||
use structopt::StructOpt;
|
||||
|
||||
use crate::{
|
||||
cli::{
|
||||
bridge::{CliBridgeBase, ParachainToRelayHeadersCliBridge},
|
||||
chain_schema::*,
|
||||
PrometheusParams,
|
||||
},
|
||||
parachains::{source::ParachainsSource, target::ParachainsTarget, ParachainsPipelineAdapter},
|
||||
TransactionParams,
|
||||
};
|
||||
|
||||
/// Parachains heads relaying params.
|
||||
#[derive(StructOpt)]
|
||||
pub struct RelayParachainsParams {
|
||||
#[structopt(flatten)]
|
||||
source: SourceConnectionParams,
|
||||
#[structopt(flatten)]
|
||||
target: TargetConnectionParams,
|
||||
#[structopt(flatten)]
|
||||
target_sign: TargetSigningParams,
|
||||
#[structopt(flatten)]
|
||||
prometheus_params: PrometheusParams,
|
||||
}
|
||||
|
||||
/// Trait used for relaying parachains finality between 2 chains.
|
||||
#[async_trait]
|
||||
pub trait ParachainsRelayer: ParachainToRelayHeadersCliBridge
|
||||
where
|
||||
ParachainsSource<Self::ParachainFinality>:
|
||||
SourceClient<ParachainsPipelineAdapter<Self::ParachainFinality>>,
|
||||
ParachainsTarget<Self::ParachainFinality>:
|
||||
TargetClient<ParachainsPipelineAdapter<Self::ParachainFinality>>,
|
||||
<Self as CliBridgeBase>::Source: Parachain,
|
||||
{
|
||||
/// Start relaying parachains finality.
|
||||
async fn relay_parachains(data: RelayParachainsParams) -> anyhow::Result<()> {
|
||||
let source_client = data.source.into_client::<Self::SourceRelay>().await?;
|
||||
let source_client = ParachainsSource::<Self::ParachainFinality>::new(
|
||||
source_client,
|
||||
Arc::new(Mutex::new(AvailableHeader::Missing)),
|
||||
);
|
||||
|
||||
let target_transaction_params = TransactionParams {
|
||||
signer: data.target_sign.to_keypair::<Self::Target>()?,
|
||||
mortality: data.target_sign.target_transactions_mortality,
|
||||
};
|
||||
let target_client = data.target.into_client::<Self::Target>().await?;
|
||||
let target_client = ParachainsTarget::<Self::ParachainFinality>::new(
|
||||
target_client.clone(),
|
||||
target_transaction_params,
|
||||
);
|
||||
|
||||
let metrics_params: relay_utils::metrics::MetricsParams =
|
||||
data.prometheus_params.into_metrics_params()?;
|
||||
GlobalMetrics::new()?.register_and_spawn(&metrics_params.registry)?;
|
||||
|
||||
parachains_relay::parachains_loop::run(
|
||||
source_client,
|
||||
target_client,
|
||||
metrics_params,
|
||||
futures::future::pending(),
|
||||
)
|
||||
.await
|
||||
.map_err(|e| anyhow::format_err!("{}", e))
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ use relay_substrate_client::{Chain, ChainWithUtilityPallet, UtilityPallet};
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub mod cli;
|
||||
pub mod equivocation;
|
||||
pub mod error;
|
||||
pub mod finality;
|
||||
|
||||
Reference in New Issue
Block a user