diff --git a/bridges/primitives/chain-bridge-hub-rococo/Cargo.toml b/bridges/primitives/chain-bridge-hub-rococo/Cargo.toml new file mode 100644 index 0000000000000..51bc88baf0e62 --- /dev/null +++ b/bridges/primitives/chain-bridge-hub-rococo/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "bp-bridge-hub-rococo" +description = "Primitives of BridgeHubRococo parachain runtime." +version = "0.1.0" +authors = ["Parity Technologies "] +edition = "2021" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" + +[dependencies] +smallvec = "1.10.0" + +# Bridge Dependencies + +bp-polkadot-core = { path = "../../primitives/polkadot-core", default-features = false } +bp-runtime = { path = "../../primitives/runtime", default-features = false } +bp-messages = { path = "../../primitives/messages", default-features = false } + +# Substrate Based Dependencies + +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +# Polkadot Dependencies +polkadot-runtime-constants = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" } + +[features] +default = ["std"] +std = [ + "bp-polkadot-core/std", + "bp-messages/std", + "bp-runtime/std", + "frame-support/std", + "sp-api/std", + "sp-std/std", + "polkadot-runtime-constants/std", +] diff --git a/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs b/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs new file mode 100644 index 0000000000000..32e8eb646a342 --- /dev/null +++ b/bridges/primitives/chain-bridge-hub-rococo/src/lib.rs @@ -0,0 +1,75 @@ +// 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 . + +//! Module with configuration which reflects BridgeHubRococo runtime setup (AccountId, Headers, +//! Hashes...) + +#![cfg_attr(not(feature = "std"), no_std)] + +use bp_messages::*; +pub use bp_polkadot_core::*; +use bp_runtime::{decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis}; +use frame_support::{ + parameter_types, + sp_runtime::{FixedU128, MultiAddress, MultiSigner}, + weights::{ + constants::ExtrinsicBaseWeight, WeightToFeeCoefficient, WeightToFeeCoefficients, + WeightToFeePolynomial, + }, + Parameter, +}; +use sp_std::prelude::*; + +pub type BridgeHubRococo = PolkadotLike; + +/// [`WeightToFee`] should reflect cumulus/bridge-hub-rococo-runtime [`WeightToFee`] +pub struct WeightToFee; +impl WeightToFeePolynomial for WeightToFee { + type Balance = Balance; + fn polynomial() -> WeightToFeeCoefficients { + pub const CENTS: Balance = polkadot_runtime_constants::currency::CENTS; + + // in Rococo, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT: + // in BridgeHub, we map to 1/10 of that, or 1/100 CENT + let p = CENTS; + let q = 100 * Balance::from(ExtrinsicBaseWeight::get().ref_time()); + smallvec::smallvec![WeightToFeeCoefficient { + degree: 1, + negative: false, + coeff_frac: Perbill::from_rational(p % q, q), + coeff_integer: p / q, + }] + } +} + +/// Public key of the chain account that may be used to verify signatures. +pub type AccountSigner = MultiSigner; + +/// The address format for describing accounts. +pub type Address = MultiAddress; + +/// Identifier of BridgeHubRococo in the Rococo relay chain. +pub const BRIDGE_HUB_ROCOCO_PARACHAIN_ID: u32 = 1013; + +/// Name of the With-BridgeHubRococo messages pallet instance that is deployed at bridged chains. +pub const WITH_BRIDGE_HUB_ROCOCO_MESSAGES_PALLET_NAME: &str = "BridgeRococoMessages"; + +parameter_types! { + pub const SS58Prefix: u16 = 42; +} + +decl_bridge_finality_runtime_apis!(bridge_hub_rococo); +decl_bridge_messages_runtime_apis!(bridge_hub_rococo); diff --git a/bridges/primitives/chain-bridge-hub-wococo/Cargo.toml b/bridges/primitives/chain-bridge-hub-wococo/Cargo.toml new file mode 100644 index 0000000000000..94ac501fbd531 --- /dev/null +++ b/bridges/primitives/chain-bridge-hub-wococo/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "bp-bridge-hub-wococo" +description = "Primitives of BridgeHubWococo parachain runtime." +version = "0.1.0" +authors = ["Parity Technologies "] +edition = "2021" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" + +[dependencies] + +# Bridge Dependencies + +bp-bridge-hub-rococo = { path = "../chain-bridge-hub-rococo", default-features = false } +bp-runtime = { path = "../../primitives/runtime", default-features = false } +bp-messages = { path = "../../primitives/messages", default-features = false } + +# Substrate Based Dependencies + +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } + +[features] +default = ["std"] +std = [ + "bp-runtime/std", + "bp-messages/std", + "frame-support/std", + "sp-api/std", + "sp-std/std", + "bp-bridge-hub-rococo/std", +] diff --git a/bridges/primitives/chain-bridge-hub-wococo/src/lib.rs b/bridges/primitives/chain-bridge-hub-wococo/src/lib.rs new file mode 100644 index 0000000000000..93f0d78dfd857 --- /dev/null +++ b/bridges/primitives/chain-bridge-hub-wococo/src/lib.rs @@ -0,0 +1,49 @@ +// 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 . + +//! Module with configuration which reflects BridgeHubWococo runtime setup +//! (AccountId, Headers, Hashes...) +//! +//! but actually this is just reexported BridgeHubRococo stuff, because they are supposed to be +//! identical, at least uses the same parachain runtime + +#![cfg_attr(not(feature = "std"), no_std)] + +// Re-export only what is really needed +pub use bp_bridge_hub_rococo::{ + account_info_storage_key, AccountId, AccountPublic, AccountSigner, Address, Balance, + BlockNumber, Hash, Hashing, Header, Nonce, SS58Prefix, Signature, SignedBlock, + SignedExtensions, UncheckedExtrinsic, WeightToFee, ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT, + DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT, EXTRA_STORAGE_PROOF_SIZE, + MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT, + MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX, + PAY_INBOUND_DISPATCH_FEE_WEIGHT, TX_EXTRA_BYTES, +}; +use bp_messages::*; +use bp_runtime::{decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis}; +use frame_support::{sp_runtime::FixedU128, Parameter}; +use sp_std::prelude::*; + +pub type BridgeHubWococo = bp_bridge_hub_rococo::BridgeHubRococo; + +/// Identifier of BridgeHubWococo in the Wococo relay chain. +pub const BRIDGE_HUB_WOCOCO_PARACHAIN_ID: u32 = 1013; + +/// Name of the With-BridgeHubWococo messages pallet instance that is deployed at bridged chains. +pub const WITH_BRIDGE_HUB_WOCOCO_MESSAGES_PALLET_NAME: &str = "BridgeWococoMessages"; + +decl_bridge_finality_runtime_apis!(bridge_hub_wococo); +decl_bridge_messages_runtime_apis!(bridge_hub_wococo); diff --git a/bridges/primitives/chain-rococo/Cargo.toml b/bridges/primitives/chain-rococo/Cargo.toml index 65d3f502db446..73a2450cd17d7 100644 --- a/bridges/primitives/chain-rococo/Cargo.toml +++ b/bridges/primitives/chain-rococo/Cargo.toml @@ -14,6 +14,7 @@ bp-runtime = { path = "../runtime", default-features = false } # Substrate Based Dependencies sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } [features] default = ["std"] @@ -21,4 +22,5 @@ std = [ "bp-polkadot-core/std", "bp-runtime/std", "sp-api/std", + "frame-support/std", ] diff --git a/bridges/primitives/chain-rococo/src/lib.rs b/bridges/primitives/chain-rococo/src/lib.rs index dd5be65dd866b..6fd7228fd75e5 100644 --- a/bridges/primitives/chain-rococo/src/lib.rs +++ b/bridges/primitives/chain-rococo/src/lib.rs @@ -20,11 +20,34 @@ pub use bp_polkadot_core::*; use bp_runtime::decl_bridge_finality_runtime_apis; +use frame_support::parameter_types; /// Rococo Chain pub type Rococo = PolkadotLike; +parameter_types! { + pub const SS58Prefix: u8 = 42; +} + +/// Name of the parachains pallet in the Rococo runtime. +pub const PARAS_PALLET_NAME: &str = "Paras"; + /// Name of the With-Rococo GRANDPA pallet instance that is deployed at bridged chains. pub const WITH_ROCOCO_GRANDPA_PALLET_NAME: &str = "BridgeRococoGrandpa"; +/// Maximal SCALE-encoded header size (in bytes) at Rococo. +/// +/// Let's assume that the largest header is header that enacts new authorities set with +/// `MAX_AUTHORITES_COUNT`. Every authority means 32-byte key and 8-byte weight. Let's also have +/// some fixed reserve for other things (digest, block hash and number, ...) as well. +pub const MAX_HEADER_SIZE: u32 = 4096 + MAX_AUTHORITIES_COUNT * 40; + +/// Maximal SCALE-encoded size of parachains headers that are stored at Rococo `Paras` pallet. +pub const MAX_NESTED_PARACHAIN_HEAD_SIZE: u32 = MAX_HEADER_SIZE; + +/// Maximal number of GRANDPA authorities at Rococo. +/// +/// Corresponds to the `MaxAuthorities` constant value from the Rococo runtime configuration. +pub const MAX_AUTHORITIES_COUNT: u32 = 100_000; + decl_bridge_finality_runtime_apis!(rococo); diff --git a/bridges/primitives/chain-wococo/Cargo.toml b/bridges/primitives/chain-wococo/Cargo.toml index 5a4c439e042a9..6b741cd4b73c6 100644 --- a/bridges/primitives/chain-wococo/Cargo.toml +++ b/bridges/primitives/chain-wococo/Cargo.toml @@ -11,6 +11,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0" # Bridge Dependencies bp-polkadot-core = { path = "../polkadot-core", default-features = false } bp-runtime = { path = "../runtime", default-features = false } +bp-rococo = { path = "../chain-rococo", default-features = false } # Substrate Based Dependencies sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } @@ -20,5 +21,6 @@ default = ["std"] std = [ "bp-polkadot-core/std", "bp-runtime/std", + "bp-rococo/std", "sp-api/std", ] diff --git a/bridges/primitives/chain-wococo/src/lib.rs b/bridges/primitives/chain-wococo/src/lib.rs index f3fe0196dc591..0436b03c0364e 100644 --- a/bridges/primitives/chain-wococo/src/lib.rs +++ b/bridges/primitives/chain-wococo/src/lib.rs @@ -19,6 +19,10 @@ #![allow(clippy::too_many_arguments)] pub use bp_polkadot_core::*; +pub use bp_rococo::{ + SS58Prefix, MAX_AUTHORITIES_COUNT, MAX_HEADER_SIZE, MAX_NESTED_PARACHAIN_HEAD_SIZE, + PARAS_PALLET_NAME, +}; use bp_runtime::decl_bridge_finality_runtime_apis; /// Wococo Chain diff --git a/bridges/primitives/runtime/src/lib.rs b/bridges/primitives/runtime/src/lib.rs index 83043f80621f6..75d75c2beff59 100644 --- a/bridges/primitives/runtime/src/lib.rs +++ b/bridges/primitives/runtime/src/lib.rs @@ -79,6 +79,12 @@ pub const ROCOCO_CHAIN_ID: ChainId = *b"roco"; /// Bridge-with-Wococo instance id. pub const WOCOCO_CHAIN_ID: ChainId = *b"woco"; +/// Bridge-with-BridgeHubRococo instance id. +pub const BRIDGE_HUB_ROCOCO_CHAIN_ID: ChainId = *b"bhro"; + +/// Bridge-with-BridgeHubWococo instance id. +pub const BRIDGE_HUB_WOCOCO_CHAIN_ID: ChainId = *b"bhwo"; + /// Call-dispatch module prefix. pub const CALL_DISPATCH_MODULE_PREFIX: &[u8] = b"pallet-bridge/dispatch"; diff --git a/bridges/relays/bin-substrate/Cargo.toml b/bridges/relays/bin-substrate/Cargo.toml index 90adaf7e6529c..c214471eb6bdf 100644 --- a/bridges/relays/bin-substrate/Cargo.toml +++ b/bridges/relays/bin-substrate/Cargo.toml @@ -20,14 +20,19 @@ strum = { version = "0.21.0", features = ["derive"] } # Bridge dependencies +bp-bridge-hub-rococo = { path = "../../primitives/chain-bridge-hub-rococo" } +bp-bridge-hub-wococo = { path = "../../primitives/chain-bridge-hub-wococo" } +bp-header-chain = { path = "../../primitives/header-chain" } bp-messages = { path = "../../primitives/messages" } bp-millau = { path = "../../primitives/chain-millau" } bp-polkadot-core = { path = "../../primitives/polkadot-core" } bp-rialto = { path = "../../primitives/chain-rialto" } bp-rialto-parachain = { path = "../../primitives/chain-rialto-parachain" } +bp-rococo = { path = "../../primitives/chain-rococo" } bp-runtime = { path = "../../primitives/runtime" } bp-statemine = { path = "../../primitives/chain-statemine" } bp-westend = { path = "../../primitives/chain-westend" } +bp-wococo = { path = "../../primitives/chain-wococo" } bridge-runtime-common = { path = "../../bin/runtime-common" } messages-relay = { path = "../messages" } millau-runtime = { path = "../../bin/millau/runtime" } @@ -37,10 +42,14 @@ parachains-relay = { path = "../parachains" } relay-millau-client = { path = "../client-millau" } relay-rialto-client = { path = "../client-rialto" } relay-rialto-parachain-client = { path = "../client-rialto-parachain" } +relay-bridge-hub-rococo-client = { path = "../client-bridge-hub-rococo" } +relay-bridge-hub-wococo-client = { path = "../client-bridge-hub-wococo" } +relay-rococo-client = { path = "../client-rococo" } relay-statemine-client = { path = "../client-statemine" } relay-substrate-client = { path = "../client-substrate" } relay-utils = { path = "../utils" } relay-westend-client = { path = "../client-westend" } +relay-wococo-client = { path = "../client-wococo" } rialto-parachain-runtime = { path = "../../bin/rialto-parachain/runtime" } rialto-runtime = { path = "../../bin/rialto/runtime" } substrate-relay-helper = { path = "../lib-substrate-relay" } diff --git a/bridges/relays/bin-substrate/src/chains/bridge_hub_rococo_messages_to_bridge_hub_wococo.rs b/bridges/relays/bin-substrate/src/chains/bridge_hub_rococo_messages_to_bridge_hub_wococo.rs new file mode 100644 index 0000000000000..915dd82969852 --- /dev/null +++ b/bridges/relays/bin-substrate/src/chains/bridge_hub_rococo_messages_to_bridge_hub_wococo.rs @@ -0,0 +1,78 @@ +// 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 . + +//! BridgeHubRococo-to-BridgeHubWococo messages sync entrypoint. + +use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge}; +use bp_messages::Weight; +use messages_relay::relay_strategy::MixStrategy; +use relay_bridge_hub_rococo_client::BridgeHubRococo; +use relay_bridge_hub_wococo_client::BridgeHubWococo; +use substrate_relay_helper::messages_lane::SubstrateMessageLane; + +pub struct BridgeHubRococoToBridgeHubWococoMessagesCliBridge {} + +impl CliBridgeBase for BridgeHubRococoToBridgeHubWococoMessagesCliBridge { + type Source = BridgeHubRococo; + type Target = BridgeHubWococo; +} + +impl MessagesCliBridge for BridgeHubRococoToBridgeHubWococoMessagesCliBridge { + const ESTIMATE_MESSAGE_FEE_METHOD: &'static str = + "TODO: not needed now, used for send_message and estimate_fee CLI"; + type MessagesLane = BridgeHubRococoMessagesToBridgeHubWococoMessageLane; +} + +substrate_relay_helper::generate_mocked_receive_message_proof_call_builder!( + BridgeHubRococoMessagesToBridgeHubWococoMessageLane, + BridgeHubRococoMessagesToBridgeHubWococoMessageLaneReceiveMessagesProofCallBuilder, + relay_bridge_hub_wococo_client::runtime::Call::BridgeRococoMessages, + relay_bridge_hub_wococo_client::runtime::BridgeRococoMessagesCall::receive_messages_proof +); + +substrate_relay_helper::generate_mocked_receive_message_delivery_proof_call_builder!( + BridgeHubRococoMessagesToBridgeHubWococoMessageLane, + BridgeHubRococoMessagesToBridgeHubWococoMessageLaneReceiveMessagesDeliveryProofCallBuilder, + relay_bridge_hub_rococo_client::runtime::Call::BridgeWococoMessages, + relay_bridge_hub_rococo_client::runtime::BridgeWococoMessagesCall::receive_messages_delivery_proof +); + +/// Description of BridgeHubRococo -> BridgeHubWococo messages bridge. +#[derive(Clone, Debug)] +pub struct BridgeHubRococoMessagesToBridgeHubWococoMessageLane; + +impl SubstrateMessageLane for BridgeHubRococoMessagesToBridgeHubWococoMessageLane { + const SOURCE_TO_TARGET_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> = None; + const TARGET_TO_SOURCE_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> = None; + + const SOURCE_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> = None; + const TARGET_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> = None; + + const AT_SOURCE_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> = None; + const AT_TARGET_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> = None; + + type SourceChain = BridgeHubRococo; + type TargetChain = BridgeHubWococo; + + type ReceiveMessagesProofCallBuilder = + BridgeHubRococoMessagesToBridgeHubWococoMessageLaneReceiveMessagesProofCallBuilder; + type ReceiveMessagesDeliveryProofCallBuilder = + BridgeHubRococoMessagesToBridgeHubWococoMessageLaneReceiveMessagesDeliveryProofCallBuilder; + + type TargetToSourceChainConversionRateUpdateBuilder = (); + + type RelayStrategy = MixStrategy; +} diff --git a/bridges/relays/bin-substrate/src/chains/bridge_hub_wococo_messages_to_bridge_hub_rococo.rs b/bridges/relays/bin-substrate/src/chains/bridge_hub_wococo_messages_to_bridge_hub_rococo.rs new file mode 100644 index 0000000000000..179b9076ba72d --- /dev/null +++ b/bridges/relays/bin-substrate/src/chains/bridge_hub_wococo_messages_to_bridge_hub_rococo.rs @@ -0,0 +1,78 @@ +// 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 . + +//! BridgeHubWococo-to-BridgeHubRococo messages sync entrypoint. + +use crate::cli::bridge::{CliBridgeBase, MessagesCliBridge}; +use bp_messages::Weight; +use messages_relay::relay_strategy::MixStrategy; +use relay_bridge_hub_rococo_client::BridgeHubRococo; +use relay_bridge_hub_wococo_client::BridgeHubWococo; +use substrate_relay_helper::messages_lane::SubstrateMessageLane; + +pub struct BridgeHubWococoToBridgeHubRococoMessagesCliBridge {} + +impl CliBridgeBase for BridgeHubWococoToBridgeHubRococoMessagesCliBridge { + type Source = BridgeHubWococo; + type Target = BridgeHubRococo; +} + +impl MessagesCliBridge for BridgeHubWococoToBridgeHubRococoMessagesCliBridge { + const ESTIMATE_MESSAGE_FEE_METHOD: &'static str = + "TODO: not needed now, used for send_message and estimate_fee CLI"; + type MessagesLane = BridgeHubWococoMessagesToBridgeHubRococoMessageLane; +} + +substrate_relay_helper::generate_mocked_receive_message_proof_call_builder!( + BridgeHubWococoMessagesToBridgeHubRococoMessageLane, + BridgeHubWococoMessagesToBridgeHubRococoMessageLaneReceiveMessagesProofCallBuilder, + relay_bridge_hub_rococo_client::runtime::Call::BridgeWococoMessages, + relay_bridge_hub_rococo_client::runtime::BridgeWococoMessagesCall::receive_messages_proof +); + +substrate_relay_helper::generate_mocked_receive_message_delivery_proof_call_builder!( + BridgeHubWococoMessagesToBridgeHubRococoMessageLane, + BridgeHubWococoMessagesToBridgeHubRococoMessageLaneReceiveMessagesDeliveryProofCallBuilder, + relay_bridge_hub_wococo_client::runtime::Call::BridgeRococoMessages, + relay_bridge_hub_wococo_client::runtime::BridgeRococoMessagesCall::receive_messages_delivery_proof +); + +/// Description of BridgeHubWococo -> BridgeHubRococo messages bridge. +#[derive(Clone, Debug)] +pub struct BridgeHubWococoMessagesToBridgeHubRococoMessageLane; + +impl SubstrateMessageLane for BridgeHubWococoMessagesToBridgeHubRococoMessageLane { + const SOURCE_TO_TARGET_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> = None; + const TARGET_TO_SOURCE_CONVERSION_RATE_PARAMETER_NAME: Option<&'static str> = None; + + const SOURCE_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> = None; + const TARGET_FEE_MULTIPLIER_PARAMETER_NAME: Option<&'static str> = None; + + const AT_SOURCE_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> = None; + const AT_TARGET_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str> = None; + + type SourceChain = BridgeHubWococo; + type TargetChain = BridgeHubRococo; + + type ReceiveMessagesProofCallBuilder = + BridgeHubWococoMessagesToBridgeHubRococoMessageLaneReceiveMessagesProofCallBuilder; + type ReceiveMessagesDeliveryProofCallBuilder = + BridgeHubWococoMessagesToBridgeHubRococoMessageLaneReceiveMessagesDeliveryProofCallBuilder; + + type TargetToSourceChainConversionRateUpdateBuilder = (); + + type RelayStrategy = MixStrategy; +} diff --git a/bridges/relays/bin-substrate/src/chains/mod.rs b/bridges/relays/bin-substrate/src/chains/mod.rs index 5d7171691bffb..6bd444cc3959f 100644 --- a/bridges/relays/bin-substrate/src/chains/mod.rs +++ b/bridges/relays/bin-substrate/src/chains/mod.rs @@ -16,6 +16,8 @@ //! Chain-specific relayer configuration. +pub mod bridge_hub_rococo_messages_to_bridge_hub_wococo; +pub mod bridge_hub_wococo_messages_to_bridge_hub_rococo; pub mod millau_headers_to_rialto; pub mod millau_headers_to_rialto_parachain; pub mod millau_messages_to_rialto; @@ -24,14 +26,20 @@ pub mod rialto_headers_to_millau; pub mod rialto_messages_to_millau; pub mod rialto_parachain_messages_to_millau; pub mod rialto_parachains_to_millau; +pub mod rococo_headers_to_bridge_hub_wococo; +pub mod rococo_parachains_to_bridge_hub_wococo; pub mod westend_headers_to_millau; pub mod westend_parachains_to_millau; +pub mod wococo_headers_to_bridge_hub_rococo; +pub mod wococo_parachains_to_bridge_hub_rococo; mod millau; mod rialto; mod rialto_parachain; +mod rococo; mod statemine; mod westend; +mod wococo; #[cfg(test)] mod tests { diff --git a/bridges/relays/bin-substrate/src/chains/rococo.rs b/bridges/relays/bin-substrate/src/chains/rococo.rs new file mode 100644 index 0000000000000..6a99eab6cb385 --- /dev/null +++ b/bridges/relays/bin-substrate/src/chains/rococo.rs @@ -0,0 +1,42 @@ +// 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 . + +//! Rococo + Rococo parachains specification for CLI. + +use crate::cli::CliChain; +use relay_bridge_hub_rococo_client::BridgeHubRococo; +use relay_rococo_client::Rococo; +use sp_version::RuntimeVersion; + +impl CliChain for Rococo { + const RUNTIME_VERSION: Option = None; + + type KeyPair = sp_core::sr25519::Pair; + + fn ss58_format() -> u16 { + bp_rococo::SS58Prefix::get() as u16 + } +} + +impl CliChain for BridgeHubRococo { + const RUNTIME_VERSION: Option = None; + + type KeyPair = sp_core::sr25519::Pair; + + fn ss58_format() -> u16 { + relay_bridge_hub_rococo_client::runtime::SS58Prefix::get() + } +} diff --git a/bridges/relays/bin-substrate/src/chains/rococo_headers_to_bridge_hub_wococo.rs b/bridges/relays/bin-substrate/src/chains/rococo_headers_to_bridge_hub_wococo.rs new file mode 100644 index 0000000000000..2ec13614a34a1 --- /dev/null +++ b/bridges/relays/bin-substrate/src/chains/rococo_headers_to_bridge_hub_wococo.rs @@ -0,0 +1,53 @@ +// 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 . + +//! Rococo-to-Wococo bridge hubs headers sync entrypoint. + +use crate::cli::bridge::{CliBridgeBase, RelayToRelayHeadersCliBridge}; +use substrate_relay_helper::finality::{ + engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalitySyncPipeline, +}; + +/// Description of Rococo -> Wococo finalized headers bridge. +#[derive(Clone, Debug)] +pub struct RococoFinalityToBridgeHubWococo; + +substrate_relay_helper::generate_mocked_submit_finality_proof_call_builder!( + RococoFinalityToBridgeHubWococo, + RococoFinalityToBridgeHubWococoCallBuilder, + relay_bridge_hub_wococo_client::runtime::Call::BridgeRococoGrandpa, + relay_bridge_hub_wococo_client::runtime::BridgeGrandpaRococoCall::submit_finality_proof +); + +impl SubstrateFinalitySyncPipeline for RococoFinalityToBridgeHubWococo { + type SourceChain = relay_rococo_client::Rococo; + type TargetChain = relay_bridge_hub_wococo_client::BridgeHubWococo; + + type FinalityEngine = GrandpaFinalityEngine; + type SubmitFinalityProofCallBuilder = RococoFinalityToBridgeHubWococoCallBuilder; +} + +/// `Rococo` to BridgeHub `Wococo` bridge definition. +pub struct RococoToBridgeHubWococoCliBridge {} + +impl CliBridgeBase for RococoToBridgeHubWococoCliBridge { + type Source = relay_rococo_client::Rococo; + type Target = relay_bridge_hub_wococo_client::BridgeHubWococo; +} + +impl RelayToRelayHeadersCliBridge for RococoToBridgeHubWococoCliBridge { + type Finality = RococoFinalityToBridgeHubWococo; +} diff --git a/bridges/relays/bin-substrate/src/chains/rococo_parachains_to_bridge_hub_wococo.rs b/bridges/relays/bin-substrate/src/chains/rococo_parachains_to_bridge_hub_wococo.rs new file mode 100644 index 0000000000000..509cbf70db160 --- /dev/null +++ b/bridges/relays/bin-substrate/src/chains/rococo_parachains_to_bridge_hub_wococo.rs @@ -0,0 +1,78 @@ +// 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 . + +//! Wococo-to-Rococo parachains sync entrypoint. + +use crate::cli::bridge::{CliBridgeBase, ParachainToRelayHeadersCliBridge}; +use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId}; +use parachains_relay::ParachainsPipeline; +use relay_substrate_client::{CallOf, HeaderIdOf}; +use substrate_relay_helper::parachains::{ + SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline, +}; + +/// BridgeHub-to-BridgeHub parachain sync description. +#[derive(Clone, Debug)] +pub struct BridgeHubRococoToBridgeHubWococo; + +impl ParachainsPipeline for BridgeHubRococoToBridgeHubWococo { + type SourceChain = relay_rococo_client::Rococo; + type TargetChain = relay_bridge_hub_wococo_client::BridgeHubWococo; +} + +impl SubstrateParachainsPipeline for BridgeHubRococoToBridgeHubWococo { + type SourceParachain = relay_bridge_hub_rococo_client::BridgeHubRococo; + type SourceRelayChain = relay_rococo_client::Rococo; + type TargetChain = relay_bridge_hub_wococo_client::BridgeHubWococo; + + type SubmitParachainHeadsCallBuilder = BridgeHubRococoToBridgeHubWococoCallBuilder; + + const SOURCE_PARACHAIN_PARA_ID: u32 = bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID; +} + +pub struct BridgeHubRococoToBridgeHubWococoCallBuilder; +impl SubmitParachainHeadsCallBuilder + for BridgeHubRococoToBridgeHubWococoCallBuilder +{ + fn build_submit_parachain_heads_call( + at_relay_block: HeaderIdOf, + parachains: Vec<(ParaId, ParaHash)>, + parachain_heads_proof: ParaHeadsProof, + ) -> CallOf { + relay_bridge_hub_wococo_client::runtime::Call::BridgeRococoParachain( + relay_bridge_hub_wococo_client::runtime::BridgeParachainCall::submit_parachain_heads( + (at_relay_block.0, at_relay_block.1), + parachains, + parachain_heads_proof, + ), + ) + } +} + +/// `BridgeHubParachain` to `BridgeHubParachain` bridge definition. +pub struct BridgeHubRococoToBridgeHubWococoCliBridge {} + +impl ParachainToRelayHeadersCliBridge for BridgeHubRococoToBridgeHubWococoCliBridge { + type SourceRelay = relay_rococo_client::Rococo; + type ParachainFinality = BridgeHubRococoToBridgeHubWococo; + type RelayFinality = + crate::chains::rococo_headers_to_bridge_hub_wococo::RococoFinalityToBridgeHubWococo; +} + +impl CliBridgeBase for BridgeHubRococoToBridgeHubWococoCliBridge { + type Source = relay_bridge_hub_rococo_client::BridgeHubRococo; + type Target = relay_bridge_hub_wococo_client::BridgeHubWococo; +} diff --git a/bridges/relays/bin-substrate/src/chains/wococo.rs b/bridges/relays/bin-substrate/src/chains/wococo.rs new file mode 100644 index 0000000000000..c44f3ac811f3f --- /dev/null +++ b/bridges/relays/bin-substrate/src/chains/wococo.rs @@ -0,0 +1,42 @@ +// 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 . + +//! Wococo + Wococo parachains specification for CLI. + +use crate::cli::CliChain; +use relay_bridge_hub_wococo_client::BridgeHubWococo; +use relay_wococo_client::Wococo; +use sp_version::RuntimeVersion; + +impl CliChain for Wococo { + const RUNTIME_VERSION: Option = None; + + type KeyPair = sp_core::sr25519::Pair; + + fn ss58_format() -> u16 { + bp_wococo::SS58Prefix::get() as u16 + } +} + +impl CliChain for BridgeHubWococo { + const RUNTIME_VERSION: Option = None; + + type KeyPair = sp_core::sr25519::Pair; + + fn ss58_format() -> u16 { + relay_bridge_hub_wococo_client::runtime::SS58Prefix::get() + } +} diff --git a/bridges/relays/bin-substrate/src/chains/wococo_headers_to_bridge_hub_rococo.rs b/bridges/relays/bin-substrate/src/chains/wococo_headers_to_bridge_hub_rococo.rs new file mode 100644 index 0000000000000..30d6af00cd3b3 --- /dev/null +++ b/bridges/relays/bin-substrate/src/chains/wococo_headers_to_bridge_hub_rococo.rs @@ -0,0 +1,53 @@ +// 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 . + +//! Wococo-to-Rococo bridge hubs headers sync entrypoint. + +use crate::cli::bridge::{CliBridgeBase, RelayToRelayHeadersCliBridge}; +use substrate_relay_helper::finality::{ + engine::Grandpa as GrandpaFinalityEngine, SubstrateFinalitySyncPipeline, +}; + +/// Description of Wococo -> Rococo finalized headers bridge. +#[derive(Clone, Debug)] +pub struct WococoFinalityToBridgeHubRococo; + +substrate_relay_helper::generate_mocked_submit_finality_proof_call_builder!( + WococoFinalityToBridgeHubRococo, + WococoFinalityToBridgeHubRococoCallBuilder, + relay_bridge_hub_rococo_client::runtime::Call::BridgeWococoGrandpa, + relay_bridge_hub_rococo_client::runtime::BridgeWococoGrandpaCall::submit_finality_proof +); + +impl SubstrateFinalitySyncPipeline for WococoFinalityToBridgeHubRococo { + type SourceChain = relay_wococo_client::Wococo; + type TargetChain = relay_bridge_hub_rococo_client::BridgeHubRococo; + + type FinalityEngine = GrandpaFinalityEngine; + type SubmitFinalityProofCallBuilder = WococoFinalityToBridgeHubRococoCallBuilder; +} + +/// `Wococo` to BridgeHub `Rococo` bridge definition. +pub struct WococoToBridgeHubRococoCliBridge {} + +impl CliBridgeBase for WococoToBridgeHubRococoCliBridge { + type Source = relay_wococo_client::Wococo; + type Target = relay_bridge_hub_rococo_client::BridgeHubRococo; +} + +impl RelayToRelayHeadersCliBridge for WococoToBridgeHubRococoCliBridge { + type Finality = WococoFinalityToBridgeHubRococo; +} diff --git a/bridges/relays/bin-substrate/src/chains/wococo_parachains_to_bridge_hub_rococo.rs b/bridges/relays/bin-substrate/src/chains/wococo_parachains_to_bridge_hub_rococo.rs new file mode 100644 index 0000000000000..d4fbf095df480 --- /dev/null +++ b/bridges/relays/bin-substrate/src/chains/wococo_parachains_to_bridge_hub_rococo.rs @@ -0,0 +1,78 @@ +// 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 . + +//! Rococo-to-Wococo parachains sync entrypoint. + +use crate::cli::bridge::{CliBridgeBase, ParachainToRelayHeadersCliBridge}; +use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId}; +use parachains_relay::ParachainsPipeline; +use relay_substrate_client::{CallOf, HeaderIdOf}; +use substrate_relay_helper::parachains::{ + SubmitParachainHeadsCallBuilder, SubstrateParachainsPipeline, +}; + +/// BridgeHub-to-BridgeHub parachain sync description. +#[derive(Clone, Debug)] +pub struct BridgeHubWococoToBridgeHubRococo; + +impl ParachainsPipeline for BridgeHubWococoToBridgeHubRococo { + type SourceChain = relay_wococo_client::Wococo; + type TargetChain = relay_bridge_hub_rococo_client::BridgeHubRococo; +} + +impl SubstrateParachainsPipeline for BridgeHubWococoToBridgeHubRococo { + type SourceParachain = relay_bridge_hub_wococo_client::BridgeHubWococo; + type SourceRelayChain = relay_wococo_client::Wococo; + type TargetChain = relay_bridge_hub_rococo_client::BridgeHubRococo; + + type SubmitParachainHeadsCallBuilder = BridgeHubWococoToBridgeHubRococoCallBuilder; + + const SOURCE_PARACHAIN_PARA_ID: u32 = bp_bridge_hub_wococo::BRIDGE_HUB_WOCOCO_PARACHAIN_ID; +} + +pub struct BridgeHubWococoToBridgeHubRococoCallBuilder; +impl SubmitParachainHeadsCallBuilder + for BridgeHubWococoToBridgeHubRococoCallBuilder +{ + fn build_submit_parachain_heads_call( + at_relay_block: HeaderIdOf, + parachains: Vec<(ParaId, ParaHash)>, + parachain_heads_proof: ParaHeadsProof, + ) -> CallOf { + relay_bridge_hub_rococo_client::runtime::Call::BridgeWococoParachain( + relay_bridge_hub_rococo_client::runtime::BridgeParachainCall::submit_parachain_heads( + (at_relay_block.0, at_relay_block.1), + parachains, + parachain_heads_proof, + ), + ) + } +} + +/// `BridgeHubParachain` to `BridgeHubParachain` bridge definition. +pub struct BridgeHubWococoToBridgeHubRococoCliBridge {} + +impl ParachainToRelayHeadersCliBridge for BridgeHubWococoToBridgeHubRococoCliBridge { + type SourceRelay = relay_wococo_client::Wococo; + type ParachainFinality = BridgeHubWococoToBridgeHubRococo; + type RelayFinality = + crate::chains::wococo_headers_to_bridge_hub_rococo::WococoFinalityToBridgeHubRococo; +} + +impl CliBridgeBase for BridgeHubWococoToBridgeHubRococoCliBridge { + type Source = relay_bridge_hub_wococo_client::BridgeHubWococo; + type Target = relay_bridge_hub_rococo_client::BridgeHubRococo; +} diff --git a/bridges/relays/bin-substrate/src/cli/bridge.rs b/bridges/relays/bin-substrate/src/cli/bridge.rs index ffe4cc51e55c9..0bed036d91a9b 100644 --- a/bridges/relays/bin-substrate/src/cli/bridge.rs +++ b/bridges/relays/bin-substrate/src/cli/bridge.rs @@ -33,6 +33,8 @@ pub enum FullBridge { RialtoToMillau, MillauToRialtoParachain, RialtoParachainToMillau, + BridgeHubRococoToBridgeHubWococo, + BridgeHubWococoToBridgeHubRococo, } impl FullBridge { @@ -43,6 +45,8 @@ impl FullBridge { Self::RialtoToMillau => RIALTO_TO_MILLAU_INDEX, Self::MillauToRialtoParachain => MILLAU_TO_RIALTO_PARACHAIN_INDEX, Self::RialtoParachainToMillau => RIALTO_PARACHAIN_TO_MILLAU_INDEX, + Self::BridgeHubRococoToBridgeHubWococo | Self::BridgeHubWococoToBridgeHubRococo => + unimplemented!("TODO: (bridge_instance_index) do we need it or refactor or remove?"), } } } diff --git a/bridges/relays/bin-substrate/src/cli/estimate_fee.rs b/bridges/relays/bin-substrate/src/cli/estimate_fee.rs index 88823eec2f292..00a175187778c 100644 --- a/bridges/relays/bin-substrate/src/cli/estimate_fee.rs +++ b/bridges/relays/bin-substrate/src/cli/estimate_fee.rs @@ -125,6 +125,9 @@ impl EstimateFee { MillauToRialtoParachainCliBridge::estimate_fee(self), FullBridge::RialtoParachainToMillau => RialtoParachainToMillauCliBridge::estimate_fee(self), + FullBridge::BridgeHubRococoToBridgeHubWococo | + FullBridge::BridgeHubWococoToBridgeHubRococo => + unimplemented!("TODO: (EstimateFee) do we need it or refactor or remove?"), } .await } diff --git a/bridges/relays/bin-substrate/src/cli/init_bridge.rs b/bridges/relays/bin-substrate/src/cli/init_bridge.rs index 218130dbe562e..54a3c74a4b6e2 100644 --- a/bridges/relays/bin-substrate/src/cli/init_bridge.rs +++ b/bridges/relays/bin-substrate/src/cli/init_bridge.rs @@ -21,7 +21,9 @@ use crate::{ millau_headers_to_rialto::MillauToRialtoCliBridge, millau_headers_to_rialto_parachain::MillauToRialtoParachainCliBridge, rialto_headers_to_millau::RialtoToMillauCliBridge, + rococo_headers_to_bridge_hub_wococo::RococoToBridgeHubWococoCliBridge, westend_headers_to_millau::WestendToMillauCliBridge, + wococo_headers_to_bridge_hub_rococo::WococoToBridgeHubRococoCliBridge, }, cli::{bridge::CliBridgeBase, chain_schema::*}, }; @@ -54,6 +56,8 @@ pub enum InitBridgeName { RialtoToMillau, WestendToMillau, MillauToRialtoParachain, + RococoToBridgeHubWococo, + WococoToBridgeHubRococo, } #[async_trait] @@ -163,6 +167,30 @@ impl BridgeInitializer for WestendToMillauCliBridge { } } +impl BridgeInitializer for RococoToBridgeHubWococoCliBridge { + type Engine = GrandpaFinalityEngine; + + fn encode_init_bridge( + init_data: >::InitializationData, + ) -> ::Call { + relay_bridge_hub_wococo_client::runtime::Call::BridgeRococoGrandpa( + relay_bridge_hub_wococo_client::runtime::BridgeGrandpaRococoCall::initialize(init_data), + ) + } +} + +impl BridgeInitializer for WococoToBridgeHubRococoCliBridge { + type Engine = GrandpaFinalityEngine; + + fn encode_init_bridge( + init_data: >::InitializationData, + ) -> ::Call { + relay_bridge_hub_rococo_client::runtime::Call::BridgeWococoGrandpa( + relay_bridge_hub_rococo_client::runtime::BridgeWococoGrandpaCall::initialize(init_data), + ) + } +} + impl InitBridge { /// Run the command. pub async fn run(self) -> anyhow::Result<()> { @@ -172,6 +200,10 @@ impl InitBridge { InitBridgeName::WestendToMillau => WestendToMillauCliBridge::init_bridge(self), InitBridgeName::MillauToRialtoParachain => MillauToRialtoParachainCliBridge::init_bridge(self), + InitBridgeName::RococoToBridgeHubWococo => + RococoToBridgeHubWococoCliBridge::init_bridge(self), + InitBridgeName::WococoToBridgeHubRococo => + WococoToBridgeHubRococoCliBridge::init_bridge(self), } .await } diff --git a/bridges/relays/bin-substrate/src/cli/relay_headers.rs b/bridges/relays/bin-substrate/src/cli/relay_headers.rs index df6d96f7223e7..37b805d720b5d 100644 --- a/bridges/relays/bin-substrate/src/cli/relay_headers.rs +++ b/bridges/relays/bin-substrate/src/cli/relay_headers.rs @@ -24,7 +24,9 @@ use crate::chains::{ millau_headers_to_rialto::MillauToRialtoCliBridge, millau_headers_to_rialto_parachain::MillauToRialtoParachainCliBridge, rialto_headers_to_millau::RialtoToMillauCliBridge, + rococo_headers_to_bridge_hub_wococo::RococoToBridgeHubWococoCliBridge, westend_headers_to_millau::WestendToMillauCliBridge, + wococo_headers_to_bridge_hub_rococo::WococoToBridgeHubRococoCliBridge, }; use relay_utils::metrics::{GlobalMetrics, StandaloneMetric}; use substrate_relay_helper::finality::SubstrateFinalitySyncPipeline; @@ -59,6 +61,8 @@ pub enum RelayHeadersBridge { RialtoToMillau, WestendToMillau, MillauToRialtoParachain, + RococoToBridgeHubWococo, + WococoToBridgeHubRococo, } #[async_trait] @@ -102,6 +106,8 @@ impl HeadersRelayer for MillauToRialtoCliBridge {} impl HeadersRelayer for RialtoToMillauCliBridge {} impl HeadersRelayer for WestendToMillauCliBridge {} impl HeadersRelayer for MillauToRialtoParachainCliBridge {} +impl HeadersRelayer for RococoToBridgeHubWococoCliBridge {} +impl HeadersRelayer for WococoToBridgeHubRococoCliBridge {} impl RelayHeaders { /// Run the command. @@ -112,6 +118,10 @@ impl RelayHeaders { RelayHeadersBridge::WestendToMillau => WestendToMillauCliBridge::relay_headers(self), RelayHeadersBridge::MillauToRialtoParachain => MillauToRialtoParachainCliBridge::relay_headers(self), + RelayHeadersBridge::RococoToBridgeHubWococo => + RococoToBridgeHubWococoCliBridge::relay_headers(self), + RelayHeadersBridge::WococoToBridgeHubRococo => + WococoToBridgeHubRococoCliBridge::relay_headers(self), } .await } diff --git a/bridges/relays/bin-substrate/src/cli/relay_messages.rs b/bridges/relays/bin-substrate/src/cli/relay_messages.rs index d03a1f97c3dd7..23f9bf0c113f7 100644 --- a/bridges/relays/bin-substrate/src/cli/relay_messages.rs +++ b/bridges/relays/bin-substrate/src/cli/relay_messages.rs @@ -20,6 +20,8 @@ use structopt::StructOpt; use strum::{EnumString, EnumVariantNames, VariantNames}; use crate::chains::{ + bridge_hub_rococo_messages_to_bridge_hub_wococo::BridgeHubRococoToBridgeHubWococoMessagesCliBridge, + bridge_hub_wococo_messages_to_bridge_hub_rococo::BridgeHubWococoToBridgeHubRococoMessagesCliBridge, millau_headers_to_rialto::MillauToRialtoCliBridge, millau_headers_to_rialto_parachain::MillauToRialtoParachainCliBridge, rialto_headers_to_millau::RialtoToMillauCliBridge, @@ -119,6 +121,8 @@ impl MessagesRelayer for MillauToRialtoCliBridge {} impl MessagesRelayer for RialtoToMillauCliBridge {} impl MessagesRelayer for MillauToRialtoParachainCliBridge {} impl MessagesRelayer for RialtoParachainToMillauCliBridge {} +impl MessagesRelayer for BridgeHubRococoToBridgeHubWococoMessagesCliBridge {} +impl MessagesRelayer for BridgeHubWococoToBridgeHubRococoMessagesCliBridge {} impl RelayMessages { /// Run the command. @@ -130,6 +134,10 @@ impl RelayMessages { MillauToRialtoParachainCliBridge::relay_messages(self), FullBridge::RialtoParachainToMillau => RialtoParachainToMillauCliBridge::relay_messages(self), + FullBridge::BridgeHubRococoToBridgeHubWococo => + BridgeHubRococoToBridgeHubWococoMessagesCliBridge::relay_messages(self), + FullBridge::BridgeHubWococoToBridgeHubRococo => + BridgeHubWococoToBridgeHubRococoMessagesCliBridge::relay_messages(self), } .await } diff --git a/bridges/relays/bin-substrate/src/cli/relay_parachains.rs b/bridges/relays/bin-substrate/src/cli/relay_parachains.rs index 94b856019f95d..286cecc914bc3 100644 --- a/bridges/relays/bin-substrate/src/cli/relay_parachains.rs +++ b/bridges/relays/bin-substrate/src/cli/relay_parachains.rs @@ -16,7 +16,9 @@ use crate::chains::{ rialto_parachains_to_millau::RialtoParachainToMillauCliBridge, + rococo_parachains_to_bridge_hub_wococo::BridgeHubRococoToBridgeHubWococoCliBridge, westend_parachains_to_millau::WestmintToMillauCliBridge, + wococo_parachains_to_bridge_hub_rococo::BridgeHubWococoToBridgeHubRococoCliBridge, }; use async_std::sync::Mutex; use async_trait::async_trait; @@ -29,7 +31,10 @@ use std::sync::Arc; use structopt::StructOpt; use strum::{EnumString, EnumVariantNames, VariantNames}; use substrate_relay_helper::{ - parachains::{source::ParachainsSource, target::ParachainsTarget, ParachainsPipelineAdapter}, + parachains::{ + source::ParachainsSource, target::ParachainsTarget, ParachainsPipelineAdapter, + SubstrateParachainsPipeline, + }, TransactionParams, }; @@ -56,7 +61,10 @@ pub struct RelayParachains { #[strum(serialize_all = "kebab_case")] pub enum RelayParachainsBridge { RialtoToMillau, + // TODO:check-parameter - rename to WestmintToMillau? WestendToMillau, + BridgeHubRococoToBridgeHubWococo, + BridgeHubWococoToBridgeHubRococo, } #[async_trait] @@ -92,7 +100,7 @@ where target_client, ParachainSyncParams { parachains: vec![ - ParaId(::SOURCE_PARACHAIN_PARA_ID) + ParaId(::SOURCE_PARACHAIN_PARA_ID) ], stall_timeout: std::time::Duration::from_secs(60), strategy: parachains_relay::parachains_loop::ParachainSyncStrategy::Any, @@ -109,6 +117,10 @@ impl ParachainsRelayer for RialtoParachainToMillauCliBridge {} impl ParachainsRelayer for WestmintToMillauCliBridge {} +impl ParachainsRelayer for BridgeHubRococoToBridgeHubWococoCliBridge {} + +impl ParachainsRelayer for BridgeHubWococoToBridgeHubRococoCliBridge {} + impl RelayParachains { /// Run the command. pub async fn run(self) -> anyhow::Result<()> { @@ -117,6 +129,10 @@ impl RelayParachains { RialtoParachainToMillauCliBridge::relay_headers(self), RelayParachainsBridge::WestendToMillau => WestmintToMillauCliBridge::relay_headers(self), + RelayParachainsBridge::BridgeHubRococoToBridgeHubWococo => + BridgeHubRococoToBridgeHubWococoCliBridge::relay_headers(self), + RelayParachainsBridge::BridgeHubWococoToBridgeHubRococo => + BridgeHubWococoToBridgeHubRococoCliBridge::relay_headers(self), } .await } diff --git a/bridges/relays/bin-substrate/src/cli/send_message.rs b/bridges/relays/bin-substrate/src/cli/send_message.rs index 2b314b921fa90..bb46762cee880 100644 --- a/bridges/relays/bin-substrate/src/cli/send_message.rs +++ b/bridges/relays/bin-substrate/src/cli/send_message.rs @@ -211,6 +211,12 @@ impl SendMessage { MillauToRialtoParachainCliBridge::send_message(self), FullBridge::RialtoParachainToMillau => RialtoParachainToMillauCliBridge::send_message(self), + FullBridge::BridgeHubRococoToBridgeHubWococo => unimplemented!( + "Sending message from BridgeHubRococo to BridgeHubWococo is not supported" + ), + FullBridge::BridgeHubWococoToBridgeHubRococo => unimplemented!( + "Sending message from BridgeHubWococo to BridgeHubRococo is not supported" + ), } .await } diff --git a/bridges/relays/client-bridge-hub-rococo/Cargo.toml b/bridges/relays/client-bridge-hub-rococo/Cargo.toml new file mode 100644 index 0000000000000..4a01d81e7771f --- /dev/null +++ b/bridges/relays/client-bridge-hub-rococo/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "relay-bridge-hub-rococo-client" +version = "0.1.0" +authors = ["Parity Technologies "] +edition = "2021" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.1.5", features = ["derive"] } +scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } +relay-substrate-client = { path = "../client-substrate" } + +# Bridge dependencies + +bp-bridge-hub-rococo = { path = "../../primitives/chain-bridge-hub-rococo" } +bp-bridge-hub-wococo = { path = "../../primitives/chain-bridge-hub-wococo" } +bp-header-chain = { path = "../../primitives/header-chain" } +bp-messages = { path = "../../primitives/messages" } +bp-polkadot-core = { path = "../../primitives/polkadot-core" } +bp-runtime = { path = "../../primitives/runtime" } + +bridge-runtime-common = { path = "../../bin/runtime-common" } +# Substrate Dependencies + +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } + +[dev-dependencies] +sp-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/bridges/relays/client-bridge-hub-rococo/src/lib.rs b/bridges/relays/client-bridge-hub-rococo/src/lib.rs new file mode 100644 index 0000000000000..375f11423a524 --- /dev/null +++ b/bridges/relays/client-bridge-hub-rococo/src/lib.rs @@ -0,0 +1,168 @@ +// 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 . + +//! Types used to connect to the BridgeHub-Rococo-Substrate parachain. + +use bp_messages::{MessageNonce, Weight}; +use codec::Encode; +use relay_substrate_client::{ + Chain, ChainBase, ChainWithMessages, ChainWithTransactions, Error as SubstrateError, SignParam, + UnsignedTransaction, +}; +use sp_core::Pair; +use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount}; +use std::time::Duration; + +/// Re-export runtime wrapper +pub mod runtime_wrapper; +pub use runtime_wrapper as runtime; + +/// Rococo chain definition +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct BridgeHubRococo; + +impl ChainBase for BridgeHubRococo { + type BlockNumber = bp_bridge_hub_rococo::BlockNumber; + type Hash = bp_bridge_hub_rococo::Hash; + type Hasher = bp_bridge_hub_rococo::Hashing; + type Header = bp_bridge_hub_rococo::Header; + + type AccountId = bp_bridge_hub_rococo::AccountId; + type Balance = bp_bridge_hub_rococo::Balance; + type Index = bp_bridge_hub_rococo::Nonce; + type Signature = bp_bridge_hub_rococo::Signature; + + fn max_extrinsic_size() -> u32 { + bp_bridge_hub_rococo::BridgeHubRococo::max_extrinsic_size() + } + + fn max_extrinsic_weight() -> Weight { + bp_bridge_hub_rococo::BridgeHubRococo::max_extrinsic_weight() + } +} + +impl Chain for BridgeHubRococo { + const NAME: &'static str = "BridgeHubRococo"; + const TOKEN_ID: Option<&'static str> = None; + const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = + bp_bridge_hub_rococo::BEST_FINALIZED_BRIDGE_HUB_ROCOCO_HEADER_METHOD; + const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6); + const STORAGE_PROOF_OVERHEAD: u32 = bp_bridge_hub_rococo::EXTRA_STORAGE_PROOF_SIZE; + + type SignedBlock = bp_bridge_hub_rococo::SignedBlock; + type Call = runtime::Call; +} + +impl ChainWithTransactions for BridgeHubRococo { + type AccountKeyPair = sp_core::sr25519::Pair; + type SignedTransaction = runtime::UncheckedExtrinsic; + + fn sign_transaction( + param: SignParam, + unsigned: UnsignedTransaction, + ) -> Result { + let raw_payload = SignedPayload::new( + unsigned.call, + bp_bridge_hub_rococo::SignedExtensions::new( + param.spec_version, + param.transaction_version, + unsigned.era, + param.genesis_hash, + unsigned.nonce, + unsigned.tip, + ), + )?; + + let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload)); + let signer: sp_runtime::MultiSigner = param.signer.public().into(); + let (call, extra, _) = raw_payload.deconstruct(); + + Ok(bp_bridge_hub_rococo::UncheckedExtrinsic::new_signed( + call, + signer.into_account().into(), + signature.into(), + extra, + )) + } + + fn is_signed(tx: &Self::SignedTransaction) -> bool { + tx.signature.is_some() + } + + fn is_signed_by(signer: &Self::AccountKeyPair, tx: &Self::SignedTransaction) -> bool { + tx.signature + .as_ref() + .map(|(address, _, _)| { + *address == bp_bridge_hub_rococo::Address::Id(signer.public().into()) + }) + .unwrap_or(false) + } + + fn parse_transaction(tx: Self::SignedTransaction) -> Option> { + let extra = &tx.signature.as_ref()?.2; + Some(UnsignedTransaction::new(tx.function, extra.nonce()).tip(extra.tip())) + } +} + +impl ChainWithMessages for BridgeHubRococo { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = + bp_bridge_hub_rococo::WITH_BRIDGE_HUB_ROCOCO_MESSAGES_PALLET_NAME; + + const TO_CHAIN_MESSAGE_DETAILS_METHOD: &'static str = + bp_bridge_hub_rococo::TO_BRIDGE_HUB_ROCOCO_MESSAGE_DETAILS_METHOD; + const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str = + bp_bridge_hub_rococo::FROM_BRIDGE_HUB_ROCOCO_MESSAGE_DETAILS_METHOD; + + const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_CHAIN: Weight = + bp_bridge_hub_rococo::PAY_INBOUND_DISPATCH_FEE_WEIGHT; + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = + bp_bridge_hub_rococo::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = + bp_bridge_hub_rococo::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; + + type WeightToFee = bp_bridge_hub_rococo::WeightToFee; + // TODO: fix (https://github.com/paritytech/parity-bridges-common/issues/1640) + type WeightInfo = (); +} + +#[cfg(test)] +mod tests { + use super::*; + use relay_substrate_client::TransactionEra; + + #[test] + fn parse_transaction_works() { + let unsigned = UnsignedTransaction { + call: runtime::Call::System(runtime::SystemCall::remark(b"Hello world!".to_vec())) + .into(), + nonce: 777, + tip: 888, + era: TransactionEra::immortal(), + }; + let signed_transaction = BridgeHubRococo::sign_transaction( + SignParam { + spec_version: 42, + transaction_version: 50000, + genesis_hash: [42u8; 32].into(), + signer: sp_core::sr25519::Pair::from_seed_slice(&[1u8; 32]).unwrap(), + }, + unsigned.clone(), + ) + .unwrap(); + let parsed_transaction = BridgeHubRococo::parse_transaction(signed_transaction).unwrap(); + assert_eq!(parsed_transaction, unsigned); + } +} diff --git a/bridges/relays/client-bridge-hub-rococo/src/runtime_wrapper.rs b/bridges/relays/client-bridge-hub-rococo/src/runtime_wrapper.rs new file mode 100644 index 0000000000000..c88a40073cb86 --- /dev/null +++ b/bridges/relays/client-bridge-hub-rococo/src/runtime_wrapper.rs @@ -0,0 +1,219 @@ +// 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 . + +// TODO: join with primitives do we need this here or move to the primitives? + +//! Types that are specific to the BridgeHubRococo runtime. + +use bp_polkadot_core::PolkadotLike; +use codec::{Decode, Encode}; +use scale_info::TypeInfo; + +pub use bp_bridge_hub_rococo::SS58Prefix; +use bp_messages::UnrewardedRelayersState; +use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId}; +use bp_runtime::Chain; + +// TODO:check-parameter - check SignedExtension +/// Unchecked BridgeHubRococo extrinsic. +pub type UncheckedExtrinsic = bp_bridge_hub_rococo::UncheckedExtrinsic; + +/// Rococo Runtime `Call` enum. +/// +/// The enum represents a subset of possible `Call`s we can send to Rococo chain. +/// Ideally this code would be auto-generated from metadata, because we want to +/// avoid depending directly on the ENTIRE runtime just to get the encoding of `Dispatchable`s. +/// +/// All entries here (like pretty much in the entire file) must be kept in sync with Rococo +/// `construct_runtime`, so that we maintain SCALE-compatibility. +/// +/// // TODO:check-parameter -> change bko-bridge-rococo-wococo when merged to master in cumulus +/// See: [link](https://github.com/paritytech/cumulus/blob/bko-bridge-rococo-wococo/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs) +#[allow(clippy::large_enum_variant)] +#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] +pub enum Call { + /// System pallet. + #[codec(index = 0)] + System(SystemCall), + /// Wococo bridge pallet. + #[codec(index = 41)] + BridgeWococoGrandpa(BridgeWococoGrandpaCall), + /// Rococo bridge pallet. + #[codec(index = 43)] + BridgeRococoGrandpa(BridgeRococoGrandpaCall), + + /// Wococo parachain bridge pallet. + #[codec(index = 42)] + BridgeWococoParachain(BridgeParachainCall), + /// Rococo parachain bridge pallet. + #[codec(index = 44)] + BridgeRococoParachain(BridgeParachainCall), + + /// Wococo messages bridge pallet. + #[codec(index = 46)] + BridgeWococoMessages(BridgeWococoMessagesCall), + /// Rococo messages bridge pallet. + #[codec(index = 45)] + BridgeRococoMessages(BridgeRococoMessagesCall), +} + +#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] +#[allow(non_camel_case_types)] +pub enum SystemCall { + #[codec(index = 1)] + remark(Vec), +} + +#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] +#[allow(non_camel_case_types)] +pub enum BridgeWococoGrandpaCall { + #[codec(index = 0)] + submit_finality_proof( + Box<::Header>, + bp_header_chain::justification::GrandpaJustification<::Header>, + ), + #[codec(index = 1)] + initialize(bp_header_chain::InitializationData<::Header>), +} + +#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] +#[allow(non_camel_case_types)] +pub enum BridgeRococoGrandpaCall { + #[codec(index = 0)] + submit_finality_proof( + Box<::Header>, + bp_header_chain::justification::GrandpaJustification<::Header>, + ), + #[codec(index = 1)] + initialize(bp_header_chain::InitializationData<::Header>), +} + +pub type RelayBlockHash = bp_polkadot_core::Hash; +pub type RelayBlockNumber = bp_polkadot_core::BlockNumber; + +#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] +#[allow(non_camel_case_types)] +pub enum BridgeParachainCall { + #[codec(index = 0)] + submit_parachain_heads( + (RelayBlockNumber, RelayBlockHash), + Vec<(ParaId, ParaHash)>, + ParaHeadsProof, + ), +} + +#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] +#[allow(non_camel_case_types)] +pub enum BridgeWococoMessagesCall { + #[codec(index = 5)] + receive_messages_proof( + relay_substrate_client::AccountIdOf, + bridge_runtime_common::messages::target::FromBridgedChainMessagesProof< + relay_substrate_client::HashOf, + >, + u32, + bp_messages::Weight, + ), + + #[codec(index = 6)] + receive_messages_delivery_proof( + bridge_runtime_common::messages::source::FromBridgedChainMessagesDeliveryProof< + relay_substrate_client::HashOf, + >, + UnrewardedRelayersState, + ), +} + +#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] +#[allow(non_camel_case_types)] +pub enum BridgeRococoMessagesCall { + #[codec(index = 5)] + receive_messages_proof( + relay_substrate_client::AccountIdOf, + bridge_runtime_common::messages::target::FromBridgedChainMessagesProof< + relay_substrate_client::HashOf, + >, + u32, + bp_messages::Weight, + ), + + #[codec(index = 6)] + receive_messages_delivery_proof( + bridge_runtime_common::messages::source::FromBridgedChainMessagesDeliveryProof< + relay_substrate_client::HashOf, + >, + UnrewardedRelayersState, + ), +} + +impl sp_runtime::traits::Dispatchable for Call { + type RuntimeOrigin = (); + type Config = (); + type Info = (); + type PostInfo = (); + + fn dispatch( + self, + _origin: Self::RuntimeOrigin, + ) -> sp_runtime::DispatchResultWithInfo { + unimplemented!("The Call is not expected to be dispatched.") + } +} + +#[cfg(test)] +mod tests { + use super::*; + use bp_runtime::BasicOperatingMode; + use sp_core::hexdisplay::HexDisplay; + use sp_finality_grandpa::AuthorityList; + use sp_runtime::traits::Header; + use std::str::FromStr; + + pub type RelayBlockHasher = bp_polkadot_core::Hasher; + pub type RelayBlockHeader = sp_runtime::generic::Header; + + #[test] + fn encode_decode_calls() { + let header = RelayBlockHeader::new( + 75, + bp_polkadot_core::Hash::from_str( + "0xd2c0afaab32de0cb8f7f0d89217e37c5ea302c1ffb5a7a83e10d20f12c32874d", + ) + .expect("invalid value"), + bp_polkadot_core::Hash::from_str( + "0x92b965f0656a4e0e5fc0167da2d4b5ee72b3be2c1583c4c1e5236c8c12aa141b", + ) + .expect("invalid value"), + bp_polkadot_core::Hash::from_str( + "0xae4a25acf250d72ed02c149ecc7dd3c9ee976d41a2888fc551de8064521dc01d", + ) + .expect("invalid value"), + Default::default(), + ); + let init_data = bp_header_chain::InitializationData { + header: Box::new(header), + authority_list: AuthorityList::default(), + set_id: 6, + operating_mode: BasicOperatingMode::Normal, + }; + let call = BridgeRococoGrandpaCall::initialize(init_data); + let tx = Call::BridgeRococoGrandpa(call); + + // encode call as hex string + let hex_encoded_call = format!("0x{:?}", HexDisplay::from(&Encode::encode(&tx))); + assert_eq!(hex_encoded_call, "0x2b01ae4a25acf250d72ed02c149ecc7dd3c9ee976d41a2888fc551de8064521dc01d2d0192b965f0656a4e0e5fc0167da2d4b5ee72b3be2c1583c4c1e5236c8c12aa141bd2c0afaab32de0cb8f7f0d89217e37c5ea302c1ffb5a7a83e10d20f12c32874d0000060000000000000000"); + } +} diff --git a/bridges/relays/client-bridge-hub-wococo/Cargo.toml b/bridges/relays/client-bridge-hub-wococo/Cargo.toml new file mode 100644 index 0000000000000..fa28dfde202aa --- /dev/null +++ b/bridges/relays/client-bridge-hub-wococo/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "relay-bridge-hub-wococo-client" +version = "0.1.0" +authors = ["Parity Technologies "] +edition = "2021" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.1.5", features = ["derive"] } +scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } +relay-substrate-client = { path = "../client-substrate" } + +# Bridge dependencies + +bp-bridge-hub-wococo = { path = "../../primitives/chain-bridge-hub-wococo" } +bp-messages = { path = "../../primitives/messages" } +relay-bridge-hub-rococo-client = { path = "../client-bridge-hub-rococo" } + +# Substrate Dependencies + +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/bridges/relays/client-bridge-hub-wococo/src/lib.rs b/bridges/relays/client-bridge-hub-wococo/src/lib.rs new file mode 100644 index 0000000000000..f00aa6a9fa910 --- /dev/null +++ b/bridges/relays/client-bridge-hub-wococo/src/lib.rs @@ -0,0 +1,168 @@ +// 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 . + +//! Types used to connect to the BridgeHub-Wococo-Substrate parachain. + +use bp_messages::{MessageNonce, Weight}; +use codec::Encode; +use relay_substrate_client::{ + Chain, ChainBase, ChainWithMessages, ChainWithTransactions, Error as SubstrateError, SignParam, + UnsignedTransaction, +}; +use sp_core::Pair; +use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount}; +use std::time::Duration; + +/// Re-export runtime wrapper +pub mod runtime_wrapper; +pub use runtime_wrapper as runtime; + +/// Wococo chain definition +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct BridgeHubWococo; + +impl ChainBase for BridgeHubWococo { + type BlockNumber = bp_bridge_hub_wococo::BlockNumber; + type Hash = bp_bridge_hub_wococo::Hash; + type Hasher = bp_bridge_hub_wococo::Hashing; + type Header = bp_bridge_hub_wococo::Header; + + type AccountId = bp_bridge_hub_wococo::AccountId; + type Balance = bp_bridge_hub_wococo::Balance; + type Index = bp_bridge_hub_wococo::Nonce; + type Signature = bp_bridge_hub_wococo::Signature; + + fn max_extrinsic_size() -> u32 { + bp_bridge_hub_wococo::BridgeHubWococo::max_extrinsic_size() + } + + fn max_extrinsic_weight() -> Weight { + bp_bridge_hub_wococo::BridgeHubWococo::max_extrinsic_weight() + } +} + +impl Chain for BridgeHubWococo { + const NAME: &'static str = "BridgeHubWococo"; + const TOKEN_ID: Option<&'static str> = None; + const BEST_FINALIZED_HEADER_ID_METHOD: &'static str = + bp_bridge_hub_wococo::BEST_FINALIZED_BRIDGE_HUB_WOCOCO_HEADER_METHOD; + const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6); + const STORAGE_PROOF_OVERHEAD: u32 = bp_bridge_hub_wococo::EXTRA_STORAGE_PROOF_SIZE; + + type SignedBlock = bp_bridge_hub_wococo::SignedBlock; + type Call = runtime::Call; +} + +impl ChainWithTransactions for BridgeHubWococo { + type AccountKeyPair = sp_core::sr25519::Pair; + type SignedTransaction = runtime::UncheckedExtrinsic; + + fn sign_transaction( + param: SignParam, + unsigned: UnsignedTransaction, + ) -> Result { + let raw_payload = SignedPayload::new( + unsigned.call, + bp_bridge_hub_wococo::SignedExtensions::new( + param.spec_version, + param.transaction_version, + unsigned.era, + param.genesis_hash, + unsigned.nonce, + unsigned.tip, + ), + )?; + + let signature = raw_payload.using_encoded(|payload| param.signer.sign(payload)); + let signer: sp_runtime::MultiSigner = param.signer.public().into(); + let (call, extra, _) = raw_payload.deconstruct(); + + Ok(bp_bridge_hub_wococo::UncheckedExtrinsic::new_signed( + call, + signer.into_account().into(), + signature.into(), + extra, + )) + } + + fn is_signed(tx: &Self::SignedTransaction) -> bool { + tx.signature.is_some() + } + + fn is_signed_by(signer: &Self::AccountKeyPair, tx: &Self::SignedTransaction) -> bool { + tx.signature + .as_ref() + .map(|(address, _, _)| { + *address == bp_bridge_hub_wococo::Address::Id(signer.public().into()) + }) + .unwrap_or(false) + } + + fn parse_transaction(tx: Self::SignedTransaction) -> Option> { + let extra = &tx.signature.as_ref()?.2; + Some(UnsignedTransaction::new(tx.function, extra.nonce()).tip(extra.tip())) + } +} + +impl ChainWithMessages for BridgeHubWococo { + const WITH_CHAIN_MESSAGES_PALLET_NAME: &'static str = + bp_bridge_hub_wococo::WITH_BRIDGE_HUB_WOCOCO_MESSAGES_PALLET_NAME; + + const TO_CHAIN_MESSAGE_DETAILS_METHOD: &'static str = + bp_bridge_hub_wococo::TO_BRIDGE_HUB_WOCOCO_MESSAGE_DETAILS_METHOD; + const FROM_CHAIN_MESSAGE_DETAILS_METHOD: &'static str = + bp_bridge_hub_wococo::FROM_BRIDGE_HUB_WOCOCO_MESSAGE_DETAILS_METHOD; + + const PAY_INBOUND_DISPATCH_FEE_WEIGHT_AT_CHAIN: Weight = + bp_bridge_hub_wococo::PAY_INBOUND_DISPATCH_FEE_WEIGHT; + const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = + bp_bridge_hub_wococo::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; + const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = + bp_bridge_hub_wococo::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; + + type WeightToFee = bp_bridge_hub_wococo::WeightToFee; + // TODO: fix (https://github.com/paritytech/parity-bridges-common/issues/1640) + type WeightInfo = (); +} + +#[cfg(test)] +mod tests { + use super::*; + use relay_substrate_client::TransactionEra; + + #[test] + fn parse_transaction_works() { + let unsigned = UnsignedTransaction { + call: runtime::Call::System(runtime::SystemCall::remark(b"Hello world!".to_vec())) + .into(), + nonce: 777, + tip: 888, + era: TransactionEra::immortal(), + }; + let signed_transaction = BridgeHubWococo::sign_transaction( + SignParam { + spec_version: 42, + transaction_version: 50000, + genesis_hash: [42u8; 32].into(), + signer: sp_core::sr25519::Pair::from_seed_slice(&[1u8; 32]).unwrap(), + }, + unsigned.clone(), + ) + .unwrap(); + let parsed_transaction = BridgeHubWococo::parse_transaction(signed_transaction).unwrap(); + assert_eq!(parsed_transaction, unsigned); + } +} diff --git a/bridges/relays/client-bridge-hub-wococo/src/runtime_wrapper.rs b/bridges/relays/client-bridge-hub-wococo/src/runtime_wrapper.rs new file mode 100644 index 0000000000000..8d94e7f9026a9 --- /dev/null +++ b/bridges/relays/client-bridge-hub-wococo/src/runtime_wrapper.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 . + +//! Types that are specific to the BridgeHubWococo runtime. + +pub use bp_bridge_hub_wococo::SS58Prefix; + +// We reuse everything from rococo runtime wrapper +pub type Call = relay_bridge_hub_rococo_client::runtime::Call; +pub type UncheckedExtrinsic = bp_bridge_hub_wococo::UncheckedExtrinsic; +pub type BridgeGrandpaRococoCall = relay_bridge_hub_rococo_client::runtime::BridgeRococoGrandpaCall; +pub type BridgeParachainCall = relay_bridge_hub_rococo_client::runtime::BridgeParachainCall; +pub type BridgeRococoMessagesCall = + relay_bridge_hub_rococo_client::runtime::BridgeRococoMessagesCall; +pub type SystemCall = relay_bridge_hub_rococo_client::runtime::SystemCall; diff --git a/bridges/relays/client-rococo/src/lib.rs b/bridges/relays/client-rococo/src/lib.rs index f4905d52dc7ee..5f1ff033559cd 100644 --- a/bridges/relays/client-rococo/src/lib.rs +++ b/bridges/relays/client-rococo/src/lib.rs @@ -17,7 +17,7 @@ //! Types used to connect to the Rococo-Substrate chain. use frame_support::weights::Weight; -use relay_substrate_client::{Chain, ChainBase, ChainWithBalances, ChainWithGrandpa}; +use relay_substrate_client::{Chain, ChainBase, ChainWithBalances, ChainWithGrandpa, RelayChain}; use sp_core::storage::StorageKey; use std::time::Duration; @@ -72,3 +72,8 @@ impl ChainWithBalances for Rococo { StorageKey(bp_rococo::account_info_storage_key(account_id)) } } + +impl RelayChain for Rococo { + const PARAS_PALLET_NAME: &'static str = bp_rococo::PARAS_PALLET_NAME; + const PARACHAINS_FINALITY_PALLET_NAME: &'static str = "bridgeRococoParachain"; +} diff --git a/bridges/relays/client-wococo/src/lib.rs b/bridges/relays/client-wococo/src/lib.rs index 87da6fb83679e..b4e9dd74d1985 100644 --- a/bridges/relays/client-wococo/src/lib.rs +++ b/bridges/relays/client-wococo/src/lib.rs @@ -17,7 +17,7 @@ //! Types used to connect to the Wococo-Substrate chain. use frame_support::weights::Weight; -use relay_substrate_client::{Chain, ChainBase, ChainWithBalances, ChainWithGrandpa}; +use relay_substrate_client::{Chain, ChainBase, ChainWithBalances, ChainWithGrandpa, RelayChain}; use sp_core::storage::StorageKey; use std::time::Duration; @@ -72,3 +72,8 @@ impl ChainWithBalances for Wococo { StorageKey(bp_wococo::account_info_storage_key(account_id)) } } + +impl RelayChain for Wococo { + const PARAS_PALLET_NAME: &'static str = bp_wococo::PARAS_PALLET_NAME; + const PARACHAINS_FINALITY_PALLET_NAME: &'static str = "bridgeWococoParachain"; +}