diff --git a/bridges/relays/bin-substrate/Cargo.toml b/bridges/relays/bin-substrate/Cargo.toml index 7b731e3cd7..85d8d7dd51 100644 --- a/bridges/relays/bin-substrate/Cargo.toml +++ b/bridges/relays/bin-substrate/Cargo.toml @@ -14,7 +14,6 @@ futures = "0.3.12" hex = "0.4" log = "0.4.14" num-format = "0.4" -num-traits = "0.2" paste = "1.0" structopt = "0.3" strum = { version = "0.21.0", features = ["derive"] } @@ -33,9 +32,7 @@ bp-wococo = { path = "../../primitives/chain-wococo" } bp-runtime = { path = "../../primitives/runtime" } bp-westend = { path = "../../primitives/chain-westend" } bridge-runtime-common = { path = "../../bin/runtime-common" } -finality-grandpa = { version = "0.14.0" } finality-relay = { path = "../finality" } -headers-relay = { path = "../headers" } messages-relay = { path = "../messages" } millau-runtime = { path = "../../bin/millau/runtime" } pallet-bridge-messages = { path = "../../modules/messages" } @@ -49,6 +46,7 @@ relay-substrate-client = { path = "../client-substrate" } relay-utils = { path = "../utils" } relay-westend-client = { path = "../client-westend" } rialto-runtime = { path = "../../bin/rialto/runtime" } +substrate-relay-helper = { path = "../lib-substrate-relay" } # Substrate Dependencies @@ -64,3 +62,5 @@ hex-literal = "0.3" pallet-bridge-grandpa = { path = "../../modules/grandpa" } sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } tempdir = "0.3" +finality-grandpa = { version = "0.14.0" } + diff --git a/bridges/relays/bin-substrate/src/chains/millau_headers_to_rialto.rs b/bridges/relays/bin-substrate/src/chains/millau_headers_to_rialto.rs index 58f0620b07..5be5083f5b 100644 --- a/bridges/relays/bin-substrate/src/chains/millau_headers_to_rialto.rs +++ b/bridges/relays/bin-substrate/src/chains/millau_headers_to_rialto.rs @@ -16,25 +16,40 @@ //! Millau-to-Rialto headers sync entrypoint. -use crate::finality_pipeline::{SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate}; - -use bp_header_chain::justification::GrandpaJustification; use codec::Encode; -use relay_millau_client::{Millau, SyncHeader as MillauSyncHeader}; -use relay_rialto_client::{Rialto, SigningParams as RialtoSigningParams}; -use relay_substrate_client::{Chain, TransactionSignScheme}; use sp_core::{Bytes, Pair}; +use bp_header_chain::justification::GrandpaJustification; +use relay_millau_client::{Millau, SyncHeader as MillauSyncHeader}; +use relay_rialto_client::{Rialto, SigningParams as RialtoSigningParams}; +use relay_substrate_client::{Chain, Client, TransactionSignScheme}; +use substrate_relay_helper::finality_pipeline::{SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate}; + /// Millau-to-Rialto finality sync pipeline. -pub(crate) type MillauFinalityToRialto = SubstrateFinalityToSubstrate; +pub(crate) type FinalityPipelineMillauToRialto = SubstrateFinalityToSubstrate; + +#[derive(Clone, Debug)] +pub(crate) struct MillauFinalityToRialto { + finality_pipeline: FinalityPipelineMillauToRialto, +} + +impl MillauFinalityToRialto { + pub fn new(target_client: Client, target_sign: RialtoSigningParams) -> Self { + Self { + finality_pipeline: FinalityPipelineMillauToRialto::new(target_client, target_sign), + } + } +} impl SubstrateFinalitySyncPipeline for MillauFinalityToRialto { + type FinalitySyncPipeline = FinalityPipelineMillauToRialto; + const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str = bp_millau::BEST_FINALIZED_MILLAU_HEADER_METHOD; type TargetChain = Rialto; fn transactions_author(&self) -> bp_rialto::AccountId { - (*self.target_sign.public().as_array_ref()).into() + (*self.finality_pipeline.target_sign.public().as_array_ref()).into() } fn make_submit_finality_proof_transaction( @@ -45,8 +60,13 @@ impl SubstrateFinalitySyncPipeline for MillauFinalityToRialto { ) -> Bytes { let call = rialto_runtime::BridgeGrandpaMillauCall::submit_finality_proof(header.into_inner(), proof).into(); - let genesis_hash = *self.target_client.genesis_hash(); - let transaction = Rialto::sign_transaction(genesis_hash, &self.target_sign, transaction_nonce, call); + let genesis_hash = *self.finality_pipeline.target_client.genesis_hash(); + let transaction = Rialto::sign_transaction( + genesis_hash, + &self.finality_pipeline.target_sign, + transaction_nonce, + call, + ); Bytes(transaction.encode()) } diff --git a/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto.rs b/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto.rs index 05ff36be1f..93662a9d6f 100644 --- a/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto.rs +++ b/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto.rs @@ -16,31 +16,39 @@ //! Millau-to-Rialto messages sync entrypoint. -use crate::messages_lane::{ - select_delivery_transaction_limits, MessagesRelayParams, StandaloneMessagesMetrics, SubstrateMessageLane, - SubstrateMessageLaneToSubstrate, -}; -use crate::messages_source::SubstrateMessagesSource; -use crate::messages_target::SubstrateMessagesTarget; +use std::{ops::RangeInclusive, time::Duration}; + +use codec::Encode; +use frame_support::dispatch::GetDispatchInfo; +use sp_core::{Bytes, Pair}; use bp_messages::MessageNonce; use bp_runtime::{MILLAU_CHAIN_ID, RIALTO_CHAIN_ID}; use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof; -use codec::Encode; -use frame_support::dispatch::GetDispatchInfo; use messages_relay::message_lane::MessageLane; use relay_millau_client::{HeaderId as MillauHeaderId, Millau, SigningParams as MillauSigningParams}; use relay_rialto_client::{HeaderId as RialtoHeaderId, Rialto, SigningParams as RialtoSigningParams}; use relay_substrate_client::{Chain, Client, TransactionSignScheme}; use relay_utils::metrics::MetricsParams; -use sp_core::{Bytes, Pair}; -use std::{ops::RangeInclusive, time::Duration}; +use substrate_relay_helper::messages_lane::{ + select_delivery_transaction_limits, MessagesRelayParams, StandaloneMessagesMetrics, SubstrateMessageLane, + SubstrateMessageLaneToSubstrate, +}; +use substrate_relay_helper::messages_source::SubstrateMessagesSource; +use substrate_relay_helper::messages_target::SubstrateMessagesTarget; /// Millau-to-Rialto message lane. -pub type MillauMessagesToRialto = +pub type MessageLaneMillauMessagesToRialto = SubstrateMessageLaneToSubstrate; +#[derive(Clone)] +pub struct MillauMessagesToRialto { + message_lane: MessageLaneMillauMessagesToRialto, +} + impl SubstrateMessageLane for MillauMessagesToRialto { + type MessageLane = MessageLaneMillauMessagesToRialto; + const OUTBOUND_LANE_MESSAGE_DETAILS_METHOD: &'static str = bp_rialto::TO_RIALTO_MESSAGE_DETAILS_METHOD; const OUTBOUND_LANE_LATEST_GENERATED_NONCE_METHOD: &'static str = bp_rialto::TO_RIALTO_LATEST_GENERATED_NONCE_METHOD; @@ -58,21 +66,22 @@ impl SubstrateMessageLane for MillauMessagesToRialto { type TargetChain = Rialto; fn source_transactions_author(&self) -> bp_millau::AccountId { - (*self.source_sign.public().as_array_ref()).into() + (*self.message_lane.source_sign.public().as_array_ref()).into() } fn make_messages_receiving_proof_transaction( &self, transaction_nonce: ::Index, _generated_at_block: RialtoHeaderId, - proof: ::MessagesReceivingProof, + proof: ::MessagesReceivingProof, ) -> Bytes { let (relayers_state, proof) = proof; let call: millau_runtime::Call = millau_runtime::MessagesCall::receive_messages_delivery_proof(proof, relayers_state).into(); let call_weight = call.get_dispatch_info().weight; - let genesis_hash = *self.source_client.genesis_hash(); - let transaction = Millau::sign_transaction(genesis_hash, &self.source_sign, transaction_nonce, call); + let genesis_hash = *self.message_lane.source_client.genesis_hash(); + let transaction = + Millau::sign_transaction(genesis_hash, &self.message_lane.source_sign, transaction_nonce, call); log::trace!( target: "bridge", "Prepared Rialto -> Millau confirmation transaction. Weight: {}/{}, size: {}/{}", @@ -85,7 +94,7 @@ impl SubstrateMessageLane for MillauMessagesToRialto { } fn target_transactions_author(&self) -> bp_rialto::AccountId { - (*self.target_sign.public().as_array_ref()).into() + (*self.message_lane.target_sign.public().as_array_ref()).into() } fn make_messages_delivery_transaction( @@ -93,7 +102,7 @@ impl SubstrateMessageLane for MillauMessagesToRialto { transaction_nonce: ::Index, _generated_at_header: MillauHeaderId, _nonces: RangeInclusive, - proof: ::MessagesProof, + proof: ::MessagesProof, ) -> Bytes { let (dispatch_weight, proof) = proof; let FromBridgedChainMessagesProof { @@ -103,15 +112,16 @@ impl SubstrateMessageLane for MillauMessagesToRialto { } = proof; let messages_count = nonces_end - nonces_start + 1; let call: rialto_runtime::Call = rialto_runtime::MessagesCall::receive_messages_proof( - self.relayer_id_at_source.clone(), + self.message_lane.relayer_id_at_source.clone(), proof, messages_count as _, dispatch_weight, ) .into(); let call_weight = call.get_dispatch_info().weight; - let genesis_hash = *self.target_client.genesis_hash(); - let transaction = Rialto::sign_transaction(genesis_hash, &self.target_sign, transaction_nonce, call); + let genesis_hash = *self.message_lane.target_client.genesis_hash(); + let transaction = + Rialto::sign_transaction(genesis_hash, &self.message_lane.target_sign, transaction_nonce, call); log::trace!( target: "bridge", "Prepared Millau -> Rialto delivery transaction. Weight: {}/{}, size: {}/{}", @@ -142,11 +152,13 @@ pub async fn run( let lane_id = params.lane_id; let source_client = params.source_client; let lane = MillauMessagesToRialto { - source_client: source_client.clone(), - source_sign: params.source_sign, - target_client: params.target_client.clone(), - target_sign: params.target_sign, - relayer_id_at_source: relayer_id_at_millau, + message_lane: SubstrateMessageLaneToSubstrate { + source_client: source_client.clone(), + source_sign: params.source_sign, + target_client: params.target_client.clone(), + target_sign: params.target_sign, + relayer_id_at_source: relayer_id_at_millau, + }, }; // 2/3 is reserved for proofs and tx overhead @@ -166,7 +178,7 @@ pub async fn run( Max messages size in single transaction: {}\n\t\ Max messages weight in single transaction: {}\n\t\ Relayer mode: {:?}", - lane.relayer_id_at_source, + lane.message_lane.relayer_id_at_source, max_messages_in_single_batch, max_messages_size_in_single_batch, max_messages_weight_in_single_batch, @@ -175,7 +187,7 @@ pub async fn run( let (metrics_params, metrics_values) = add_standalone_metrics( Some(messages_relay::message_lane_loop::metrics_prefix::< - MillauMessagesToRialto, + ::MessageLane, >(&lane_id)), params.metrics_params, source_client.clone(), @@ -223,7 +235,7 @@ pub(crate) fn add_standalone_metrics( metrics_params: MetricsParams, source_client: Client, ) -> anyhow::Result<(MetricsParams, StandaloneMessagesMetrics)> { - crate::messages_lane::add_standalone_metrics::( + substrate_relay_helper::messages_lane::add_standalone_metrics::( metrics_prefix, metrics_params, source_client, diff --git a/bridges/relays/bin-substrate/src/chains/mod.rs b/bridges/relays/bin-substrate/src/chains/mod.rs index 9aec7d19d2..d2b72d4448 100644 --- a/bridges/relays/bin-substrate/src/chains/mod.rs +++ b/bridges/relays/bin-substrate/src/chains/mod.rs @@ -41,7 +41,7 @@ pub(crate) const RIALTO_ASSOCIATED_TOKEN_ID: &str = "bitcoin"; /// The identifier of token, which value is associated with Millau token value by relayer. pub(crate) const MILLAU_ASSOCIATED_TOKEN_ID: &str = "wrapped-bitcoin"; -use relay_utils::metrics::{FloatJsonValueMetric, MetricsParams, PrometheusError, Registry}; +use relay_utils::metrics::MetricsParams; pub(crate) fn add_polkadot_kusama_price_metrics( prefix: Option, @@ -50,33 +50,15 @@ pub(crate) fn add_polkadot_kusama_price_metrics Kusama // relays, but we want to test metrics/dashboards in advance Ok(relay_utils::relay_metrics(prefix, params) - .standalone_metric(|registry, prefix| token_price_metric(registry, prefix, "polkadot"))? - .standalone_metric(|registry, prefix| token_price_metric(registry, prefix, "kusama"))? + .standalone_metric(|registry, prefix| { + substrate_relay_helper::helpers::token_price_metric(registry, prefix, "polkadot") + })? + .standalone_metric(|registry, prefix| { + substrate_relay_helper::helpers::token_price_metric(registry, prefix, "kusama") + })? .into_params()) } -/// Creates standalone token price metric. -pub(crate) fn token_price_metric( - registry: &Registry, - prefix: Option<&str>, - token_id: &str, -) -> Result { - FloatJsonValueMetric::new( - registry, - prefix, - format!( - "https://api.coingecko.com/api/v3/simple/price?ids={}&vs_currencies=btc", - token_id - ), - format!("$.{}.btc", token_id), - format!("{}_to_base_conversion_rate", token_id.replace("-", "_")), - format!( - "Rate used to convert from {} to some BASE tokens", - token_id.to_uppercase() - ), - ) -} - #[cfg(test)] mod tests { use crate::cli::{encode_call, send_message}; diff --git a/bridges/relays/bin-substrate/src/chains/rialto_headers_to_millau.rs b/bridges/relays/bin-substrate/src/chains/rialto_headers_to_millau.rs index 39295c8943..2604e79983 100644 --- a/bridges/relays/bin-substrate/src/chains/rialto_headers_to_millau.rs +++ b/bridges/relays/bin-substrate/src/chains/rialto_headers_to_millau.rs @@ -16,25 +16,41 @@ //! Rialto-to-Millau headers sync entrypoint. -use crate::finality_pipeline::{SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate}; - -use bp_header_chain::justification::GrandpaJustification; use codec::Encode; -use relay_millau_client::{Millau, SigningParams as MillauSigningParams}; -use relay_rialto_client::{Rialto, SyncHeader as RialtoSyncHeader}; -use relay_substrate_client::{Chain, TransactionSignScheme}; use sp_core::{Bytes, Pair}; +use bp_header_chain::justification::GrandpaJustification; +use relay_millau_client::{Millau, SigningParams as MillauSigningParams}; +use relay_rialto_client::{Rialto, SyncHeader as RialtoSyncHeader}; +use relay_substrate_client::{Chain, Client, TransactionSignScheme}; +use substrate_relay_helper::finality_pipeline::{SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate}; + /// Rialto-to-Millau finality sync pipeline. -pub(crate) type RialtoFinalityToMillau = SubstrateFinalityToSubstrate; +pub(crate) type FinalityPipelineRialtoFinalityToMillau = + SubstrateFinalityToSubstrate; + +#[derive(Clone, Debug)] +pub struct RialtoFinalityToMillau { + finality_pipeline: FinalityPipelineRialtoFinalityToMillau, +} + +impl RialtoFinalityToMillau { + pub fn new(target_client: Client, target_sign: MillauSigningParams) -> Self { + Self { + finality_pipeline: FinalityPipelineRialtoFinalityToMillau::new(target_client, target_sign), + } + } +} impl SubstrateFinalitySyncPipeline for RialtoFinalityToMillau { + type FinalitySyncPipeline = FinalityPipelineRialtoFinalityToMillau; + const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str = bp_rialto::BEST_FINALIZED_RIALTO_HEADER_METHOD; type TargetChain = Millau; fn transactions_author(&self) -> bp_millau::AccountId { - (*self.target_sign.public().as_array_ref()).into() + (*self.finality_pipeline.target_sign.public().as_array_ref()).into() } fn make_submit_finality_proof_transaction( @@ -49,8 +65,13 @@ impl SubstrateFinalitySyncPipeline for RialtoFinalityToMillau { >::submit_finality_proof(header.into_inner(), proof) .into(); - let genesis_hash = *self.target_client.genesis_hash(); - let transaction = Millau::sign_transaction(genesis_hash, &self.target_sign, transaction_nonce, call); + let genesis_hash = *self.finality_pipeline.target_client.genesis_hash(); + let transaction = Millau::sign_transaction( + genesis_hash, + &self.finality_pipeline.target_sign, + transaction_nonce, + call, + ); Bytes(transaction.encode()) } diff --git a/bridges/relays/bin-substrate/src/chains/rialto_messages_to_millau.rs b/bridges/relays/bin-substrate/src/chains/rialto_messages_to_millau.rs index 0aec33a339..2b7f32f2d4 100644 --- a/bridges/relays/bin-substrate/src/chains/rialto_messages_to_millau.rs +++ b/bridges/relays/bin-substrate/src/chains/rialto_messages_to_millau.rs @@ -16,31 +16,39 @@ //! Rialto-to-Millau messages sync entrypoint. -use crate::messages_lane::{ - select_delivery_transaction_limits, MessagesRelayParams, StandaloneMessagesMetrics, SubstrateMessageLane, - SubstrateMessageLaneToSubstrate, -}; -use crate::messages_source::SubstrateMessagesSource; -use crate::messages_target::SubstrateMessagesTarget; +use std::{ops::RangeInclusive, time::Duration}; + +use codec::Encode; +use frame_support::dispatch::GetDispatchInfo; +use sp_core::{Bytes, Pair}; use bp_messages::MessageNonce; use bp_runtime::{MILLAU_CHAIN_ID, RIALTO_CHAIN_ID}; use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof; -use codec::Encode; -use frame_support::dispatch::GetDispatchInfo; use messages_relay::message_lane::MessageLane; use relay_millau_client::{HeaderId as MillauHeaderId, Millau, SigningParams as MillauSigningParams}; use relay_rialto_client::{HeaderId as RialtoHeaderId, Rialto, SigningParams as RialtoSigningParams}; use relay_substrate_client::{Chain, Client, TransactionSignScheme}; use relay_utils::metrics::MetricsParams; -use sp_core::{Bytes, Pair}; -use std::{ops::RangeInclusive, time::Duration}; +use substrate_relay_helper::messages_lane::{ + select_delivery_transaction_limits, MessagesRelayParams, StandaloneMessagesMetrics, SubstrateMessageLane, + SubstrateMessageLaneToSubstrate, +}; +use substrate_relay_helper::messages_source::SubstrateMessagesSource; +use substrate_relay_helper::messages_target::SubstrateMessagesTarget; /// Rialto-to-Millau message lane. -pub type RialtoMessagesToMillau = +pub type MessageLaneRialtoMessagesToMillau = SubstrateMessageLaneToSubstrate; +#[derive(Clone)] +pub struct RialtoMessagesToMillau { + message_lane: MessageLaneRialtoMessagesToMillau, +} + impl SubstrateMessageLane for RialtoMessagesToMillau { + type MessageLane = MessageLaneRialtoMessagesToMillau; + const OUTBOUND_LANE_MESSAGE_DETAILS_METHOD: &'static str = bp_millau::TO_MILLAU_MESSAGE_DETAILS_METHOD; const OUTBOUND_LANE_LATEST_GENERATED_NONCE_METHOD: &'static str = bp_millau::TO_MILLAU_LATEST_GENERATED_NONCE_METHOD; @@ -58,21 +66,22 @@ impl SubstrateMessageLane for RialtoMessagesToMillau { type TargetChain = Millau; fn source_transactions_author(&self) -> bp_rialto::AccountId { - (*self.source_sign.public().as_array_ref()).into() + (*self.message_lane.source_sign.public().as_array_ref()).into() } fn make_messages_receiving_proof_transaction( &self, transaction_nonce: ::Index, _generated_at_block: MillauHeaderId, - proof: ::MessagesReceivingProof, + proof: ::MessagesReceivingProof, ) -> Bytes { let (relayers_state, proof) = proof; let call: rialto_runtime::Call = rialto_runtime::MessagesCall::receive_messages_delivery_proof(proof, relayers_state).into(); let call_weight = call.get_dispatch_info().weight; - let genesis_hash = *self.source_client.genesis_hash(); - let transaction = Rialto::sign_transaction(genesis_hash, &self.source_sign, transaction_nonce, call); + let genesis_hash = *self.message_lane.source_client.genesis_hash(); + let transaction = + Rialto::sign_transaction(genesis_hash, &self.message_lane.source_sign, transaction_nonce, call); log::trace!( target: "bridge", "Prepared Millau -> Rialto confirmation transaction. Weight: {}/{}, size: {}/{}", @@ -85,7 +94,7 @@ impl SubstrateMessageLane for RialtoMessagesToMillau { } fn target_transactions_author(&self) -> bp_millau::AccountId { - (*self.target_sign.public().as_array_ref()).into() + (*self.message_lane.target_sign.public().as_array_ref()).into() } fn make_messages_delivery_transaction( @@ -93,7 +102,7 @@ impl SubstrateMessageLane for RialtoMessagesToMillau { transaction_nonce: ::Index, _generated_at_header: RialtoHeaderId, _nonces: RangeInclusive, - proof: ::MessagesProof, + proof: ::MessagesProof, ) -> Bytes { let (dispatch_weight, proof) = proof; let FromBridgedChainMessagesProof { @@ -103,15 +112,16 @@ impl SubstrateMessageLane for RialtoMessagesToMillau { } = proof; let messages_count = nonces_end - nonces_start + 1; let call: millau_runtime::Call = millau_runtime::MessagesCall::receive_messages_proof( - self.relayer_id_at_source.clone(), + self.message_lane.relayer_id_at_source.clone(), proof, messages_count as _, dispatch_weight, ) .into(); let call_weight = call.get_dispatch_info().weight; - let genesis_hash = *self.target_client.genesis_hash(); - let transaction = Millau::sign_transaction(genesis_hash, &self.target_sign, transaction_nonce, call); + let genesis_hash = *self.message_lane.target_client.genesis_hash(); + let transaction = + Millau::sign_transaction(genesis_hash, &self.message_lane.target_sign, transaction_nonce, call); log::trace!( target: "bridge", "Prepared Rialto -> Millau delivery transaction. Weight: {}/{}, size: {}/{}", @@ -142,11 +152,13 @@ pub async fn run( let lane_id = params.lane_id; let source_client = params.source_client; let lane = RialtoMessagesToMillau { - source_client: source_client.clone(), - source_sign: params.source_sign, - target_client: params.target_client.clone(), - target_sign: params.target_sign, - relayer_id_at_source: relayer_id_at_rialto, + message_lane: SubstrateMessageLaneToSubstrate { + source_client: source_client.clone(), + source_sign: params.source_sign, + target_client: params.target_client.clone(), + target_sign: params.target_sign, + relayer_id_at_source: relayer_id_at_rialto, + }, }; // 2/3 is reserved for proofs and tx overhead @@ -165,7 +177,7 @@ pub async fn run( Max messages size in single transaction: {}\n\t\ Max messages weight in single transaction: {}\n\t\ Relayer mode: {:?}", - lane.relayer_id_at_source, + lane.message_lane.relayer_id_at_source, max_messages_in_single_batch, max_messages_size_in_single_batch, max_messages_weight_in_single_batch, @@ -174,7 +186,7 @@ pub async fn run( let (metrics_params, metrics_values) = add_standalone_metrics( Some(messages_relay::message_lane_loop::metrics_prefix::< - RialtoMessagesToMillau, + ::MessageLane, >(&lane_id)), params.metrics_params, source_client.clone(), @@ -222,7 +234,7 @@ pub(crate) fn add_standalone_metrics( metrics_params: MetricsParams, source_client: Client, ) -> anyhow::Result<(MetricsParams, StandaloneMessagesMetrics)> { - crate::messages_lane::add_standalone_metrics::( + substrate_relay_helper::messages_lane::add_standalone_metrics::( metrics_prefix, metrics_params, source_client, diff --git a/bridges/relays/bin-substrate/src/chains/rococo_headers_to_wococo.rs b/bridges/relays/bin-substrate/src/chains/rococo_headers_to_wococo.rs index 026c918bec..38bb54ddbc 100644 --- a/bridges/relays/bin-substrate/src/chains/rococo_headers_to_wococo.rs +++ b/bridges/relays/bin-substrate/src/chains/rococo_headers_to_wococo.rs @@ -16,43 +16,63 @@ //! Rococo-to-Wococo headers sync entrypoint. -use crate::chains::wococo_headers_to_rococo::MAXIMAL_BALANCE_DECREASE_PER_DAY; -use crate::finality_pipeline::{SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate}; - -use bp_header_chain::justification::GrandpaJustification; use codec::Encode; -use relay_rococo_client::{Rococo, SyncHeader as RococoSyncHeader}; -use relay_substrate_client::{Chain, TransactionSignScheme}; -use relay_utils::metrics::MetricsParams; -use relay_wococo_client::{SigningParams as WococoSigningParams, Wococo}; use sp_core::{Bytes, Pair}; +use bp_header_chain::justification::GrandpaJustification; +use relay_rococo_client::{Rococo, SyncHeader as RococoSyncHeader}; +use relay_substrate_client::{Chain, Client, TransactionSignScheme}; +use relay_utils::metrics::MetricsParams; +use relay_wococo_client::{SigningParams as WococoSigningParams, Wococo}; +use substrate_relay_helper::finality_pipeline::{SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate}; + +use crate::chains::wococo_headers_to_rococo::MAXIMAL_BALANCE_DECREASE_PER_DAY; + /// Rococo-to-Wococo finality sync pipeline. -pub(crate) type RococoFinalityToWococo = SubstrateFinalityToSubstrate; +pub(crate) type FinalityPipelineRococoFinalityToWococo = + SubstrateFinalityToSubstrate; + +#[derive(Clone, Debug)] +pub(crate) struct RococoFinalityToWococo { + finality_pipeline: FinalityPipelineRococoFinalityToWococo, +} + +impl RococoFinalityToWococo { + pub fn new(target_client: Client, target_sign: WococoSigningParams) -> Self { + Self { + finality_pipeline: FinalityPipelineRococoFinalityToWococo::new(target_client, target_sign), + } + } +} impl SubstrateFinalitySyncPipeline for RococoFinalityToWococo { + type FinalitySyncPipeline = FinalityPipelineRococoFinalityToWococo; + const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str = bp_rococo::BEST_FINALIZED_ROCOCO_HEADER_METHOD; type TargetChain = Wococo; fn customize_metrics(params: MetricsParams) -> anyhow::Result { - crate::chains::add_polkadot_kusama_price_metrics::(Some(finality_relay::metrics_prefix::()), params) + crate::chains::add_polkadot_kusama_price_metrics::( + Some(finality_relay::metrics_prefix::()), + params, + ) } fn start_relay_guards(&self) { relay_substrate_client::guard::abort_on_spec_version_change( - self.target_client.clone(), + self.finality_pipeline.target_client.clone(), bp_wococo::VERSION.spec_version, ); relay_substrate_client::guard::abort_when_account_balance_decreased( - self.target_client.clone(), + self.finality_pipeline.target_client.clone(), self.transactions_author(), MAXIMAL_BALANCE_DECREASE_PER_DAY, ); } fn transactions_author(&self) -> bp_wococo::AccountId { - (*self.target_sign.public().as_array_ref()).into() + (*self.finality_pipeline.target_sign.public().as_array_ref()).into() } fn make_submit_finality_proof_transaction( @@ -64,8 +84,13 @@ impl SubstrateFinalitySyncPipeline for RococoFinalityToWococo { let call = relay_wococo_client::runtime::Call::BridgeGrandpaRococo( relay_wococo_client::runtime::BridgeGrandpaRococoCall::submit_finality_proof(header.into_inner(), proof), ); - let genesis_hash = *self.target_client.genesis_hash(); - let transaction = Wococo::sign_transaction(genesis_hash, &self.target_sign, transaction_nonce, call); + let genesis_hash = *self.finality_pipeline.target_client.genesis_hash(); + let transaction = Wococo::sign_transaction( + genesis_hash, + &self.finality_pipeline.target_sign, + transaction_nonce, + call, + ); Bytes(transaction.encode()) } diff --git a/bridges/relays/bin-substrate/src/chains/rococo_messages_to_wococo.rs b/bridges/relays/bin-substrate/src/chains/rococo_messages_to_wococo.rs index 080fa3b049..043e6c89e4 100644 --- a/bridges/relays/bin-substrate/src/chains/rococo_messages_to_wococo.rs +++ b/bridges/relays/bin-substrate/src/chains/rococo_messages_to_wococo.rs @@ -16,30 +16,38 @@ //! Rococo-to-Wococo messages sync entrypoint. -use crate::messages_lane::{ - select_delivery_transaction_limits, MessagesRelayParams, StandaloneMessagesMetrics, SubstrateMessageLane, - SubstrateMessageLaneToSubstrate, -}; -use crate::messages_source::SubstrateMessagesSource; -use crate::messages_target::SubstrateMessagesTarget; +use std::{ops::RangeInclusive, time::Duration}; + +use codec::Encode; +use sp_core::{Bytes, Pair}; use bp_messages::MessageNonce; use bp_runtime::{ROCOCO_CHAIN_ID, WOCOCO_CHAIN_ID}; use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof; -use codec::Encode; use messages_relay::message_lane::MessageLane; use relay_rococo_client::{HeaderId as RococoHeaderId, Rococo, SigningParams as RococoSigningParams}; use relay_substrate_client::{Chain, Client, TransactionSignScheme}; use relay_utils::metrics::MetricsParams; use relay_wococo_client::{HeaderId as WococoHeaderId, SigningParams as WococoSigningParams, Wococo}; -use sp_core::{Bytes, Pair}; -use std::{ops::RangeInclusive, time::Duration}; +use substrate_relay_helper::messages_lane::{ + select_delivery_transaction_limits, MessagesRelayParams, StandaloneMessagesMetrics, SubstrateMessageLane, + SubstrateMessageLaneToSubstrate, +}; +use substrate_relay_helper::messages_source::SubstrateMessagesSource; +use substrate_relay_helper::messages_target::SubstrateMessagesTarget; /// Rococo-to-Wococo message lane. -pub type RococoMessagesToWococo = +pub type MessageLaneRococoMessagesToWococo = SubstrateMessageLaneToSubstrate; +#[derive(Clone)] +pub struct RococoMessagesToWococo { + message_lane: MessageLaneRococoMessagesToWococo, +} + impl SubstrateMessageLane for RococoMessagesToWococo { + type MessageLane = MessageLaneRococoMessagesToWococo; + const OUTBOUND_LANE_MESSAGE_DETAILS_METHOD: &'static str = bp_wococo::TO_WOCOCO_MESSAGE_DETAILS_METHOD; const OUTBOUND_LANE_LATEST_GENERATED_NONCE_METHOD: &'static str = bp_wococo::TO_WOCOCO_LATEST_GENERATED_NONCE_METHOD; @@ -57,14 +65,14 @@ impl SubstrateMessageLane for RococoMessagesToWococo { type TargetChain = Wococo; fn source_transactions_author(&self) -> bp_rococo::AccountId { - (*self.source_sign.public().as_array_ref()).into() + (*self.message_lane.source_sign.public().as_array_ref()).into() } fn make_messages_receiving_proof_transaction( &self, transaction_nonce: ::Index, _generated_at_block: WococoHeaderId, - proof: ::MessagesReceivingProof, + proof: ::MessagesReceivingProof, ) -> Bytes { let (relayers_state, proof) = proof; let call = relay_rococo_client::runtime::Call::BridgeMessagesWococo( @@ -73,8 +81,9 @@ impl SubstrateMessageLane for RococoMessagesToWococo { relayers_state, ), ); - let genesis_hash = *self.source_client.genesis_hash(); - let transaction = Rococo::sign_transaction(genesis_hash, &self.source_sign, transaction_nonce, call); + let genesis_hash = *self.message_lane.source_client.genesis_hash(); + let transaction = + Rococo::sign_transaction(genesis_hash, &self.message_lane.source_sign, transaction_nonce, call); log::trace!( target: "bridge", "Prepared Wococo -> Rococo confirmation transaction. Weight: /{}, size: {}/{}", @@ -86,7 +95,7 @@ impl SubstrateMessageLane for RococoMessagesToWococo { } fn target_transactions_author(&self) -> bp_wococo::AccountId { - (*self.target_sign.public().as_array_ref()).into() + (*self.message_lane.target_sign.public().as_array_ref()).into() } fn make_messages_delivery_transaction( @@ -94,7 +103,7 @@ impl SubstrateMessageLane for RococoMessagesToWococo { transaction_nonce: ::Index, _generated_at_header: RococoHeaderId, _nonces: RangeInclusive, - proof: ::MessagesProof, + proof: ::MessagesProof, ) -> Bytes { let (dispatch_weight, proof) = proof; let FromBridgedChainMessagesProof { @@ -106,14 +115,15 @@ impl SubstrateMessageLane for RococoMessagesToWococo { let call = relay_wococo_client::runtime::Call::BridgeMessagesRococo( relay_wococo_client::runtime::BridgeMessagesRococoCall::receive_messages_proof( - self.relayer_id_at_source.clone(), + self.message_lane.relayer_id_at_source.clone(), proof, messages_count as _, dispatch_weight, ), ); - let genesis_hash = *self.target_client.genesis_hash(); - let transaction = Wococo::sign_transaction(genesis_hash, &self.target_sign, transaction_nonce, call); + let genesis_hash = *self.message_lane.target_client.genesis_hash(); + let transaction = + Wococo::sign_transaction(genesis_hash, &self.message_lane.target_sign, transaction_nonce, call); log::trace!( target: "bridge", "Prepared Rococo -> Wococo delivery transaction. Weight: /{}, size: {}/{}", @@ -151,11 +161,13 @@ pub async fn run( let lane_id = params.lane_id; let source_client = params.source_client; let lane = RococoMessagesToWococo { - source_client: source_client.clone(), - source_sign: params.source_sign, - target_client: params.target_client.clone(), - target_sign: params.target_sign, - relayer_id_at_source: relayer_id_at_rococo, + message_lane: SubstrateMessageLaneToSubstrate { + source_client: source_client.clone(), + source_sign: params.source_sign, + target_client: params.target_client.clone(), + target_sign: params.target_sign, + relayer_id_at_source: relayer_id_at_rococo, + }, }; // 2/3 is reserved for proofs and tx overhead @@ -180,7 +192,7 @@ pub async fn run( Max messages size in single transaction: {}\n\t\ Max messages weight in single transaction: {}\n\t\ Relayer mode: {:?}", - lane.relayer_id_at_source, + lane.message_lane.relayer_id_at_source, max_messages_in_single_batch, max_messages_size_in_single_batch, max_messages_weight_in_single_batch, @@ -189,7 +201,7 @@ pub async fn run( let (metrics_params, metrics_values) = add_standalone_metrics( Some(messages_relay::message_lane_loop::metrics_prefix::< - RococoMessagesToWococo, + ::MessageLane, >(&lane_id)), params.metrics_params, source_client.clone(), @@ -237,7 +249,7 @@ pub(crate) fn add_standalone_metrics( metrics_params: MetricsParams, source_client: Client, ) -> anyhow::Result<(MetricsParams, StandaloneMessagesMetrics)> { - crate::messages_lane::add_standalone_metrics::( + substrate_relay_helper::messages_lane::add_standalone_metrics::( metrics_prefix, metrics_params, source_client, diff --git a/bridges/relays/bin-substrate/src/chains/westend_headers_to_millau.rs b/bridges/relays/bin-substrate/src/chains/westend_headers_to_millau.rs index f0395dc10d..9fdf8b1a81 100644 --- a/bridges/relays/bin-substrate/src/chains/westend_headers_to_millau.rs +++ b/bridges/relays/bin-substrate/src/chains/westend_headers_to_millau.rs @@ -16,30 +16,49 @@ //! Westend-to-Millau headers sync entrypoint. -use crate::finality_pipeline::{SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate}; - -use bp_header_chain::justification::GrandpaJustification; use codec::Encode; -use relay_millau_client::{Millau, SigningParams as MillauSigningParams}; -use relay_substrate_client::{Chain, TransactionSignScheme}; -use relay_utils::metrics::MetricsParams; -use relay_westend_client::{SyncHeader as WestendSyncHeader, Westend}; use sp_core::{Bytes, Pair}; +use bp_header_chain::justification::GrandpaJustification; +use relay_millau_client::{Millau, SigningParams as MillauSigningParams}; +use relay_substrate_client::{Chain, Client, TransactionSignScheme}; +use relay_utils::metrics::MetricsParams; +use relay_westend_client::{SyncHeader as WestendSyncHeader, Westend}; +use substrate_relay_helper::finality_pipeline::{SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate}; + /// Westend-to-Millau finality sync pipeline. -pub(crate) type WestendFinalityToMillau = SubstrateFinalityToSubstrate; +pub(crate) type FinalityPipelineWestendFinalityToMillau = + SubstrateFinalityToSubstrate; + +#[derive(Clone, Debug)] +pub(crate) struct WestendFinalityToMillau { + finality_pipeline: FinalityPipelineWestendFinalityToMillau, +} + +impl WestendFinalityToMillau { + pub fn new(target_client: Client, target_sign: MillauSigningParams) -> Self { + Self { + finality_pipeline: FinalityPipelineWestendFinalityToMillau::new(target_client, target_sign), + } + } +} impl SubstrateFinalitySyncPipeline for WestendFinalityToMillau { + type FinalitySyncPipeline = FinalityPipelineWestendFinalityToMillau; + const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str = bp_westend::BEST_FINALIZED_WESTEND_HEADER_METHOD; type TargetChain = Millau; fn customize_metrics(params: MetricsParams) -> anyhow::Result { - crate::chains::add_polkadot_kusama_price_metrics::(Some(finality_relay::metrics_prefix::()), params) + crate::chains::add_polkadot_kusama_price_metrics::( + Some(finality_relay::metrics_prefix::()), + params, + ) } fn transactions_author(&self) -> bp_millau::AccountId { - (*self.target_sign.public().as_array_ref()).into() + (*self.finality_pipeline.target_sign.public().as_array_ref()).into() } fn make_submit_finality_proof_transaction( @@ -54,8 +73,13 @@ impl SubstrateFinalitySyncPipeline for WestendFinalityToMillau { >::submit_finality_proof(header.into_inner(), proof) .into(); - let genesis_hash = *self.target_client.genesis_hash(); - let transaction = Millau::sign_transaction(genesis_hash, &self.target_sign, transaction_nonce, call); + let genesis_hash = *self.finality_pipeline.target_client.genesis_hash(); + let transaction = Millau::sign_transaction( + genesis_hash, + &self.finality_pipeline.target_sign, + transaction_nonce, + call, + ); Bytes(transaction.encode()) } diff --git a/bridges/relays/bin-substrate/src/chains/wococo_headers_to_rococo.rs b/bridges/relays/bin-substrate/src/chains/wococo_headers_to_rococo.rs index d23266c649..a65bfd7624 100644 --- a/bridges/relays/bin-substrate/src/chains/wococo_headers_to_rococo.rs +++ b/bridges/relays/bin-substrate/src/chains/wococo_headers_to_rococo.rs @@ -16,15 +16,15 @@ //! Wococo-to-Rococo headers sync entrypoint. -use crate::finality_pipeline::{SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate}; +use codec::Encode; +use sp_core::{Bytes, Pair}; use bp_header_chain::justification::GrandpaJustification; -use codec::Encode; use relay_rococo_client::{Rococo, SigningParams as RococoSigningParams}; -use relay_substrate_client::{Chain, TransactionSignScheme}; +use relay_substrate_client::{Chain, Client, TransactionSignScheme}; use relay_utils::metrics::MetricsParams; use relay_wococo_client::{SyncHeader as WococoSyncHeader, Wococo}; -use sp_core::{Bytes, Pair}; +use substrate_relay_helper::finality_pipeline::{SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate}; /// Maximal saturating difference between `balance(now)` and `balance(now-24h)` to treat /// relay as gone wild. @@ -34,31 +34,50 @@ use sp_core::{Bytes, Pair}; pub(crate) const MAXIMAL_BALANCE_DECREASE_PER_DAY: bp_rococo::Balance = 1_500_000_000_000_000; /// Wococo-to-Rococo finality sync pipeline. -pub(crate) type WococoFinalityToRococo = SubstrateFinalityToSubstrate; +pub(crate) type FinalityPipelineWococoFinalityToRococo = + SubstrateFinalityToSubstrate; + +#[derive(Clone, Debug)] +pub(crate) struct WococoFinalityToRococo { + finality_pipeline: FinalityPipelineWococoFinalityToRococo, +} + +impl WococoFinalityToRococo { + pub fn new(target_client: Client, target_sign: RococoSigningParams) -> Self { + Self { + finality_pipeline: FinalityPipelineWococoFinalityToRococo::new(target_client, target_sign), + } + } +} impl SubstrateFinalitySyncPipeline for WococoFinalityToRococo { + type FinalitySyncPipeline = FinalityPipelineWococoFinalityToRococo; + const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str = bp_wococo::BEST_FINALIZED_WOCOCO_HEADER_METHOD; type TargetChain = Rococo; fn customize_metrics(params: MetricsParams) -> anyhow::Result { - crate::chains::add_polkadot_kusama_price_metrics::(Some(finality_relay::metrics_prefix::()), params) + crate::chains::add_polkadot_kusama_price_metrics::( + Some(finality_relay::metrics_prefix::()), + params, + ) } fn start_relay_guards(&self) { relay_substrate_client::guard::abort_on_spec_version_change( - self.target_client.clone(), + self.finality_pipeline.target_client.clone(), bp_rococo::VERSION.spec_version, ); relay_substrate_client::guard::abort_when_account_balance_decreased( - self.target_client.clone(), + self.finality_pipeline.target_client.clone(), self.transactions_author(), MAXIMAL_BALANCE_DECREASE_PER_DAY, ); } fn transactions_author(&self) -> bp_rococo::AccountId { - (*self.target_sign.public().as_array_ref()).into() + (*self.finality_pipeline.target_sign.public().as_array_ref()).into() } fn make_submit_finality_proof_transaction( @@ -70,8 +89,13 @@ impl SubstrateFinalitySyncPipeline for WococoFinalityToRococo { let call = relay_rococo_client::runtime::Call::BridgeGrandpaWococo( relay_rococo_client::runtime::BridgeGrandpaWococoCall::submit_finality_proof(header.into_inner(), proof), ); - let genesis_hash = *self.target_client.genesis_hash(); - let transaction = Rococo::sign_transaction(genesis_hash, &self.target_sign, transaction_nonce, call); + let genesis_hash = *self.finality_pipeline.target_client.genesis_hash(); + let transaction = Rococo::sign_transaction( + genesis_hash, + &self.finality_pipeline.target_sign, + transaction_nonce, + call, + ); Bytes(transaction.encode()) } @@ -79,10 +103,12 @@ impl SubstrateFinalitySyncPipeline for WococoFinalityToRococo { #[cfg(test)] mod tests { - use super::*; use frame_support::weights::WeightToFeePolynomial; + use pallet_bridge_grandpa::weights::WeightInfo; + use super::*; + #[test] fn maximal_balance_decrease_per_day_is_sane() { // Rococo/Wococo GRANDPA pallet weights. They're now using Rialto weights => using `RialtoWeight` is justified. diff --git a/bridges/relays/bin-substrate/src/chains/wococo_messages_to_rococo.rs b/bridges/relays/bin-substrate/src/chains/wococo_messages_to_rococo.rs index b36088388f..d068dc2f11 100644 --- a/bridges/relays/bin-substrate/src/chains/wococo_messages_to_rococo.rs +++ b/bridges/relays/bin-substrate/src/chains/wococo_messages_to_rococo.rs @@ -16,30 +16,37 @@ //! Wococo-to-Rococo messages sync entrypoint. -use crate::messages_lane::{ - select_delivery_transaction_limits, MessagesRelayParams, StandaloneMessagesMetrics, SubstrateMessageLane, - SubstrateMessageLaneToSubstrate, -}; -use crate::messages_source::SubstrateMessagesSource; -use crate::messages_target::SubstrateMessagesTarget; +use std::{ops::RangeInclusive, time::Duration}; + +use codec::Encode; +use sp_core::{Bytes, Pair}; use bp_messages::MessageNonce; use bp_runtime::{ROCOCO_CHAIN_ID, WOCOCO_CHAIN_ID}; use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof; -use codec::Encode; use messages_relay::message_lane::MessageLane; use relay_rococo_client::{HeaderId as RococoHeaderId, Rococo, SigningParams as RococoSigningParams}; use relay_substrate_client::{Chain, Client, TransactionSignScheme}; use relay_utils::metrics::MetricsParams; use relay_wococo_client::{HeaderId as WococoHeaderId, SigningParams as WococoSigningParams, Wococo}; -use sp_core::{Bytes, Pair}; -use std::{ops::RangeInclusive, time::Duration}; +use substrate_relay_helper::messages_lane::{ + select_delivery_transaction_limits, MessagesRelayParams, StandaloneMessagesMetrics, SubstrateMessageLane, + SubstrateMessageLaneToSubstrate, +}; +use substrate_relay_helper::messages_source::SubstrateMessagesSource; +use substrate_relay_helper::messages_target::SubstrateMessagesTarget; /// Wococo-to-Rococo message lane. -pub type WococoMessagesToRococo = +pub type MessageLaneWococoMessagesToRococo = SubstrateMessageLaneToSubstrate; +#[derive(Clone)] +pub struct WococoMessagesToRococo { + message_lane: MessageLaneWococoMessagesToRococo, +} + impl SubstrateMessageLane for WococoMessagesToRococo { + type MessageLane = MessageLaneWococoMessagesToRococo; const OUTBOUND_LANE_MESSAGE_DETAILS_METHOD: &'static str = bp_rococo::TO_ROCOCO_MESSAGE_DETAILS_METHOD; const OUTBOUND_LANE_LATEST_GENERATED_NONCE_METHOD: &'static str = bp_rococo::TO_ROCOCO_LATEST_GENERATED_NONCE_METHOD; @@ -57,14 +64,14 @@ impl SubstrateMessageLane for WococoMessagesToRococo { type TargetChain = Rococo; fn source_transactions_author(&self) -> bp_wococo::AccountId { - (*self.source_sign.public().as_array_ref()).into() + (*self.message_lane.source_sign.public().as_array_ref()).into() } fn make_messages_receiving_proof_transaction( &self, transaction_nonce: ::Index, _generated_at_block: RococoHeaderId, - proof: ::MessagesReceivingProof, + proof: ::MessagesReceivingProof, ) -> Bytes { let (relayers_state, proof) = proof; let call = relay_wococo_client::runtime::Call::BridgeMessagesRococo( @@ -73,8 +80,9 @@ impl SubstrateMessageLane for WococoMessagesToRococo { relayers_state, ), ); - let genesis_hash = *self.source_client.genesis_hash(); - let transaction = Wococo::sign_transaction(genesis_hash, &self.source_sign, transaction_nonce, call); + let genesis_hash = *self.message_lane.source_client.genesis_hash(); + let transaction = + Wococo::sign_transaction(genesis_hash, &self.message_lane.source_sign, transaction_nonce, call); log::trace!( target: "bridge", "Prepared Rococo -> Wococo confirmation transaction. Weight: /{}, size: {}/{}", @@ -86,7 +94,7 @@ impl SubstrateMessageLane for WococoMessagesToRococo { } fn target_transactions_author(&self) -> bp_rococo::AccountId { - (*self.target_sign.public().as_array_ref()).into() + (*self.message_lane.target_sign.public().as_array_ref()).into() } fn make_messages_delivery_transaction( @@ -94,7 +102,7 @@ impl SubstrateMessageLane for WococoMessagesToRococo { transaction_nonce: ::Index, _generated_at_header: WococoHeaderId, _nonces: RangeInclusive, - proof: ::MessagesProof, + proof: ::MessagesProof, ) -> Bytes { let (dispatch_weight, proof) = proof; let FromBridgedChainMessagesProof { @@ -106,14 +114,15 @@ impl SubstrateMessageLane for WococoMessagesToRococo { let call = relay_rococo_client::runtime::Call::BridgeMessagesWococo( relay_rococo_client::runtime::BridgeMessagesWococoCall::receive_messages_proof( - self.relayer_id_at_source.clone(), + self.message_lane.relayer_id_at_source.clone(), proof, messages_count as _, dispatch_weight, ), ); - let genesis_hash = *self.target_client.genesis_hash(); - let transaction = Rococo::sign_transaction(genesis_hash, &self.target_sign, transaction_nonce, call); + let genesis_hash = *self.message_lane.target_client.genesis_hash(); + let transaction = + Rococo::sign_transaction(genesis_hash, &self.message_lane.target_sign, transaction_nonce, call); log::trace!( target: "bridge", "Prepared Wococo -> Rococo delivery transaction. Weight: /{}, size: {}/{}", @@ -151,11 +160,13 @@ pub async fn run( let lane_id = params.lane_id; let source_client = params.source_client; let lane = WococoMessagesToRococo { - source_client: source_client.clone(), - source_sign: params.source_sign, - target_client: params.target_client.clone(), - target_sign: params.target_sign, - relayer_id_at_source: relayer_id_at_wococo, + message_lane: SubstrateMessageLaneToSubstrate { + source_client: source_client.clone(), + source_sign: params.source_sign, + target_client: params.target_client.clone(), + target_sign: params.target_sign, + relayer_id_at_source: relayer_id_at_wococo, + }, }; // 2/3 is reserved for proofs and tx overhead @@ -180,7 +191,7 @@ pub async fn run( Max messages size in single transaction: {}\n\t\ Max messages weight in single transaction: {}\n\t\ Relayer mode: {:?}", - lane.relayer_id_at_source, + lane.message_lane.relayer_id_at_source, max_messages_in_single_batch, max_messages_size_in_single_batch, max_messages_weight_in_single_batch, @@ -189,7 +200,7 @@ pub async fn run( let (metrics_params, metrics_values) = add_standalone_metrics( Some(messages_relay::message_lane_loop::metrics_prefix::< - WococoMessagesToRococo, + ::MessageLane, >(&lane_id)), params.metrics_params, source_client.clone(), @@ -237,7 +248,7 @@ pub(crate) fn add_standalone_metrics( metrics_params: MetricsParams, source_client: Client, ) -> anyhow::Result<(MetricsParams, StandaloneMessagesMetrics)> { - crate::messages_lane::add_standalone_metrics::( + substrate_relay_helper::messages_lane::add_standalone_metrics::( metrics_prefix, metrics_params, source_client, diff --git a/bridges/relays/bin-substrate/src/cli/init_bridge.rs b/bridges/relays/bin-substrate/src/cli/init_bridge.rs index 647978e430..846d3a575e 100644 --- a/bridges/relays/bin-substrate/src/cli/init_bridge.rs +++ b/bridges/relays/bin-substrate/src/cli/init_bridge.rs @@ -141,7 +141,7 @@ impl InitBridge { let target_client = self.target.to_client::().await?; let target_sign = self.target_sign.to_keypair::()?; - crate::headers_initialize::initialize( + substrate_relay_helper::headers_initialize::initialize( source_client, target_client.clone(), target_sign.public().into(), diff --git a/bridges/relays/bin-substrate/src/cli/relay_headers.rs b/bridges/relays/bin-substrate/src/cli/relay_headers.rs index 0f699ff978..404e571c2c 100644 --- a/bridges/relays/bin-substrate/src/cli/relay_headers.rs +++ b/bridges/relays/bin-substrate/src/cli/relay_headers.rs @@ -14,11 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -use crate::cli::{PrometheusParams, SourceConnectionParams, TargetConnectionParams, TargetSigningParams}; -use crate::finality_pipeline::SubstrateFinalitySyncPipeline; use structopt::StructOpt; use strum::{EnumString, EnumVariantNames, VariantNames}; +use substrate_relay_helper::finality_pipeline::SubstrateFinalitySyncPipeline; + +use crate::cli::{PrometheusParams, SourceConnectionParams, TargetConnectionParams, TargetSigningParams}; + /// Start headers relayer process. #[derive(StructOpt)] pub struct RelayHeaders { @@ -102,7 +104,7 @@ impl RelayHeaders { let finality = Finality::new(target_client.clone(), target_sign); finality.start_relay_guards(); - crate::finality_pipeline::run( + substrate_relay_helper::finality_pipeline::run( finality, source_client, target_client, diff --git a/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages.rs b/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages.rs index 04ee1a6bc2..4747939085 100644 --- a/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages.rs +++ b/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages.rs @@ -22,16 +22,17 @@ //! 2) add `declare_bridge_options!(...)` for the bridge; //! 3) add bridge support to the `select_bridge! { ... }` macro. -use crate::cli::{relay_messages::RelayerMode, CliChain, HexLaneId, PrometheusParams}; -use crate::declare_chain_options; -use crate::messages_lane::MessagesRelayParams; -use crate::on_demand_headers::OnDemandHeadersRelay; - use futures::{FutureExt, TryFutureExt}; -use relay_utils::metrics::MetricsParams; use structopt::StructOpt; use strum::VariantNames; +use relay_utils::metrics::MetricsParams; +use substrate_relay_helper::messages_lane::{MessagesRelayParams, SubstrateMessageLane}; +use substrate_relay_helper::on_demand_headers::OnDemandHeadersRelay; + +use crate::cli::{relay_messages::RelayerMode, CliChain, HexLaneId, PrometheusParams}; +use crate::declare_chain_options; + /// Start headers+messages relayer process. #[derive(StructOpt)] pub enum RelayHeadersAndMessages { @@ -195,7 +196,9 @@ impl RelayHeadersAndMessages { lane_id: lane, relayer_mode, metrics_params: metrics_params.clone().disable().metrics_prefix( - messages_relay::message_lane_loop::metrics_prefix::(&lane), + messages_relay::message_lane_loop::metrics_prefix::< + ::MessageLane, + >(&lane), ), }) .map_err(|e| anyhow::format_err!("{}", e)) @@ -210,7 +213,9 @@ impl RelayHeadersAndMessages { lane_id: lane, relayer_mode, metrics_params: metrics_params.clone().disable().metrics_prefix( - messages_relay::message_lane_loop::metrics_prefix::(&lane), + messages_relay::message_lane_loop::metrics_prefix::< + ::MessageLane, + >(&lane), ), }) .map_err(|e| anyhow::format_err!("{}", e)) diff --git a/bridges/relays/bin-substrate/src/cli/relay_messages.rs b/bridges/relays/bin-substrate/src/cli/relay_messages.rs index afd59c7a3a..0f89e9843f 100644 --- a/bridges/relays/bin-substrate/src/cli/relay_messages.rs +++ b/bridges/relays/bin-substrate/src/cli/relay_messages.rs @@ -14,15 +14,17 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . +use structopt::StructOpt; +use strum::{EnumString, EnumVariantNames, VariantNames}; + +use substrate_relay_helper::messages_lane::MessagesRelayParams; + use crate::cli::bridge::FullBridge; use crate::cli::{ HexLaneId, PrometheusParams, SourceConnectionParams, SourceSigningParams, TargetConnectionParams, TargetSigningParams, }; -use crate::messages_lane::MessagesRelayParams; use crate::select_full_bridge; -use structopt::StructOpt; -use strum::{EnumString, EnumVariantNames, VariantNames}; /// Relayer operating mode. #[derive(Debug, EnumString, EnumVariantNames, Clone, Copy, PartialEq)] diff --git a/bridges/relays/bin-substrate/src/main.rs b/bridges/relays/bin-substrate/src/main.rs index d119042b0d..13db6beefa 100644 --- a/bridges/relays/bin-substrate/src/main.rs +++ b/bridges/relays/bin-substrate/src/main.rs @@ -20,13 +20,6 @@ mod chains; mod cli; -mod finality_pipeline; -mod finality_target; -mod headers_initialize; -mod messages_lane; -mod messages_source; -mod messages_target; -mod on_demand_headers; fn main() { let command = cli::parse_args(); diff --git a/bridges/relays/lib-substrate-relay/Cargo.toml b/bridges/relays/lib-substrate-relay/Cargo.toml new file mode 100644 index 0000000000..944a2d3479 --- /dev/null +++ b/bridges/relays/lib-substrate-relay/Cargo.toml @@ -0,0 +1,51 @@ +[package] +name = "substrate-relay-helper" +version = "0.1.0" +authors = ["Parity Technologies "] +edition = "2018" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" + +[dependencies] +anyhow = "1.0" +async-std = "1.9.0" +async-trait = "0.1.42" +codec = { package = "parity-scale-codec", version = "2.2.0" } +futures = "0.3.12" +num-format = "0.4" +num-traits = "0.2" +log = "0.4.14" + + +# Bridge dependencies + +bp-header-chain = { path = "../../primitives/header-chain" } +bridge-runtime-common = { path = "../../bin/runtime-common" } + +finality-grandpa = { version = "0.14.0" } +finality-relay = { path = "../finality" } +relay-utils = { path = "../utils" } +headers-relay = { path = "../headers" } +messages-relay = { path = "../messages" } +relay-substrate-client = { path = "../client-substrate" } + +pallet-bridge-messages = { path = "../../modules/messages" } + +bp-runtime = { path = "../../primitives/runtime" } +bp-messages = { path = "../../primitives/messages" } + + +# Substrate Dependencies + +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-version = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[dev-dependencies] +relay-millau-client = { path = "../client-millau" } +relay-rialto-client = { path = "../client-rialto" } +bp-rialto = { path = "../../primitives/chain-rialto" } +bp-millau = { path = "../../primitives/chain-millau" } +rialto-runtime = { path = "../../bin/rialto/runtime" } diff --git a/bridges/relays/bin-substrate/src/finality_pipeline.rs b/bridges/relays/lib-substrate-relay/src/finality_pipeline.rs similarity index 92% rename from bridges/relays/bin-substrate/src/finality_pipeline.rs rename to bridges/relays/lib-substrate-relay/src/finality_pipeline.rs index 2013ec646b..deb83d4ea9 100644 --- a/bridges/relays/bin-substrate/src/finality_pipeline.rs +++ b/bridges/relays/lib-substrate-relay/src/finality_pipeline.rs @@ -34,7 +34,9 @@ pub(crate) const STALL_TIMEOUT: Duration = Duration::from_secs(120); pub(crate) const RECENT_FINALITY_PROOFS_LIMIT: usize = 4096; /// Headers sync pipeline for Substrate <-> Substrate relays. -pub trait SubstrateFinalitySyncPipeline: FinalitySyncPipeline { +pub trait SubstrateFinalitySyncPipeline: 'static + Clone + Debug + Send + Sync { + type FinalitySyncPipeline: FinalitySyncPipeline; + /// Name of the runtime method that returns id of best finalized source header at target chain. const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str; @@ -60,8 +62,8 @@ pub trait SubstrateFinalitySyncPipeline: FinalitySyncPipeline { fn make_submit_finality_proof_transaction( &self, transaction_nonce: ::Index, - header: Self::Header, - proof: Self::FinalityProof, + header: ::Header, + proof: ::FinalityProof, ) -> Bytes; } @@ -69,9 +71,9 @@ pub trait SubstrateFinalitySyncPipeline: FinalitySyncPipeline { #[derive(Clone)] pub struct SubstrateFinalityToSubstrate { /// Client for the target chain. - pub(crate) target_client: Client, + pub target_client: Client, /// Data required to sign target chain transactions. - pub(crate) target_sign: TargetSign, + pub target_sign: TargetSign, /// Unused generic arguments dump. _marker: PhantomData, } @@ -123,12 +125,12 @@ pub async fn run( metrics_params: MetricsParams, ) -> anyhow::Result<()> where - P: SubstrateFinalitySyncPipeline< + P: SubstrateFinalitySyncPipeline, + P::FinalitySyncPipeline: FinalitySyncPipeline< Hash = HashOf, Number = BlockNumberOf, Header = SyncHeader, FinalityProof = GrandpaJustification, - TargetChain = TargetChain, >, SourceChain: Clone + Chain, BlockNumberOf: BlockNumberBase, diff --git a/bridges/relays/bin-substrate/src/finality_target.rs b/bridges/relays/lib-substrate-relay/src/finality_target.rs similarity index 75% rename from bridges/relays/bin-substrate/src/finality_target.rs rename to bridges/relays/lib-substrate-relay/src/finality_target.rs index 6c4c384d11..bcf09b1a6d 100644 --- a/bridges/relays/bin-substrate/src/finality_target.rs +++ b/bridges/relays/lib-substrate-relay/src/finality_target.rs @@ -22,7 +22,7 @@ use crate::finality_pipeline::SubstrateFinalitySyncPipeline; use async_trait::async_trait; use codec::Decode; -use finality_relay::TargetClient; +use finality_relay::{FinalitySyncPipeline, TargetClient}; use relay_substrate_client::{Chain, Client, Error as SubstrateError}; use relay_utils::relay_loop::Client as RelayClient; @@ -58,28 +58,35 @@ impl RelayClient for SubstrateFinali } #[async_trait] -impl TargetClient

for SubstrateFinalityTarget +impl TargetClient for SubstrateFinalityTarget where C: Chain, - P::Number: Decode, - P::Hash: Decode, P: SubstrateFinalitySyncPipeline, + ::Number: Decode, + ::Hash: Decode, { - async fn best_finalized_source_block_number(&self) -> Result { + async fn best_finalized_source_block_number( + &self, + ) -> Result<::Number, SubstrateError> { // we can't continue to relay finality if target node is out of sync, because // it may have already received (some of) headers that we're going to relay self.client.ensure_synced().await?; - Ok(crate::messages_source::read_client_state::( - &self.client, - P::BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET, - ) + Ok(crate::messages_source::read_client_state::< + C, + ::Hash, + ::Number, + >(&self.client, P::BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET) .await? .best_finalized_peer_at_best_self .0) } - async fn submit_finality_proof(&self, header: P::Header, proof: P::FinalityProof) -> Result<(), SubstrateError> { + async fn submit_finality_proof( + &self, + header: ::Header, + proof: ::FinalityProof, + ) -> Result<(), SubstrateError> { let transactions_author = self.pipeline.transactions_author(); let pipeline = self.pipeline.clone(); self.client diff --git a/bridges/relays/bin-substrate/src/headers_initialize.rs b/bridges/relays/lib-substrate-relay/src/headers_initialize.rs similarity index 100% rename from bridges/relays/bin-substrate/src/headers_initialize.rs rename to bridges/relays/lib-substrate-relay/src/headers_initialize.rs diff --git a/bridges/relays/lib-substrate-relay/src/helpers.rs b/bridges/relays/lib-substrate-relay/src/helpers.rs new file mode 100644 index 0000000000..91d551140c --- /dev/null +++ b/bridges/relays/lib-substrate-relay/src/helpers.rs @@ -0,0 +1,41 @@ +// 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 . + +//! Substrate relay helpers + +use relay_utils::metrics::{FloatJsonValueMetric, PrometheusError, Registry}; + +/// Creates standalone token price metric. +pub fn token_price_metric( + registry: &Registry, + prefix: Option<&str>, + token_id: &str, +) -> Result { + FloatJsonValueMetric::new( + registry, + prefix, + format!( + "https://api.coingecko.com/api/v3/simple/price?ids={}&vs_currencies=btc", + token_id + ), + format!("$.{}.btc", token_id), + format!("{}_to_base_conversion_rate", token_id.replace("-", "_")), + format!( + "Rate used to convert from {} to some BASE tokens", + token_id.to_uppercase() + ), + ) +} diff --git a/bridges/relays/lib-substrate-relay/src/lib.rs b/bridges/relays/lib-substrate-relay/src/lib.rs new file mode 100644 index 0000000000..32eaa2276e --- /dev/null +++ b/bridges/relays/lib-substrate-relay/src/lib.rs @@ -0,0 +1,28 @@ +// 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 . + +//! The library of substrate relay. contains some public codes to provide to substrate relay. + +#![warn(missing_docs)] + +pub mod finality_pipeline; +pub mod finality_target; +pub mod headers_initialize; +pub mod helpers; +pub mod messages_lane; +pub mod messages_source; +pub mod messages_target; +pub mod on_demand_headers; diff --git a/bridges/relays/bin-substrate/src/messages_lane.rs b/bridges/relays/lib-substrate-relay/src/messages_lane.rs similarity index 94% rename from bridges/relays/bin-substrate/src/messages_lane.rs rename to bridges/relays/lib-substrate-relay/src/messages_lane.rs index cea43058d8..fae07c33b3 100644 --- a/bridges/relays/bin-substrate/src/messages_lane.rs +++ b/bridges/relays/lib-substrate-relay/src/messages_lane.rs @@ -56,7 +56,9 @@ pub struct MessagesRelayParams { } /// Message sync pipeline for Substrate <-> Substrate relays. -pub trait SubstrateMessageLane: MessageLane { +pub trait SubstrateMessageLane: 'static + Clone + Send + Sync { + type MessageLane: MessageLane; + /// Name of the runtime method that returns dispatch weight of outbound messages at the source chain. const OUTBOUND_LANE_MESSAGE_DETAILS_METHOD: &'static str; /// Name of the runtime method that returns latest generated nonce at the source chain. @@ -88,9 +90,9 @@ pub trait SubstrateMessageLane: MessageLane { fn make_messages_delivery_transaction( &self, transaction_nonce: ::Index, - generated_at_header: SourceHeaderIdOf, + generated_at_header: SourceHeaderIdOf, nonces: RangeInclusive, - proof: Self::MessagesProof, + proof: ::MessagesProof, ) -> Bytes; /// Returns id of account that we're using to sign transactions at source chain (delivery proof). @@ -100,8 +102,8 @@ pub trait SubstrateMessageLane: MessageLane { fn make_messages_receiving_proof_transaction( &self, transaction_nonce: ::Index, - generated_at_header: TargetHeaderIdOf, - proof: Self::MessagesReceivingProof, + generated_at_header: TargetHeaderIdOf, + proof: ::MessagesReceivingProof, ) -> Bytes; } @@ -109,15 +111,15 @@ pub trait SubstrateMessageLane: MessageLane { #[derive(Debug)] pub struct SubstrateMessageLaneToSubstrate { /// Client for the source Substrate chain. - pub(crate) source_client: Client, + pub source_client: Client, /// Parameters required to sign transactions for source chain. - pub(crate) source_sign: SourceSignParams, + pub source_sign: SourceSignParams, /// Client for the target Substrate chain. - pub(crate) target_client: Client, + pub target_client: Client, /// Parameters required to sign transactions for target chain. - pub(crate) target_sign: TargetSignParams, + pub target_sign: TargetSignParams, /// Account id of relayer at the source chain. - pub(crate) relayer_id_at_source: Source::AccountId, + pub relayer_id_at_source: Source::AccountId, } impl Clone @@ -261,14 +263,14 @@ pub fn add_standalone_metrics( } if let Some(source_chain_token_id) = source_chain_token_id { metrics_params = metrics_params.standalone_metric(|registry, prefix| { - let metric = crate::chains::token_price_metric(registry, prefix, source_chain_token_id)?; + let metric = crate::helpers::token_price_metric(registry, prefix, source_chain_token_id)?; source_to_base_conversion_rate = Some(metric.shared_value_ref()); Ok(metric) })?; } if let Some(target_chain_token_id) = target_chain_token_id { metrics_params = metrics_params.standalone_metric(|registry, prefix| { - let metric = crate::chains::token_price_metric(registry, prefix, target_chain_token_id)?; + let metric = crate::helpers::token_price_metric(registry, prefix, target_chain_token_id)?; target_to_base_conversion_rate = Some(metric.shared_value_ref()); Ok(metric) })?; @@ -276,8 +278,8 @@ pub fn add_standalone_metrics( Ok(( metrics_params.into_params(), StandaloneMessagesMetrics { - source_to_base_conversion_rate, target_to_base_conversion_rate, + source_to_base_conversion_rate, }, )) } diff --git a/bridges/relays/bin-substrate/src/messages_source.rs b/bridges/relays/lib-substrate-relay/src/messages_source.rs similarity index 89% rename from bridges/relays/bin-substrate/src/messages_source.rs rename to bridges/relays/lib-substrate-relay/src/messages_source.rs index 6792848e4a..279b2c45e0 100644 --- a/bridges/relays/bin-substrate/src/messages_source.rs +++ b/bridges/relays/lib-substrate-relay/src/messages_source.rs @@ -30,6 +30,7 @@ use bridge_runtime_common::messages::{ }; use codec::{Decode, Encode}; use frame_support::{traits::Instance, weights::Weight}; +use messages_relay::message_lane::MessageLane; use messages_relay::{ message_lane::{SourceHeaderIdOf, TargetHeaderIdOf}, message_lane_loop::{ @@ -107,42 +108,49 @@ where } #[async_trait] -impl SourceClient

for SubstrateMessagesSource +impl SourceClient for SubstrateMessagesSource where - SC: Chain, + SC: Chain< + Hash = ::SourceHeaderHash, + BlockNumber = ::SourceHeaderNumber, + Balance = ::SourceChainBalance, + >, SC::Hash: Copy, SC::BlockNumber: Copy, SC::Balance: Decode + Bounded, SC::Header: DeserializeOwned, SC::Index: DeserializeOwned, SC::BlockNumber: BlockNumberBase, - TC: Chain, - P: SubstrateMessageLane< + TC: Chain< + Hash = ::TargetHeaderHash, + BlockNumber = ::TargetHeaderNumber, + >, + P: SubstrateMessageLane, + P::MessageLane: MessageLane< MessagesProof = SubstrateMessagesProof, MessagesReceivingProof = SubstrateMessagesReceivingProof, - SourceChain = SC, - TargetChain = TC, >, - P::TargetHeaderNumber: Decode, - P::TargetHeaderHash: Decode, + ::TargetHeaderNumber: Decode, + ::TargetHeaderHash: Decode, I: Send + Sync + Instance, { - async fn state(&self) -> Result, SubstrateError> { + async fn state(&self) -> Result, SubstrateError> { // we can't continue to deliver confirmations if source node is out of sync, because // it may have already received confirmations that we're going to deliver self.client.ensure_synced().await?; - read_client_state::<_, P::TargetHeaderHash, P::TargetHeaderNumber>( - &self.client, - P::BEST_FINALIZED_TARGET_HEADER_ID_AT_SOURCE, - ) + read_client_state::< + _, + ::TargetHeaderHash, + ::TargetHeaderNumber, + >(&self.client, P::BEST_FINALIZED_TARGET_HEADER_ID_AT_SOURCE) .await } async fn latest_generated_nonce( &self, - id: SourceHeaderIdOf

, - ) -> Result<(SourceHeaderIdOf

, MessageNonce), SubstrateError> { + id: SourceHeaderIdOf, + ) -> Result<(SourceHeaderIdOf, MessageNonce), SubstrateError> { let encoded_response = self .client .state_call( @@ -158,8 +166,8 @@ where async fn latest_confirmed_received_nonce( &self, - id: SourceHeaderIdOf

, - ) -> Result<(SourceHeaderIdOf

, MessageNonce), SubstrateError> { + id: SourceHeaderIdOf, + ) -> Result<(SourceHeaderIdOf, MessageNonce), SubstrateError> { let encoded_response = self .client .state_call( @@ -175,9 +183,9 @@ where async fn generated_message_details( &self, - id: SourceHeaderIdOf

, + id: SourceHeaderIdOf, nonces: RangeInclusive, - ) -> Result, SubstrateError> { + ) -> Result::SourceChainBalance>, SubstrateError> { let encoded_response = self .client .state_call( @@ -195,10 +203,17 @@ where async fn prove_messages( &self, - id: SourceHeaderIdOf

, + id: SourceHeaderIdOf, nonces: RangeInclusive, proof_parameters: MessageProofParameters, - ) -> Result<(SourceHeaderIdOf

, RangeInclusive, P::MessagesProof), SubstrateError> { + ) -> Result< + ( + SourceHeaderIdOf, + RangeInclusive, + ::MessagesProof, + ), + SubstrateError, + > { let mut storage_keys = Vec::with_capacity(nonces.end().saturating_sub(*nonces.start()) as usize + 1); let mut message_nonce = *nonces.start(); while message_nonce <= *nonces.end() { @@ -230,8 +245,8 @@ where async fn submit_messages_receiving_proof( &self, - generated_at_block: TargetHeaderIdOf

, - proof: P::MessagesReceivingProof, + generated_at_block: TargetHeaderIdOf, + proof: ::MessagesReceivingProof, ) -> Result<(), SubstrateError> { let lane = self.lane.clone(); self.client @@ -242,13 +257,13 @@ where Ok(()) } - async fn require_target_header_on_source(&self, id: TargetHeaderIdOf

) { + async fn require_target_header_on_source(&self, id: TargetHeaderIdOf) { if let Some(ref target_to_source_headers_relay) = self.target_to_source_headers_relay { target_to_source_headers_relay.require_finalized_header(id).await; } } - async fn estimate_confirmation_transaction(&self) -> P::SourceChainBalance { + async fn estimate_confirmation_transaction(&self) -> ::SourceChainBalance { self.client .estimate_extrinsic_fee(self.lane.make_messages_receiving_proof_transaction( Zero::zero(), diff --git a/bridges/relays/bin-substrate/src/messages_target.rs b/bridges/relays/lib-substrate-relay/src/messages_target.rs similarity index 85% rename from bridges/relays/bin-substrate/src/messages_target.rs rename to bridges/relays/lib-substrate-relay/src/messages_target.rs index 666bfc48c2..4cafcc4866 100644 --- a/bridges/relays/bin-substrate/src/messages_target.rs +++ b/bridges/relays/lib-substrate-relay/src/messages_target.rs @@ -30,6 +30,7 @@ use bridge_runtime_common::messages::{ }; use codec::{Decode, Encode}; use frame_support::{traits::Instance, weights::Weight}; +use messages_relay::message_lane::MessageLane; use messages_relay::{ message_lane::{SourceHeaderIdOf, TargetHeaderIdOf}, message_lane_loop::{TargetClient, TargetClientState}, @@ -110,42 +111,49 @@ where } #[async_trait] -impl TargetClient

for SubstrateMessagesTarget +impl TargetClient for SubstrateMessagesTarget where - SC: Chain, + SC: Chain< + Hash = ::SourceHeaderHash, + BlockNumber = ::SourceHeaderNumber, + Balance = ::SourceChainBalance, + >, SC::Balance: TryFrom + Bounded, - TC: Chain, + TC: Chain< + Hash = ::TargetHeaderHash, + BlockNumber = ::TargetHeaderNumber, + >, TC::Hash: Copy, TC::BlockNumber: Copy, TC::Header: DeserializeOwned, TC::Index: DeserializeOwned, ::Number: BlockNumberBase, - P: SubstrateMessageLane< + P: SubstrateMessageLane, + P::MessageLane: MessageLane< MessagesProof = SubstrateMessagesProof, MessagesReceivingProof = SubstrateMessagesReceivingProof, - SourceChain = SC, - TargetChain = TC, >, - P::SourceHeaderNumber: Decode, - P::SourceHeaderHash: Decode, + ::SourceHeaderNumber: Decode, + ::SourceHeaderHash: Decode, I: Send + Sync + Instance, { - async fn state(&self) -> Result, SubstrateError> { + async fn state(&self) -> Result, SubstrateError> { // we can't continue to deliver messages if target node is out of sync, because // it may have already received (some of) messages that we're going to deliver self.client.ensure_synced().await?; - read_client_state::<_, P::SourceHeaderHash, P::SourceHeaderNumber>( - &self.client, - P::BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET, - ) + read_client_state::< + _, + ::SourceHeaderHash, + ::SourceHeaderNumber, + >(&self.client, P::BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET) .await } async fn latest_received_nonce( &self, - id: TargetHeaderIdOf

, - ) -> Result<(TargetHeaderIdOf

, MessageNonce), SubstrateError> { + id: TargetHeaderIdOf, + ) -> Result<(TargetHeaderIdOf, MessageNonce), SubstrateError> { let encoded_response = self .client .state_call( @@ -161,8 +169,8 @@ where async fn latest_confirmed_received_nonce( &self, - id: TargetHeaderIdOf

, - ) -> Result<(TargetHeaderIdOf

, MessageNonce), SubstrateError> { + id: TargetHeaderIdOf, + ) -> Result<(TargetHeaderIdOf, MessageNonce), SubstrateError> { let encoded_response = self .client .state_call( @@ -178,8 +186,8 @@ where async fn unrewarded_relayers_state( &self, - id: TargetHeaderIdOf

, - ) -> Result<(TargetHeaderIdOf

, UnrewardedRelayersState), SubstrateError> { + id: TargetHeaderIdOf, + ) -> Result<(TargetHeaderIdOf, UnrewardedRelayersState), SubstrateError> { let encoded_response = self .client .state_call( @@ -195,8 +203,14 @@ where async fn prove_messages_receiving( &self, - id: TargetHeaderIdOf

, - ) -> Result<(TargetHeaderIdOf

, P::MessagesReceivingProof), SubstrateError> { + id: TargetHeaderIdOf, + ) -> Result< + ( + TargetHeaderIdOf, + ::MessagesReceivingProof, + ), + SubstrateError, + > { let (id, relayers_state) = self.unrewarded_relayers_state(id).await?; let inbound_data_key = pallet_bridge_messages::storage_keys::inbound_lane_data_key::(&self.lane_id); let proof = self @@ -215,9 +229,9 @@ where async fn submit_messages_proof( &self, - generated_at_header: SourceHeaderIdOf

, + generated_at_header: SourceHeaderIdOf, nonces: RangeInclusive, - proof: P::MessagesProof, + proof: ::MessagesProof, ) -> Result, SubstrateError> { let lane = self.lane.clone(); let nonces_clone = nonces.clone(); @@ -229,7 +243,7 @@ where Ok(nonces) } - async fn require_source_header_on_target(&self, id: SourceHeaderIdOf

) { + async fn require_source_header_on_target(&self, id: SourceHeaderIdOf) { if let Some(ref source_to_target_headers_relay) = self.source_to_target_headers_relay { source_to_target_headers_relay.require_finalized_header(id).await; } @@ -240,7 +254,7 @@ where nonces: RangeInclusive, total_dispatch_weight: Weight, total_size: u32, - ) -> Result { + ) -> Result<::SourceChainBalance, SubstrateError> { let conversion_rate = self .metric_values .target_to_source_conversion_rate() diff --git a/bridges/relays/bin-substrate/src/on_demand_headers.rs b/bridges/relays/lib-substrate-relay/src/on_demand_headers.rs similarity index 91% rename from bridges/relays/bin-substrate/src/on_demand_headers.rs rename to bridges/relays/lib-substrate-relay/src/on_demand_headers.rs index 4a2b04328b..74166b89e7 100644 --- a/bridges/relays/bin-substrate/src/on_demand_headers.rs +++ b/bridges/relays/lib-substrate-relay/src/on_demand_headers.rs @@ -16,27 +16,28 @@ //! On-demand Substrate -> Substrate headers relay. -use crate::finality_pipeline::{ - SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate, RECENT_FINALITY_PROOFS_LIMIT, STALL_TIMEOUT, -}; -use crate::finality_target::SubstrateFinalityTarget; +use std::fmt::Debug; use async_std::sync::{Arc, Mutex}; -use bp_header_chain::justification::GrandpaJustification; +use futures::{select, FutureExt}; +use num_traits::{CheckedSub, One, Zero}; + use finality_relay::{ FinalitySyncParams, FinalitySyncPipeline, SourceClient as FinalitySourceClient, SourceHeader, TargetClient as FinalityTargetClient, }; -use futures::{select, FutureExt}; -use num_traits::{CheckedSub, One, Zero}; use relay_substrate_client::{ finality_source::{FinalitySource as SubstrateFinalitySource, RequiredHeaderNumberRef}, - BlockNumberOf, Chain, Client, HashOf, HeaderIdOf, SyncHeader, + Chain, Client, HeaderIdOf, SyncHeader, }; use relay_utils::{ metrics::MetricsParams, relay_loop::Client as RelayClient, BlockNumberBase, FailedClient, MaybeConnectionError, }; -use std::fmt::Debug; + +use crate::finality_pipeline::{ + SubstrateFinalitySyncPipeline, SubstrateFinalityToSubstrate, RECENT_FINALITY_PROOFS_LIMIT, STALL_TIMEOUT, +}; +use crate::finality_target::SubstrateFinalityTarget; /// On-demand Substrate <-> Substrate headers relay. /// @@ -52,10 +53,10 @@ pub struct OnDemandHeadersRelay { impl OnDemandHeadersRelay { /// Create new on-demand headers relay. - pub fn new( + pub fn new( source_client: Client, target_client: Client, - pipeline: SubstrateFinalityToSubstrate, + pipeline: P, maximal_headers_difference: SourceChain::BlockNumber, ) -> Self where @@ -64,15 +65,10 @@ impl OnDemandHeadersRelay { TargetChain: Chain + Debug, TargetChain::BlockNumber: BlockNumberBase, TargetSign: Clone + Send + Sync + 'static, - SubstrateFinalityToSubstrate: SubstrateFinalitySyncPipeline< - Hash = HashOf, - Number = BlockNumberOf, - Header = SyncHeader, - FinalityProof = GrandpaJustification, + P: SubstrateFinalitySyncPipeline< + FinalitySyncPipeline = SubstrateFinalityToSubstrate, TargetChain = TargetChain, >, - SubstrateFinalityTarget>: - FinalityTargetClient>, { let required_header_number = Arc::new(Mutex::new(Zero::zero())); let this = OnDemandHeadersRelay { @@ -111,10 +107,11 @@ impl OnDemandHeadersRelay { } /// Background task that is responsible for starting headers relay. -async fn background_task( +async fn background_task( source_client: Client, target_client: Client, - pipeline: SubstrateFinalityToSubstrate, + // pipeline: SubstrateFinalityToSubstrate, + pipeline: P, maximal_headers_difference: SourceChain::BlockNumber, required_header_number: RequiredHeaderNumberRef, ) where @@ -123,15 +120,10 @@ async fn background_task( TargetChain: Chain + Debug, TargetChain::BlockNumber: BlockNumberBase, TargetSign: Clone + Send + Sync + 'static, - SubstrateFinalityToSubstrate: SubstrateFinalitySyncPipeline< - Hash = HashOf, - Number = BlockNumberOf, - Header = SyncHeader, - FinalityProof = GrandpaJustification, + P: SubstrateFinalitySyncPipeline< + FinalitySyncPipeline = SubstrateFinalityToSubstrate, TargetChain = TargetChain, >, - SubstrateFinalityTarget>: - FinalityTargetClient>, { let relay_task_name = on_demand_headers_relay_name::(); let mut finality_source = SubstrateFinalitySource::< @@ -373,8 +365,9 @@ async fn best_finalized_source_header_at_target Result as RelayClient>::Error> where - SubstrateFinalityTarget: FinalityTargetClient

, - P: FinalitySyncPipeline, + SubstrateFinalityTarget: FinalityTargetClient, + P: SubstrateFinalitySyncPipeline, + P::FinalitySyncPipeline: FinalitySyncPipeline, { finality_target .best_finalized_source_block_number()