mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 04:01:02 +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.
|
//! BridgeHubKusama-to-BridgeHubPolkadot messages sync entrypoint.
|
||||||
|
|
||||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge};
|
|
||||||
use relay_bridge_hub_kusama_client::BridgeHubKusama;
|
use relay_bridge_hub_kusama_client::BridgeHubKusama;
|
||||||
use relay_bridge_hub_polkadot_client::BridgeHubPolkadot;
|
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.
|
/// BridgeHubKusama-to-BridgeHubPolkadot messages bridge.
|
||||||
pub struct BridgeHubKusamaToBridgeHubPolkadotMessagesCliBridge {}
|
pub struct BridgeHubKusamaToBridgeHubPolkadotMessagesCliBridge {}
|
||||||
|
|||||||
+5
-2
@@ -16,10 +16,13 @@
|
|||||||
|
|
||||||
//! BridgeHubPolkadot-to-BridgeHubKusama messages sync entrypoint.
|
//! BridgeHubPolkadot-to-BridgeHubKusama messages sync entrypoint.
|
||||||
|
|
||||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge};
|
|
||||||
use relay_bridge_hub_kusama_client::BridgeHubKusama;
|
use relay_bridge_hub_kusama_client::BridgeHubKusama;
|
||||||
use relay_bridge_hub_polkadot_client::BridgeHubPolkadot;
|
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.
|
/// BridgeHubPolkadot-to-BridgeHubKusama messages bridge.
|
||||||
pub struct BridgeHubPolkadotToBridgeHubKusamaMessagesCliBridge {}
|
pub struct BridgeHubPolkadotToBridgeHubKusamaMessagesCliBridge {}
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
//! Kusama-to-BridgeHubPolkadot headers sync entrypoint.
|
//! Kusama-to-BridgeHubPolkadot headers sync entrypoint.
|
||||||
|
|
||||||
use crate::cli::bridge::{
|
use substrate_relay_helper::cli::bridge::{
|
||||||
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -16,11 +16,11 @@
|
|||||||
|
|
||||||
//! Kusama-to-BridgeHubPolkadot parachains sync entrypoint.
|
//! Kusama-to-BridgeHubPolkadot parachains sync entrypoint.
|
||||||
|
|
||||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge};
|
|
||||||
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
|
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
|
||||||
use relay_substrate_client::{CallOf, HeaderIdOf};
|
use relay_substrate_client::{CallOf, HeaderIdOf};
|
||||||
use substrate_relay_helper::parachains::{
|
use substrate_relay_helper::{
|
||||||
SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline,
|
cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge},
|
||||||
|
parachains::{SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Kusama-to-BridgeHubPolkadot parachain sync description.
|
/// Kusama-to-BridgeHubPolkadot parachain sync description.
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
//! Polkadot-to-KusamaBridgeHub headers sync entrypoint.
|
//! Polkadot-to-KusamaBridgeHub headers sync entrypoint.
|
||||||
|
|
||||||
use crate::cli::bridge::{
|
use substrate_relay_helper::cli::bridge::{
|
||||||
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -16,11 +16,11 @@
|
|||||||
|
|
||||||
//! Polkadot-to-BridgeHubKusama parachains sync entrypoint.
|
//! Polkadot-to-BridgeHubKusama parachains sync entrypoint.
|
||||||
|
|
||||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge};
|
|
||||||
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
|
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
|
||||||
use relay_substrate_client::{CallOf, HeaderIdOf};
|
use relay_substrate_client::{CallOf, HeaderIdOf};
|
||||||
use substrate_relay_helper::parachains::{
|
use substrate_relay_helper::{
|
||||||
SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline,
|
cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge},
|
||||||
|
parachains::{SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Polkadot-to-BridgeHubKusama parachain sync description.
|
/// Polkadot-to-BridgeHubKusama parachain sync description.
|
||||||
|
|||||||
+5
-2
@@ -16,10 +16,13 @@
|
|||||||
|
|
||||||
//! BridgeHubPolkadot-to-PolkadotBulletin messages sync entrypoint.
|
//! BridgeHubPolkadot-to-PolkadotBulletin messages sync entrypoint.
|
||||||
|
|
||||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge};
|
|
||||||
use relay_bridge_hub_polkadot_client::BridgeHubPolkadot;
|
use relay_bridge_hub_polkadot_client::BridgeHubPolkadot;
|
||||||
use relay_polkadot_bulletin_client::PolkadotBulletin;
|
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.
|
/// BridgeHubPolkadot-to-PolkadotBulletin messages bridge.
|
||||||
pub struct BridgeHubPolkadotToPolkadotBulletinMessagesCliBridge {}
|
pub struct BridgeHubPolkadotToPolkadotBulletinMessagesCliBridge {}
|
||||||
|
|||||||
+5
-5
@@ -16,11 +16,6 @@
|
|||||||
|
|
||||||
//! PolkadotBulletin-to-BridgeHubPolkadot headers sync entrypoint.
|
//! PolkadotBulletin-to-BridgeHubPolkadot headers sync entrypoint.
|
||||||
|
|
||||||
use crate::cli::bridge::{
|
|
||||||
CliBridgeBase, MessagesCliBridge, RelayToRelayEquivocationDetectionCliBridge,
|
|
||||||
RelayToRelayHeadersCliBridge,
|
|
||||||
};
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use substrate_relay_helper::{
|
use substrate_relay_helper::{
|
||||||
equivocation::SubstrateEquivocationDetectionPipeline,
|
equivocation::SubstrateEquivocationDetectionPipeline,
|
||||||
@@ -28,6 +23,11 @@ use substrate_relay_helper::{
|
|||||||
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
|
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use substrate_relay_helper::cli::bridge::{
|
||||||
|
CliBridgeBase, MessagesCliBridge, RelayToRelayEquivocationDetectionCliBridge,
|
||||||
|
RelayToRelayHeadersCliBridge,
|
||||||
|
};
|
||||||
|
|
||||||
/// Description of `PolkadotBulletin` -> `PolkadotBridgeHub` finalized headers bridge.
|
/// Description of `PolkadotBulletin` -> `PolkadotBridgeHub` finalized headers bridge.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct PolkadotBulletinFinalityToBridgeHubPolkadot;
|
pub struct PolkadotBulletinFinalityToBridgeHubPolkadot;
|
||||||
|
|||||||
+5
-2
@@ -16,10 +16,13 @@
|
|||||||
|
|
||||||
//! PolkadotBulletin-to-BridgeHubPolkadot messages sync entrypoint.
|
//! PolkadotBulletin-to-BridgeHubPolkadot messages sync entrypoint.
|
||||||
|
|
||||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge};
|
|
||||||
use relay_bridge_hub_polkadot_client::BridgeHubPolkadot;
|
use relay_bridge_hub_polkadot_client::BridgeHubPolkadot;
|
||||||
use relay_polkadot_bulletin_client::PolkadotBulletin;
|
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.
|
/// PolkadotBulletin-to-BridgeHubPolkadot messages bridge.
|
||||||
pub struct PolkadotBulletinToBridgeHubPolkadotMessagesCliBridge {}
|
pub struct PolkadotBulletinToBridgeHubPolkadotMessagesCliBridge {}
|
||||||
|
|||||||
+4
-4
@@ -16,10 +16,6 @@
|
|||||||
|
|
||||||
//! Polkadot-to-PolkadotBulletin headers sync entrypoint.
|
//! Polkadot-to-PolkadotBulletin headers sync entrypoint.
|
||||||
|
|
||||||
use crate::cli::bridge::{
|
|
||||||
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
|
||||||
};
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use substrate_relay_helper::{
|
use substrate_relay_helper::{
|
||||||
equivocation::SubstrateEquivocationDetectionPipeline,
|
equivocation::SubstrateEquivocationDetectionPipeline,
|
||||||
@@ -27,6 +23,10 @@ use substrate_relay_helper::{
|
|||||||
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
|
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use substrate_relay_helper::cli::bridge::{
|
||||||
|
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
||||||
|
};
|
||||||
|
|
||||||
/// Description of Polkadot -> `PolkadotBulletin` finalized headers bridge.
|
/// Description of Polkadot -> `PolkadotBulletin` finalized headers bridge.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct PolkadotFinalityToPolkadotBulletin;
|
pub struct PolkadotFinalityToPolkadotBulletin;
|
||||||
|
|||||||
+3
-1
@@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
//! Polkadot-to-PolkadotBulletin parachains sync entrypoint.
|
//! 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_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
|
||||||
use bp_runtime::Chain;
|
use bp_runtime::Chain;
|
||||||
|
|||||||
+5
-2
@@ -17,9 +17,12 @@
|
|||||||
//! BridgeHubRococo-to-RococoBulletin messages sync entrypoint.
|
//! BridgeHubRococo-to-RococoBulletin messages sync entrypoint.
|
||||||
|
|
||||||
use super::BridgeHubRococoAsBridgeHubPolkadot;
|
use super::BridgeHubRococoAsBridgeHubPolkadot;
|
||||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge};
|
|
||||||
use relay_polkadot_bulletin_client::PolkadotBulletin as RococoBulletin;
|
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.
|
/// BridgeHubRococo-to-RococoBulletin messages bridge.
|
||||||
pub struct BridgeHubRococoToRococoBulletinMessagesCliBridge {}
|
pub struct BridgeHubRococoToRococoBulletinMessagesCliBridge {}
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
//! Declaration of all bridges between Rococo Bulletin Chain and Rococo Bridge Hub.
|
//! Declaration of all bridges between Rococo Bulletin Chain and Rococo Bridge Hub.
|
||||||
|
|
||||||
use crate::cli::CliChain;
|
|
||||||
|
|
||||||
use bp_messages::MessageNonce;
|
use bp_messages::MessageNonce;
|
||||||
use bp_runtime::{
|
use bp_runtime::{
|
||||||
AccountIdOf, BalanceOf, BlockNumberOf, ChainId, HashOf, HasherOf, HeaderOf, NonceOf,
|
AccountIdOf, BalanceOf, BlockNumberOf, ChainId, HashOf, HasherOf, HeaderOf, NonceOf,
|
||||||
@@ -25,7 +23,8 @@ use bp_runtime::{
|
|||||||
};
|
};
|
||||||
use frame_support::pallet_prelude::Weight;
|
use frame_support::pallet_prelude::Weight;
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{
|
||||||
Error as SubstrateError, SignParam, SimpleRuntimeVersion, UnsignedTransaction,
|
ChainWithRuntimeVersion, Error as SubstrateError, SignParam, SimpleRuntimeVersion,
|
||||||
|
UnsignedTransaction,
|
||||||
};
|
};
|
||||||
use sp_core::storage::StorageKey;
|
use sp_core::storage::StorageKey;
|
||||||
use std::time::Duration;
|
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;
|
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;
|
relay_bridge_hub_polkadot_client::BridgeHubPolkadot::FROM_CHAIN_MESSAGE_DETAILS_METHOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CliChain for BridgeHubRococoAsBridgeHubPolkadot {
|
impl ChainWithRuntimeVersion for BridgeHubRococoAsBridgeHubPolkadot {
|
||||||
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
const RUNTIME_VERSION: Option<SimpleRuntimeVersion> =
|
||||||
Some(SimpleRuntimeVersion { spec_version: 1_003_000, transaction_version: 3 });
|
Some(SimpleRuntimeVersion { spec_version: 1_003_000, transaction_version: 3 });
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-4
@@ -17,10 +17,6 @@
|
|||||||
//! RococoBulletin-to-BridgeHubRococo headers sync entrypoint.
|
//! RococoBulletin-to-BridgeHubRococo headers sync entrypoint.
|
||||||
|
|
||||||
use super::BridgeHubRococoAsBridgeHubPolkadot;
|
use super::BridgeHubRococoAsBridgeHubPolkadot;
|
||||||
use crate::cli::bridge::{
|
|
||||||
CliBridgeBase, MessagesCliBridge, RelayToRelayEquivocationDetectionCliBridge,
|
|
||||||
RelayToRelayHeadersCliBridge,
|
|
||||||
};
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use substrate_relay_helper::{
|
use substrate_relay_helper::{
|
||||||
@@ -29,6 +25,11 @@ use substrate_relay_helper::{
|
|||||||
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
|
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use substrate_relay_helper::cli::bridge::{
|
||||||
|
CliBridgeBase, MessagesCliBridge, RelayToRelayEquivocationDetectionCliBridge,
|
||||||
|
RelayToRelayHeadersCliBridge,
|
||||||
|
};
|
||||||
|
|
||||||
/// Description of `RococoBulletin` -> `RococoBridgeHub` finalized headers bridge.
|
/// Description of `RococoBulletin` -> `RococoBridgeHub` finalized headers bridge.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct RococoBulletinFinalityToBridgeHubRococo;
|
pub struct RococoBulletinFinalityToBridgeHubRococo;
|
||||||
|
|||||||
+5
-2
@@ -17,9 +17,12 @@
|
|||||||
//! RococoBulletin-to-BridgeHubRococo messages sync entrypoint.
|
//! RococoBulletin-to-BridgeHubRococo messages sync entrypoint.
|
||||||
|
|
||||||
use super::BridgeHubRococoAsBridgeHubPolkadot;
|
use super::BridgeHubRococoAsBridgeHubPolkadot;
|
||||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge};
|
|
||||||
use relay_polkadot_bulletin_client::PolkadotBulletin as RococoBulletin;
|
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.
|
/// RococoBulletin-to-BridgeHubRococo messages bridge.
|
||||||
pub struct RococoBulletinToBridgeHubRococoMessagesCliBridge {}
|
pub struct RococoBulletinToBridgeHubRococoMessagesCliBridge {}
|
||||||
|
|||||||
+4
-3
@@ -17,9 +17,6 @@
|
|||||||
//! Rococo-to-RococoBulletin headers sync entrypoint.
|
//! Rococo-to-RococoBulletin headers sync entrypoint.
|
||||||
|
|
||||||
use super::RococoAsPolkadot;
|
use super::RococoAsPolkadot;
|
||||||
use crate::cli::bridge::{
|
|
||||||
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
|
||||||
};
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use substrate_relay_helper::{
|
use substrate_relay_helper::{
|
||||||
@@ -28,6 +25,10 @@ use substrate_relay_helper::{
|
|||||||
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
|
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use substrate_relay_helper::cli::bridge::{
|
||||||
|
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
||||||
|
};
|
||||||
|
|
||||||
/// Description of Rococo -> `RococoBulletin` finalized headers bridge.
|
/// Description of Rococo -> `RococoBulletin` finalized headers bridge.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct RococoFinalityToRococoBulletin;
|
pub struct RococoFinalityToRococoBulletin;
|
||||||
|
|||||||
+1
-1
@@ -17,12 +17,12 @@
|
|||||||
//! Rococo-to-RococoBulletin parachains sync entrypoint.
|
//! Rococo-to-RococoBulletin parachains sync entrypoint.
|
||||||
|
|
||||||
use super::{BridgeHubRococoAsBridgeHubPolkadot, RococoAsPolkadot};
|
use super::{BridgeHubRococoAsBridgeHubPolkadot, RococoAsPolkadot};
|
||||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge};
|
|
||||||
|
|
||||||
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
|
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
|
||||||
use bp_runtime::Chain;
|
use bp_runtime::Chain;
|
||||||
use relay_substrate_client::{CallOf, HeaderIdOf};
|
use relay_substrate_client::{CallOf, HeaderIdOf};
|
||||||
use substrate_relay_helper::{
|
use substrate_relay_helper::{
|
||||||
|
cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge},
|
||||||
messages_lane::MessagesRelayLimits,
|
messages_lane::MessagesRelayLimits,
|
||||||
parachains::{SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline},
|
parachains::{SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline},
|
||||||
};
|
};
|
||||||
|
|||||||
+5
-2
@@ -16,10 +16,13 @@
|
|||||||
|
|
||||||
//! BridgeHubRococo-to-BridgeHubWestend messages sync entrypoint.
|
//! BridgeHubRococo-to-BridgeHubWestend messages sync entrypoint.
|
||||||
|
|
||||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge};
|
|
||||||
use relay_bridge_hub_rococo_client::BridgeHubRococo;
|
use relay_bridge_hub_rococo_client::BridgeHubRococo;
|
||||||
use relay_bridge_hub_westend_client::BridgeHubWestend;
|
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 {}
|
pub struct BridgeHubRococoToBridgeHubWestendMessagesCliBridge {}
|
||||||
|
|
||||||
|
|||||||
+5
-2
@@ -16,10 +16,13 @@
|
|||||||
|
|
||||||
//! BridgeHubWestend-to-BridgeHubRococo messages sync entrypoint.
|
//! BridgeHubWestend-to-BridgeHubRococo messages sync entrypoint.
|
||||||
|
|
||||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge};
|
|
||||||
use relay_bridge_hub_rococo_client::BridgeHubRococo;
|
use relay_bridge_hub_rococo_client::BridgeHubRococo;
|
||||||
use relay_bridge_hub_westend_client::BridgeHubWestend;
|
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 {}
|
pub struct BridgeHubWestendToBridgeHubRococoMessagesCliBridge {}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -16,10 +16,6 @@
|
|||||||
|
|
||||||
//! Rococo-to-Westend bridge hubs headers sync entrypoint.
|
//! Rococo-to-Westend bridge hubs headers sync entrypoint.
|
||||||
|
|
||||||
use crate::cli::bridge::{
|
|
||||||
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
|
||||||
};
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use substrate_relay_helper::{
|
use substrate_relay_helper::{
|
||||||
equivocation::SubstrateEquivocationDetectionPipeline,
|
equivocation::SubstrateEquivocationDetectionPipeline,
|
||||||
@@ -27,6 +23,10 @@ use substrate_relay_helper::{
|
|||||||
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
|
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use substrate_relay_helper::cli::bridge::{
|
||||||
|
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
||||||
|
};
|
||||||
|
|
||||||
/// Description of Rococo -> Westend finalized headers bridge.
|
/// Description of Rococo -> Westend finalized headers bridge.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct RococoFinalityToBridgeHubWestend;
|
pub struct RococoFinalityToBridgeHubWestend;
|
||||||
|
|||||||
+3
-3
@@ -16,11 +16,11 @@
|
|||||||
|
|
||||||
//! Westend-to-Rococo parachains sync entrypoint.
|
//! Westend-to-Rococo parachains sync entrypoint.
|
||||||
|
|
||||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge};
|
|
||||||
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
|
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
|
||||||
use relay_substrate_client::{CallOf, HeaderIdOf};
|
use relay_substrate_client::{CallOf, HeaderIdOf};
|
||||||
use substrate_relay_helper::parachains::{
|
use substrate_relay_helper::{
|
||||||
SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline,
|
cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge},
|
||||||
|
parachains::{SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// BridgeHub-to-BridgeHub parachain sync description.
|
/// BridgeHub-to-BridgeHub parachain sync description.
|
||||||
|
|||||||
+4
-4
@@ -16,10 +16,6 @@
|
|||||||
|
|
||||||
//! Westend-to-Rococo bridge hubs headers sync entrypoint.
|
//! Westend-to-Rococo bridge hubs headers sync entrypoint.
|
||||||
|
|
||||||
use crate::cli::bridge::{
|
|
||||||
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
|
||||||
};
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use substrate_relay_helper::{
|
use substrate_relay_helper::{
|
||||||
equivocation::SubstrateEquivocationDetectionPipeline,
|
equivocation::SubstrateEquivocationDetectionPipeline,
|
||||||
@@ -27,6 +23,10 @@ use substrate_relay_helper::{
|
|||||||
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
|
finality_base::{engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalityPipeline},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use substrate_relay_helper::cli::bridge::{
|
||||||
|
CliBridgeBase, RelayToRelayEquivocationDetectionCliBridge, RelayToRelayHeadersCliBridge,
|
||||||
|
};
|
||||||
|
|
||||||
/// Description of Westend -> Rococo finalized headers bridge.
|
/// Description of Westend -> Rococo finalized headers bridge.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct WestendFinalityToBridgeHubRococo;
|
pub struct WestendFinalityToBridgeHubRococo;
|
||||||
|
|||||||
+3
-3
@@ -16,11 +16,11 @@
|
|||||||
|
|
||||||
//! Rococo-to-Westend parachains sync entrypoint.
|
//! Rococo-to-Westend parachains sync entrypoint.
|
||||||
|
|
||||||
use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge};
|
|
||||||
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
|
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
|
||||||
use relay_substrate_client::{CallOf, HeaderIdOf};
|
use relay_substrate_client::{CallOf, HeaderIdOf};
|
||||||
use substrate_relay_helper::parachains::{
|
use substrate_relay_helper::{
|
||||||
SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline,
|
cli::bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge},
|
||||||
|
parachains::{SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// BridgeHub-to-BridgeHub parachain sync description.
|
/// 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.
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
// 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/>.
|
// 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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
|
||||||
use sp_core::Pair;
|
use sp_core::Pair;
|
||||||
|
use substrate_relay_helper::cli::chain_schema::TargetSigningParams;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn reads_suri_from_file() {
|
fn reads_suri_from_file() {
|
||||||
|
|||||||
@@ -14,25 +14,23 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// 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/>.
|
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::{
|
use crate::bridges::{
|
||||||
bridges::{
|
kusama_polkadot::{
|
||||||
kusama_polkadot::{
|
kusama_headers_to_bridge_hub_polkadot::KusamaToBridgeHubPolkadotCliBridge,
|
||||||
kusama_headers_to_bridge_hub_polkadot::KusamaToBridgeHubPolkadotCliBridge,
|
polkadot_headers_to_bridge_hub_kusama::PolkadotToBridgeHubKusamaCliBridge,
|
||||||
polkadot_headers_to_bridge_hub_kusama::PolkadotToBridgeHubKusamaCliBridge,
|
},
|
||||||
},
|
rococo_westend::{
|
||||||
rococo_westend::{
|
rococo_headers_to_bridge_hub_westend::RococoToBridgeHubWestendCliBridge,
|
||||||
rococo_headers_to_bridge_hub_westend::RococoToBridgeHubWestendCliBridge,
|
westend_headers_to_bridge_hub_rococo::WestendToBridgeHubRococoCliBridge,
|
||||||
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 structopt::StructOpt;
|
||||||
use strum::{EnumString, VariantNames};
|
use strum::{EnumString, VariantNames};
|
||||||
use substrate_relay_helper::{equivocation, equivocation::SubstrateEquivocationDetectionPipeline};
|
|
||||||
|
use substrate_relay_helper::cli::detect_equivocations::{
|
||||||
|
DetectEquivocationsParams, EquivocationsDetector,
|
||||||
|
};
|
||||||
|
|
||||||
/// Start equivocation detection loop.
|
/// Start equivocation detection loop.
|
||||||
#[derive(StructOpt)]
|
#[derive(StructOpt)]
|
||||||
@@ -40,13 +38,7 @@ pub struct DetectEquivocations {
|
|||||||
#[structopt(possible_values = DetectEquivocationsBridge::VARIANTS, case_insensitive = true)]
|
#[structopt(possible_values = DetectEquivocationsBridge::VARIANTS, case_insensitive = true)]
|
||||||
bridge: DetectEquivocationsBridge,
|
bridge: DetectEquivocationsBridge,
|
||||||
#[structopt(flatten)]
|
#[structopt(flatten)]
|
||||||
source: SourceConnectionParams,
|
params: DetectEquivocationsParams,
|
||||||
#[structopt(flatten)]
|
|
||||||
source_sign: SourceSigningParams,
|
|
||||||
#[structopt(flatten)]
|
|
||||||
target: TargetConnectionParams,
|
|
||||||
#[structopt(flatten)]
|
|
||||||
prometheus_params: PrometheusParams,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, EnumString, VariantNames)]
|
#[derive(Debug, EnumString, VariantNames)]
|
||||||
@@ -59,29 +51,6 @@ pub enum DetectEquivocationsBridge {
|
|||||||
WestendToBridgeHubRococo,
|
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 KusamaToBridgeHubPolkadotCliBridge {}
|
||||||
impl EquivocationsDetector for PolkadotToBridgeHubKusamaCliBridge {}
|
impl EquivocationsDetector for PolkadotToBridgeHubKusamaCliBridge {}
|
||||||
impl EquivocationsDetector for RococoToBridgeHubWestendCliBridge {}
|
impl EquivocationsDetector for RococoToBridgeHubWestendCliBridge {}
|
||||||
@@ -92,13 +61,13 @@ impl DetectEquivocations {
|
|||||||
pub async fn run(self) -> anyhow::Result<()> {
|
pub async fn run(self) -> anyhow::Result<()> {
|
||||||
match self.bridge {
|
match self.bridge {
|
||||||
DetectEquivocationsBridge::KusamaToBridgeHubPolkadot =>
|
DetectEquivocationsBridge::KusamaToBridgeHubPolkadot =>
|
||||||
KusamaToBridgeHubPolkadotCliBridge::start(self),
|
KusamaToBridgeHubPolkadotCliBridge::start(self.params),
|
||||||
DetectEquivocationsBridge::PolkadotToBridgeHubKusama =>
|
DetectEquivocationsBridge::PolkadotToBridgeHubKusama =>
|
||||||
PolkadotToBridgeHubKusamaCliBridge::start(self),
|
PolkadotToBridgeHubKusamaCliBridge::start(self.params),
|
||||||
DetectEquivocationsBridge::RococoToBridgeHubWestend =>
|
DetectEquivocationsBridge::RococoToBridgeHubWestend =>
|
||||||
RococoToBridgeHubWestendCliBridge::start(self),
|
RococoToBridgeHubWestendCliBridge::start(self.params),
|
||||||
DetectEquivocationsBridge::WestendToBridgeHubRococo =>
|
DetectEquivocationsBridge::WestendToBridgeHubRococo =>
|
||||||
WestendToBridgeHubRococoCliBridge::start(self),
|
WestendToBridgeHubRococoCliBridge::start(self.params),
|
||||||
}
|
}
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,107 +14,31 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// 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/>.
|
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use crate::bridges::{
|
||||||
use codec::Encode;
|
kusama_polkadot::{
|
||||||
|
kusama_headers_to_bridge_hub_polkadot::KusamaToBridgeHubPolkadotCliBridge,
|
||||||
use crate::{
|
polkadot_headers_to_bridge_hub_kusama::PolkadotToBridgeHubKusamaCliBridge,
|
||||||
bridges::{
|
},
|
||||||
kusama_polkadot::{
|
polkadot_bulletin::{
|
||||||
kusama_headers_to_bridge_hub_polkadot::KusamaToBridgeHubPolkadotCliBridge,
|
polkadot_bulletin_headers_to_bridge_hub_polkadot::PolkadotBulletinToBridgeHubPolkadotCliBridge,
|
||||||
polkadot_headers_to_bridge_hub_kusama::PolkadotToBridgeHubKusamaCliBridge,
|
polkadot_headers_to_polkadot_bulletin::PolkadotToPolkadotBulletinCliBridge,
|
||||||
},
|
},
|
||||||
polkadot_bulletin::{
|
rococo_bulletin::{
|
||||||
polkadot_bulletin_headers_to_bridge_hub_polkadot::PolkadotBulletinToBridgeHubPolkadotCliBridge,
|
rococo_bulletin_headers_to_bridge_hub_rococo::RococoBulletinToBridgeHubRococoCliBridge,
|
||||||
polkadot_headers_to_polkadot_bulletin::PolkadotToPolkadotBulletinCliBridge,
|
rococo_headers_to_rococo_bulletin::RococoToRococoBulletinCliBridge,
|
||||||
},
|
},
|
||||||
rococo_bulletin::{
|
rococo_westend::{
|
||||||
rococo_bulletin_headers_to_bridge_hub_rococo::RococoBulletinToBridgeHubRococoCliBridge,
|
rococo_headers_to_bridge_hub_westend::RococoToBridgeHubWestendCliBridge,
|
||||||
rococo_headers_to_rococo_bulletin::RococoToRococoBulletinCliBridge,
|
westend_headers_to_bridge_hub_rococo::WestendToBridgeHubRococoCliBridge,
|
||||||
},
|
|
||||||
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::Chain;
|
||||||
use relay_substrate_client::{AccountKeyPairOf, Chain, UnsignedTransaction};
|
|
||||||
use sp_core::Pair;
|
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
use strum::{EnumString, VariantNames};
|
use strum::{EnumString, VariantNames};
|
||||||
use substrate_relay_helper::finality_base::engine::{Engine, Grandpa as GrandpaFinalityEngine};
|
use substrate_relay_helper::{
|
||||||
|
cli::init_bridge::{BridgeInitializer, InitBridgeParams},
|
||||||
/// Initialize bridge pallet.
|
finality_base::engine::{Engine, Grandpa as GrandpaFinalityEngine},
|
||||||
#[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(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BridgeInitializer for RococoToBridgeHubWestendCliBridge {
|
impl BridgeInitializer for RococoToBridgeHubWestendCliBridge {
|
||||||
type Engine = GrandpaFinalityEngine<Self::Source>;
|
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 {
|
impl InitBridge {
|
||||||
/// Run the command.
|
/// Run the command.
|
||||||
pub async fn run(self) -> anyhow::Result<()> {
|
pub async fn run(self) -> anyhow::Result<()> {
|
||||||
match self.bridge {
|
match self.bridge {
|
||||||
InitBridgeName::KusamaToBridgeHubPolkadot =>
|
InitBridgeName::KusamaToBridgeHubPolkadot =>
|
||||||
KusamaToBridgeHubPolkadotCliBridge::init_bridge(self),
|
KusamaToBridgeHubPolkadotCliBridge::init_bridge(self.params),
|
||||||
InitBridgeName::PolkadotToBridgeHubKusama =>
|
InitBridgeName::PolkadotToBridgeHubKusama =>
|
||||||
PolkadotToBridgeHubKusamaCliBridge::init_bridge(self),
|
PolkadotToBridgeHubKusamaCliBridge::init_bridge(self.params),
|
||||||
InitBridgeName::PolkadotToPolkadotBulletin =>
|
InitBridgeName::PolkadotToPolkadotBulletin =>
|
||||||
PolkadotToPolkadotBulletinCliBridge::init_bridge(self),
|
PolkadotToPolkadotBulletinCliBridge::init_bridge(self.params),
|
||||||
InitBridgeName::PolkadotBulletinToBridgeHubPolkadot =>
|
InitBridgeName::PolkadotBulletinToBridgeHubPolkadot =>
|
||||||
PolkadotBulletinToBridgeHubPolkadotCliBridge::init_bridge(self),
|
PolkadotBulletinToBridgeHubPolkadotCliBridge::init_bridge(self.params),
|
||||||
InitBridgeName::RococoToRococoBulletin =>
|
InitBridgeName::RococoToRococoBulletin =>
|
||||||
RococoToRococoBulletinCliBridge::init_bridge(self),
|
RococoToRococoBulletinCliBridge::init_bridge(self.params),
|
||||||
InitBridgeName::RococoBulletinToBridgeHubRococo =>
|
InitBridgeName::RococoBulletinToBridgeHubRococo =>
|
||||||
RococoBulletinToBridgeHubRococoCliBridge::init_bridge(self),
|
RococoBulletinToBridgeHubRococoCliBridge::init_bridge(self.params),
|
||||||
InitBridgeName::RococoToBridgeHubWestend =>
|
InitBridgeName::RococoToBridgeHubWestend =>
|
||||||
RococoToBridgeHubWestendCliBridge::init_bridge(self),
|
RococoToBridgeHubWestendCliBridge::init_bridge(self.params),
|
||||||
InitBridgeName::WestendToBridgeHubRococo =>
|
InitBridgeName::WestendToBridgeHubRococo =>
|
||||||
WestendToBridgeHubRococoCliBridge::init_bridge(self),
|
WestendToBridgeHubRococoCliBridge::init_bridge(self.params),
|
||||||
}
|
}
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,18 +17,10 @@
|
|||||||
//! Deal with CLI args of substrate-to-substrate relay.
|
//! Deal with CLI args of substrate-to-substrate relay.
|
||||||
|
|
||||||
use async_std::prelude::*;
|
use async_std::prelude::*;
|
||||||
use codec::{Decode, Encode};
|
|
||||||
use futures::{select, FutureExt};
|
use futures::{select, FutureExt};
|
||||||
use rbtag::BuildInfo;
|
|
||||||
use signal_hook::consts::*;
|
use signal_hook::consts::*;
|
||||||
use signal_hook_async_std::Signals;
|
use signal_hook_async_std::Signals;
|
||||||
use structopt::{clap::arg_enum, StructOpt};
|
use structopt::StructOpt;
|
||||||
use strum::{EnumString, VariantNames};
|
|
||||||
|
|
||||||
use bp_messages::LaneId;
|
|
||||||
use relay_substrate_client::SimpleRuntimeVersion;
|
|
||||||
|
|
||||||
pub(crate) mod bridge;
|
|
||||||
|
|
||||||
mod chain_schema;
|
mod chain_schema;
|
||||||
mod detect_equivocations;
|
mod detect_equivocations;
|
||||||
@@ -50,11 +42,17 @@ pub fn parse_args() -> Command {
|
|||||||
#[derive(StructOpt)]
|
#[derive(StructOpt)]
|
||||||
#[structopt(about = "Substrate-to-Substrate relay")]
|
#[structopt(about = "Substrate-to-Substrate relay")]
|
||||||
pub enum Command {
|
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.
|
/// Start headers relay between two chains.
|
||||||
///
|
///
|
||||||
/// The on-chain bridge component should have been already initialized with
|
/// The on-chain bridge component should have been already initialized with
|
||||||
/// `init-bridge` sub-command.
|
/// `init-bridge` sub-command.
|
||||||
RelayHeaders(relay_headers::RelayHeaders),
|
RelayHeaders(relay_headers::RelayHeaders),
|
||||||
|
/// Relay parachain heads.
|
||||||
|
RelayParachains(relay_parachains::RelayParachains),
|
||||||
/// Start messages relay between two chains.
|
/// Start messages relay between two chains.
|
||||||
///
|
///
|
||||||
/// Ties up to `Messages` pallets on both chains and starts relaying messages.
|
/// 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
|
/// the message relays - i.e. when there are messages or confirmations that needs to be
|
||||||
/// relayed between chains.
|
/// relayed between chains.
|
||||||
RelayHeadersAndMessages(Box<relay_headers_and_messages::RelayHeadersAndMessages>),
|
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.
|
/// Detect and report equivocations.
|
||||||
///
|
///
|
||||||
/// Parses the source chain headers that were synchronized with the target chain looking for
|
/// 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};
|
use relay_utils::initialize::{initialize_logger, initialize_relay};
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
|
Self::InitBridge(_) |
|
||||||
Self::RelayHeaders(_) |
|
Self::RelayHeaders(_) |
|
||||||
Self::RelayMessages(_) |
|
Self::RelayMessages(_) |
|
||||||
Self::RelayHeadersAndMessages(_) |
|
Self::RelayHeadersAndMessages(_) => {
|
||||||
Self::InitBridge(_) => {
|
|
||||||
initialize_relay();
|
initialize_relay();
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
@@ -101,11 +93,11 @@ impl Command {
|
|||||||
/// Run the command.
|
/// Run the command.
|
||||||
async fn do_run(self) -> anyhow::Result<()> {
|
async fn do_run(self) -> anyhow::Result<()> {
|
||||||
match self {
|
match self {
|
||||||
|
Self::InitBridge(arg) => arg.run().await?,
|
||||||
Self::RelayHeaders(arg) => arg.run().await?,
|
Self::RelayHeaders(arg) => arg.run().await?,
|
||||||
|
Self::RelayParachains(arg) => arg.run().await?,
|
||||||
Self::RelayMessages(arg) => arg.run().await?,
|
Self::RelayMessages(arg) => arg.run().await?,
|
||||||
Self::RelayHeadersAndMessages(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?,
|
Self::DetectEquivocations(arg) => arg.run().await?,
|
||||||
}
|
}
|
||||||
Ok(())
|
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
|
// 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/>.
|
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
use strum::{EnumString, VariantNames};
|
use strum::{EnumString, VariantNames};
|
||||||
|
|
||||||
@@ -32,10 +31,8 @@ use crate::bridges::{
|
|||||||
rococo_headers_to_rococo_bulletin::RococoToRococoBulletinCliBridge,
|
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.
|
/// Start headers relayer process.
|
||||||
#[derive(StructOpt)]
|
#[derive(StructOpt)]
|
||||||
@@ -43,18 +40,8 @@ pub struct RelayHeaders {
|
|||||||
/// A bridge instance to relay headers for.
|
/// A bridge instance to relay headers for.
|
||||||
#[structopt(possible_values = RelayHeadersBridge::VARIANTS, case_insensitive = true)]
|
#[structopt(possible_values = RelayHeadersBridge::VARIANTS, case_insensitive = true)]
|
||||||
bridge: RelayHeadersBridge,
|
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)]
|
#[structopt(flatten)]
|
||||||
source: SourceConnectionParams,
|
params: RelayHeadersParams,
|
||||||
#[structopt(flatten)]
|
|
||||||
target: TargetConnectionParams,
|
|
||||||
#[structopt(flatten)]
|
|
||||||
target_sign: TargetSigningParams,
|
|
||||||
#[structopt(flatten)]
|
|
||||||
prometheus_params: PrometheusParams,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, EnumString, VariantNames)]
|
#[derive(Debug, EnumString, VariantNames)]
|
||||||
@@ -69,37 +56,6 @@ pub enum RelayHeadersBridge {
|
|||||||
RococoBulletinToBridgeHubRococo,
|
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 KusamaToBridgeHubPolkadotCliBridge {}
|
||||||
impl HeadersRelayer for PolkadotToBridgeHubKusamaCliBridge {}
|
impl HeadersRelayer for PolkadotToBridgeHubKusamaCliBridge {}
|
||||||
impl HeadersRelayer for PolkadotToPolkadotBulletinCliBridge {}
|
impl HeadersRelayer for PolkadotToPolkadotBulletinCliBridge {}
|
||||||
@@ -112,17 +68,17 @@ impl RelayHeaders {
|
|||||||
pub async fn run(self) -> anyhow::Result<()> {
|
pub async fn run(self) -> anyhow::Result<()> {
|
||||||
match self.bridge {
|
match self.bridge {
|
||||||
RelayHeadersBridge::KusamaToBridgeHubPolkadot =>
|
RelayHeadersBridge::KusamaToBridgeHubPolkadot =>
|
||||||
KusamaToBridgeHubPolkadotCliBridge::relay_headers(self),
|
KusamaToBridgeHubPolkadotCliBridge::relay_headers(self.params),
|
||||||
RelayHeadersBridge::PolkadotToBridgeHubKusama =>
|
RelayHeadersBridge::PolkadotToBridgeHubKusama =>
|
||||||
PolkadotToBridgeHubKusamaCliBridge::relay_headers(self),
|
PolkadotToBridgeHubKusamaCliBridge::relay_headers(self.params),
|
||||||
RelayHeadersBridge::PolkadotToPolkadotBulletin =>
|
RelayHeadersBridge::PolkadotToPolkadotBulletin =>
|
||||||
PolkadotToPolkadotBulletinCliBridge::relay_headers(self),
|
PolkadotToPolkadotBulletinCliBridge::relay_headers(self.params),
|
||||||
RelayHeadersBridge::PolkadotBulletinToBridgeHubPolkadot =>
|
RelayHeadersBridge::PolkadotBulletinToBridgeHubPolkadot =>
|
||||||
PolkadotBulletinToBridgeHubPolkadotCliBridge::relay_headers(self),
|
PolkadotBulletinToBridgeHubPolkadotCliBridge::relay_headers(self.params),
|
||||||
RelayHeadersBridge::RococoToRococoBulletin =>
|
RelayHeadersBridge::RococoToRococoBulletin =>
|
||||||
RococoToRococoBulletinCliBridge::relay_headers(self),
|
RococoToRococoBulletinCliBridge::relay_headers(self.params),
|
||||||
RelayHeadersBridge::RococoBulletinToBridgeHubRococo =>
|
RelayHeadersBridge::RococoBulletinToBridgeHubRococo =>
|
||||||
RococoBulletinToBridgeHubRococoCliBridge::relay_headers(self),
|
RococoBulletinToBridgeHubRococoCliBridge::relay_headers(self.params),
|
||||||
}
|
}
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|||||||
+31
-323
@@ -23,176 +23,48 @@
|
|||||||
//! `declare_chain_to_parachain_bridge_schema` for the bridge.
|
//! `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.
|
//! 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 async_trait::async_trait;
|
||||||
use std::{marker::PhantomData, sync::Arc};
|
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
use futures::{FutureExt, TryFutureExt};
|
use crate::bridges::{
|
||||||
use relay_to_parachain::*;
|
kusama_polkadot::{
|
||||||
|
kusama_parachains_to_bridge_hub_polkadot::BridgeHubKusamaToBridgeHubPolkadotCliBridge,
|
||||||
use crate::{
|
polkadot_parachains_to_bridge_hub_kusama::BridgeHubPolkadotToBridgeHubKusamaCliBridge,
|
||||||
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,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
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::{
|
cli::{
|
||||||
bridge::{
|
bridge::{
|
||||||
CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge,
|
CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge,
|
||||||
RelayToRelayHeadersCliBridge,
|
RelayToRelayHeadersCliBridge,
|
||||||
},
|
},
|
||||||
chain_schema::*,
|
chain_schema::*,
|
||||||
relay_headers_and_messages::parachain_to_parachain::ParachainToParachainBridge,
|
relay_headers_and_messages::{
|
||||||
CliChain, HexLaneId, PrometheusParams,
|
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.
|
// All supported chains.
|
||||||
declare_chain_cli_schema!(Rococo, rococo);
|
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!(PolkadotBulletin, BridgeHubPolkadot, Polkadot);
|
||||||
declare_relay_to_parachain_bridge_schema!(RococoBulletin, BridgeHubRococo, Rococo);
|
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.
|
/// BridgeHubRococo <> BridgeHubWestend complex relay.
|
||||||
pub struct BridgeHubRococoBridgeHubWestendFull2WayBridge {
|
pub struct BridgeHubRococoBridgeHubWestendFull2WayBridge {
|
||||||
base: <Self as Full2WayBridge>::Base,
|
base: <Self as Full2WayBridge>::Base,
|
||||||
@@ -556,6 +263,7 @@ impl RelayHeadersAndMessages {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use substrate_relay_helper::cli::{HexLaneId, PrometheusParams};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_parse_parachain_to_parachain_options() {
|
fn should_parse_parachain_to_parachain_options() {
|
||||||
@@ -14,10 +14,8 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// 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/>.
|
// 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 structopt::StructOpt;
|
||||||
use strum::VariantNames;
|
use strum::{EnumString, VariantNames};
|
||||||
|
|
||||||
use crate::bridges::{
|
use crate::bridges::{
|
||||||
kusama_polkadot::{
|
kusama_polkadot::{
|
||||||
@@ -37,10 +35,21 @@ use crate::bridges::{
|
|||||||
bridge_hub_westend_messages_to_bridge_hub_rococo::BridgeHubWestendToBridgeHubRococoMessagesCliBridge,
|
bridge_hub_westend_messages_to_bridge_hub_rococo::BridgeHubWestendToBridgeHubRococoMessagesCliBridge,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use relay_substrate_client::{AccountIdOf, AccountKeyPairOf, BalanceOf, ChainWithTransactions};
|
use substrate_relay_helper::cli::relay_messages::{MessagesRelayer, RelayMessagesParams};
|
||||||
use substrate_relay_helper::{messages_lane::MessagesRelayParams, TransactionParams};
|
|
||||||
|
|
||||||
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.
|
/// Start messages relayer process.
|
||||||
#[derive(StructOpt)]
|
#[derive(StructOpt)]
|
||||||
@@ -48,57 +57,8 @@ pub struct RelayMessages {
|
|||||||
/// A bridge instance to relay messages for.
|
/// A bridge instance to relay messages for.
|
||||||
#[structopt(possible_values = FullBridge::VARIANTS, case_insensitive = true)]
|
#[structopt(possible_values = FullBridge::VARIANTS, case_insensitive = true)]
|
||||||
bridge: FullBridge,
|
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)]
|
#[structopt(flatten)]
|
||||||
source: SourceConnectionParams,
|
params: RelayMessagesParams,
|
||||||
#[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))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MessagesRelayer for BridgeHubRococoToBridgeHubWestendMessagesCliBridge {}
|
impl MessagesRelayer for BridgeHubRococoToBridgeHubWestendMessagesCliBridge {}
|
||||||
@@ -115,21 +75,21 @@ impl RelayMessages {
|
|||||||
pub async fn run(self) -> anyhow::Result<()> {
|
pub async fn run(self) -> anyhow::Result<()> {
|
||||||
match self.bridge {
|
match self.bridge {
|
||||||
FullBridge::BridgeHubRococoToBridgeHubWestend =>
|
FullBridge::BridgeHubRococoToBridgeHubWestend =>
|
||||||
BridgeHubRococoToBridgeHubWestendMessagesCliBridge::relay_messages(self),
|
BridgeHubRococoToBridgeHubWestendMessagesCliBridge::relay_messages(self.params),
|
||||||
FullBridge::BridgeHubWestendToBridgeHubRococo =>
|
FullBridge::BridgeHubWestendToBridgeHubRococo =>
|
||||||
BridgeHubWestendToBridgeHubRococoMessagesCliBridge::relay_messages(self),
|
BridgeHubWestendToBridgeHubRococoMessagesCliBridge::relay_messages(self.params),
|
||||||
FullBridge::BridgeHubKusamaToBridgeHubPolkadot =>
|
FullBridge::BridgeHubKusamaToBridgeHubPolkadot =>
|
||||||
BridgeHubKusamaToBridgeHubPolkadotMessagesCliBridge::relay_messages(self),
|
BridgeHubKusamaToBridgeHubPolkadotMessagesCliBridge::relay_messages(self.params),
|
||||||
FullBridge::BridgeHubPolkadotToBridgeHubKusama =>
|
FullBridge::BridgeHubPolkadotToBridgeHubKusama =>
|
||||||
BridgeHubPolkadotToBridgeHubKusamaMessagesCliBridge::relay_messages(self),
|
BridgeHubPolkadotToBridgeHubKusamaMessagesCliBridge::relay_messages(self.params),
|
||||||
FullBridge::PolkadotBulletinToBridgeHubPolkadot =>
|
FullBridge::PolkadotBulletinToBridgeHubPolkadot =>
|
||||||
PolkadotBulletinToBridgeHubPolkadotMessagesCliBridge::relay_messages(self),
|
PolkadotBulletinToBridgeHubPolkadotMessagesCliBridge::relay_messages(self.params),
|
||||||
FullBridge::BridgeHubPolkadotToPolkadotBulletin =>
|
FullBridge::BridgeHubPolkadotToPolkadotBulletin =>
|
||||||
BridgeHubPolkadotToPolkadotBulletinMessagesCliBridge::relay_messages(self),
|
BridgeHubPolkadotToPolkadotBulletinMessagesCliBridge::relay_messages(self.params),
|
||||||
FullBridge::RococoBulletinToBridgeHubRococo =>
|
FullBridge::RococoBulletinToBridgeHubRococo =>
|
||||||
RococoBulletinToBridgeHubRococoMessagesCliBridge::relay_messages(self),
|
RococoBulletinToBridgeHubRococoMessagesCliBridge::relay_messages(self.params),
|
||||||
FullBridge::BridgeHubRococoToRococoBulletin =>
|
FullBridge::BridgeHubRococoToRococoBulletin =>
|
||||||
BridgeHubRococoToRococoBulletinMessagesCliBridge::relay_messages(self),
|
BridgeHubRococoToRococoBulletinMessagesCliBridge::relay_messages(self.params),
|
||||||
}
|
}
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,24 +26,9 @@ use crate::bridges::{
|
|||||||
westend_parachains_to_bridge_hub_rococo::BridgeHubWestendToBridgeHubRococoCliBridge,
|
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 structopt::StructOpt;
|
||||||
use strum::{EnumString, VariantNames};
|
use strum::{EnumString, VariantNames};
|
||||||
use substrate_relay_helper::{
|
use substrate_relay_helper::cli::relay_parachains::{ParachainsRelayer, RelayParachainsParams};
|
||||||
parachains::{source::ParachainsSource, target::ParachainsTarget, ParachainsPipelineAdapter},
|
|
||||||
TransactionParams,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::cli::{
|
|
||||||
bridge::{CliBridgeBase, ParachainToRelayHeadersCliBridge},
|
|
||||||
chain_schema::*,
|
|
||||||
PrometheusParams,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Start parachain heads relayer process.
|
/// Start parachain heads relayer process.
|
||||||
#[derive(StructOpt)]
|
#[derive(StructOpt)]
|
||||||
@@ -52,13 +37,7 @@ pub struct RelayParachains {
|
|||||||
#[structopt(possible_values = RelayParachainsBridge::VARIANTS, case_insensitive = true)]
|
#[structopt(possible_values = RelayParachainsBridge::VARIANTS, case_insensitive = true)]
|
||||||
bridge: RelayParachainsBridge,
|
bridge: RelayParachainsBridge,
|
||||||
#[structopt(flatten)]
|
#[structopt(flatten)]
|
||||||
source: SourceConnectionParams,
|
params: RelayParachainsParams,
|
||||||
#[structopt(flatten)]
|
|
||||||
target: TargetConnectionParams,
|
|
||||||
#[structopt(flatten)]
|
|
||||||
target_sign: TargetSigningParams,
|
|
||||||
#[structopt(flatten)]
|
|
||||||
prometheus_params: PrometheusParams,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parachain heads relay bridge.
|
/// Parachain heads relay bridge.
|
||||||
@@ -73,47 +52,6 @@ pub enum RelayParachainsBridge {
|
|||||||
WestendToBridgeHubRococo,
|
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 BridgeHubRococoToBridgeHubWestendCliBridge {}
|
||||||
impl ParachainsRelayer for BridgeHubWestendToBridgeHubRococoCliBridge {}
|
impl ParachainsRelayer for BridgeHubWestendToBridgeHubRococoCliBridge {}
|
||||||
impl ParachainsRelayer for BridgeHubKusamaToBridgeHubPolkadotCliBridge {}
|
impl ParachainsRelayer for BridgeHubKusamaToBridgeHubPolkadotCliBridge {}
|
||||||
@@ -126,17 +64,17 @@ impl RelayParachains {
|
|||||||
pub async fn run(self) -> anyhow::Result<()> {
|
pub async fn run(self) -> anyhow::Result<()> {
|
||||||
match self.bridge {
|
match self.bridge {
|
||||||
RelayParachainsBridge::RococoToBridgeHubWestend =>
|
RelayParachainsBridge::RococoToBridgeHubWestend =>
|
||||||
BridgeHubRococoToBridgeHubWestendCliBridge::relay_parachains(self),
|
BridgeHubRococoToBridgeHubWestendCliBridge::relay_parachains(self.params),
|
||||||
RelayParachainsBridge::WestendToBridgeHubRococo =>
|
RelayParachainsBridge::WestendToBridgeHubRococo =>
|
||||||
BridgeHubWestendToBridgeHubRococoCliBridge::relay_parachains(self),
|
BridgeHubWestendToBridgeHubRococoCliBridge::relay_parachains(self.params),
|
||||||
RelayParachainsBridge::KusamaToBridgeHubPolkadot =>
|
RelayParachainsBridge::KusamaToBridgeHubPolkadot =>
|
||||||
BridgeHubKusamaToBridgeHubPolkadotCliBridge::relay_parachains(self),
|
BridgeHubKusamaToBridgeHubPolkadotCliBridge::relay_parachains(self.params),
|
||||||
RelayParachainsBridge::PolkadotToBridgeHubKusama =>
|
RelayParachainsBridge::PolkadotToBridgeHubKusama =>
|
||||||
BridgeHubPolkadotToBridgeHubKusamaCliBridge::relay_parachains(self),
|
BridgeHubPolkadotToBridgeHubKusamaCliBridge::relay_parachains(self.params),
|
||||||
RelayParachainsBridge::PolkadotToPolkadotBulletin =>
|
RelayParachainsBridge::PolkadotToPolkadotBulletin =>
|
||||||
PolkadotToPolkadotBulletinCliBridge::relay_parachains(self),
|
PolkadotToPolkadotBulletinCliBridge::relay_parachains(self.params),
|
||||||
RelayParachainsBridge::RococoToRococoBulletin =>
|
RelayParachainsBridge::RococoToRococoBulletin =>
|
||||||
RococoToRococoBulletinCliBridge::relay_parachains(self),
|
RococoToRococoBulletinCliBridge::relay_parachains(self.params),
|
||||||
}
|
}
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
mod bridges;
|
mod bridges;
|
||||||
mod chains;
|
|
||||||
mod cli;
|
mod cli;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
@@ -23,8 +23,9 @@ use bp_polkadot::SuffixedCommonTransactionExtensionExt;
|
|||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{
|
||||||
calls::UtilityCall as MockUtilityCall, Chain, ChainWithBalances, ChainWithMessages,
|
calls::UtilityCall as MockUtilityCall, Chain, ChainWithBalances, ChainWithMessages,
|
||||||
ChainWithTransactions, ChainWithUtilityPallet, Error as SubstrateError,
|
ChainWithRuntimeVersion, ChainWithTransactions, ChainWithUtilityPallet,
|
||||||
MockedRuntimeUtilityPallet, SignParam, UnderlyingChainProvider, UnsignedTransaction,
|
Error as SubstrateError, MockedRuntimeUtilityPallet, SignParam, SimpleRuntimeVersion,
|
||||||
|
UnderlyingChainProvider, UnsignedTransaction,
|
||||||
};
|
};
|
||||||
use sp_core::{storage::StorageKey, Pair};
|
use sp_core::{storage::StorageKey, Pair};
|
||||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
|
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
|
||||||
@@ -120,3 +121,8 @@ impl ChainWithMessages for BridgeHubKusama {
|
|||||||
const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
|
const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
|
||||||
bp_bridge_hub_kusama::FROM_BRIDGE_HUB_KUSAMA_MESSAGE_DETAILS_METHOD;
|
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 codec::Encode;
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{
|
||||||
calls::UtilityCall as MockUtilityCall, Chain, ChainWithBalances, ChainWithMessages,
|
calls::UtilityCall as MockUtilityCall, Chain, ChainWithBalances, ChainWithMessages,
|
||||||
ChainWithTransactions, ChainWithUtilityPallet, Error as SubstrateError,
|
ChainWithRuntimeVersion, ChainWithTransactions, ChainWithUtilityPallet,
|
||||||
MockedRuntimeUtilityPallet, SignParam, UnderlyingChainProvider, UnsignedTransaction,
|
Error as SubstrateError, MockedRuntimeUtilityPallet, SignParam, SimpleRuntimeVersion,
|
||||||
|
UnderlyingChainProvider, UnsignedTransaction,
|
||||||
};
|
};
|
||||||
use sp_core::{storage::StorageKey, Pair};
|
use sp_core::{storage::StorageKey, Pair};
|
||||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
|
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
|
||||||
@@ -124,3 +125,8 @@ impl ChainWithMessages for BridgeHubPolkadot {
|
|||||||
const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
|
const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
|
||||||
bp_bridge_hub_polkadot::FROM_BRIDGE_HUB_POLKADOT_MESSAGE_DETAILS_METHOD;
|
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 codec::Encode;
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{
|
||||||
calls::UtilityCall as MockUtilityCall, Chain, ChainWithBalances, ChainWithMessages,
|
calls::UtilityCall as MockUtilityCall, Chain, ChainWithBalances, ChainWithMessages,
|
||||||
ChainWithTransactions, ChainWithUtilityPallet, Error as SubstrateError,
|
ChainWithRuntimeVersion, ChainWithTransactions, ChainWithUtilityPallet,
|
||||||
MockedRuntimeUtilityPallet, SignParam, UnderlyingChainProvider, UnsignedTransaction,
|
Error as SubstrateError, MockedRuntimeUtilityPallet, SignParam, SimpleRuntimeVersion,
|
||||||
|
UnderlyingChainProvider, UnsignedTransaction,
|
||||||
};
|
};
|
||||||
use sp_core::{storage::StorageKey, Pair};
|
use sp_core::{storage::StorageKey, Pair};
|
||||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
|
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
|
||||||
@@ -122,3 +123,8 @@ impl ChainWithMessages for BridgeHubRococo {
|
|||||||
const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
|
const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
|
||||||
bp_bridge_hub_rococo::FROM_BRIDGE_HUB_ROCOCO_MESSAGE_DETAILS_METHOD;
|
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 codec::Encode;
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{
|
||||||
calls::UtilityCall as MockUtilityCall, Chain, ChainWithBalances, ChainWithMessages,
|
calls::UtilityCall as MockUtilityCall, Chain, ChainWithBalances, ChainWithMessages,
|
||||||
ChainWithTransactions, ChainWithUtilityPallet, Error as SubstrateError,
|
ChainWithRuntimeVersion, ChainWithTransactions, ChainWithUtilityPallet,
|
||||||
MockedRuntimeUtilityPallet, SignParam, UnderlyingChainProvider, UnsignedTransaction,
|
Error as SubstrateError, MockedRuntimeUtilityPallet, SignParam, SimpleRuntimeVersion,
|
||||||
|
UnderlyingChainProvider, UnsignedTransaction,
|
||||||
};
|
};
|
||||||
use sp_core::{storage::StorageKey, Pair};
|
use sp_core::{storage::StorageKey, Pair};
|
||||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
|
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
|
||||||
@@ -120,3 +121,8 @@ impl ChainWithMessages for BridgeHubWestend {
|
|||||||
const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
|
const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str =
|
||||||
bp_bridge_hub_westend::FROM_BRIDGE_HUB_WESTEND_MESSAGE_DETAILS_METHOD;
|
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 bp_polkadot_core::SuffixedCommonTransactionExtensionExt;
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{
|
||||||
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithTransactions, Error as SubstrateError,
|
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithRuntimeVersion, ChainWithTransactions,
|
||||||
RelayChain, SignParam, UnderlyingChainProvider, UnsignedTransaction,
|
Error as SubstrateError, RelayChain, SignParam, SimpleRuntimeVersion, UnderlyingChainProvider,
|
||||||
|
UnsignedTransaction,
|
||||||
};
|
};
|
||||||
use sp_core::{storage::StorageKey, Pair};
|
use sp_core::{storage::StorageKey, Pair};
|
||||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount, MultiAddress};
|
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 bp_polkadot_bulletin::POLKADOT_BULLETIN_SYNCED_HEADERS_GRANDPA_INFO_METHOD;
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{
|
||||||
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithMessages, ChainWithTransactions,
|
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithMessages, ChainWithRuntimeVersion,
|
||||||
Error as SubstrateError, SignParam, UnderlyingChainProvider, UnsignedTransaction,
|
ChainWithTransactions, Error as SubstrateError, SignParam, SimpleRuntimeVersion,
|
||||||
|
UnderlyingChainProvider, UnsignedTransaction,
|
||||||
};
|
};
|
||||||
use sp_core::{storage::StorageKey, Pair};
|
use sp_core::{storage::StorageKey, Pair};
|
||||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount, MultiAddress};
|
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 bp_polkadot_core::SuffixedCommonTransactionExtensionExt;
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{
|
||||||
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithTransactions, Error as SubstrateError,
|
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithRuntimeVersion, ChainWithTransactions,
|
||||||
RelayChain, SignParam, UnderlyingChainProvider, UnsignedTransaction,
|
Error as SubstrateError, RelayChain, SignParam, SimpleRuntimeVersion, UnderlyingChainProvider,
|
||||||
|
UnsignedTransaction,
|
||||||
};
|
};
|
||||||
use sp_core::{storage::StorageKey, Pair};
|
use sp_core::{storage::StorageKey, Pair};
|
||||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount, MultiAddress};
|
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 bp_rococo::ROCOCO_SYNCED_HEADERS_GRANDPA_INFO_METHOD;
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{
|
||||||
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithTransactions, Error as SubstrateError,
|
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithRuntimeVersion, ChainWithTransactions,
|
||||||
RelayChain, SignParam, UnderlyingChainProvider, UnsignedTransaction,
|
Error as SubstrateError, RelayChain, SignParam, SimpleRuntimeVersion, UnderlyingChainProvider,
|
||||||
|
UnsignedTransaction,
|
||||||
};
|
};
|
||||||
use sp_core::{storage::StorageKey, Pair};
|
use sp_core::{storage::StorageKey, Pair};
|
||||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount, MultiAddress};
|
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::calls::UtilityCall;
|
||||||
|
|
||||||
|
use crate::SimpleRuntimeVersion;
|
||||||
use bp_header_chain::ChainWithGrandpa as ChainWithGrandpaBase;
|
use bp_header_chain::ChainWithGrandpa as ChainWithGrandpaBase;
|
||||||
use bp_messages::ChainWithMessages as ChainWithMessagesBase;
|
use bp_messages::ChainWithMessages as ChainWithMessagesBase;
|
||||||
use bp_runtime::{
|
use bp_runtime::{
|
||||||
@@ -58,6 +59,16 @@ pub trait Chain: ChainBase + Clone {
|
|||||||
type Call: Clone + Codec + Debug + Send + Sync;
|
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.
|
/// Substrate-based relay chain that supports parachains.
|
||||||
///
|
///
|
||||||
/// We assume that the parachains are supported using `runtime_parachains::paras` pallet.
|
/// We assume that the parachains are supported using `runtime_parachains::paras` pallet.
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ use std::time::Duration;
|
|||||||
pub use crate::{
|
pub use crate::{
|
||||||
chain::{
|
chain::{
|
||||||
AccountKeyPairOf, BlockWithJustification, CallOf, Chain, ChainWithBalances,
|
AccountKeyPairOf, BlockWithJustification, CallOf, Chain, ChainWithBalances,
|
||||||
ChainWithGrandpa, ChainWithMessages, ChainWithTransactions, ChainWithUtilityPallet,
|
ChainWithGrandpa, ChainWithMessages, ChainWithRuntimeVersion, ChainWithTransactions,
|
||||||
FullRuntimeUtilityPallet, MockedRuntimeUtilityPallet, Parachain, RelayChain, SignParam,
|
ChainWithUtilityPallet, FullRuntimeUtilityPallet, MockedRuntimeUtilityPallet, Parachain,
|
||||||
TransactionStatusOf, UnsignedTransaction, UtilityPallet,
|
RelayChain, SignParam, TransactionStatusOf, UnsignedTransaction, UtilityPallet,
|
||||||
},
|
},
|
||||||
client::{
|
client::{
|
||||||
is_ancient_block, ChainRuntimeVersion, Client, OpaqueGrandpaAuthoritiesSet,
|
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 bp_westend::WESTEND_SYNCED_HEADERS_GRANDPA_INFO_METHOD;
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{
|
||||||
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithTransactions, Error as SubstrateError,
|
Chain, ChainWithBalances, ChainWithGrandpa, ChainWithRuntimeVersion, ChainWithTransactions,
|
||||||
RelayChain, SignParam, UnderlyingChainProvider, UnsignedTransaction,
|
Error as SubstrateError, RelayChain, SignParam, SimpleRuntimeVersion, UnderlyingChainProvider,
|
||||||
|
UnsignedTransaction,
|
||||||
};
|
};
|
||||||
use sp_core::{storage::StorageKey, Pair};
|
use sp_core::{storage::StorageKey, Pair};
|
||||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount, MultiAddress};
|
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]
|
[dependencies]
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
thiserror = { workspace = true }
|
|
||||||
async-std = "1.9.0"
|
async-std = "1.9.0"
|
||||||
async-trait = "0.1"
|
async-trait = "0.1"
|
||||||
codec = { package = "parity-scale-codec", version = "3.1.5" }
|
codec = { package = "parity-scale-codec", version = "3.1.5" }
|
||||||
futures = "0.3.30"
|
futures = "0.3.30"
|
||||||
hex = "0.4"
|
hex = "0.4"
|
||||||
num-traits = "0.2"
|
|
||||||
log = { workspace = true }
|
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
|
# Bridge dependencies
|
||||||
|
|
||||||
|
|||||||
+13
-24
@@ -14,38 +14,26 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// 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/>.
|
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::cli::CliChain;
|
//! Basic traits for exposing bridges in the CLI.
|
||||||
use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
|
|
||||||
use relay_substrate_client::{Chain, ChainWithTransactions, Parachain, RelayChain};
|
use crate::{
|
||||||
use strum::{EnumString, VariantNames};
|
|
||||||
use substrate_relay_helper::{
|
|
||||||
equivocation::SubstrateEquivocationDetectionPipeline,
|
equivocation::SubstrateEquivocationDetectionPipeline,
|
||||||
finality::SubstrateFinalitySyncPipeline,
|
finality::SubstrateFinalitySyncPipeline,
|
||||||
messages_lane::{MessagesRelayLimits, SubstrateMessageLane},
|
messages_lane::{MessagesRelayLimits, SubstrateMessageLane},
|
||||||
parachains::SubstrateParachainsPipeline,
|
parachains::SubstrateParachainsPipeline,
|
||||||
};
|
};
|
||||||
|
use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
|
||||||
#[derive(Debug, PartialEq, Eq, EnumString, VariantNames)]
|
use relay_substrate_client::{
|
||||||
#[strum(serialize_all = "kebab_case")]
|
Chain, ChainWithRuntimeVersion, ChainWithTransactions, Parachain, RelayChain,
|
||||||
/// Supported full bridges (headers + messages).
|
};
|
||||||
pub enum FullBridge {
|
|
||||||
BridgeHubRococoToBridgeHubWestend,
|
|
||||||
BridgeHubWestendToBridgeHubRococo,
|
|
||||||
BridgeHubKusamaToBridgeHubPolkadot,
|
|
||||||
BridgeHubPolkadotToBridgeHubKusama,
|
|
||||||
PolkadotBulletinToBridgeHubPolkadot,
|
|
||||||
BridgeHubPolkadotToPolkadotBulletin,
|
|
||||||
RococoBulletinToBridgeHubRococo,
|
|
||||||
BridgeHubRococoToRococoBulletin,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Minimal bridge representation that can be used from the CLI.
|
/// Minimal bridge representation that can be used from the CLI.
|
||||||
/// It connects a source chain to a target chain.
|
/// It connects a source chain to a target chain.
|
||||||
pub trait CliBridgeBase: Sized {
|
pub trait CliBridgeBase: Sized {
|
||||||
/// The source chain.
|
/// The source chain.
|
||||||
type Source: Chain + CliChain;
|
type Source: Chain + ChainWithRuntimeVersion;
|
||||||
/// The target chain.
|
/// The target chain.
|
||||||
type Target: ChainWithTransactions + CliChain;
|
type Target: ChainWithTransactions + ChainWithRuntimeVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bridge representation that can be used from the CLI for relaying headers
|
/// 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`.
|
/// Convenience trait that adds bounds to `CliBridgeBase`.
|
||||||
pub trait RelayToRelayEquivocationDetectionCliBridgeBase: CliBridgeBase {
|
pub trait RelayToRelayEquivocationDetectionCliBridgeBase: CliBridgeBase {
|
||||||
|
/// The source chain with extra bounds.
|
||||||
type BoundedSource: ChainWithTransactions;
|
type BoundedSource: ChainWithTransactions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,10 +78,10 @@ pub trait ParachainToRelayHeadersCliBridge: CliBridgeBase
|
|||||||
where
|
where
|
||||||
Self::Source: Parachain,
|
Self::Source: Parachain,
|
||||||
{
|
{
|
||||||
// The `CliBridgeBase` type represents the parachain in this situation.
|
/// The `CliBridgeBase` type represents the parachain in this situation.
|
||||||
// We need to add an extra type for the relay chain.
|
/// We need to add an extra type for the relay chain.
|
||||||
type SourceRelay: Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>
|
type SourceRelay: Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>
|
||||||
+ CliChain
|
+ ChainWithRuntimeVersion
|
||||||
+ RelayChain;
|
+ RelayChain;
|
||||||
/// Finality proofs synchronization pipeline (source parachain -> target).
|
/// Finality proofs synchronization pipeline (source parachain -> target).
|
||||||
type ParachainFinality: SubstrateParachainsPipeline<
|
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
|
// 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/>.
|
// 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 async_trait::async_trait;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::cli::{
|
use crate::{
|
||||||
bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge},
|
cli::{
|
||||||
relay_headers_and_messages::{Full2WayBridgeBase, Full2WayBridgeCommonParams},
|
bridge::{CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge},
|
||||||
CliChain,
|
relay_headers_and_messages::{Full2WayBridgeBase, Full2WayBridgeCommonParams},
|
||||||
};
|
},
|
||||||
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,
|
finality::SubstrateFinalitySyncPipeline,
|
||||||
on_demand::{
|
on_demand::{
|
||||||
headers::OnDemandHeadersRelay, parachains::OnDemandParachainsRelay, OnDemandRelay,
|
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.
|
/// 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>,
|
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 {
|
macro_rules! declare_parachain_to_parachain_bridge_schema {
|
||||||
// left-parachain, relay-chain-of-left-parachain, right-parachain, relay-chain-of-right-parachain
|
// 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) => {
|
($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>] {
|
impl [<$left_parachain $right_parachain HeadersAndMessages>] {
|
||||||
async fn into_bridge<
|
async fn into_bridge<
|
||||||
Left: ChainWithTransactions + CliChain + Parachain,
|
Left: ChainWithTransactions + ChainWithRuntimeVersion + Parachain,
|
||||||
LeftRelay: CliChain,
|
LeftRelay: ChainWithRuntimeVersion,
|
||||||
Right: ChainWithTransactions + CliChain + Parachain,
|
Right: ChainWithTransactions + ChainWithRuntimeVersion + Parachain,
|
||||||
RightRelay: CliChain,
|
RightRelay: ChainWithRuntimeVersion,
|
||||||
L2R: CliBridgeBase<Source = Left, Target = Right>
|
L2R: $crate::cli::bridge::CliBridgeBase<Source = Left, Target = Right>
|
||||||
+ MessagesCliBridge
|
+ MessagesCliBridge
|
||||||
+ ParachainToRelayHeadersCliBridge<SourceRelay = LeftRelay>,
|
+ $crate::cli::bridge::ParachainToRelayHeadersCliBridge<SourceRelay = LeftRelay>,
|
||||||
R2L: CliBridgeBase<Source = Right, Target = Left>
|
R2L: $crate::cli::bridge::CliBridgeBase<Source = Right, Target = Left>
|
||||||
+ MessagesCliBridge
|
+ MessagesCliBridge
|
||||||
+ ParachainToRelayHeadersCliBridge<SourceRelay = RightRelay>,
|
+ $crate::cli::bridge::ParachainToRelayHeadersCliBridge<SourceRelay = RightRelay>,
|
||||||
>(
|
>(
|
||||||
self,
|
self,
|
||||||
) -> anyhow::Result<ParachainToParachainBridge<L2R, R2L>> {
|
) -> anyhow::Result<$crate::cli::relay_headers_and_messages::parachain_to_parachain::ParachainToParachainBridge<L2R, R2L>> {
|
||||||
Ok(ParachainToParachainBridge {
|
Ok($crate::cli::relay_headers_and_messages::parachain_to_parachain::ParachainToParachainBridge {
|
||||||
common: Full2WayBridgeCommonParams::new::<L2R>(
|
common: Full2WayBridgeCommonParams::new::<L2R>(
|
||||||
self.shared,
|
self.shared,
|
||||||
BridgeEndCommonParams {
|
BridgeEndCommonParams {
|
||||||
@@ -125,12 +129,12 @@ macro_rules! declare_parachain_to_parachain_bridge_schema {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<
|
impl<
|
||||||
Left: Chain<Hash = ParaHash> + ChainWithTransactions + CliChain + Parachain,
|
Left: Chain<Hash = ParaHash> + ChainWithTransactions + ChainWithRuntimeVersion + Parachain,
|
||||||
Right: Chain<Hash = ParaHash> + ChainWithTransactions + CliChain + Parachain,
|
Right: Chain<Hash = ParaHash> + ChainWithTransactions + ChainWithRuntimeVersion + Parachain,
|
||||||
LeftRelay: Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>
|
LeftRelay: Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>
|
||||||
+ CliChain,
|
+ ChainWithRuntimeVersion,
|
||||||
RightRelay: Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>
|
RightRelay: Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>
|
||||||
+ CliChain,
|
+ ChainWithRuntimeVersion,
|
||||||
L2R: CliBridgeBase<Source = Left, Target = Right>
|
L2R: CliBridgeBase<Source = Left, Target = Right>
|
||||||
+ MessagesCliBridge
|
+ MessagesCliBridge
|
||||||
+ ParachainToRelayHeadersCliBridge<SourceRelay = LeftRelay>,
|
+ ParachainToRelayHeadersCliBridge<SourceRelay = LeftRelay>,
|
||||||
+24
-20
@@ -14,29 +14,31 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// 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/>.
|
// 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 async_trait::async_trait;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::cli::{
|
use crate::{
|
||||||
bridge::{
|
cli::{
|
||||||
CliBridgeBase, MessagesCliBridge, ParachainToRelayHeadersCliBridge,
|
bridge::{
|
||||||
RelayToRelayHeadersCliBridge,
|
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,
|
finality::SubstrateFinalitySyncPipeline,
|
||||||
on_demand::{
|
on_demand::{
|
||||||
headers::OnDemandHeadersRelay, parachains::OnDemandParachainsRelay, OnDemandRelay,
|
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.
|
/// 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>,
|
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 {
|
macro_rules! declare_relay_to_parachain_bridge_schema {
|
||||||
// chain, parachain, relay-chain-of-parachain
|
// chain, parachain, relay-chain-of-parachain
|
||||||
($left_chain:ident, $right_parachain:ident, $right_chain:ident) => {
|
($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>] {
|
impl [<$left_chain $right_parachain HeadersAndMessages>] {
|
||||||
async fn into_bridge<
|
async fn into_bridge<
|
||||||
Left: ChainWithTransactions + CliChain,
|
Left: ChainWithTransactions + ChainWithRuntimeVersion,
|
||||||
Right: ChainWithTransactions + CliChain + Parachain,
|
Right: ChainWithTransactions + ChainWithRuntimeVersion + Parachain,
|
||||||
RightRelay: CliChain,
|
RightRelay: ChainWithRuntimeVersion,
|
||||||
L2R: CliBridgeBase<Source = Left, Target = Right> + MessagesCliBridge + RelayToRelayHeadersCliBridge,
|
L2R: CliBridgeBase<Source = Left, Target = Right> + MessagesCliBridge + RelayToRelayHeadersCliBridge,
|
||||||
R2L: CliBridgeBase<Source = Right, Target = Left>
|
R2L: CliBridgeBase<Source = Right, Target = Left>
|
||||||
+ MessagesCliBridge
|
+ MessagesCliBridge
|
||||||
@@ -118,10 +122,10 @@ macro_rules! declare_relay_to_parachain_bridge_schema {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<
|
impl<
|
||||||
Left: ChainWithTransactions + CliChain,
|
Left: ChainWithTransactions + ChainWithRuntimeVersion,
|
||||||
Right: Chain<Hash = ParaHash> + ChainWithTransactions + CliChain + Parachain,
|
Right: Chain<Hash = ParaHash> + ChainWithTransactions + ChainWithRuntimeVersion + Parachain,
|
||||||
RightRelay: Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>
|
RightRelay: Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>
|
||||||
+ CliChain,
|
+ ChainWithRuntimeVersion,
|
||||||
L2R: CliBridgeBase<Source = Left, Target = Right>
|
L2R: CliBridgeBase<Source = Left, Target = Right>
|
||||||
+ MessagesCliBridge
|
+ MessagesCliBridge
|
||||||
+ RelayToRelayHeadersCliBridge,
|
+ RelayToRelayHeadersCliBridge,
|
||||||
+14
-10
@@ -18,20 +18,23 @@
|
|||||||
// future
|
// future
|
||||||
#![allow(unused_macros)]
|
#![allow(unused_macros)]
|
||||||
|
|
||||||
|
//! Relay chain to Relay chain relayer CLI primitives.
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::cli::{
|
use crate::{
|
||||||
bridge::{CliBridgeBase, MessagesCliBridge, RelayToRelayHeadersCliBridge},
|
cli::{
|
||||||
relay_headers_and_messages::{Full2WayBridgeBase, Full2WayBridgeCommonParams},
|
bridge::{CliBridgeBase, MessagesCliBridge, RelayToRelayHeadersCliBridge},
|
||||||
CliChain,
|
relay_headers_and_messages::{Full2WayBridgeBase, Full2WayBridgeCommonParams},
|
||||||
};
|
},
|
||||||
use relay_substrate_client::{AccountIdOf, AccountKeyPairOf, ChainWithTransactions};
|
|
||||||
use sp_core::Pair;
|
|
||||||
use substrate_relay_helper::{
|
|
||||||
finality::SubstrateFinalitySyncPipeline,
|
finality::SubstrateFinalitySyncPipeline,
|
||||||
on_demand::{headers::OnDemandHeadersRelay, OnDemandRelay},
|
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.
|
/// A base relay between two standalone (relay) chains.
|
||||||
///
|
///
|
||||||
@@ -45,6 +48,7 @@ pub struct RelayToRelayBridge<
|
|||||||
Full2WayBridgeCommonParams<<R2L as CliBridgeBase>::Target, <L2R as CliBridgeBase>::Target>,
|
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 {
|
macro_rules! declare_relay_to_relay_bridge_schema {
|
||||||
($left_chain:ident, $right_chain:ident) => {
|
($left_chain:ident, $right_chain:ident) => {
|
||||||
bp_runtime::paste::item! {
|
bp_runtime::paste::item! {
|
||||||
@@ -101,8 +105,8 @@ macro_rules! declare_relay_to_relay_bridge_schema {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<
|
impl<
|
||||||
Left: ChainWithTransactions + CliChain,
|
Left: ChainWithTransactions + ChainWithRuntimeVersion,
|
||||||
Right: ChainWithTransactions + CliChain,
|
Right: ChainWithTransactions + ChainWithRuntimeVersion,
|
||||||
L2R: CliBridgeBase<Source = Left, Target = Right>
|
L2R: CliBridgeBase<Source = Left, Target = Right>
|
||||||
+ MessagesCliBridge
|
+ MessagesCliBridge
|
||||||
+ RelayToRelayHeadersCliBridge,
|
+ 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;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
pub mod cli;
|
||||||
pub mod equivocation;
|
pub mod equivocation;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod finality;
|
pub mod finality;
|
||||||
|
|||||||
Reference in New Issue
Block a user