From 19943780114feacddf3d554fca160c6787495ec5 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 3 Sep 2024 00:34:14 +0200 Subject: [PATCH 01/38] Removed `pallet::getter` --- .../modules/xcm-bridge-hub/src/exporter.rs | 20 ++++++++++++------- bridges/modules/xcm-bridge-hub/src/lib.rs | 8 ++++++-- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index b42ae1e267f4..fca565eb787e 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -141,7 +141,13 @@ where ); SendError::Unroutable })?; - let bridge = Self::bridge(locations.bridge_id()).ok_or(SendError::Unroutable)?; + let Some(bridge) = Self::bridge(locations.bridge_id()) else { + log::error!( + target: LOG_TARGET, + "Missing opened bridge for requested locations: {locations:?}", + ); + return Err(SendError::Unroutable) + }; let bridge_message = MessagesPallet::::validate_message(bridge.lane_id, &blob) .map_err(|e| { @@ -466,7 +472,7 @@ mod tests { run_test(|| { let (bridge_id, _) = open_lane_and_send_regular_message(); assert!(!TestLocalXcmChannelManager::is_bridge_suspened()); - assert_eq!(XcmOverBridge::bridge(bridge_id).unwrap().state, BridgeState::Opened); + assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Opened); }); } @@ -495,11 +501,11 @@ mod tests { } assert!(!TestLocalXcmChannelManager::is_bridge_suspened()); - assert_eq!(XcmOverBridge::bridge(bridge_id).unwrap().state, BridgeState::Opened); + assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Opened); open_lane_and_send_regular_message(); assert!(TestLocalXcmChannelManager::is_bridge_suspened()); - assert_eq!(XcmOverBridge::bridge(bridge_id).unwrap().state, BridgeState::Suspended); + assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended); }); } @@ -516,7 +522,7 @@ mod tests { ); assert!(!TestLocalXcmChannelManager::is_bridge_resumed()); - assert_eq!(XcmOverBridge::bridge(bridge_id).unwrap().state, BridgeState::Suspended); + assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended); }); } @@ -530,7 +536,7 @@ mod tests { ); assert!(!TestLocalXcmChannelManager::is_bridge_resumed()); - assert_eq!(XcmOverBridge::bridge(bridge_id).unwrap().state, BridgeState::Opened); + assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Opened); }); } @@ -547,7 +553,7 @@ mod tests { ); assert!(TestLocalXcmChannelManager::is_bridge_resumed()); - assert_eq!(XcmOverBridge::bridge(bridge_id).unwrap().state, BridgeState::Opened); + assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Opened); }); } diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 02d578386a75..adbd32712078 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -585,10 +585,15 @@ pub mod pallet { }) } + /// Return bridge metadata by bridge_id + pub fn bridge(bridge_id: &BridgeId) -> Option> { + Bridges::::get(bridge_id) + } + /// Return bridge metadata by lane_id pub fn bridge_by_lane_id(lane_id: &LaneId) -> Option<(BridgeId, BridgeOf)> { LaneToBridge::::get(lane_id) - .and_then(|bridge_id| Self::bridge(bridge_id).map(|bridge| (bridge_id, bridge))) + .and_then(|bridge_id| Self::bridge(&bridge_id).map(|bridge| (bridge_id, bridge))) } } @@ -707,7 +712,6 @@ pub mod pallet { /// All registered bridges. #[pallet::storage] - #[pallet::getter(fn bridge)] pub type Bridges, I: 'static = ()> = StorageMap<_, Identity, BridgeId, BridgeOf>; /// All registered `lane_id` and `bridge_id` mappings. From 133360371e482430a998e713287c721fb694db1b Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 3 Sep 2024 00:35:10 +0200 Subject: [PATCH 02/38] xcm-executor doc nits --- polkadot/xcm/xcm-executor/src/traits/export.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/polkadot/xcm/xcm-executor/src/traits/export.rs b/polkadot/xcm/xcm-executor/src/traits/export.rs index 78aa68ce2644..b356e0da7df7 100644 --- a/polkadot/xcm/xcm-executor/src/traits/export.rs +++ b/polkadot/xcm/xcm-executor/src/traits/export.rs @@ -20,7 +20,7 @@ use xcm::latest::prelude::*; /// spoofed origin. This essentially defines the behaviour of the `ExportMessage` XCM instruction. /// /// This is quite different to `SendXcm`; `SendXcm` assumes that the local side's location will be -/// preserved to be represented as the value of the Origin register in the messages execution. +/// preserved to be represented as the value of the Origin register during the message's execution. /// /// This trait on the other hand assumes that we do not necessarily want the Origin register to /// contain the local (i.e. the caller chain's) location, since it will generally be exporting a @@ -44,8 +44,8 @@ pub trait ExportXcm { /// The `destination` and `message` must be `Some` (or else an error will be returned) and they /// may only be consumed if the `Err` is not `NotApplicable`. /// - /// If it is not a destination which can be reached with this type but possibly could by others, - /// then this *MUST* return `NotApplicable`. Any other error will cause the tuple + /// If it is not a destination that can be reached with this type, but possibly could be with + /// others, then this *MUST* return `NotApplicable`. Any other error will cause the tuple /// implementation (used to compose routing systems from different delivery agents) to exit /// early without trying alternative means of delivery. fn validate( From b24e92b1dedb64394e4b14bb17ca530d10f3047f Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 3 Sep 2024 16:34:08 +0200 Subject: [PATCH 03/38] Better log --- bridges/modules/xcm-bridge-hub/src/exporter.rs | 4 +++- bridges/testing/README.md | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index fca565eb787e..5e1051c5fac7 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -144,7 +144,9 @@ where let Some(bridge) = Self::bridge(locations.bridge_id()) else { log::error!( target: LOG_TARGET, - "Missing opened bridge for requested locations: {locations:?}", + "No opened bridge for requested bridge_origin_relative_location: {:?} and bridge_destination_universal_location: {:?}", + locations.bridge_origin_relative_location(), + locations.bridge_destination_universal_location(), ); return Err(SendError::Unroutable) }; diff --git a/bridges/testing/README.md b/bridges/testing/README.md index 158dfd73b1ad..89a07c421e3e 100644 --- a/bridges/testing/README.md +++ b/bridges/testing/README.md @@ -22,7 +22,7 @@ Prerequisites for running the tests locally: - copy the `substrate-relay` binary, built in the previous step, to `~/local_bridge_testing/bin/substrate-relay`; After that, any test can be run using the `run-test.sh` command. -Example: `./run-new-test.sh 0001-asset-transfer` +Example: `./run-test.sh 0001-asset-transfer` Hopefully, it'll show the "All tests have completed successfully" message in the end. Otherwise, it'll print paths to zombienet From af658ce0bac9c798dc32d2b5e762042628024bc0 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 3 Sep 2024 16:34:51 +0200 Subject: [PATCH 04/38] Renamed AdminOrigin to ForceOrigin --- bridges/modules/xcm-bridge-hub/src/lib.rs | 5 ++--- bridges/modules/xcm-bridge-hub/src/mock.rs | 2 +- .../bridge-hub-rococo/src/bridge_to_bulletin_config.rs | 2 +- .../bridge-hub-rococo/src/bridge_to_westend_config.rs | 2 +- .../bridge-hub-westend/src/bridge_to_rococo_config.rs | 2 +- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index adbd32712078..d10df406874c 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -213,9 +213,8 @@ pub mod pallet { type DestinationVersion: GetVersion; /// The origin that is allowed to call privileged operations on the pallet, e.g. open/close - /// bridge for location that coresponds to `Self::BridgeOriginAccountIdConverter` and - /// `Self::BridgedNetwork`. - type AdminOrigin: EnsureOrigin<::RuntimeOrigin>; + /// bridge for locations. + type ForceOrigin: EnsureOrigin<::RuntimeOrigin>; /// A set of XCM locations within local consensus system that are allowed to open /// bridges with remote destinations. type OpenBridgeOrigin: EnsureOrigin< diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index aff3526b5589..4d76b56aeb4c 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -190,7 +190,7 @@ impl pallet_xcm_bridge_hub::Config for TestRuntime { type MessageExportPrice = (); type DestinationVersion = AlwaysLatest; - type AdminOrigin = frame_system::EnsureNever<()>; + type ForceOrigin = frame_system::EnsureNever<()>; type OpenBridgeOrigin = OpenBridgeOrigin; type BridgeOriginAccountIdConverter = LocationToAccountId; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs index 00d902486c85..d426e27cea9f 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs @@ -139,7 +139,7 @@ impl pallet_xcm_bridge_hub::Config for Runtime type DestinationVersion = XcmVersionOfDestAndRemoteBridge; - type AdminOrigin = EnsureRoot; + type ForceOrigin = EnsureRoot; // Only allow calls from sibling People parachain to directly open the bridge. type OpenBridgeOrigin = EnsureXcm>; // Converter aligned with `OpenBridgeOrigin`. diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index fc52413a909f..bce05034ea99 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -137,7 +137,7 @@ impl pallet_xcm_bridge_hub::Config for Runtime type DestinationVersion = XcmVersionOfDestAndRemoteBridge; - type AdminOrigin = EnsureRoot; + type ForceOrigin = EnsureRoot; // Only allow calls from relay chains and sibling parachains to directly open the bridge. type OpenBridgeOrigin = EnsureXcm; // Converter aligned with `OpenBridgeOrigin`. diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index 2d9e8f664276..694ad4efa792 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -168,7 +168,7 @@ impl pallet_xcm_bridge_hub::Config for Runtime { type MessageExportPrice = (); type DestinationVersion = XcmVersionOfDestAndRemoteBridge; - type AdminOrigin = EnsureRoot; + type ForceOrigin = EnsureRoot; // Only allow calls from relay chains and sibling parachains to directly open the bridge. type OpenBridgeOrigin = EnsureXcm; // Converter aligned with `OpenBridgeOrigin`. From f95b114538215e6a84cc804fd931e2a7efe9989e Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 4 Sep 2024 14:56:30 +0200 Subject: [PATCH 05/38] Add optional laneId to genesis config + open AHR<>AHW for local genesis --- Cargo.lock | 1 + bridges/modules/xcm-bridge-hub/src/lib.rs | 16 ++++++--- cumulus/polkadot-parachain/Cargo.toml | 3 ++ .../src/chain_spec/bridge_hubs.rs | 35 +++++++++++++++---- 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7b3e54ff1fc2..27a3f9ba18ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14869,6 +14869,7 @@ version = "4.0.0" dependencies = [ "asset-hub-rococo-runtime", "asset-hub-westend-runtime", + "bp-messages", "bridge-hub-rococo-runtime", "bridge-hub-westend-runtime", "collectives-westend-runtime", diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index d10df406874c..f28e3e5967c9 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -726,7 +726,7 @@ pub mod pallet { /// Keep in mind that we are **NOT** reserving any amount for the bridges opened at /// genesis. We are **NOT** opening lanes, used by this bridge. It all must be done using /// other pallets genesis configuration or some other means. - pub opened_bridges: Vec<(Location, InteriorLocation)>, + pub opened_bridges: Vec<(Location, InteriorLocation, Option)>, /// Dummy marker. #[serde(skip)] pub _phantom: sp_std::marker::PhantomData<(T, I)>, @@ -738,16 +738,22 @@ pub mod pallet { T: frame_system::Config>>, { fn build(&self) { - for (bridge_origin_relative_location, bridge_destination_universal_location) in - &self.opened_bridges + for ( + bridge_origin_relative_location, + bridge_destination_universal_location, + maybe_lane_id, + ) in &self.opened_bridges { let locations = Pallet::::bridge_locations( bridge_origin_relative_location.clone(), bridge_destination_universal_location.clone().into(), ) .expect("Invalid genesis configuration"); - let lane_id = - locations.calculate_lane_id(xcm::latest::VERSION).expect("Valid locations"); + let lane_id = match maybe_lane_id { + Some(lane_id) => lane_id.clone(), + None => + locations.calculate_lane_id(xcm::latest::VERSION).expect("Valid locations"), + }; let bridge_owner_account = T::BridgeOriginAccountIdConverter::convert_location( locations.bridge_origin_relative_location(), ) diff --git a/cumulus/polkadot-parachain/Cargo.toml b/cumulus/polkadot-parachain/Cargo.toml index 383e0f158bf4..6729ad8b66eb 100644 --- a/cumulus/polkadot-parachain/Cargo.toml +++ b/cumulus/polkadot-parachain/Cargo.toml @@ -58,6 +58,9 @@ xcm = { workspace = true, default-features = true } # Cumulus cumulus-primitives-core = { workspace = true, default-features = true } +# Bridges +bp-messages = { workspace = true, default-features = true } + [build-dependencies] substrate-build-script-utils = { workspace = true, default-features = true } diff --git a/cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs b/cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs index 754bd851b40a..16bbca416579 100644 --- a/cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs +++ b/cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs @@ -15,12 +15,15 @@ // along with Cumulus. If not, see . use crate::chain_spec::{get_account_id_from_seed, get_collator_keys_from_seed}; +use bp_messages::LaneId; use cumulus_primitives_core::ParaId; use parachains_common::Balance as BridgeHubBalance; use polkadot_parachain_lib::chain_spec::GenericChainSpec; use sc_chain_spec::ChainSpec; use sp_core::sr25519; +use sp_runtime::Either; use std::str::FromStr; +use xcm::latest::prelude::*; /// Collects all supported BridgeHub configurations #[derive(Debug, PartialEq)] @@ -82,6 +85,11 @@ impl BridgeHubRuntimeType { "westend-local", ParaId::new(1002), Some("Bob".to_string()), + vec![( + Location::new(1, [Parachain(1000)]), + Junctions::from([Rococo.into(), Parachain(1000)]), + Some(LaneId::from_inner(Either::Right([0, 0, 0, 2]))), + )], ))), BridgeHubRuntimeType::WestendDevelopment => Ok(Box::new(westend::local_config( westend::BRIDGE_HUB_WESTEND_DEVELOPMENT, @@ -89,6 +97,7 @@ impl BridgeHubRuntimeType { "westend-dev", ParaId::new(1002), Some("Bob".to_string()), + vec![], ))), BridgeHubRuntimeType::Rococo => Ok(Box::new(GenericChainSpec::from_json_bytes( &include_bytes!("../../chain-specs/bridge-hub-rococo.json")[..], @@ -99,6 +108,11 @@ impl BridgeHubRuntimeType { "rococo-local", ParaId::new(1013), Some("Bob".to_string()), + vec![( + Location::new(1, [Parachain(1000)]), + Junctions::from([Westend.into(), Parachain(1000)]), + Some(LaneId::from_inner(Either::Right([0, 0, 0, 2]))), + )], |_| (), ))), BridgeHubRuntimeType::RococoDevelopment => Ok(Box::new(rococo::local_config( @@ -107,6 +121,7 @@ impl BridgeHubRuntimeType { "rococo-dev", ParaId::new(1013), Some("Bob".to_string()), + vec![], |_| (), ))), other => Err(std::format!("No default config present for {:?}", other)), @@ -129,14 +144,12 @@ fn ensure_id(id: &str) -> Result<&str, String> { /// Sub-module for Rococo setup pub mod rococo { - use super::{get_account_id_from_seed, get_collator_keys_from_seed, sr25519, ParaId}; + use super::*; use crate::chain_spec::SAFE_XCM_VERSION; use parachains_common::{AccountId, AuraId}; use polkadot_parachain_lib::chain_spec::{Extensions, GenericChainSpec}; use sc_chain_spec::ChainType; - use super::BridgeHubBalance; - pub(crate) const BRIDGE_HUB_ROCOCO: &str = "bridge-hub-rococo"; pub(crate) const BRIDGE_HUB_ROCOCO_LOCAL: &str = "bridge-hub-rococo-local"; pub(crate) const BRIDGE_HUB_ROCOCO_DEVELOPMENT: &str = "bridge-hub-rococo-dev"; @@ -149,6 +162,7 @@ pub mod rococo { relay_chain: &str, para_id: ParaId, bridges_pallet_owner_seed: Option, + opened_bridges: Vec<(Location, InteriorLocation, Option)>, modify_props: ModifyProperties, ) -> GenericChainSpec { // Rococo defaults @@ -196,6 +210,7 @@ pub mod rococo { bridges_pallet_owner_seed .as_ref() .map(|seed| get_account_id_from_seed::(seed)), + opened_bridges, )) .with_properties(properties) .build() @@ -206,6 +221,7 @@ pub mod rococo { endowed_accounts: Vec, id: ParaId, bridges_pallet_owner: Option, + opened_bridges: Vec<(Location, InteriorLocation, Option)>, ) -> serde_json::Value { serde_json::json!({ "balances": { @@ -239,6 +255,9 @@ pub mod rococo { "bridgeWestendMessages": { "owner": bridges_pallet_owner.clone(), }, + "xcmOverBridgeHubWestend": { + "openedBridges": opened_bridges, + }, "ethereumSystem": { "paraId": id, "assetHubParaId": 1000 @@ -255,14 +274,12 @@ pub mod kusama { /// Sub-module for Westend setup. pub mod westend { - use super::{get_account_id_from_seed, get_collator_keys_from_seed, sr25519, ParaId}; + use super::*; use crate::chain_spec::SAFE_XCM_VERSION; use parachains_common::{AccountId, AuraId}; use polkadot_parachain_lib::chain_spec::{Extensions, GenericChainSpec}; use sc_chain_spec::ChainType; - use super::BridgeHubBalance; - pub(crate) const BRIDGE_HUB_WESTEND: &str = "bridge-hub-westend"; pub(crate) const BRIDGE_HUB_WESTEND_LOCAL: &str = "bridge-hub-westend-local"; pub(crate) const BRIDGE_HUB_WESTEND_DEVELOPMENT: &str = "bridge-hub-westend-dev"; @@ -275,6 +292,7 @@ pub mod westend { relay_chain: &str, para_id: ParaId, bridges_pallet_owner_seed: Option, + opened_bridges: Vec<(Location, InteriorLocation, Option)>, ) -> GenericChainSpec { let mut properties = sc_chain_spec::Properties::new(); properties.insert("tokenSymbol".into(), "WND".into()); @@ -318,6 +336,7 @@ pub mod westend { bridges_pallet_owner_seed .as_ref() .map(|seed| get_account_id_from_seed::(seed)), + opened_bridges, )) .with_properties(properties) .build() @@ -328,6 +347,7 @@ pub mod westend { endowed_accounts: Vec, id: ParaId, bridges_pallet_owner: Option, + opened_bridges: Vec<(Location, InteriorLocation, Option)>, ) -> serde_json::Value { serde_json::json!({ "balances": { @@ -361,6 +381,9 @@ pub mod westend { "bridgeRococoMessages": { "owner": bridges_pallet_owner.clone(), }, + "xcmOverBridgeHubRococo": { + "openedBridges": opened_bridges, + }, "ethereumSystem": { "paraId": id, "assetHubParaId": 1000 From 8061876351aa39c616406946aa56fcc81e0acdc9 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 4 Sep 2024 16:53:45 +0200 Subject: [PATCH 06/38] Fix metrics labels --- Cargo.lock | 2 ++ bridges/primitives/messages/src/lane.rs | 8 ++++++++ .../src/messages/metrics.rs | 5 +++-- bridges/relays/messages/Cargo.toml | 4 ++++ bridges/relays/messages/src/lib.rs | 1 + .../relays/messages/src/message_lane_loop.rs | 8 ++++++-- bridges/relays/messages/src/metrics.rs | 20 ++++++++++++++++++- 7 files changed, 43 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 27a3f9ba18ec..e07b20517b99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9554,6 +9554,8 @@ dependencies = [ "parking_lot 0.12.3", "relay-utils", "sp-arithmetic 23.0.0", + "sp-core 28.0.0", + "sp-runtime 31.0.1", ] [[package]] diff --git a/bridges/primitives/messages/src/lane.rs b/bridges/primitives/messages/src/lane.rs index 6d4ca402eb34..41e38517cea9 100644 --- a/bridges/primitives/messages/src/lane.rs +++ b/bridges/primitives/messages/src/lane.rs @@ -86,6 +86,14 @@ impl LaneId { Either::Right(array) => InnerLaneId::Array(array), }) } + + /// Access the inner lane representation. + pub fn inner(&self) -> Either<&H256, &[u8; 4]> { + match &self.0 { + InnerLaneId::Array(array) => Either::Right(array), + InnerLaneId::Hash(hash) => Either::Left(hash), + } + } } impl core::fmt::Display for LaneId { diff --git a/bridges/relays/lib-substrate-relay/src/messages/metrics.rs b/bridges/relays/lib-substrate-relay/src/messages/metrics.rs index 8845f43dcb62..201fee0b1c1c 100644 --- a/bridges/relays/lib-substrate-relay/src/messages/metrics.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/metrics.rs @@ -23,6 +23,7 @@ use bp_relayers::{RewardsAccountOwner, RewardsAccountParams}; use bp_runtime::StorageDoubleMapKeyProvider; use codec::Decode; use frame_system::AccountInfo; +use messages_relay::lane_to_label; use pallet_balances::AccountData; use relay_substrate_client::{ metrics::{FloatStorageValue, FloatStorageValueMetric}, @@ -91,7 +92,7 @@ where account.id(), &RewardsAccountParams::new(*lane, BC::ID, RewardsAccountOwner::ThisChain), ), - format!("at_{}_relay_{}_reward_for_msgs_from_{}_on_lane_{}", C::NAME, account.tag(), BC::NAME, hex::encode(lane.as_ref())), + format!("at_{}_relay_{}_reward_for_msgs_from_{}_on_lane_{}", C::NAME, account.tag(), BC::NAME, lane_to_label(lane)), format!("Reward of the {} relay account at {} for delivering messages from {} on lane {:?}", account.tag(), C::NAME, BC::NAME, lane), )?.register_and_spawn(&metrics.registry)?; @@ -103,7 +104,7 @@ where account.id(), &RewardsAccountParams::new(*lane, BC::ID, RewardsAccountOwner::BridgedChain), ), - format!("at_{}_relay_{}_reward_for_msgs_to_{}_on_lane_{}", C::NAME, account.tag(), BC::NAME, hex::encode(lane.as_ref())), + format!("at_{}_relay_{}_reward_for_msgs_to_{}_on_lane_{}", C::NAME, account.tag(), BC::NAME, lane_to_label(lane)), format!("Reward of the {} relay account at {} for delivering messages confirmations from {} on lane {:?}", account.tag(), C::NAME, BC::NAME, lane), )?.register_and_spawn(&metrics.registry)?; } diff --git a/bridges/relays/messages/Cargo.toml b/bridges/relays/messages/Cargo.toml index c7a132bb3bae..7708a494d1c7 100644 --- a/bridges/relays/messages/Cargo.toml +++ b/bridges/relays/messages/Cargo.toml @@ -26,3 +26,7 @@ finality-relay = { workspace = true } relay-utils = { workspace = true } sp-arithmetic = { workspace = true, default-features = true } +sp-runtime = { workspace = true } + +[dev-dependencies] +sp-core = { workspace = true } \ No newline at end of file diff --git a/bridges/relays/messages/src/lib.rs b/bridges/relays/messages/src/lib.rs index 78a3237ba4fe..2b834d424361 100644 --- a/bridges/relays/messages/src/lib.rs +++ b/bridges/relays/messages/src/lib.rs @@ -38,3 +38,4 @@ mod message_race_strategy; pub use message_race_delivery::relay_messages_range; pub use message_race_receiving::relay_messages_delivery_confirmation; +pub use metrics::lane_to_label; diff --git a/bridges/relays/messages/src/message_lane_loop.rs b/bridges/relays/messages/src/message_lane_loop.rs index 995499092c3e..ccad334dcb56 100644 --- a/bridges/relays/messages/src/message_lane_loop.rs +++ b/bridges/relays/messages/src/message_lane_loop.rs @@ -39,7 +39,7 @@ use crate::{ message_lane::{MessageLane, SourceHeaderIdOf, TargetHeaderIdOf}, message_race_delivery::run as run_message_delivery_race, message_race_receiving::run as run_message_receiving_race, - metrics::MessageLaneLoopMetrics, + metrics::{lane_to_label, MessageLaneLoopMetrics}, }; /// Message lane loop configuration params. @@ -276,7 +276,7 @@ pub struct ClientsState { /// Return prefix that will be used by default to expose Prometheus metrics of the finality proofs /// sync loop. pub fn metrics_prefix(lane: &LaneId) -> String { - format!("{}_to_{}_MessageLane_{:?}", P::SOURCE_NAME, P::TARGET_NAME, lane) + format!("{}_to_{}_MessageLane_{}", P::SOURCE_NAME, P::TARGET_NAME, lane_to_label(lane)) } /// Run message lane service loop. @@ -1281,5 +1281,9 @@ pub(crate) mod tests { &LaneId::new(1, 2) ))) .is_ok()); + assert!(MessageLaneLoopMetrics::new(Some(&metrics_prefix::( + &LaneId::from_inner(sp_runtime::Either::Right([0, 0, 0, 1])) + ))) + .is_ok()); } } diff --git a/bridges/relays/messages/src/metrics.rs b/bridges/relays/messages/src/metrics.rs index 69d80d178de8..d1ae1bb989dc 100644 --- a/bridges/relays/messages/src/metrics.rs +++ b/bridges/relays/messages/src/metrics.rs @@ -21,11 +21,12 @@ use crate::{ message_lane_loop::{SourceClientState, TargetClientState}, }; -use bp_messages::MessageNonce; +use bp_messages::{LaneId, MessageNonce}; use finality_relay::SyncLoopMetrics; use relay_utils::metrics::{ metric_name, register, GaugeVec, Metric, Opts, PrometheusError, Registry, U64, }; +use sp_runtime::Either; /// Message lane relay metrics. /// @@ -146,3 +147,20 @@ impl Metric for MessageLaneLoopMetrics { Ok(()) } } + +/// Unified label for `LaneId`. +pub fn lane_to_label(lane: &LaneId) -> String { + match lane.inner() { + Either::Left(hash) => format!("{:?}", hash), + Either::Right(array) => hex::encode(array), + } +} + +#[test] +fn lane_to_label_works() { + assert_eq!( + "0x0101010101010101010101010101010101010101010101010101010101010101", + lane_to_label(&LaneId::from_inner(Either::Left(sp_core::H256::from([1u8; 32])))), + ); + assert_eq!("00000001", lane_to_label(&LaneId::from_inner(Either::Right([0, 0, 0, 1])))); +} From bcad8a225490308013970e851694c48dcfc3cffe Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 4 Sep 2024 23:13:22 +0200 Subject: [PATCH 07/38] Fix `LaneId` encode/decode for backwards compatibility --- bridges/modules/messages/src/lib.rs | 13 +- .../messages/src/tests/pallet_tests.rs | 7 +- bridges/modules/xcm-bridge-hub/src/lib.rs | 22 +-- bridges/primitives/messages/src/lane.rs | 152 ++++++++++++------ bridges/primitives/messages/src/lib.rs | 6 +- .../primitives/messages/src/storage_keys.rs | 6 +- bridges/primitives/relayers/src/lib.rs | 8 +- 7 files changed, 138 insertions(+), 76 deletions(-) diff --git a/bridges/modules/messages/src/lib.rs b/bridges/modules/messages/src/lib.rs index b7fe1c7dbb19..4ef2818f271c 100644 --- a/bridges/modules/messages/src/lib.rs +++ b/bridges/modules/messages/src/lib.rs @@ -97,7 +97,7 @@ pub const LOG_TARGET: &str = "runtime::bridge-messages"; #[frame_support::pallet] pub mod pallet { use super::*; - use bp_messages::{ReceivedMessages, ReceptionResult}; + use bp_messages::{LaneIdBytes, ReceivedMessages, ReceptionResult}; use bp_runtime::RangeInclusiveExt; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; @@ -387,7 +387,7 @@ pub mod pallet { // emit 'delivered' event let received_range = confirmed_messages.begin..=confirmed_messages.end; Self::deposit_event(Event::MessagesDelivered { - lane_id, + lane_id: lane_id.into(), messages: confirmed_messages, }); @@ -441,7 +441,7 @@ pub mod pallet { /// Message has been accepted and is waiting to be delivered. MessageAccepted { /// Lane, which has accepted the message. - lane_id: LaneId, + lane_id: LaneIdBytes, /// Nonce of accepted message. nonce: MessageNonce, }, @@ -453,7 +453,7 @@ pub mod pallet { /// Messages in the inclusive range have been delivered to the bridged chain. MessagesDelivered { /// Lane for which the delivery has been confirmed. - lane_id: LaneId, + lane_id: LaneIdBytes, /// Delivered messages. messages: DeliveredMessages, }, @@ -703,7 +703,10 @@ where message_len, ); - Pallet::::deposit_event(Event::MessageAccepted { lane_id: args.lane_id, nonce }); + Pallet::::deposit_event(Event::MessageAccepted { + lane_id: args.lane_id.into(), + nonce, + }); SendMessageArtifacts { nonce, enqueued_messages } } diff --git a/bridges/modules/messages/src/tests/pallet_tests.rs b/bridges/modules/messages/src/tests/pallet_tests.rs index ceb1744c0665..d2391cd1775d 100644 --- a/bridges/modules/messages/src/tests/pallet_tests.rs +++ b/bridges/modules/messages/src/tests/pallet_tests.rs @@ -67,7 +67,10 @@ fn send_regular_message(lane_id: LaneId) { System::::events(), vec![EventRecord { phase: Phase::Initialization, - event: TestEvent::Messages(Event::MessageAccepted { lane_id, nonce: message_nonce }), + event: TestEvent::Messages(Event::MessageAccepted { + lane_id: lane_id.into(), + nonce: message_nonce + }), topics: vec![], }], ); @@ -105,7 +108,7 @@ fn receive_messages_delivery_proof() { vec![EventRecord { phase: Phase::Initialization, event: TestEvent::Messages(Event::MessagesDelivered { - lane_id: test_lane_id(), + lane_id: test_lane_id().into(), messages: DeliveredMessages::new(1), }), topics: vec![], diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index f28e3e5967c9..02e6753c3755 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -143,7 +143,7 @@ #![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -use bp_messages::{LaneId, LaneState, MessageNonce}; +use bp_messages::{LaneId, LaneIdBytes, LaneState, MessageNonce}; use bp_runtime::{AccountIdOf, BalanceOf, RangeInclusiveExt}; pub use bp_xcm_bridge_hub::{Bridge, BridgeId, BridgeState}; use bp_xcm_bridge_hub::{BridgeLocations, BridgeLocationsError, LocalXcmChannelManager}; @@ -391,7 +391,7 @@ pub mod pallet { // deposit the `ClosingBridge` event Self::deposit_event(Event::::ClosingBridge { bridge_id: *locations.bridge_id(), - lane_id: bridge.lane_id, + lane_id: bridge.lane_id.into(), pruned_messages, enqueued_messages, }); @@ -438,7 +438,7 @@ pub mod pallet { // deposit the `BridgePruned` event Self::deposit_event(Event::::BridgePruned { bridge_id: *locations.bridge_id(), - lane_id: bridge.lane_id, + lane_id: bridge.lane_id.into(), bridge_deposit: released_deposit, pruned_messages, }); @@ -541,7 +541,7 @@ pub mod pallet { remote_endpoint: Box::new( locations.bridge_destination_universal_location().clone(), ), - lane_id, + lane_id: lane_id.into(), }); Ok(()) @@ -805,14 +805,14 @@ pub mod pallet { /// Universal location of remote bridge endpoint. remote_endpoint: Box, /// Lane identifier. - lane_id: LaneId, + lane_id: LaneIdBytes, }, /// Bridge is going to be closed, but not yet fully pruned from the runtime storage. ClosingBridge { /// Bridge identifier. bridge_id: BridgeId, /// Lane identifier. - lane_id: LaneId, + lane_id: LaneIdBytes, /// Number of pruned messages during the close call. pruned_messages: MessageNonce, /// Number of enqueued messages that need to be pruned in follow up calls. @@ -824,7 +824,7 @@ pub mod pallet { /// Bridge identifier. bridge_id: BridgeId, /// Lane identifier. - lane_id: LaneId, + lane_id: LaneIdBytes, /// Amount of deposit released. bridge_deposit: BalanceOf>, /// Number of pruned messages during the close call. @@ -1221,7 +1221,7 @@ mod tests { remote_endpoint: Box::new( locations.bridge_destination_universal_location().clone() ), - lane_id + lane_id: lane_id.into() }), topics: vec![], }), @@ -1364,7 +1364,7 @@ mod tests { phase: Phase::Initialization, event: RuntimeEvent::XcmOverBridge(Event::ClosingBridge { bridge_id: *locations.bridge_id(), - lane_id: bridge.lane_id, + lane_id: bridge.lane_id.into(), pruned_messages: 16, enqueued_messages: 16, }), @@ -1412,7 +1412,7 @@ mod tests { phase: Phase::Initialization, event: RuntimeEvent::XcmOverBridge(Event::ClosingBridge { bridge_id: *locations.bridge_id(), - lane_id: bridge.lane_id, + lane_id: bridge.lane_id.into(), pruned_messages: 8, enqueued_messages: 8, }), @@ -1453,7 +1453,7 @@ mod tests { phase: Phase::Initialization, event: RuntimeEvent::XcmOverBridge(Event::BridgePruned { bridge_id: *locations.bridge_id(), - lane_id: bridge.lane_id, + lane_id: bridge.lane_id.into(), bridge_deposit: expected_deposit, pruned_messages: 8, }), diff --git a/bridges/primitives/messages/src/lane.rs b/bridges/primitives/messages/src/lane.rs index 41e38517cea9..9f3b6d687bfd 100644 --- a/bridges/primitives/messages/src/lane.rs +++ b/bridges/primitives/messages/src/lane.rs @@ -108,53 +108,66 @@ impl core::fmt::Debug for LaneId { } } -impl AsRef<[u8]> for LaneId { - fn as_ref(&self) -> &[u8] { - self.0.as_ref() - } -} - impl TypeId for LaneId { const TYPE_ID: [u8; 4] = *b"blan"; } -#[derive( - Clone, Copy, Eq, Ord, PartialOrd, PartialEq, TypeInfo, MaxEncodedLen, Serialize, Deserialize, -)] +#[derive(Clone, Copy, Eq, Ord, PartialOrd, PartialEq, TypeInfo, Serialize, Deserialize)] enum InnerLaneId { - /// Old format (for backwards compatibility). - Array([u8; 4]), /// New format 32-byte hash generated by `blake2_256`. Hash(H256), + /// Old format (for backwards compatibility). + Array([u8; 4]), +} + +// Prefix used to differentiate `LaneId` for backward compatibility. +// Hex value: `48615368` +const INNER_LANE_ID_AS_HASH_PREFIX: &[u8; 4] = b"HaSh"; + +impl MaxEncodedLen for InnerLaneId { + fn max_encoded_len() -> usize { + INNER_LANE_ID_AS_HASH_PREFIX + .encoded_size() + .saturating_add(H256::max_encoded_len()) + } } impl Encode for InnerLaneId { fn encode(&self) -> sp_std::vec::Vec { match self { - InnerLaneId::Array(array) => array.encode(), - InnerLaneId::Hash(hash) => hash.encode(), + InnerLaneId::Hash(hash) => { + // prefix new hash, so we can easily decode + (INNER_LANE_ID_AS_HASH_PREFIX, hash).encode() + }, + InnerLaneId::Array(array) => { + // encode backwards compatible + array.encode() + }, } } } impl Decode for InnerLaneId { fn decode(input: &mut I) -> Result { - // check backwards compatibly first - if input.remaining_len() == Ok(Some(4)) { - let array: [u8; 4] = Decode::decode(input)?; - return Ok(InnerLaneId::Array(array)) + // read 4 bytes first + let prefix_or_array: [u8; 4] = Decode::decode(input)?; + + // if matches prefix, it is a new format + if prefix_or_array.eq(INNER_LANE_ID_AS_HASH_PREFIX) { + // now read more 32 bytes for hash + return H256::decode(input).map(InnerLaneId::Hash) } - // else check new format - H256::decode(input).map(InnerLaneId::Hash) + // return prefix `[u8; 4]` for backwards compatibly as a best effort + Ok(InnerLaneId::Array(prefix_or_array)) } } impl core::fmt::Display for InnerLaneId { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { match self { - InnerLaneId::Array(array) => write!(f, "Array({:?})", array), - InnerLaneId::Hash(hash) => write!(f, "Hash({:?})", hash), + InnerLaneId::Array(array) => write!(f, "InnerLaneId::Array({:?})", array), + InnerLaneId::Hash(hash) => write!(f, "InnerLaneId::Hash({:?})", hash), } } } @@ -168,11 +181,14 @@ impl core::fmt::Debug for InnerLaneId { } } -impl AsRef<[u8]> for InnerLaneId { - fn as_ref(&self) -> &[u8] { - match self { - InnerLaneId::Array(array) => array.as_ref(), - InnerLaneId::Hash(hash) => hash.as_ref(), +/// The representation of `LaneId`'s inner bytes. +#[derive(Clone, Encode, Decode, RuntimeDebug, PartialEq, Eq, TypeInfo)] +pub struct LaneIdBytes(sp_std::vec::Vec); +impl From for LaneIdBytes { + fn from(lane_id: LaneId) -> Self { + match lane_id.inner() { + Either::Left(hash) => Self(hash.as_bytes().to_vec()), + Either::Right(array) => Self(array.to_vec()), } } } @@ -202,6 +218,7 @@ impl LaneState { #[cfg(test)] mod tests { use super::*; + use crate::MessageNonce; #[test] fn lane_id_debug_format_matches_inner_hash_format() { @@ -216,35 +233,74 @@ mod tests { } #[test] - fn lane_id_as_ref_works() { + fn encode_decode_works() { + // simple encode/decode - new format + let lane_id = LaneId(InnerLaneId::Hash(H256::from([1u8; 32]))); + let encoded_lane_id = lane_id.encode(); + let decoded_lane_id = LaneId::decode(&mut &encoded_lane_id[..]).expect("decodable"); + assert_eq!(lane_id, decoded_lane_id); assert_eq!( - "0101010101010101010101010101010101010101010101010101010101010101", - hex::encode(LaneId(InnerLaneId::Hash(H256::from([1u8; 32]))).as_ref()), + "486153680101010101010101010101010101010101010101010101010101010101010101", + hex::encode(encoded_lane_id) ); - assert_eq!("00000001", hex::encode(LaneId(InnerLaneId::Array([0, 0, 0, 1])).as_ref()),); + + // simple encode/decode - old format + let lane_id = LaneId(InnerLaneId::Array([0, 0, 0, 1])); + let encoded_lane_id = lane_id.encode(); + let decoded_lane_id = LaneId::decode(&mut &encoded_lane_id[..]).expect("decodable"); + assert_eq!(lane_id, decoded_lane_id); + assert_eq!("00000001", hex::encode(encoded_lane_id)); + + // decode sample + let bytes = vec![0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]; + let (lane, nonce_start, nonce_end): (LaneId, MessageNonce, MessageNonce) = + Decode::decode(&mut &bytes[..]).unwrap(); + assert_eq!(lane, LaneId(InnerLaneId::Array([0, 0, 0, 2]))); + assert_eq!(nonce_start, 1); + assert_eq!(nonce_end, 1); + + // run encode/decode for `LaneId` with different positions + let test_data = vec![ + (LaneId(InnerLaneId::Array([0, 0, 0, 1])), 1088_u64, 9185_u64), + (LaneId(InnerLaneId::Hash(H256::from([1u8; 32]))), 1088_u64, 9185_u64), + ]; + for (expected_lane, expected_nonce_start, expected_nonce_end) in test_data { + // decode: LaneId,Nonce,Nonce + let bytes = (expected_lane, expected_nonce_start, expected_nonce_end).encode(); + let (lane, nonce_start, nonce_end): (LaneId, MessageNonce, MessageNonce) = + Decode::decode(&mut &bytes[..]).unwrap(); + assert_eq!(lane, expected_lane); + assert_eq!(nonce_start, expected_nonce_start); + assert_eq!(nonce_end, expected_nonce_end); + + // decode: Nonce,LaneId,Nonce + let bytes = (expected_nonce_start, expected_lane, expected_nonce_end).encode(); + let (nonce_start, lane, nonce_end): (MessageNonce, LaneId, MessageNonce) = + Decode::decode(&mut &bytes[..]).unwrap(); + assert_eq!(lane, expected_lane); + assert_eq!(nonce_start, expected_nonce_start); + assert_eq!(nonce_end, expected_nonce_end); + + // decode: Nonce,Nonce,LaneId + let bytes = (expected_nonce_start, expected_nonce_end, expected_lane).encode(); + let (nonce_start, nonce_end, lane): (MessageNonce, MessageNonce, LaneId) = + Decode::decode(&mut &bytes[..]).unwrap(); + assert_eq!(lane, expected_lane); + assert_eq!(nonce_start, expected_nonce_start); + assert_eq!(nonce_end, expected_nonce_end); + } } #[test] - fn lane_id_encode_decode_works() { - let test_encode_decode = |expected_hex, lane_id: LaneId| { - let enc = lane_id.encode(); - let decoded_lane_id = LaneId::decode(&mut &enc[..]).expect("decodable"); - assert_eq!(lane_id, decoded_lane_id); - - assert_eq!(expected_hex, hex::encode(lane_id.as_ref()),); - assert_eq!(expected_hex, hex::encode(decoded_lane_id.as_ref()),); - - let hex_bytes = hex::decode(expected_hex).expect("valid hex"); - let hex_decoded_lane_id = LaneId::decode(&mut &hex_bytes[..]).expect("decodable"); - assert_eq!(hex_decoded_lane_id, lane_id); - assert_eq!(hex_decoded_lane_id, decoded_lane_id); - }; - - test_encode_decode( + fn lane_id_bytes_works() { + let lane_id_bytes: LaneIdBytes = LaneId(InnerLaneId::Array([0, 0, 0, 1])).into(); + assert_eq!("00000001", hex::encode(lane_id_bytes.0)); + + let lane_id_bytes: LaneIdBytes = LaneId(InnerLaneId::Hash(H256::from([1u8; 32]))).into(); + assert_eq!( "0101010101010101010101010101010101010101010101010101010101010101", - LaneId(InnerLaneId::Hash(H256::from([1u8; 32]))), + hex::encode(lane_id_bytes.0) ); - test_encode_decode("00000001", LaneId(InnerLaneId::Array([0, 0, 0, 1]))); } #[test] diff --git a/bridges/primitives/messages/src/lib.rs b/bridges/primitives/messages/src/lib.rs index 7eb0c5629395..f8812c6a1952 100644 --- a/bridges/primitives/messages/src/lib.rs +++ b/bridges/primitives/messages/src/lib.rs @@ -38,7 +38,7 @@ pub use call_info::{ BaseMessagesProofInfo, BridgeMessagesCall, BridgeMessagesCallOf, MessagesCallInfo, ReceiveMessagesDeliveryProofInfo, ReceiveMessagesProofInfo, UnrewardedRelayerOccupation, }; -pub use lane::{LaneId, LaneState}; +pub use lane::{LaneId, LaneIdBytes, LaneState}; mod call_info; mod lane; @@ -339,7 +339,7 @@ pub struct UnrewardedRelayer { #[derive(Clone, Encode, Decode, RuntimeDebug, PartialEq, Eq, TypeInfo)] pub struct ReceivedMessages { /// Id of the lane which is receiving messages. - pub lane: LaneId, + pub lane: LaneIdBytes, /// Result of messages which we tried to dispatch pub receive_results: Vec<(MessageNonce, ReceptionResult)>, } @@ -350,7 +350,7 @@ impl ReceivedMessages { lane: LaneId, receive_results: Vec<(MessageNonce, ReceptionResult)>, ) -> Self { - ReceivedMessages { lane, receive_results } + ReceivedMessages { lane: lane.into(), receive_results } } /// Push `result` of the `message` delivery onto `receive_results` vector. diff --git a/bridges/primitives/messages/src/storage_keys.rs b/bridges/primitives/messages/src/storage_keys.rs index ff62dab078e7..77bdb1bbe567 100644 --- a/bridges/primitives/messages/src/storage_keys.rs +++ b/bridges/primitives/messages/src/storage_keys.rs @@ -95,7 +95,7 @@ mod tests { let storage_key = message_key("BridgeMessages", &LaneId::new(1, 2), 42).0; assert_eq!( storage_key, - hex!("dd16c784ebd3390a9bc0357c7511ed018a395e6242c6813b196ca31ed0547ea70e9bdb8f50c68d12f06eabb57759ee5eb1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dcf87f9793be208e5ea02a00000000000000").to_vec(), + hex!("dd16c784ebd3390a9bc0357c7511ed018a395e6242c6813b196ca31ed0547ea7d69c6fd1fe3b4dd5f5d67ce7c585813a48615368b1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dcf87f9793be208e5ea02a00000000000000").to_vec(), "Unexpected storage key: {}", hex::encode(&storage_key), ); @@ -118,7 +118,7 @@ mod tests { let storage_key = outbound_lane_data_key("BridgeMessages", &LaneId::new(1, 2)).0; assert_eq!( storage_key, - hex!("dd16c784ebd3390a9bc0357c7511ed0196c246acb9b55077390e3ca723a0ca1fd3bef8b00df8ca7b01813b5e2741950db1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dcf87f9793be208e5ea0").to_vec(), + hex!("dd16c784ebd3390a9bc0357c7511ed0196c246acb9b55077390e3ca723a0ca1f35a17fa33e857f05a3b8d3b8b7f0eeb548615368b1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dcf87f9793be208e5ea0").to_vec(), "Unexpected storage key: {}", hex::encode(&storage_key), ); @@ -142,7 +142,7 @@ mod tests { let storage_key = inbound_lane_data_key("BridgeMessages", &LaneId::new(1, 2)).0; assert_eq!( storage_key, - hex!("dd16c784ebd3390a9bc0357c7511ed01e5f83cf83f2127eb47afdc35d6e43fabd3bef8b00df8ca7b01813b5e2741950db1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dcf87f9793be208e5ea0").to_vec(), + hex!("dd16c784ebd3390a9bc0357c7511ed01e5f83cf83f2127eb47afdc35d6e43fab35a17fa33e857f05a3b8d3b8b7f0eeb548615368b1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dcf87f9793be208e5ea0").to_vec(), "Unexpected storage key: {}", hex::encode(&storage_key), ); diff --git a/bridges/primitives/relayers/src/lib.rs b/bridges/primitives/relayers/src/lib.rs index 1e63c89ecd70..e23de3074943 100644 --- a/bridges/primitives/relayers/src/lib.rs +++ b/bridges/primitives/relayers/src/lib.rs @@ -174,7 +174,7 @@ mod tests { *b"test", RewardsAccountOwner::ThisChain )), - hex_literal::hex!("627261700074657374b1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dc") + hex_literal::hex!("62726170007465737448615368b1d3dccd8b3c3a012afe265f3e3c4432129b8a") .into(), ); @@ -184,7 +184,7 @@ mod tests { *b"test", RewardsAccountOwner::ThisChain )), - hex_literal::hex!("627261700074657374a43e8951aa302c133beb5f85821a21645f07b487270ef3") + hex_literal::hex!("62726170007465737448615368a43e8951aa302c133beb5f85821a21645f07b4") .into(), ); } @@ -197,7 +197,7 @@ mod tests { *b"test", RewardsAccountOwner::ThisChain )), - hex_literal::hex!("627261700074657374b1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dc") + hex_literal::hex!("62726170007465737448615368b1d3dccd8b3c3a012afe265f3e3c4432129b8a") .into(), ); @@ -207,7 +207,7 @@ mod tests { *b"test", RewardsAccountOwner::BridgedChain )), - hex_literal::hex!("627261700174657374b1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dc") + hex_literal::hex!("62726170017465737448615368b1d3dccd8b3c3a012afe265f3e3c4432129b8a") .into(), ); } From df91ef250b9472ad77bbc44d9e75f2401dd8976c Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Fri, 6 Sep 2024 12:49:25 +0200 Subject: [PATCH 08/38] Lets see BridgeId in the logs --- bridges/primitives/xcm-bridge-hub/src/lib.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/bridges/primitives/xcm-bridge-hub/src/lib.rs b/bridges/primitives/xcm-bridge-hub/src/lib.rs index 44a90a57d4fb..19c8362ee171 100644 --- a/bridges/primitives/xcm-bridge-hub/src/lib.rs +++ b/bridges/primitives/xcm-bridge-hub/src/lib.rs @@ -63,7 +63,6 @@ pub type XcmAsPlainPayload = sp_std::vec::Vec; Ord, PartialOrd, PartialEq, - RuntimeDebug, TypeInfo, MaxEncodedLen, Serialize, @@ -90,6 +89,12 @@ impl BridgeId { } } +impl core::fmt::Debug for BridgeId { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + core::fmt::Debug::fmt(&self.0, f) + } +} + /// Local XCM channel manager. pub trait LocalXcmChannelManager { /// Error that may be returned when suspending/resuming the bridge. From e9fc6eb9951f7d53e2db6050fb0ff100791f11b2 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Fri, 6 Sep 2024 13:43:41 +0200 Subject: [PATCH 09/38] Make `LaneId` generic for backwards compatibility Introduce LegacyLaneId --- bridges/primitives/messages/src/call_info.rs | 38 +-- bridges/primitives/messages/src/lane.rs | 297 ++++++++---------- bridges/primitives/messages/src/lib.rs | 18 +- .../primitives/messages/src/source_chain.rs | 20 +- .../primitives/messages/src/storage_keys.rs | 41 +-- .../primitives/messages/src/target_chain.rs | 44 ++- 6 files changed, 210 insertions(+), 248 deletions(-) diff --git a/bridges/primitives/messages/src/call_info.rs b/bridges/primitives/messages/src/call_info.rs index c8f06ed8cb7c..65f1a9fb783f 100644 --- a/bridges/primitives/messages/src/call_info.rs +++ b/bridges/primitives/messages/src/call_info.rs @@ -16,22 +16,14 @@ //! Defines structures related to calls of the `pallet-bridge-messages` pallet. -use crate::{source_chain, target_chain, LaneId, MessageNonce, UnrewardedRelayersState}; +use crate::{MessageNonce, UnrewardedRelayersState}; -use bp_runtime::{AccountIdOf, HashOf}; use codec::{Decode, Encode}; use frame_support::weights::Weight; use scale_info::TypeInfo; use sp_core::RuntimeDebug; use sp_std::ops::RangeInclusive; -/// The `BridgeMessagesCall` used to bridge with a given chain. -pub type BridgeMessagesCallOf = BridgeMessagesCall< - AccountIdOf, - target_chain::FromBridgedChainMessagesProof>, - source_chain::FromBridgedChainMessagesDeliveryProof>, ->; - /// A minimized version of `pallet-bridge-messages::Call` that can be used without a runtime. #[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] #[allow(non_camel_case_types)] @@ -60,7 +52,7 @@ pub enum BridgeMessagesCall { /// Generic info about a messages delivery/confirmation proof. #[derive(PartialEq, RuntimeDebug)] -pub struct BaseMessagesProofInfo { +pub struct BaseMessagesProofInfo { /// Message lane, used by the call. pub lane_id: LaneId, /// Nonces of messages, included in the call. @@ -75,7 +67,7 @@ pub struct BaseMessagesProofInfo { pub best_stored_nonce: MessageNonce, } -impl BaseMessagesProofInfo { +impl BaseMessagesProofInfo { /// Returns true if `bundled_range` continues the `0..=best_stored_nonce` range. pub fn appends_to_stored_nonce(&self) -> bool { Some(*self.bundled_range.start()) == self.best_stored_nonce.checked_add(1) @@ -94,14 +86,14 @@ pub struct UnrewardedRelayerOccupation { /// Info about a `ReceiveMessagesProof` call which tries to update a single lane. #[derive(PartialEq, RuntimeDebug)] -pub struct ReceiveMessagesProofInfo { +pub struct ReceiveMessagesProofInfo { /// Base messages proof info - pub base: BaseMessagesProofInfo, + pub base: BaseMessagesProofInfo, /// State of unrewarded relayers vector. pub unrewarded_relayers: UnrewardedRelayerOccupation, } -impl ReceiveMessagesProofInfo { +impl ReceiveMessagesProofInfo { /// Returns true if: /// /// - either inbound lane is ready to accept bundled messages; @@ -134,9 +126,9 @@ impl ReceiveMessagesProofInfo { /// Info about a `ReceiveMessagesDeliveryProof` call which tries to update a single lane. #[derive(PartialEq, RuntimeDebug)] -pub struct ReceiveMessagesDeliveryProofInfo(pub BaseMessagesProofInfo); +pub struct ReceiveMessagesDeliveryProofInfo(pub BaseMessagesProofInfo); -impl ReceiveMessagesDeliveryProofInfo { +impl ReceiveMessagesDeliveryProofInfo { /// Returns true if outbound lane is ready to accept confirmations of bundled messages. pub fn is_obsolete(&self) -> bool { self.0.bundled_range.is_empty() || !self.0.appends_to_stored_nonce() @@ -146,19 +138,19 @@ impl ReceiveMessagesDeliveryProofInfo { /// Info about a `ReceiveMessagesProof` or a `ReceiveMessagesDeliveryProof` call /// which tries to update a single lane. #[derive(PartialEq, RuntimeDebug)] -pub enum MessagesCallInfo { +pub enum MessagesCallInfo { /// Messages delivery call info. - ReceiveMessagesProof(ReceiveMessagesProofInfo), + ReceiveMessagesProof(ReceiveMessagesProofInfo), /// Messages delivery confirmation call info. - ReceiveMessagesDeliveryProof(ReceiveMessagesDeliveryProofInfo), + ReceiveMessagesDeliveryProof(ReceiveMessagesDeliveryProofInfo), } -impl MessagesCallInfo { +impl MessagesCallInfo { /// Returns lane, used by the call. - pub fn lane_id(&self) -> LaneId { + pub fn lane_id(&self) -> &LaneId { match *self { - Self::ReceiveMessagesProof(ref info) => info.base.lane_id, - Self::ReceiveMessagesDeliveryProof(ref info) => info.0.lane_id, + Self::ReceiveMessagesProof(ref info) => &info.base.lane_id, + Self::ReceiveMessagesDeliveryProof(ref info) => &info.0.lane_id, } } diff --git a/bridges/primitives/messages/src/lane.rs b/bridges/primitives/messages/src/lane.rs index 9f3b6d687bfd..9ced85b3fa32 100644 --- a/bridges/primitives/messages/src/lane.rs +++ b/bridges/primitives/messages/src/lane.rs @@ -16,12 +16,66 @@ //! Primitives of messages module, that represents lane id. -use codec::{Decode, Encode, Error as CodecError, Input, MaxEncodedLen}; -use frame_support::sp_runtime::Either; +use codec::{Codec, Decode, Encode, EncodeLike, MaxEncodedLen}; use scale_info::TypeInfo; -use serde::{Deserialize, Serialize}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; use sp_core::{RuntimeDebug, TypeId, H256}; use sp_io::hashing::blake2_256; +use sp_std::fmt::Debug; + +/// Trait representing a generic `LaneId` type. +pub trait LaneIdType: + Clone + + Copy + + Codec + + EncodeLike + + Debug + + PartialEq + + Eq + + TypeInfo + + MaxEncodedLen + + Serialize + + DeserializeOwned +{ + /// Creates a new `LaneId` type. + fn new(endpoint1: E, endpoint2: E) -> Self; +} + +/// Bridge lane identifier (legacy). +/// +/// Note: For backwards compatibility reasons, we also handle the older format `[u8; 4]`. +#[derive( + Clone, + Copy, + Decode, + Default, + Encode, + Eq, + Ord, + PartialOrd, + PartialEq, + TypeInfo, + MaxEncodedLen, + Serialize, + Deserialize, +)] +pub struct LegacyLaneId(pub [u8; 4]); + +impl core::fmt::Debug for LegacyLaneId { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + self.0.fmt(fmt) + } +} + +impl AsRef<[u8]> for LegacyLaneId { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + +impl TypeId for LegacyLaneId { + const TYPE_ID: [u8; 4] = *b"blan"; +} /// Bridge lane identifier. /// @@ -41,8 +95,6 @@ use sp_io::hashing::blake2_256; /// (endpoint2, VALUES_SEPARATOR, endpoint1) /// }.using_encoded(blake2_256); /// ``` -/// -/// Note: For backwards compatibility reasons, we also handle the older format `[u8; 4]`. #[derive( Clone, Copy, @@ -57,139 +109,54 @@ use sp_io::hashing::blake2_256; Serialize, Deserialize, )] -pub struct LaneId(InnerLaneId); - -impl LaneId { - /// Create lane identifier from two locations. - pub fn new(endpoint1: T, endpoint2: T) -> Self { - const VALUES_SEPARATOR: [u8; 31] = *b"bridges-lane-id-value-separator"; - - LaneId(InnerLaneId::Hash( - if endpoint1 < endpoint2 { - (endpoint1, VALUES_SEPARATOR, endpoint2) - } else { - (endpoint2, VALUES_SEPARATOR, endpoint1) - } - .using_encoded(blake2_256) - .into(), - )) - } +pub struct HashedLaneId(H256); +impl HashedLaneId { /// Create lane identifier from given hash. /// /// There's no `From` implementation for the `LaneId`, because using this conversion /// in a wrong way (i.e. computing hash of endpoints manually) may lead to issues. So we /// want the call to be explicit. - pub const fn from_inner(inner: Either) -> Self { - LaneId(match inner { - Either::Left(hash) => InnerLaneId::Hash(hash), - Either::Right(array) => InnerLaneId::Array(array), - }) + pub const fn from_inner(inner: H256) -> Self { + Self(inner) } /// Access the inner lane representation. - pub fn inner(&self) -> Either<&H256, &[u8; 4]> { - match &self.0 { - InnerLaneId::Array(array) => Either::Right(array), - InnerLaneId::Hash(hash) => Either::Left(hash), - } + pub fn inner(&self) -> &H256 { + &self.0 } } -impl core::fmt::Display for LaneId { +impl core::fmt::Display for HashedLaneId { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { core::fmt::Display::fmt(&self.0, f) } } -impl core::fmt::Debug for LaneId { +impl core::fmt::Debug for HashedLaneId { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { core::fmt::Debug::fmt(&self.0, f) } } -impl TypeId for LaneId { - const TYPE_ID: [u8; 4] = *b"blan"; -} - -#[derive(Clone, Copy, Eq, Ord, PartialOrd, PartialEq, TypeInfo, Serialize, Deserialize)] -enum InnerLaneId { - /// New format 32-byte hash generated by `blake2_256`. - Hash(H256), - /// Old format (for backwards compatibility). - Array([u8; 4]), -} - -// Prefix used to differentiate `LaneId` for backward compatibility. -// Hex value: `48615368` -const INNER_LANE_ID_AS_HASH_PREFIX: &[u8; 4] = b"HaSh"; - -impl MaxEncodedLen for InnerLaneId { - fn max_encoded_len() -> usize { - INNER_LANE_ID_AS_HASH_PREFIX - .encoded_size() - .saturating_add(H256::max_encoded_len()) - } -} - -impl Encode for InnerLaneId { - fn encode(&self) -> sp_std::vec::Vec { - match self { - InnerLaneId::Hash(hash) => { - // prefix new hash, so we can easily decode - (INNER_LANE_ID_AS_HASH_PREFIX, hash).encode() - }, - InnerLaneId::Array(array) => { - // encode backwards compatible - array.encode() - }, - } - } -} - -impl Decode for InnerLaneId { - fn decode(input: &mut I) -> Result { - // read 4 bytes first - let prefix_or_array: [u8; 4] = Decode::decode(input)?; - - // if matches prefix, it is a new format - if prefix_or_array.eq(INNER_LANE_ID_AS_HASH_PREFIX) { - // now read more 32 bytes for hash - return H256::decode(input).map(InnerLaneId::Hash) - } - - // return prefix `[u8; 4]` for backwards compatibly as a best effort - Ok(InnerLaneId::Array(prefix_or_array)) - } -} - -impl core::fmt::Display for InnerLaneId { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - match self { - InnerLaneId::Array(array) => write!(f, "InnerLaneId::Array({:?})", array), - InnerLaneId::Hash(hash) => write!(f, "InnerLaneId::Hash({:?})", hash), - } - } +impl TypeId for HashedLaneId { + const TYPE_ID: [u8; 4] = *b"hlan"; } -impl core::fmt::Debug for InnerLaneId { - fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { - match self { - InnerLaneId::Array(array) => array.fmt(fmt), - InnerLaneId::Hash(hash) => hash.fmt(fmt), - } - } -} +impl LaneIdType for HashedLaneId { + /// Create lane identifier from two locations. + fn new(endpoint1: T, endpoint2: T) -> Self { + const VALUES_SEPARATOR: [u8; 31] = *b"bridges-lane-id-value-separator"; -/// The representation of `LaneId`'s inner bytes. -#[derive(Clone, Encode, Decode, RuntimeDebug, PartialEq, Eq, TypeInfo)] -pub struct LaneIdBytes(sp_std::vec::Vec); -impl From for LaneIdBytes { - fn from(lane_id: LaneId) -> Self { - match lane_id.inner() { - Either::Left(hash) => Self(hash.as_bytes().to_vec()), - Either::Right(array) => Self(array.to_vec()), - } + HashedLaneId( + if endpoint1 < endpoint2 { + (endpoint1, VALUES_SEPARATOR, endpoint2) + } else { + (endpoint2, VALUES_SEPARATOR, endpoint1) + } + .using_encoded(blake2_256) + .into(), + ) } } @@ -223,98 +190,84 @@ mod tests { #[test] fn lane_id_debug_format_matches_inner_hash_format() { assert_eq!( - format!("{:?}", LaneId(InnerLaneId::Hash(H256::from([1u8; 32])))), + format!("{:?}", HashedLaneId(H256::from([1u8; 32]))), format!("{:?}", H256::from([1u8; 32])), ); - assert_eq!( - format!("{:?}", LaneId(InnerLaneId::Array([0, 0, 0, 1]))), - format!("{:?}", [0, 0, 0, 1]), - ); + assert_eq!(format!("{:?}", LegacyLaneId([0, 0, 0, 1])), format!("{:?}", [0, 0, 0, 1]),); } #[test] - fn encode_decode_works() { + fn hashed_encode_decode_works() { // simple encode/decode - new format - let lane_id = LaneId(InnerLaneId::Hash(H256::from([1u8; 32]))); + let lane_id = HashedLaneId(H256::from([1u8; 32])); let encoded_lane_id = lane_id.encode(); - let decoded_lane_id = LaneId::decode(&mut &encoded_lane_id[..]).expect("decodable"); + let decoded_lane_id = HashedLaneId::decode(&mut &encoded_lane_id[..]).expect("decodable"); assert_eq!(lane_id, decoded_lane_id); assert_eq!( - "486153680101010101010101010101010101010101010101010101010101010101010101", + "0101010101010101010101010101010101010101010101010101010101010101", hex::encode(encoded_lane_id) ); + } + #[test] + fn legacy_encode_decode_works() { // simple encode/decode - old format - let lane_id = LaneId(InnerLaneId::Array([0, 0, 0, 1])); + let lane_id = LegacyLaneId([0, 0, 0, 1]); let encoded_lane_id = lane_id.encode(); - let decoded_lane_id = LaneId::decode(&mut &encoded_lane_id[..]).expect("decodable"); + let decoded_lane_id = LegacyLaneId::decode(&mut &encoded_lane_id[..]).expect("decodable"); assert_eq!(lane_id, decoded_lane_id); assert_eq!("00000001", hex::encode(encoded_lane_id)); // decode sample let bytes = vec![0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]; - let (lane, nonce_start, nonce_end): (LaneId, MessageNonce, MessageNonce) = + let (lane, nonce_start, nonce_end): (LegacyLaneId, MessageNonce, MessageNonce) = Decode::decode(&mut &bytes[..]).unwrap(); - assert_eq!(lane, LaneId(InnerLaneId::Array([0, 0, 0, 2]))); + assert_eq!(lane, LegacyLaneId([0, 0, 0, 2])); assert_eq!(nonce_start, 1); assert_eq!(nonce_end, 1); // run encode/decode for `LaneId` with different positions - let test_data = vec![ - (LaneId(InnerLaneId::Array([0, 0, 0, 1])), 1088_u64, 9185_u64), - (LaneId(InnerLaneId::Hash(H256::from([1u8; 32]))), 1088_u64, 9185_u64), - ]; - for (expected_lane, expected_nonce_start, expected_nonce_end) in test_data { - // decode: LaneId,Nonce,Nonce - let bytes = (expected_lane, expected_nonce_start, expected_nonce_end).encode(); - let (lane, nonce_start, nonce_end): (LaneId, MessageNonce, MessageNonce) = - Decode::decode(&mut &bytes[..]).unwrap(); - assert_eq!(lane, expected_lane); - assert_eq!(nonce_start, expected_nonce_start); - assert_eq!(nonce_end, expected_nonce_end); - - // decode: Nonce,LaneId,Nonce - let bytes = (expected_nonce_start, expected_lane, expected_nonce_end).encode(); - let (nonce_start, lane, nonce_end): (MessageNonce, LaneId, MessageNonce) = - Decode::decode(&mut &bytes[..]).unwrap(); - assert_eq!(lane, expected_lane); - assert_eq!(nonce_start, expected_nonce_start); - assert_eq!(nonce_end, expected_nonce_end); - - // decode: Nonce,Nonce,LaneId - let bytes = (expected_nonce_start, expected_nonce_end, expected_lane).encode(); - let (nonce_start, nonce_end, lane): (MessageNonce, MessageNonce, LaneId) = - Decode::decode(&mut &bytes[..]).unwrap(); - assert_eq!(lane, expected_lane); - assert_eq!(nonce_start, expected_nonce_start); - assert_eq!(nonce_end, expected_nonce_end); - } - } + let expected_lane = LegacyLaneId([0, 0, 0, 1]); + let expected_nonce_start = 1088_u64; + let expected_nonce_end = 9185_u64; - #[test] - fn lane_id_bytes_works() { - let lane_id_bytes: LaneIdBytes = LaneId(InnerLaneId::Array([0, 0, 0, 1])).into(); - assert_eq!("00000001", hex::encode(lane_id_bytes.0)); + // decode: LaneId,Nonce,Nonce + let bytes = (expected_lane, expected_nonce_start, expected_nonce_end).encode(); + let (lane, nonce_start, nonce_end): (LegacyLaneId, MessageNonce, MessageNonce) = + Decode::decode(&mut &bytes[..]).unwrap(); + assert_eq!(lane, expected_lane); + assert_eq!(nonce_start, expected_nonce_start); + assert_eq!(nonce_end, expected_nonce_end); - let lane_id_bytes: LaneIdBytes = LaneId(InnerLaneId::Hash(H256::from([1u8; 32]))).into(); - assert_eq!( - "0101010101010101010101010101010101010101010101010101010101010101", - hex::encode(lane_id_bytes.0) - ); + // decode: Nonce,LaneId,Nonce + let bytes = (expected_nonce_start, expected_lane, expected_nonce_end).encode(); + let (nonce_start, lane, nonce_end): (MessageNonce, LegacyLaneId, MessageNonce) = + Decode::decode(&mut &bytes[..]).unwrap(); + assert_eq!(lane, expected_lane); + assert_eq!(nonce_start, expected_nonce_start); + assert_eq!(nonce_end, expected_nonce_end); + + // decode: Nonce,Nonce,LaneId + let bytes = (expected_nonce_start, expected_nonce_end, expected_lane).encode(); + let (nonce_start, nonce_end, lane): (MessageNonce, MessageNonce, LegacyLaneId) = + Decode::decode(&mut &bytes[..]).unwrap(); + assert_eq!(lane, expected_lane); + assert_eq!(nonce_start, expected_nonce_start); + assert_eq!(nonce_end, expected_nonce_end); } #[test] - fn lane_id_is_generated_using_ordered_endpoints() { - assert_eq!(LaneId::new(1, 2), LaneId::new(2, 1)); + fn hashed_lane_id_is_generated_using_ordered_endpoints() { + assert_eq!(HashedLaneId::new(1, 2), HashedLaneId::new(2, 1)); } #[test] - fn lane_id_is_different_for_different_endpoints() { - assert_ne!(LaneId::new(1, 2), LaneId::new(1, 3)); + fn hashed_lane_id_is_different_for_different_endpoints() { + assert_ne!(HashedLaneId::new(1, 2), HashedLaneId::new(1, 3)); } #[test] - fn lane_id_is_different_even_if_arguments_has_partial_matching_encoding() { + fn hashed_lane_id_is_different_even_if_arguments_has_partial_matching_encoding() { /// Some artificial type that generates the same encoding for different values /// concatenations. I.e. the encoding for `(Either::Two(1, 2), Either::Two(3, 4))` /// is the same as encoding of `(Either::Three(1, 2, 3), Either::One(4))`. @@ -338,8 +291,8 @@ mod tests { } assert_ne!( - LaneId::new(Either::Two(1, 2), Either::Two(3, 4)), - LaneId::new(Either::Three(1, 2, 3), Either::One(4)), + HashedLaneId::new(Either::Two(1, 2), Either::Two(3, 4)), + HashedLaneId::new(Either::Three(1, 2, 3), Either::One(4)), ); } } diff --git a/bridges/primitives/messages/src/lib.rs b/bridges/primitives/messages/src/lib.rs index f8812c6a1952..a6cc7c88f8a9 100644 --- a/bridges/primitives/messages/src/lib.rs +++ b/bridges/primitives/messages/src/lib.rs @@ -35,10 +35,10 @@ use sp_core::RuntimeDebug; use sp_std::{collections::vec_deque::VecDeque, ops::RangeInclusive, prelude::*}; pub use call_info::{ - BaseMessagesProofInfo, BridgeMessagesCall, BridgeMessagesCallOf, MessagesCallInfo, - ReceiveMessagesDeliveryProofInfo, ReceiveMessagesProofInfo, UnrewardedRelayerOccupation, + BaseMessagesProofInfo, BridgeMessagesCall, MessagesCallInfo, ReceiveMessagesDeliveryProofInfo, + ReceiveMessagesProofInfo, UnrewardedRelayerOccupation, }; -pub use lane::{LaneId, LaneIdBytes, LaneState}; +pub use lane::{HashedLaneId, LaneIdType, LaneState, LegacyLaneId}; mod call_info; mod lane; @@ -181,7 +181,7 @@ pub type MessagePayload = Vec; /// Message key (unique message identifier) as it is stored in the storage. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -pub struct MessageKey { +pub struct MessageKey { /// ID of the message lane. pub lane_id: LaneId, /// Message nonce. @@ -190,9 +190,9 @@ pub struct MessageKey { /// Message as it is stored in the storage. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] -pub struct Message { +pub struct Message { /// Message key. - pub key: MessageKey, + pub key: MessageKey, /// Message payload. pub payload: MessagePayload, } @@ -337,14 +337,14 @@ pub struct UnrewardedRelayer { /// Received messages with their dispatch result. #[derive(Clone, Encode, Decode, RuntimeDebug, PartialEq, Eq, TypeInfo)] -pub struct ReceivedMessages { +pub struct ReceivedMessages { /// Id of the lane which is receiving messages. - pub lane: LaneIdBytes, + pub lane: LaneId, /// Result of messages which we tried to dispatch pub receive_results: Vec<(MessageNonce, ReceptionResult)>, } -impl ReceivedMessages { +impl ReceivedMessages { /// Creates new `ReceivedMessages` structure from given results. pub fn new( lane: LaneId, diff --git a/bridges/primitives/messages/src/source_chain.rs b/bridges/primitives/messages/src/source_chain.rs index 64f015bdb822..1d4a513035c7 100644 --- a/bridges/primitives/messages/src/source_chain.rs +++ b/bridges/primitives/messages/src/source_chain.rs @@ -16,7 +16,7 @@ //! Primitives of messages module, that are used on the source chain. -use crate::{LaneId, MessageNonce, UnrewardedRelayer}; +use crate::{MessageNonce, UnrewardedRelayer}; use bp_runtime::{raw_storage_proof_size, RawStorageProof, Size}; use codec::{Decode, Encode}; @@ -39,7 +39,7 @@ use sp_std::{ /// /// - lane id. #[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebug, TypeInfo)] -pub struct FromBridgedChainMessagesDeliveryProof { +pub struct FromBridgedChainMessagesDeliveryProof { /// Hash of the bridge header the proof is for. pub bridged_header_hash: BridgedHeaderHash, /// Storage trie proof generated for [`Self::bridged_header_hash`]. @@ -48,7 +48,9 @@ pub struct FromBridgedChainMessagesDeliveryProof { pub lane: LaneId, } -impl Size for FromBridgedChainMessagesDeliveryProof { +impl Size + for FromBridgedChainMessagesDeliveryProof +{ fn size(&self) -> u32 { use frame_support::sp_runtime::SaturatedConversion; raw_storage_proof_size(&self.storage_proof).saturated_into() @@ -60,7 +62,7 @@ pub type RelayersRewards = BTreeMap; /// Manages payments that are happening at the source chain during delivery confirmation /// transaction. -pub trait DeliveryConfirmationPayments { +pub trait DeliveryConfirmationPayments { /// Error type. type Error: Debug + Into<&'static str>; @@ -78,7 +80,7 @@ pub trait DeliveryConfirmationPayments { ) -> MessageNonce; } -impl DeliveryConfirmationPayments for () { +impl DeliveryConfirmationPayments for () { type Error = &'static str; fn pay_reward( @@ -94,14 +96,14 @@ impl DeliveryConfirmationPayments for () { /// Callback that is called at the source chain (bridge hub) when we get delivery confirmation /// for new messages. -pub trait OnMessagesDelivered { +pub trait OnMessagesDelivered { /// New messages delivery has been confirmed. /// /// The only argument of the function is the number of yet undelivered messages fn on_messages_delivered(lane: LaneId, enqueued_messages: MessageNonce); } -impl OnMessagesDelivered for () { +impl OnMessagesDelivered for () { fn on_messages_delivered(_lane: LaneId, _enqueued_messages: MessageNonce) {} } @@ -115,7 +117,7 @@ pub struct SendMessageArtifacts { } /// Messages bridge API to be used from other pallets. -pub trait MessagesBridge { +pub trait MessagesBridge { /// Error type. type Error: Debug; @@ -141,7 +143,7 @@ pub trait MessagesBridge { /// where outbound messages are forbidden. pub struct ForbidOutboundMessages; -impl DeliveryConfirmationPayments for ForbidOutboundMessages { +impl DeliveryConfirmationPayments for ForbidOutboundMessages { type Error = &'static str; fn pay_reward( diff --git a/bridges/primitives/messages/src/storage_keys.rs b/bridges/primitives/messages/src/storage_keys.rs index 77bdb1bbe567..0db0690447ff 100644 --- a/bridges/primitives/messages/src/storage_keys.rs +++ b/bridges/primitives/messages/src/storage_keys.rs @@ -25,7 +25,7 @@ pub const OUTBOUND_LANES_MAP_NAME: &str = "OutboundLanes"; /// Name of the `InboundLanes` storage map. pub const INBOUND_LANES_MAP_NAME: &str = "InboundLanes"; -use crate::{LaneId, MessageKey, MessageNonce}; +use crate::{MessageKey, MessageNonce}; use codec::Encode; use frame_support::Blake2_128Concat; @@ -43,16 +43,20 @@ pub fn operating_mode_key(pallet_prefix: &str) -> StorageKey { } /// Storage key of the outbound message in the runtime storage. -pub fn message_key(pallet_prefix: &str, lane: &LaneId, nonce: MessageNonce) -> StorageKey { +pub fn message_key( + pallet_prefix: &str, + lane: LaneId, + nonce: MessageNonce, +) -> StorageKey { bp_runtime::storage_map_final_key::( pallet_prefix, OUTBOUND_MESSAGES_MAP_NAME, - &MessageKey { lane_id: *lane, nonce }.encode(), + &MessageKey { lane_id: lane, nonce }.encode(), ) } /// Storage key of the outbound message lane state in the runtime storage. -pub fn outbound_lane_data_key(pallet_prefix: &str, lane: &LaneId) -> StorageKey { +pub fn outbound_lane_data_key(pallet_prefix: &str, lane: &LaneId) -> StorageKey { bp_runtime::storage_map_final_key::( pallet_prefix, OUTBOUND_LANES_MAP_NAME, @@ -61,7 +65,7 @@ pub fn outbound_lane_data_key(pallet_prefix: &str, lane: &LaneId) -> StorageKey } /// Storage key of the inbound message lane state in the runtime storage. -pub fn inbound_lane_data_key(pallet_prefix: &str, lane: &LaneId) -> StorageKey { +pub fn inbound_lane_data_key(pallet_prefix: &str, lane: &LaneId) -> StorageKey { bp_runtime::storage_map_final_key::( pallet_prefix, INBOUND_LANES_MAP_NAME, @@ -72,7 +76,10 @@ pub fn inbound_lane_data_key(pallet_prefix: &str, lane: &LaneId) -> StorageKey { #[cfg(test)] mod tests { use super::*; - use frame_support::sp_runtime::Either; + use crate::{ + lane::{HashedLaneId, LegacyLaneId}, + LaneIdType, + }; use hex_literal::hex; #[test] @@ -92,17 +99,16 @@ mod tests { fn storage_message_key_computed_properly() { // If this test fails, then something has been changed in module storage that is breaking // all previously crafted messages proofs. - let storage_key = message_key("BridgeMessages", &LaneId::new(1, 2), 42).0; + let storage_key = message_key("BridgeMessages", &HashedLaneId::new(1, 2), 42).0; assert_eq!( storage_key, - hex!("dd16c784ebd3390a9bc0357c7511ed018a395e6242c6813b196ca31ed0547ea7d69c6fd1fe3b4dd5f5d67ce7c585813a48615368b1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dcf87f9793be208e5ea02a00000000000000").to_vec(), + hex!("dd16c784ebd3390a9bc0357c7511ed018a395e6242c6813b196ca31ed0547ea70e9bdb8f50c68d12f06eabb57759ee5eb1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dcf87f9793be208e5ea02a00000000000000").to_vec(), "Unexpected storage key: {}", hex::encode(&storage_key), ); // check backwards compatibility - let storage_key = - message_key("BridgeMessages", &LaneId::from_inner(Either::Right(*b"test")), 42).0; + let storage_key = message_key("BridgeMessages", &LegacyLaneId(*b"test"), 42).0; assert_eq!( storage_key, hex!("dd16c784ebd3390a9bc0357c7511ed018a395e6242c6813b196ca31ed0547ea79446af0e09063bd4a7874aef8a997cec746573742a00000000000000").to_vec(), @@ -115,18 +121,16 @@ mod tests { fn outbound_lane_data_key_computed_properly() { // If this test fails, then something has been changed in module storage that is breaking // all previously crafted outbound lane state proofs. - let storage_key = outbound_lane_data_key("BridgeMessages", &LaneId::new(1, 2)).0; + let storage_key = outbound_lane_data_key("BridgeMessages", &HashedLaneId::new(1, 2)).0; assert_eq!( storage_key, - hex!("dd16c784ebd3390a9bc0357c7511ed0196c246acb9b55077390e3ca723a0ca1f35a17fa33e857f05a3b8d3b8b7f0eeb548615368b1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dcf87f9793be208e5ea0").to_vec(), + hex!("dd16c784ebd3390a9bc0357c7511ed0196c246acb9b55077390e3ca723a0ca1fd3bef8b00df8ca7b01813b5e2741950db1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dcf87f9793be208e5ea0").to_vec(), "Unexpected storage key: {}", hex::encode(&storage_key), ); // check backwards compatibility - let storage_key = - outbound_lane_data_key("BridgeMessages", &LaneId::from_inner(Either::Right(*b"test"))) - .0; + let storage_key = outbound_lane_data_key("BridgeMessages", &LegacyLaneId(*b"test")).0; assert_eq!( storage_key, hex!("dd16c784ebd3390a9bc0357c7511ed0196c246acb9b55077390e3ca723a0ca1f44a8995dd50b6657a037a7839304535b74657374").to_vec(), @@ -139,17 +143,16 @@ mod tests { fn inbound_lane_data_key_computed_properly() { // If this test fails, then something has been changed in module storage that is breaking // all previously crafted inbound lane state proofs. - let storage_key = inbound_lane_data_key("BridgeMessages", &LaneId::new(1, 2)).0; + let storage_key = inbound_lane_data_key("BridgeMessages", &HashedLaneId::new(1, 2)).0; assert_eq!( storage_key, - hex!("dd16c784ebd3390a9bc0357c7511ed01e5f83cf83f2127eb47afdc35d6e43fab35a17fa33e857f05a3b8d3b8b7f0eeb548615368b1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dcf87f9793be208e5ea0").to_vec(), + hex!("dd16c784ebd3390a9bc0357c7511ed01e5f83cf83f2127eb47afdc35d6e43fabd3bef8b00df8ca7b01813b5e2741950db1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dcf87f9793be208e5ea0").to_vec(), "Unexpected storage key: {}", hex::encode(&storage_key), ); // check backwards compatibility - let storage_key = - inbound_lane_data_key("BridgeMessages", &LaneId::from_inner(Either::Right(*b"test"))).0; + let storage_key = inbound_lane_data_key("BridgeMessages", &LegacyLaneId(*b"test")).0; assert_eq!( storage_key, hex!("dd16c784ebd3390a9bc0357c7511ed01e5f83cf83f2127eb47afdc35d6e43fab44a8995dd50b6657a037a7839304535b74657374").to_vec(), diff --git a/bridges/primitives/messages/src/target_chain.rs b/bridges/primitives/messages/src/target_chain.rs index 67868ff7c7cd..cf07a400933a 100644 --- a/bridges/primitives/messages/src/target_chain.rs +++ b/bridges/primitives/messages/src/target_chain.rs @@ -16,7 +16,7 @@ //! Primitives of messages module, that are used on the target chain. -use crate::{LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData}; +use crate::{Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData}; use bp_runtime::{messages::MessageDispatchResult, raw_storage_proof_size, RawStorageProof, Size}; use codec::{Decode, Encode, Error as CodecError}; @@ -38,20 +38,20 @@ use sp_std::{fmt::Debug, marker::PhantomData, prelude::*}; /// /// - nonces (inclusive range) of messages which are included in this proof. #[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebug, TypeInfo)] -pub struct FromBridgedChainMessagesProof { +pub struct FromBridgedChainMessagesProof { /// Hash of the finalized bridged header the proof is for. pub bridged_header_hash: BridgedHeaderHash, /// A storage trie proof of messages being delivered. pub storage_proof: RawStorageProof, /// Messages in this proof are sent over this lane. - pub lane: LaneId, + pub lane: Lane, /// Nonce of the first message being delivered. pub nonces_start: MessageNonce, /// Nonce of the last message being delivered. pub nonces_end: MessageNonce, } -impl Size for FromBridgedChainMessagesProof { +impl Size for FromBridgedChainMessagesProof { fn size(&self) -> u32 { use frame_support::sp_runtime::SaturatedConversion; raw_storage_proof_size(&self.storage_proof).saturated_into() @@ -59,7 +59,7 @@ impl Size for FromBridgedChainMessagesProof = (LaneId, ProvedLaneMessages); +pub type ProvedMessages = (LaneId, ProvedLaneMessages); /// Proved messages from single lane of the source chain. #[derive(RuntimeDebug, Encode, Decode, Clone, PartialEq, Eq, TypeInfo)] @@ -79,9 +79,9 @@ pub struct DispatchMessageData { /// Message with decoded dispatch payload. #[derive(RuntimeDebug)] -pub struct DispatchMessage { +pub struct DispatchMessage { /// Message key. - pub key: MessageKey, + pub key: MessageKey, /// Message data with decoded dispatch payload. pub data: DispatchMessageData, } @@ -96,6 +96,9 @@ pub trait MessageDispatch { /// Fine-grained result of single message dispatch (for better diagnostic purposes) type DispatchLevelResult: Clone + sp_std::fmt::Debug + Eq; + /// Lane identifier type. + type LaneId: Encode; + /// Returns `true` if dispatcher is ready to accept additional messages. The `false` should /// be treated as a hint by both dispatcher and its consumers - i.e. dispatcher shall not /// simply drop messages if it returns `false`. The consumer may still call the `dispatch` @@ -103,21 +106,23 @@ pub trait MessageDispatch { /// /// We check it in the messages delivery transaction prologue. So if it becomes `false` /// after some portion of messages is already dispatched, it doesn't fail the whole transaction. - fn is_active(lane: LaneId) -> bool; + fn is_active(lane: Self::LaneId) -> bool; /// Estimate dispatch weight. /// /// This function must return correct upper bound of dispatch weight. The return value /// of this function is expected to match return value of the corresponding /// `FromInboundLaneApi::message_details().dispatch_weight` call. - fn dispatch_weight(message: &mut DispatchMessage) -> Weight; + fn dispatch_weight( + message: &mut DispatchMessage, + ) -> Weight; /// Called when inbound message is received. /// /// It is up to the implementers of this trait to determine whether the message /// is invalid (i.e. improperly encoded, has too large weight, ...) or not. fn dispatch( - message: DispatchMessage, + message: DispatchMessage, ) -> MessageDispatchResult; } @@ -146,8 +151,10 @@ impl Default for ProvedLaneMessages { } } -impl From for DispatchMessage { - fn from(message: Message) -> Self { +impl From> + for DispatchMessage +{ + fn from(message: Message) -> Self { DispatchMessage { key: message.key, data: message.payload.into() } } } @@ -173,22 +180,27 @@ impl DeliveryPayments for () { /// Structure that may be used in place of `MessageDispatch` on chains, /// where inbound messages are forbidden. -pub struct ForbidInboundMessages(PhantomData); +pub struct ForbidInboundMessages(PhantomData<(DispatchPayload, LaneId)>); -impl MessageDispatch for ForbidInboundMessages { +impl MessageDispatch + for ForbidInboundMessages +{ type DispatchPayload = DispatchPayload; type DispatchLevelResult = (); + type LaneId = LaneId; fn is_active(_: LaneId) -> bool { false } - fn dispatch_weight(_message: &mut DispatchMessage) -> Weight { + fn dispatch_weight( + _message: &mut DispatchMessage, + ) -> Weight { Weight::MAX } fn dispatch( - _: DispatchMessage, + _: DispatchMessage, ) -> MessageDispatchResult { MessageDispatchResult { unspent_weight: Weight::zero(), dispatch_level_result: () } } From 9c55ad79a0fe2642e43de306b1139a23930a7180 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Sun, 8 Sep 2024 22:50:04 +0200 Subject: [PATCH 10/38] Generic `LaneId` for `pallet_bridge_messages` --- bridges/modules/messages/src/benchmarking.rs | 18 ++-- bridges/modules/messages/src/call_ext.rs | 30 +++--- bridges/modules/messages/src/inbound_lane.rs | 10 +- bridges/modules/messages/src/lanes_manager.rs | 32 ++++--- bridges/modules/messages/src/lib.rs | 73 ++++++++------ bridges/modules/messages/src/outbound_lane.rs | 6 +- bridges/modules/messages/src/proofs.rs | 43 ++++----- .../messages/src/tests/messages_generation.rs | 16 +++- bridges/modules/messages/src/tests/mock.rs | 94 ++++++++++--------- .../messages/src/tests/pallet_tests.rs | 18 ++-- bridges/primitives/xcm-bridge-hub/src/lib.rs | 16 ++-- 11 files changed, 197 insertions(+), 159 deletions(-) diff --git a/bridges/modules/messages/src/benchmarking.rs b/bridges/modules/messages/src/benchmarking.rs index b3a4447fb021..7c723e567315 100644 --- a/bridges/modules/messages/src/benchmarking.rs +++ b/bridges/modules/messages/src/benchmarking.rs @@ -26,7 +26,7 @@ use crate::{ use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, target_chain::FromBridgedChainMessagesProof, ChainWithMessages, DeliveredMessages, - InboundLaneData, LaneId, LaneState, MessageNonce, OutboundLaneData, UnrewardedRelayer, + InboundLaneData, LaneIdType, LaneState, MessageNonce, OutboundLaneData, UnrewardedRelayer, UnrewardedRelayersState, }; use bp_runtime::{AccountIdOf, HashOf, UnverifiedStorageProofParams}; @@ -44,7 +44,7 @@ pub struct Pallet, I: 'static = ()>(crate::Pallet); /// Benchmark-specific message proof parameters. #[derive(Debug)] -pub struct MessageProofParams { +pub struct MessageProofParams { /// Id of the lane. pub lane: LaneId, /// Range of messages to include in the proof. @@ -62,7 +62,7 @@ pub struct MessageProofParams { /// Benchmark-specific message delivery proof parameters. #[derive(Debug)] -pub struct MessageDeliveryProofParams { +pub struct MessageDeliveryProofParams { /// Id of the lane. pub lane: LaneId, /// The proof needs to include this inbound lane data. @@ -74,8 +74,8 @@ pub struct MessageDeliveryProofParams { /// Trait that must be implemented by runtime. pub trait Config: crate::Config { /// Lane id to use in benchmarks. - fn bench_lane_id() -> LaneId { - LaneId::new(1, 2) + fn bench_lane_id() -> Self::LaneId { + Self::LaneId::new(1, 2) } /// Return id of relayer account at the bridged chain. @@ -94,12 +94,12 @@ pub trait Config: crate::Config { /// Prepare messages proof to receive by the module. fn prepare_message_proof( - params: MessageProofParams, - ) -> (FromBridgedChainMessagesProof>>, Weight); + params: MessageProofParams, + ) -> (FromBridgedChainMessagesProof>, Self::LaneId>, Weight); /// Prepare messages delivery proof to receive by the module. fn prepare_message_delivery_proof( - params: MessageDeliveryProofParams, - ) -> FromBridgedChainMessagesDeliveryProof>>; + params: MessageDeliveryProofParams, + ) -> FromBridgedChainMessagesDeliveryProof>, Self::LaneId>; /// Returns true if message has been successfully dispatched or not. fn is_message_successfully_dispatched(_nonce: MessageNonce) -> bool { diff --git a/bridges/modules/messages/src/call_ext.rs b/bridges/modules/messages/src/call_ext.rs index 8e021c8e5e24..9e5f5f8d1129 100644 --- a/bridges/modules/messages/src/call_ext.rs +++ b/bridges/modules/messages/src/call_ext.rs @@ -20,8 +20,8 @@ use crate::{BridgedChainOf, Config, InboundLanes, OutboundLanes, Pallet, LOG_TAR use bp_messages::{ target_chain::MessageDispatch, BaseMessagesProofInfo, ChainWithMessages, InboundLaneData, - LaneId, MessageNonce, MessagesCallInfo, ReceiveMessagesDeliveryProofInfo, - ReceiveMessagesProofInfo, UnrewardedRelayerOccupation, + MessageNonce, MessagesCallInfo, ReceiveMessagesDeliveryProofInfo, ReceiveMessagesProofInfo, + UnrewardedRelayerOccupation, }; use bp_runtime::{AccountIdOf, OwnedBridgeModule}; use frame_support::{dispatch::CallableCallFor, traits::IsSubType}; @@ -39,7 +39,7 @@ impl, I: 'static> CallHelper { /// /// - call is `receive_messages_delivery_proof` and all messages confirmations have been /// received. - pub fn was_successful(info: &MessagesCallInfo) -> bool { + pub fn was_successful(info: &MessagesCallInfo) -> bool { match info { MessagesCallInfo::ReceiveMessagesProof(info) => { let inbound_lane_data = match InboundLanes::::get(info.base.lane_id) { @@ -75,19 +75,21 @@ pub trait CallSubType, I: 'static>: IsSubType, T>> { /// Create a new instance of `ReceiveMessagesProofInfo` from a `ReceiveMessagesProof` call. - fn receive_messages_proof_info(&self) -> Option; + fn receive_messages_proof_info(&self) -> Option>; /// Create a new instance of `ReceiveMessagesDeliveryProofInfo` from /// a `ReceiveMessagesDeliveryProof` call. - fn receive_messages_delivery_proof_info(&self) -> Option; + fn receive_messages_delivery_proof_info( + &self, + ) -> Option>; /// Create a new instance of `MessagesCallInfo` from a `ReceiveMessagesProof` /// or a `ReceiveMessagesDeliveryProof` call. - fn call_info(&self) -> Option; + fn call_info(&self) -> Option>; /// Create a new instance of `MessagesCallInfo` from a `ReceiveMessagesProof` /// or a `ReceiveMessagesDeliveryProof` call, if the call is for the provided lane. - fn call_info_for(&self, lane_id: LaneId) -> Option; + fn call_info_for(&self, lane_id: T::LaneId) -> Option>; /// Ensures that a `ReceiveMessagesProof` or a `ReceiveMessagesDeliveryProof` call: /// @@ -114,7 +116,7 @@ impl< I: 'static, > CallSubType for T::RuntimeCall { - fn receive_messages_proof_info(&self) -> Option { + fn receive_messages_proof_info(&self) -> Option> { if let Some(crate::Call::::receive_messages_proof { ref proof, .. }) = self.is_sub_type() { @@ -135,7 +137,9 @@ impl< None } - fn receive_messages_delivery_proof_info(&self) -> Option { + fn receive_messages_delivery_proof_info( + &self, + ) -> Option> { if let Some(crate::Call::::receive_messages_delivery_proof { ref proof, ref relayers_state, @@ -159,7 +163,7 @@ impl< None } - fn call_info(&self) -> Option { + fn call_info(&self) -> Option> { if let Some(info) = self.receive_messages_proof_info() { return Some(MessagesCallInfo::ReceiveMessagesProof(info)) } @@ -171,7 +175,7 @@ impl< None } - fn call_info_for(&self, lane_id: LaneId) -> Option { + fn call_info_for(&self, lane_id: T::LaneId) -> Option> { self.call_info().filter(|info| { let actual_lane_id = match info { MessagesCallInfo::ReceiveMessagesProof(info) => info.base.lane_id, @@ -251,10 +255,6 @@ mod tests { }; use sp_std::ops::RangeInclusive; - fn test_lane_id() -> LaneId { - LaneId::new(1, 2) - } - fn fill_unrewarded_relayers() { let mut inbound_lane_state = InboundLanes::::get(test_lane_id()).unwrap(); for n in 0..BridgedChain::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX { diff --git a/bridges/modules/messages/src/inbound_lane.rs b/bridges/modules/messages/src/inbound_lane.rs index 65240feb7194..91f1159f8f91 100644 --- a/bridges/modules/messages/src/inbound_lane.rs +++ b/bridges/modules/messages/src/inbound_lane.rs @@ -20,8 +20,8 @@ use crate::{BridgedChainOf, Config}; use bp_messages::{ target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch}, - ChainWithMessages, DeliveredMessages, InboundLaneData, LaneId, LaneState, MessageKey, - MessageNonce, OutboundLaneData, ReceptionResult, UnrewardedRelayer, + ChainWithMessages, DeliveredMessages, InboundLaneData, LaneState, MessageKey, MessageNonce, + OutboundLaneData, ReceptionResult, UnrewardedRelayer, }; use bp_runtime::AccountIdOf; use codec::{Decode, Encode, EncodeLike, MaxEncodedLen}; @@ -33,9 +33,11 @@ use sp_std::prelude::PartialEq; pub trait InboundLaneStorage { /// Id of relayer on source chain. type Relayer: Clone + PartialEq; + /// Lane identifier type. + type LaneId: Encode; /// Lane id. - fn id(&self) -> LaneId; + fn id(&self) -> Self::LaneId; /// Return maximal number of unrewarded relayer entries in inbound lane. fn max_unrewarded_relayer_entries(&self) -> MessageNonce; /// Return maximal number of unconfirmed messages in inbound lane. @@ -181,7 +183,7 @@ impl InboundLane { } /// Receive new message. - pub fn receive_message( + pub fn receive_message>( &mut self, relayer_at_bridged_chain: &S::Relayer, nonce: MessageNonce, diff --git a/bridges/modules/messages/src/lanes_manager.rs b/bridges/modules/messages/src/lanes_manager.rs index 4f5ac1c0a403..27cab48535d7 100644 --- a/bridges/modules/messages/src/lanes_manager.rs +++ b/bridges/modules/messages/src/lanes_manager.rs @@ -21,8 +21,8 @@ use crate::{ }; use bp_messages::{ - target_chain::MessageDispatch, ChainWithMessages, InboundLaneData, LaneId, LaneState, - MessageKey, MessageNonce, OutboundLaneData, + target_chain::MessageDispatch, ChainWithMessages, InboundLaneData, LaneState, MessageKey, + MessageNonce, OutboundLaneData, }; use bp_runtime::AccountIdOf; use codec::{Decode, Encode, MaxEncodedLen}; @@ -68,7 +68,7 @@ impl, I: 'static> LanesManager { /// Create new inbound lane in `Opened` state. pub fn create_inbound_lane( &self, - lane_id: LaneId, + lane_id: T::LaneId, ) -> Result>, LanesManagerError> { InboundLanes::::try_mutate(lane_id, |lane| match lane { Some(_) => Err(LanesManagerError::InboundLaneAlreadyExists), @@ -87,7 +87,7 @@ impl, I: 'static> LanesManager { /// Create new outbound lane in `Opened` state. pub fn create_outbound_lane( &self, - lane_id: LaneId, + lane_id: T::LaneId, ) -> Result>, LanesManagerError> { OutboundLanes::::try_mutate(lane_id, |lane| match lane { Some(_) => Err(LanesManagerError::OutboundLaneAlreadyExists), @@ -103,7 +103,7 @@ impl, I: 'static> LanesManager { /// Get existing inbound lane, checking that it is in usable state. pub fn active_inbound_lane( &self, - lane_id: LaneId, + lane_id: T::LaneId, ) -> Result>, LanesManagerError> { Ok(InboundLane::new(RuntimeInboundLaneStorage::from_lane_id(lane_id, true)?)) } @@ -111,7 +111,7 @@ impl, I: 'static> LanesManager { /// Get existing outbound lane, checking that it is in usable state. pub fn active_outbound_lane( &self, - lane_id: LaneId, + lane_id: T::LaneId, ) -> Result>, LanesManagerError> { Ok(OutboundLane::new(RuntimeOutboundLaneStorage::from_lane_id(lane_id, true)?)) } @@ -119,7 +119,7 @@ impl, I: 'static> LanesManager { /// Get existing inbound lane without any additional state checks. pub fn any_state_inbound_lane( &self, - lane_id: LaneId, + lane_id: T::LaneId, ) -> Result>, LanesManagerError> { Ok(InboundLane::new(RuntimeInboundLaneStorage::from_lane_id(lane_id, false)?)) } @@ -127,7 +127,7 @@ impl, I: 'static> LanesManager { /// Get existing outbound lane without any additional state checks. pub fn any_state_outbound_lane( &self, - lane_id: LaneId, + lane_id: T::LaneId, ) -> Result>, LanesManagerError> { Ok(OutboundLane::new(RuntimeOutboundLaneStorage::from_lane_id(lane_id, false)?)) } @@ -135,14 +135,14 @@ impl, I: 'static> LanesManager { /// Runtime inbound lane storage. pub struct RuntimeInboundLaneStorage, I: 'static = ()> { - pub(crate) lane_id: LaneId, + pub(crate) lane_id: T::LaneId, pub(crate) cached_data: InboundLaneData>>, } impl, I: 'static> RuntimeInboundLaneStorage { /// Creates new runtime inbound lane storage for given **existing** lane. fn from_lane_id( - lane_id: LaneId, + lane_id: T::LaneId, check_active: bool, ) -> Result, LanesManagerError> { let cached_data = @@ -196,8 +196,9 @@ impl, I: 'static> RuntimeInboundLaneStorage { impl, I: 'static> InboundLaneStorage for RuntimeInboundLaneStorage { type Relayer = AccountIdOf>; + type LaneId = T::LaneId; - fn id(&self) -> LaneId { + fn id(&self) -> Self::LaneId { self.lane_id } @@ -225,15 +226,15 @@ impl, I: 'static> InboundLaneStorage for RuntimeInboundLaneStorage< /// Runtime outbound lane storage. #[derive(Debug, PartialEq, Eq)] -pub struct RuntimeOutboundLaneStorage { - pub(crate) lane_id: LaneId, +pub struct RuntimeOutboundLaneStorage, I: 'static> { + pub(crate) lane_id: T::LaneId, pub(crate) cached_data: OutboundLaneData, pub(crate) _phantom: PhantomData<(T, I)>, } impl, I: 'static> RuntimeOutboundLaneStorage { /// Creates new runtime outbound lane storage for given **existing** lane. - fn from_lane_id(lane_id: LaneId, check_active: bool) -> Result { + fn from_lane_id(lane_id: T::LaneId, check_active: bool) -> Result { let cached_data = OutboundLanes::::get(lane_id).ok_or(LanesManagerError::UnknownOutboundLane)?; ensure!( @@ -246,8 +247,9 @@ impl, I: 'static> RuntimeOutboundLaneStorage { impl, I: 'static> OutboundLaneStorage for RuntimeOutboundLaneStorage { type StoredMessagePayload = StoredMessagePayload; + type LaneId = T::LaneId; - fn id(&self) -> LaneId { + fn id(&self) -> Self::LaneId { self.lane_id } diff --git a/bridges/modules/messages/src/lib.rs b/bridges/modules/messages/src/lib.rs index 4ef2818f271c..657c3b902be3 100644 --- a/bridges/modules/messages/src/lib.rs +++ b/bridges/modules/messages/src/lib.rs @@ -60,9 +60,9 @@ use bp_messages::{ DeliveryPayments, DispatchMessage, FromBridgedChainMessagesProof, MessageDispatch, ProvedLaneMessages, ProvedMessages, }, - ChainWithMessages, DeliveredMessages, InboundLaneData, InboundMessageDetails, LaneId, - MessageKey, MessageNonce, MessagePayload, MessagesOperatingMode, OutboundLaneData, - OutboundMessageDetails, UnrewardedRelayersState, VerificationError, + ChainWithMessages, DeliveredMessages, InboundLaneData, InboundMessageDetails, MessageKey, + MessageNonce, MessagePayload, MessagesOperatingMode, OutboundLaneData, OutboundMessageDetails, + UnrewardedRelayersState, VerificationError, }; use bp_runtime::{ AccountIdOf, BasicOperatingMode, HashOf, OwnedBridgeModule, PreComputedSize, RangeInclusiveExt, @@ -97,7 +97,7 @@ pub const LOG_TARGET: &str = "runtime::bridge-messages"; #[frame_support::pallet] pub mod pallet { use super::*; - use bp_messages::{LaneIdBytes, ReceivedMessages, ReceptionResult}; + use bp_messages::{LaneIdType, ReceivedMessages, ReceptionResult}; use bp_runtime::RangeInclusiveExt; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; @@ -123,17 +123,25 @@ pub mod pallet { type OutboundPayload: Parameter + Size; /// Payload type of inbound messages. This payload is dispatched on this chain. type InboundPayload: Decode; + /// Type of a lane identifier. + type LaneId: LaneIdType; /// Handler for relayer payments that happen during message delivery transaction. type DeliveryPayments: DeliveryPayments; /// Handler for relayer payments that happen during message delivery confirmation /// transaction. - type DeliveryConfirmationPayments: DeliveryConfirmationPayments; + type DeliveryConfirmationPayments: DeliveryConfirmationPayments< + Self::AccountId, + Self::LaneId, + >; /// Delivery confirmation callback. - type OnMessagesDelivered: OnMessagesDelivered; + type OnMessagesDelivered: OnMessagesDelivered; /// Message dispatch handler. - type MessageDispatch: MessageDispatch; + type MessageDispatch: MessageDispatch< + DispatchPayload = Self::InboundPayload, + LaneId = Self::LaneId, + >; } /// Shortcut to this chain type for Config. @@ -203,7 +211,7 @@ pub mod pallet { pub fn receive_messages_proof( origin: OriginFor, relayer_id_at_bridged_chain: AccountIdOf>, - proof: Box>>>, + proof: Box>, T::LaneId>>, messages_count: u32, dispatch_weight: Weight, ) -> DispatchResultWithPostInfo { @@ -350,7 +358,7 @@ pub mod pallet { ))] pub fn receive_messages_delivery_proof( origin: OriginFor, - proof: FromBridgedChainMessagesDeliveryProof>>, + proof: FromBridgedChainMessagesDeliveryProof>, T::LaneId>, mut relayers_state: UnrewardedRelayersState, ) -> DispatchResultWithPostInfo { Self::ensure_not_halted().map_err(Error::::BridgeModule)?; @@ -441,19 +449,22 @@ pub mod pallet { /// Message has been accepted and is waiting to be delivered. MessageAccepted { /// Lane, which has accepted the message. - lane_id: LaneIdBytes, + lane_id: T::LaneId, /// Nonce of accepted message. nonce: MessageNonce, }, /// Messages have been received from the bridged chain. MessagesReceived( /// Result of received messages dispatch. - ReceivedMessages<::DispatchLevelResult>, + ReceivedMessages< + ::DispatchLevelResult, + T::LaneId, + >, ), /// Messages in the inclusive range have been delivered to the bridged chain. MessagesDelivered { /// Lane for which the delivery has been confirmed. - lane_id: LaneIdBytes, + lane_id: T::LaneId, /// Delivered messages. messages: DeliveredMessages, }, @@ -510,13 +521,13 @@ pub mod pallet { /// Map of lane id => inbound lane data. #[pallet::storage] pub type InboundLanes, I: 'static = ()> = - StorageMap<_, Blake2_128Concat, LaneId, StoredInboundLaneData, OptionQuery>; + StorageMap<_, Blake2_128Concat, T::LaneId, StoredInboundLaneData, OptionQuery>; /// Map of lane id => outbound lane data. #[pallet::storage] pub type OutboundLanes, I: 'static = ()> = StorageMap< Hasher = Blake2_128Concat, - Key = LaneId, + Key = T::LaneId, Value = OutboundLaneData, QueryKind = OptionQuery, >; @@ -524,7 +535,7 @@ pub mod pallet { /// All queued outbound messages. #[pallet::storage] pub type OutboundMessages, I: 'static = ()> = - StorageMap<_, Blake2_128Concat, MessageKey, StoredMessagePayload>; + StorageMap<_, Blake2_128Concat, MessageKey, StoredMessagePayload>; #[pallet::genesis_config] #[derive(DefaultNoBound)] @@ -534,7 +545,7 @@ pub mod pallet { /// Initial pallet owner. pub owner: Option, /// Opened lanes. - pub opened_lanes: Vec, + pub opened_lanes: Vec, /// Dummy marker. #[serde(skip)] pub _phantom: sp_std::marker::PhantomData, @@ -565,13 +576,16 @@ pub mod pallet { impl, I: 'static> Pallet { /// Get stored data of the outbound message with given nonce. - pub fn outbound_message_data(lane: LaneId, nonce: MessageNonce) -> Option { + pub fn outbound_message_data( + lane: T::LaneId, + nonce: MessageNonce, + ) -> Option { OutboundMessages::::get(MessageKey { lane_id: lane, nonce }).map(Into::into) } /// Prepare data, related to given inbound message. pub fn inbound_message_data( - lane: LaneId, + lane: T::LaneId, payload: MessagePayload, outbound_details: OutboundMessageDetails, ) -> InboundMessageDetails { @@ -585,13 +599,13 @@ pub mod pallet { } /// Return outbound lane data. - pub fn outbound_lane_data(lane: LaneId) -> Option { + pub fn outbound_lane_data(lane: T::LaneId) -> Option { OutboundLanes::::get(lane) } /// Return inbound lane data. pub fn inbound_lane_data( - lane: LaneId, + lane: T::LaneId, ) -> Option>>> { InboundLanes::::get(lane).map(|lane| lane.0) } @@ -654,12 +668,12 @@ pub mod pallet { /// to send it on the bridge. #[derive(Debug, PartialEq, Eq)] pub struct SendMessageArgs, I: 'static> { - lane_id: LaneId, + lane_id: T::LaneId, lane: OutboundLane>, payload: StoredMessagePayload, } -impl bp_messages::source_chain::MessagesBridge for Pallet +impl bp_messages::source_chain::MessagesBridge for Pallet where T: Config, I: 'static, @@ -668,7 +682,7 @@ where type SendMessageArgs = SendMessageArgs; fn validate_message( - lane_id: LaneId, + lane_id: T::LaneId, message: &T::OutboundPayload, ) -> Result, Self::Error> { // we can't accept any messages if the pallet is halted @@ -725,7 +739,7 @@ fn ensure_normal_operating_mode, I: 'static>() -> Result<(), Error< /// Creates new inbound lane object, backed by runtime storage. Lane must be active. fn active_inbound_lane, I: 'static>( - lane_id: LaneId, + lane_id: T::LaneId, ) -> Result>, Error> { LanesManager::::new() .active_inbound_lane(lane_id) @@ -734,7 +748,7 @@ fn active_inbound_lane, I: 'static>( /// Creates new outbound lane object, backed by runtime storage. Lane must be active. fn active_outbound_lane, I: 'static>( - lane_id: LaneId, + lane_id: T::LaneId, ) -> Result>, Error> { LanesManager::::new() .active_outbound_lane(lane_id) @@ -743,7 +757,7 @@ fn active_outbound_lane, I: 'static>( /// Creates new outbound lane object, backed by runtime storage. fn any_state_outbound_lane, I: 'static>( - lane_id: LaneId, + lane_id: T::LaneId, ) -> Result>, Error> { LanesManager::::new() .any_state_outbound_lane(lane_id) @@ -752,9 +766,12 @@ fn any_state_outbound_lane, I: 'static>( /// Verify messages proof and return proved messages with decoded payload. fn verify_and_decode_messages_proof, I: 'static>( - proof: FromBridgedChainMessagesProof>>, + proof: FromBridgedChainMessagesProof>, T::LaneId>, messages_count: u32, -) -> Result>, VerificationError> { +) -> Result< + ProvedMessages>, + VerificationError, +> { // `receive_messages_proof` weight formula and `MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX` // check guarantees that the `message_count` is sane and Vec may be allocated. // (tx with too many messages will either be rejected from the pool, or will fail earlier) diff --git a/bridges/modules/messages/src/outbound_lane.rs b/bridges/modules/messages/src/outbound_lane.rs index f71240ab7c70..c72713e7455a 100644 --- a/bridges/modules/messages/src/outbound_lane.rs +++ b/bridges/modules/messages/src/outbound_lane.rs @@ -19,7 +19,7 @@ use crate::{Config, LOG_TARGET}; use bp_messages::{ - ChainWithMessages, DeliveredMessages, LaneId, LaneState, MessageNonce, OutboundLaneData, + ChainWithMessages, DeliveredMessages, LaneState, MessageNonce, OutboundLaneData, UnrewardedRelayer, }; use codec::{Decode, Encode}; @@ -32,9 +32,11 @@ use sp_std::{collections::vec_deque::VecDeque, marker::PhantomData, ops::RangeIn pub trait OutboundLaneStorage { /// Stored message payload type. type StoredMessagePayload; + /// Lane identifier type. + type LaneId: Encode; /// Lane id. - fn id(&self) -> LaneId; + fn id(&self) -> Self::LaneId; /// Get lane data from the storage. fn data(&self) -> OutboundLaneData; /// Update lane data in the storage. diff --git a/bridges/modules/messages/src/proofs.rs b/bridges/modules/messages/src/proofs.rs index f35eb24d98c5..dcd642341d77 100644 --- a/bridges/modules/messages/src/proofs.rs +++ b/bridges/modules/messages/src/proofs.rs @@ -22,7 +22,7 @@ use bp_header_chain::{HeaderChain, HeaderChainError}; use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, target_chain::{FromBridgedChainMessagesProof, ProvedLaneMessages, ProvedMessages}, - ChainWithMessages, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, + ChainWithMessages, InboundLaneData, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, VerificationError, }; use bp_runtime::{ @@ -32,8 +32,8 @@ use codec::Decode; use sp_std::vec::Vec; /// 'Parsed' message delivery proof - inbound lane id and its state. -pub(crate) type ParsedMessagesDeliveryProofFromBridgedChain = - (LaneId, InboundLaneData<::AccountId>); +pub(crate) type ParsedMessagesDeliveryProofFromBridgedChain = + (>::LaneId, InboundLaneData<::AccountId>); /// Verify proof of Bridged -> This chain messages. /// @@ -44,9 +44,9 @@ pub(crate) type ParsedMessagesDeliveryProofFromBridgedChain = /// outside of this function. This function only verifies that the proof declares exactly /// `messages_count` messages. pub fn verify_messages_proof, I: 'static>( - proof: FromBridgedChainMessagesProof>>, + proof: FromBridgedChainMessagesProof>, T::LaneId>, messages_count: u32, -) -> Result, VerificationError> { +) -> Result>, VerificationError> { let FromBridgedChainMessagesProof { bridged_header_hash, storage_proof, @@ -103,8 +103,8 @@ pub fn verify_messages_proof, I: 'static>( /// Verify proof of This -> Bridged chain messages delivery. pub fn verify_messages_delivery_proof, I: 'static>( - proof: FromBridgedChainMessagesDeliveryProof>>, -) -> Result, VerificationError> { + proof: FromBridgedChainMessagesDeliveryProof>, T::LaneId>, +) -> Result, VerificationError> { let FromBridgedChainMessagesDeliveryProof { bridged_header_hash, storage_proof, lane } = proof; let mut parser: MessagesStorageProofAdapter = MessagesStorageProofAdapter::try_new_with_verified_storage_proof( @@ -143,7 +143,7 @@ trait StorageProofAdapter, I: 'static> { fn read_and_decode_outbound_lane_data( &mut self, - lane_id: &LaneId, + lane_id: &T::LaneId, ) -> Result, StorageProofError> { let storage_outbound_lane_data_key = bp_messages::storage_keys::outbound_lane_data_key( T::ThisChain::WITH_CHAIN_MESSAGES_PALLET_NAME, @@ -154,7 +154,7 @@ trait StorageProofAdapter, I: 'static> { fn read_and_decode_message_payload( &mut self, - message_key: &MessageKey, + message_key: &MessageKey, ) -> Result { let storage_message_key = bp_messages::storage_keys::message_key( T::ThisChain::WITH_CHAIN_MESSAGES_PALLET_NAME, @@ -229,19 +229,20 @@ mod tests { encode_outbound_lane_data: impl Fn(&OutboundLaneData) -> Vec, add_duplicate_key: bool, add_unused_key: bool, - test: impl Fn(FromBridgedChainMessagesProof) -> R, + test: impl Fn(FromBridgedChainMessagesProof) -> R, ) -> R { - let (state_root, storage_proof) = prepare_messages_storage_proof::( - test_lane_id(), - 1..=nonces_end, - outbound_lane_data, - bp_runtime::UnverifiedStorageProofParams::default(), - generate_dummy_message, - encode_message, - encode_outbound_lane_data, - add_duplicate_key, - add_unused_key, - ); + let (state_root, storage_proof) = + prepare_messages_storage_proof::( + test_lane_id(), + 1..=nonces_end, + outbound_lane_data, + bp_runtime::UnverifiedStorageProofParams::default(), + generate_dummy_message, + encode_message, + encode_outbound_lane_data, + add_duplicate_key, + add_unused_key, + ); sp_io::TestExternalities::new(Default::default()).execute_with(move || { let bridged_header = BridgedChainHeader::new( diff --git a/bridges/modules/messages/src/tests/messages_generation.rs b/bridges/modules/messages/src/tests/messages_generation.rs index 6c4867fa6de3..00b1d3eefe43 100644 --- a/bridges/modules/messages/src/tests/messages_generation.rs +++ b/bridges/modules/messages/src/tests/messages_generation.rs @@ -17,8 +17,8 @@ //! Helpers for generating message storage proofs, that are used by tests and by benchmarks. use bp_messages::{ - storage_keys, ChainWithMessages, InboundLaneData, LaneId, MessageKey, MessageNonce, - MessagePayload, OutboundLaneData, + storage_keys, ChainWithMessages, InboundLaneData, MessageKey, MessageNonce, MessagePayload, + OutboundLaneData, }; use bp_runtime::{ grow_storage_value, record_all_trie_keys, AccountIdOf, Chain, HashOf, HasherOf, @@ -47,7 +47,11 @@ pub fn encode_lane_data(d: &OutboundLaneData) -> Vec { /// /// Returns state trie root and nodes with prepared messages. #[allow(clippy::too_many_arguments)] -pub fn prepare_messages_storage_proof( +pub fn prepare_messages_storage_proof< + BridgedChain: Chain, + ThisChain: ChainWithMessages, + LaneId: Encode + Copy, +>( lane: LaneId, message_nonces: RangeInclusive, outbound_lane_data: Option, @@ -132,7 +136,11 @@ where /// Prepare storage proof of given messages delivery. /// /// Returns state trie root and nodes with prepared messages. -pub fn prepare_message_delivery_storage_proof( +pub fn prepare_message_delivery_storage_proof< + BridgedChain: Chain, + ThisChain: ChainWithMessages, + LaneId: Encode, +>( lane: LaneId, inbound_lane_data: InboundLaneData>, proof_params: UnverifiedStorageProofParams, diff --git a/bridges/modules/messages/src/tests/mock.rs b/bridges/modules/messages/src/tests/mock.rs index 2caea9813e82..85bd85cce2ad 100644 --- a/bridges/modules/messages/src/tests/mock.rs +++ b/bridges/modules/messages/src/tests/mock.rs @@ -35,8 +35,9 @@ use bp_messages::{ DeliveryPayments, DispatchMessage, DispatchMessageData, FromBridgedChainMessagesProof, MessageDispatch, }, - ChainWithMessages, DeliveredMessages, InboundLaneData, LaneId, LaneState, Message, MessageKey, - MessageNonce, OutboundLaneData, UnrewardedRelayer, UnrewardedRelayersState, + ChainWithMessages, DeliveredMessages, HashedLaneId, InboundLaneData, LaneIdType, LaneState, + Message, MessageKey, MessageNonce, OutboundLaneData, UnrewardedRelayer, + UnrewardedRelayersState, }; use bp_runtime::{ messages::MessageDispatchResult, Chain, ChainId, Size, UnverifiedStorageProofParams, @@ -74,6 +75,7 @@ pub struct TestPayload { pub type TestMessageFee = u64; pub type TestRelayer = u64; pub type TestDispatchLevelResult = (); +pub type TestLaneIdType = HashedLaneId; pub struct ThisChain; @@ -195,10 +197,10 @@ impl Config for TestRuntime { type BridgedHeaderChain = BridgedChainGrandpa; type OutboundPayload = TestPayload; - type InboundPayload = TestPayload; - type DeliveryPayments = TestDeliveryPayments; + type LaneId = TestLaneIdType; + type DeliveryPayments = TestDeliveryPayments; type DeliveryConfirmationPayments = TestDeliveryConfirmationPayments; type OnMessagesDelivered = TestOnMessagesDelivered; @@ -207,13 +209,13 @@ impl Config for TestRuntime { #[cfg(feature = "runtime-benchmarks")] impl crate::benchmarking::Config<()> for TestRuntime { - fn bench_lane_id() -> LaneId { + fn bench_lane_id() -> Self::LaneId { test_lane_id() } fn prepare_message_proof( - params: crate::benchmarking::MessageProofParams, - ) -> (FromBridgedChainMessagesProof, Weight) { + params: crate::benchmarking::MessageProofParams, + ) -> (FromBridgedChainMessagesProof, Weight) { use bp_runtime::RangeInclusiveExt; let dispatch_weight = @@ -228,8 +230,8 @@ impl crate::benchmarking::Config<()> for TestRuntime { } fn prepare_message_delivery_proof( - params: crate::benchmarking::MessageDeliveryProofParams, - ) -> FromBridgedChainMessagesDeliveryProof { + params: crate::benchmarking::MessageDeliveryProofParams, + ) -> FromBridgedChainMessagesDeliveryProof { // in mock run we only care about benchmarks correctness, not the benchmark results // => ignore size related arguments prepare_messages_delivery_proof(params.lane, params.inbound_lane_data) @@ -259,18 +261,18 @@ pub const TEST_RELAYER_B: AccountId = 101; pub const TEST_RELAYER_C: AccountId = 102; /// Lane that we're using in tests. -pub fn test_lane_id() -> LaneId { - LaneId::new(1, 2) +pub fn test_lane_id() -> TestLaneIdType { + TestLaneIdType::new(1, 2) } /// Lane that is completely unknown to our runtime. -pub fn unknown_lane_id() -> LaneId { - LaneId::new(1, 3) +pub fn unknown_lane_id() -> TestLaneIdType { + TestLaneIdType::new(1, 3) } /// Lane that is registered, but it is closed. -pub fn closed_lane_id() -> LaneId { - LaneId::new(1, 4) +pub fn closed_lane_id() -> TestLaneIdType { + TestLaneIdType::new(1, 4) } /// Regular message payload. @@ -316,11 +318,11 @@ impl TestDeliveryConfirmationPayments { } } -impl DeliveryConfirmationPayments for TestDeliveryConfirmationPayments { +impl DeliveryConfirmationPayments for TestDeliveryConfirmationPayments { type Error = &'static str; fn pay_reward( - _lane_id: LaneId, + _lane_id: TestLaneIdType, messages_relayers: VecDeque>, _confirmation_relayer: &AccountId, received_range: &RangeInclusive, @@ -341,7 +343,7 @@ impl DeliveryConfirmationPayments for TestDeliveryConfirmationPayment pub struct TestMessageDispatch; impl TestMessageDispatch { - pub fn deactivate(lane: LaneId) { + pub fn deactivate(lane: TestLaneIdType) { // "enqueue" enough (to deactivate dispatcher) messages at dispatcher let latest_received_nonce = BridgedChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX + 1; for _ in 1..=latest_received_nonce { @@ -349,7 +351,7 @@ impl TestMessageDispatch { } } - pub fn emulate_enqueued_message(lane: LaneId) { + pub fn emulate_enqueued_message(lane: TestLaneIdType) { let key = (b"dispatched", lane).encode(); let dispatched = frame_support::storage::unhashed::get_or_default::(&key[..]); frame_support::storage::unhashed::put(&key[..], &(dispatched + 1)); @@ -359,14 +361,15 @@ impl TestMessageDispatch { impl MessageDispatch for TestMessageDispatch { type DispatchPayload = TestPayload; type DispatchLevelResult = TestDispatchLevelResult; + type LaneId = TestLaneIdType; - fn is_active(lane: LaneId) -> bool { + fn is_active(lane: Self::LaneId) -> bool { frame_support::storage::unhashed::get_or_default::( &(b"dispatched", lane).encode()[..], ) <= BridgedChain::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX } - fn dispatch_weight(message: &mut DispatchMessage) -> Weight { + fn dispatch_weight(message: &mut DispatchMessage) -> Weight { match message.data.payload.as_ref() { Ok(payload) => payload.declared_weight, Err(_) => Weight::zero(), @@ -374,7 +377,7 @@ impl MessageDispatch for TestMessageDispatch { } fn dispatch( - message: DispatchMessage, + message: DispatchMessage, ) -> MessageDispatchResult { match message.data.payload.as_ref() { Ok(payload) => { @@ -390,13 +393,13 @@ impl MessageDispatch for TestMessageDispatch { pub struct TestOnMessagesDelivered; impl TestOnMessagesDelivered { - pub fn call_arguments() -> Option<(LaneId, MessageNonce)> { + pub fn call_arguments() -> Option<(TestLaneIdType, MessageNonce)> { frame_support::storage::unhashed::get(b"TestOnMessagesDelivered.OnMessagesDelivered") } } -impl OnMessagesDelivered for TestOnMessagesDelivered { - fn on_messages_delivered(lane: LaneId, enqueued_messages: MessageNonce) { +impl OnMessagesDelivered for TestOnMessagesDelivered { + fn on_messages_delivered(lane: TestLaneIdType, enqueued_messages: MessageNonce) { frame_support::storage::unhashed::put( b"TestOnMessagesDelivered.OnMessagesDelivered", &(lane, enqueued_messages), @@ -405,7 +408,7 @@ impl OnMessagesDelivered for TestOnMessagesDelivered { } /// Return test lane message with given nonce and payload. -pub fn message(nonce: MessageNonce, payload: TestPayload) -> Message { +pub fn message(nonce: MessageNonce, payload: TestPayload) -> Message { Message { key: MessageKey { lane_id: test_lane_id(), nonce }, payload: payload.encode() } } @@ -449,7 +452,7 @@ pub fn unrewarded_relayer( } /// Returns unrewarded relayers state at given lane. -pub fn inbound_unrewarded_relayers_state(lane: bp_messages::LaneId) -> UnrewardedRelayersState { +pub fn inbound_unrewarded_relayers_state(lane: TestLaneIdType) -> UnrewardedRelayersState { let inbound_lane_data = crate::InboundLanes::::get(lane).unwrap().0; UnrewardedRelayersState::from(&inbound_lane_data) } @@ -486,24 +489,25 @@ pub fn run_test(test: impl FnOnce() -> T) -> T { /// Since this function changes the runtime storage, you can't "inline" it in the /// `asset_noop` macro calls. pub fn prepare_messages_proof( - messages: Vec, + messages: Vec>, outbound_lane_data: Option, -) -> Box> { +) -> Box> { // first - let's generate storage proof let lane = messages.first().unwrap().key.lane_id; let nonces_start = messages.first().unwrap().key.nonce; let nonces_end = messages.last().unwrap().key.nonce; - let (storage_root, storage_proof) = prepare_messages_storage_proof::( - lane, - nonces_start..=nonces_end, - outbound_lane_data, - UnverifiedStorageProofParams::default(), - |nonce| messages[(nonce - nonces_start) as usize].payload.clone(), - encode_all_messages, - encode_lane_data, - false, - false, - ); + let (storage_root, storage_proof) = + prepare_messages_storage_proof::( + lane, + nonces_start..=nonces_end, + outbound_lane_data, + UnverifiedStorageProofParams::default(), + |nonce| messages[(nonce - nonces_start) as usize].payload.clone(), + encode_all_messages, + encode_lane_data, + false, + false, + ); // let's now insert bridged chain header into the storage let bridged_header_hash = Default::default(); @@ -512,7 +516,7 @@ pub fn prepare_messages_proof( StoredHeaderData { number: 0, state_root: storage_root }, ); - Box::new(FromBridgedChainMessagesProof:: { + Box::new(FromBridgedChainMessagesProof:: { bridged_header_hash, storage_proof, lane, @@ -527,12 +531,12 @@ pub fn prepare_messages_proof( /// Since this function changes the runtime storage, you can't "inline" it in the /// `asset_noop` macro calls. pub fn prepare_messages_delivery_proof( - lane: LaneId, + lane: TestLaneIdType, inbound_lane_data: InboundLaneData, -) -> FromBridgedChainMessagesDeliveryProof { +) -> FromBridgedChainMessagesDeliveryProof { // first - let's generate storage proof let (storage_root, storage_proof) = - prepare_message_delivery_storage_proof::( + prepare_message_delivery_storage_proof::( lane, inbound_lane_data, UnverifiedStorageProofParams::default(), @@ -545,7 +549,7 @@ pub fn prepare_messages_delivery_proof( StoredHeaderData { number: 0, state_root: storage_root }, ); - FromBridgedChainMessagesDeliveryProof:: { + FromBridgedChainMessagesDeliveryProof:: { bridged_header_hash, storage_proof, lane, diff --git a/bridges/modules/messages/src/tests/pallet_tests.rs b/bridges/modules/messages/src/tests/pallet_tests.rs index d2391cd1775d..3bab5e48d6b8 100644 --- a/bridges/modules/messages/src/tests/pallet_tests.rs +++ b/bridges/modules/messages/src/tests/pallet_tests.rs @@ -30,7 +30,7 @@ use bp_messages::{ source_chain::{FromBridgedChainMessagesDeliveryProof, MessagesBridge}, target_chain::{FromBridgedChainMessagesProof, MessageDispatch}, BridgeMessagesCall, ChainWithMessages, DeliveredMessages, InboundLaneData, - InboundMessageDetails, LaneId, LaneState, MessageKey, MessageNonce, MessagesOperatingMode, + InboundMessageDetails, LaneIdType, LaneState, MessageKey, MessageNonce, MessagesOperatingMode, OutboundLaneData, OutboundMessageDetails, UnrewardedRelayer, UnrewardedRelayersState, VerificationError, }; @@ -51,7 +51,7 @@ fn get_ready_for_events() { System::::reset_events(); } -fn send_regular_message(lane_id: LaneId) { +fn send_regular_message(lane_id: TestLaneIdType) { get_ready_for_events(); let outbound_lane = active_outbound_lane::(lane_id).unwrap(); @@ -632,7 +632,7 @@ fn receive_messages_delivery_proof_rewards_relayers() { fn receive_messages_delivery_proof_rejects_invalid_proof() { run_test(|| { let mut proof = prepare_messages_delivery_proof(test_lane_id(), Default::default()); - proof.lane = bp_messages::LaneId::new(42, 84); + proof.lane = TestLaneIdType::new(42, 84); assert_noop!( Pallet::::receive_messages_delivery_proof( @@ -1041,8 +1041,8 @@ fn test_bridge_messages_call_is_correctly_defined() { }; let indirect_receive_messages_proof_call = BridgeMessagesCall::< AccountId, - FromBridgedChainMessagesProof, - FromBridgedChainMessagesDeliveryProof, + FromBridgedChainMessagesProof, + FromBridgedChainMessagesDeliveryProof, >::receive_messages_proof { relayer_id_at_bridged_chain: account_id, proof: *message_proof, @@ -1061,8 +1061,8 @@ fn test_bridge_messages_call_is_correctly_defined() { }; let indirect_receive_messages_delivery_proof_call = BridgeMessagesCall::< AccountId, - FromBridgedChainMessagesProof, - FromBridgedChainMessagesDeliveryProof, + FromBridgedChainMessagesProof, + FromBridgedChainMessagesDeliveryProof, >::receive_messages_delivery_proof { proof: message_delivery_proof, relayers_state: unrewarded_relayer_state, @@ -1087,7 +1087,7 @@ fn inbound_storage_extra_proof_size_bytes_works() { fn storage(relayer_entries: usize) -> RuntimeInboundLaneStorage { RuntimeInboundLaneStorage { - lane_id: LaneId::new(1, 2), + lane_id: TestLaneIdType::new(1, 2), cached_data: InboundLaneData { state: LaneState::Opened, relayers: vec![relayer_entry(); relayer_entries].into(), @@ -1168,7 +1168,7 @@ fn receive_messages_proof_fails_if_inbound_lane_is_not_opened() { #[test] fn receive_messages_delivery_proof_fails_if_outbound_lane_is_unknown() { run_test(|| { - let make_proof = |lane: LaneId| { + let make_proof = |lane: TestLaneIdType| { prepare_messages_delivery_proof( lane, InboundLaneData { diff --git a/bridges/primitives/xcm-bridge-hub/src/lib.rs b/bridges/primitives/xcm-bridge-hub/src/lib.rs index 19c8362ee171..45e3090f8289 100644 --- a/bridges/primitives/xcm-bridge-hub/src/lib.rs +++ b/bridges/primitives/xcm-bridge-hub/src/lib.rs @@ -19,7 +19,7 @@ #![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -use bp_messages::LaneId; +use bp_messages::LaneIdType; use bp_runtime::{AccountIdOf, BalanceOf, Chain}; pub use call_info::XcmBridgeHubCall; use codec::{Decode, Encode, MaxEncodedLen}; @@ -155,7 +155,7 @@ pub enum BridgeState { CloneNoBound, Decode, Encode, Eq, PartialEqNoBound, TypeInfo, MaxEncodedLen, RuntimeDebugNoBound, )] #[scale_info(skip_type_params(ThisChain))] -pub struct Bridge { +pub struct Bridge { /// Relative location of the bridge origin chain. This is expected to be **convertible** to the /// `latest` XCM, so the check and migration needs to be ensured. pub bridge_origin_relative_location: Box, @@ -323,7 +323,7 @@ impl BridgeLocations { /// Generates the exact same `LaneId` on the both bridge hubs. /// /// Note: Use this **only** when opening a new bridge. - pub fn calculate_lane_id( + pub fn calculate_lane_id( &self, xcm_version: XcmVersion, ) -> Result { @@ -595,6 +595,8 @@ mod tests { #[test] fn calculate_lane_id_works() { + type TestLaneId = bp_messages::HashedLaneId; + let from_local_to_remote = run_successful_test(SuccessfulTest { here_universal_location: [GlobalConsensus(LOCAL_NETWORK), Parachain(LOCAL_BRIDGE_HUB)] .into(), @@ -636,12 +638,12 @@ mod tests { }); assert_ne!( - from_local_to_remote.calculate_lane_id(xcm::latest::VERSION), - from_remote_to_local.calculate_lane_id(xcm::latest::VERSION - 1), + from_local_to_remote.calculate_lane_id::(xcm::latest::VERSION), + from_remote_to_local.calculate_lane_id::(xcm::latest::VERSION - 1), ); assert_eq!( - from_local_to_remote.calculate_lane_id(xcm::latest::VERSION), - from_remote_to_local.calculate_lane_id(xcm::latest::VERSION), + from_local_to_remote.calculate_lane_id::(xcm::latest::VERSION), + from_remote_to_local.calculate_lane_id::(xcm::latest::VERSION), ); } From 4c52f86427da0510d948a9247241caf69d69c32f Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Mon, 9 Sep 2024 15:47:52 +0200 Subject: [PATCH 11/38] Generic `LaneId` for `pallet_xcm_bridge_hub` --- bridges/modules/messages/src/tests/mock.rs | 1 + .../modules/xcm-bridge-hub/src/dispatcher.rs | 32 ++++++++--------- .../modules/xcm-bridge-hub/src/exporter.rs | 14 ++++---- bridges/modules/xcm-bridge-hub/src/lib.rs | 34 +++++++++---------- .../modules/xcm-bridge-hub/src/migration.rs | 3 +- bridges/modules/xcm-bridge-hub/src/mock.rs | 16 ++++++--- bridges/primitives/messages/src/lane.rs | 1 + bridges/primitives/xcm-bridge-hub/src/lib.rs | 2 +- 8 files changed, 55 insertions(+), 48 deletions(-) diff --git a/bridges/modules/messages/src/tests/mock.rs b/bridges/modules/messages/src/tests/mock.rs index 85bd85cce2ad..d09f612aa0c0 100644 --- a/bridges/modules/messages/src/tests/mock.rs +++ b/bridges/modules/messages/src/tests/mock.rs @@ -75,6 +75,7 @@ pub struct TestPayload { pub type TestMessageFee = u64; pub type TestRelayer = u64; pub type TestDispatchLevelResult = (); +/// Lane identifier type used for tests. pub type TestLaneIdType = HashedLaneId; pub struct ThisChain; diff --git a/bridges/modules/xcm-bridge-hub/src/dispatcher.rs b/bridges/modules/xcm-bridge-hub/src/dispatcher.rs index 2412bb0f3bb0..ca5c3755778e 100644 --- a/bridges/modules/xcm-bridge-hub/src/dispatcher.rs +++ b/bridges/modules/xcm-bridge-hub/src/dispatcher.rs @@ -23,10 +23,7 @@ use crate::{Config, Pallet, LOG_TARGET}; -use bp_messages::{ - target_chain::{DispatchMessage, MessageDispatch}, - LaneId, -}; +use bp_messages::target_chain::{DispatchMessage, MessageDispatch}; use bp_runtime::messages::MessageDispatchResult; use bp_xcm_bridge_hub::{LocalXcmChannelManager, XcmAsPlainPayload}; use codec::{Decode, Encode}; @@ -58,15 +55,18 @@ where { type DispatchPayload = XcmAsPlainPayload; type DispatchLevelResult = XcmBlobMessageDispatchResult; + type LaneId = T::LaneId; - fn is_active(lane: LaneId) -> bool { + fn is_active(lane: Self::LaneId) -> bool { Pallet::::bridge_by_lane_id(&lane) .and_then(|(_, bridge)| bridge.bridge_origin_relative_location.try_as().cloned().ok()) .map(|recipient: Location| !T::LocalXcmChannelManager::is_congested(&recipient)) .unwrap_or(false) } - fn dispatch_weight(message: &mut DispatchMessage) -> Weight { + fn dispatch_weight( + message: &mut DispatchMessage, + ) -> Weight { match message.data.payload { Ok(ref payload) => { let payload_size = payload.encoded_size().saturated_into(); @@ -77,14 +77,14 @@ where } fn dispatch( - message: DispatchMessage, + message: DispatchMessage, ) -> MessageDispatchResult { let payload = match message.data.payload { Ok(payload) => payload, Err(e) => { log::error!( target: LOG_TARGET, - "dispatch - payload error: {e:?} for lane_id: {} and message_nonce: {:?}", + "dispatch - payload error: {e:?} for lane_id: {:?} and message_nonce: {:?}", message.key.lane_id, message.key.nonce ); @@ -98,7 +98,7 @@ where Ok(_) => { log::debug!( target: LOG_TARGET, - "dispatch - `DispatchBlob::dispatch_blob` was ok for lane_id: {} and message_nonce: {:?}", + "dispatch - `DispatchBlob::dispatch_blob` was ok for lane_id: {:?} and message_nonce: {:?}", message.key.lane_id, message.key.nonce ); @@ -107,7 +107,7 @@ where Err(e) => { log::error!( target: LOG_TARGET, - "dispatch - `DispatchBlob::dispatch_blob` failed with error: {e:?} for lane_id: {} and message_nonce: {:?}", + "dispatch - `DispatchBlob::dispatch_blob` failed with error: {e:?} for lane_id: {:?} and message_nonce: {:?}", message.key.lane_id, message.key.nonce ); @@ -123,13 +123,13 @@ mod tests { use super::*; use crate::{mock::*, Bridges, LaneToBridge, LanesManagerOf}; - use bp_messages::{target_chain::DispatchMessageData, MessageKey}; + use bp_messages::{target_chain::DispatchMessageData, LaneIdType, MessageKey}; use bp_xcm_bridge_hub::{Bridge, BridgeLocations, BridgeState}; use frame_support::assert_ok; use pallet_bridge_messages::InboundLaneStorage; use xcm_executor::traits::ConvertLocation; - fn bridge() -> (Box, LaneId) { + fn bridge() -> (Box, TestLaneIdType) { let origin = OpenBridgeOrigin::sibling_parachain_origin(); let with = bridged_asset_hub_universal_location(); let locations = @@ -194,16 +194,16 @@ mod tests { }); } - fn invalid_message() -> DispatchMessage> { + fn invalid_message() -> DispatchMessage, TestLaneIdType> { DispatchMessage { - key: MessageKey { lane_id: LaneId::new(1, 2), nonce: 1 }, + key: MessageKey { lane_id: TestLaneIdType::new(1, 2), nonce: 1 }, data: DispatchMessageData { payload: Err(codec::Error::from("test")) }, } } - fn valid_message() -> DispatchMessage> { + fn valid_message() -> DispatchMessage, TestLaneIdType> { DispatchMessage { - key: MessageKey { lane_id: LaneId::new(1, 2), nonce: 1 }, + key: MessageKey { lane_id: TestLaneIdType::new(1, 2), nonce: 1 }, data: DispatchMessageData { payload: Ok(vec![42]) }, } } diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index 5e1051c5fac7..bc91c966e4d6 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -26,7 +26,7 @@ use crate::{BridgeOf, Bridges}; use bp_messages::{ source_chain::{MessagesBridge, OnMessagesDelivered}, - LaneId, MessageNonce, + MessageNonce, }; use bp_xcm_bridge_hub::{BridgeId, BridgeState, LocalXcmChannelManager, XcmAsPlainPayload}; use frame_support::{ensure, traits::Get}; @@ -62,7 +62,7 @@ where type Ticket = ( BridgeId, BridgeOf, - as MessagesBridge>::SendMessageArgs, + as MessagesBridge>::SendMessageArgs, XcmHash, ); @@ -198,8 +198,8 @@ where } } -impl, I: 'static> OnMessagesDelivered for Pallet { - fn on_messages_delivered(lane_id: LaneId, enqueued_messages: MessageNonce) { +impl, I: 'static> OnMessagesDelivered for Pallet { + fn on_messages_delivered(lane_id: T::LaneId, enqueued_messages: MessageNonce) { Self::on_bridge_messages_delivered(lane_id, enqueued_messages); } } @@ -273,7 +273,7 @@ impl, I: 'static> Pallet { } /// Must be called whenever we receive a message delivery confirmation. - fn on_bridge_messages_delivered(lane_id: LaneId, enqueued_messages: MessageNonce) { + fn on_bridge_messages_delivered(lane_id: T::LaneId, enqueued_messages: MessageNonce) { // if the bridge queue is still congested, we don't want to do anything let is_congested = enqueued_messages > OUTBOUND_LANE_UNCONGESTED_THRESHOLD; if is_congested { @@ -381,7 +381,7 @@ mod tests { BridgedUniversalDestination::get() } - fn open_lane() -> (BridgeLocations, LaneId) { + fn open_lane() -> (BridgeLocations, TestLaneIdType) { // open expected outbound lane let origin = OpenBridgeOrigin::sibling_parachain_origin(); let with = bridged_asset_hub_universal_location(); @@ -438,7 +438,7 @@ mod tests { (*locations, lane_id) } - fn open_lane_and_send_regular_message() -> (BridgeId, LaneId) { + fn open_lane_and_send_regular_message() -> (BridgeId, TestLaneIdType) { let (locations, lane_id) = open_lane(); // now let's try to enqueue message using our `ExportXcm` implementation diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 02e6753c3755..8e7632f9eabd 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -143,7 +143,7 @@ #![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -use bp_messages::{LaneId, LaneIdBytes, LaneState, MessageNonce}; +use bp_messages::{LaneState, MessageNonce}; use bp_runtime::{AccountIdOf, BalanceOf, RangeInclusiveExt}; pub use bp_xcm_bridge_hub::{Bridge, BridgeId, BridgeState}; use bp_xcm_bridge_hub::{BridgeLocations, BridgeLocationsError, LocalXcmChannelManager}; @@ -247,10 +247,13 @@ pub mod pallet { } /// An alias for the bridge metadata. - pub type BridgeOf = Bridge>; + pub type BridgeOf = Bridge, LaneIdOf>; /// An alias for this chain. pub type ThisChainOf = pallet_bridge_messages::ThisChainOf>::BridgeMessagesPalletInstance>; + /// An alias for lane identifier type. + type LaneIdOf = + >::BridgeMessagesPalletInstance>>::LaneId; /// An alias for the associated lanes manager. pub type LanesManagerOf = pallet_bridge_messages::LanesManager>::BridgeMessagesPalletInstance>; @@ -450,7 +453,7 @@ pub mod pallet { impl, I: 'static> Pallet { pub(crate) fn do_open_bridge( locations: Box, - lane_id: LaneId, + lane_id: T::LaneId, create_lanes: bool, ) -> Result<(), DispatchError> { // reserve balance on the origin's sovereign account (if needed) @@ -590,7 +593,7 @@ pub mod pallet { } /// Return bridge metadata by lane_id - pub fn bridge_by_lane_id(lane_id: &LaneId) -> Option<(BridgeId, BridgeOf)> { + pub fn bridge_by_lane_id(lane_id: &T::LaneId) -> Option<(BridgeId, BridgeOf)> { LaneToBridge::::get(lane_id) .and_then(|bridge_id| Self::bridge(&bridge_id).map(|bridge| (bridge_id, bridge))) } @@ -638,7 +641,7 @@ pub mod pallet { pub fn do_try_state_for_bridge( bridge_id: BridgeId, bridge: BridgeOf, - ) -> Result { + ) -> Result { log::info!(target: LOG_TARGET, "Checking `do_try_state_for_bridge` for bridge_id: {bridge_id:?} and bridge: {bridge:?}"); // check `BridgeId` points to the same `LaneId` and vice versa. @@ -716,7 +719,7 @@ pub mod pallet { /// All registered `lane_id` and `bridge_id` mappings. #[pallet::storage] pub type LaneToBridge, I: 'static = ()> = - StorageMap<_, Identity, LaneId, BridgeId>; + StorageMap<_, Identity, T::LaneId, BridgeId>; #[pallet::genesis_config] #[derive(DefaultNoBound)] @@ -726,7 +729,7 @@ pub mod pallet { /// Keep in mind that we are **NOT** reserving any amount for the bridges opened at /// genesis. We are **NOT** opening lanes, used by this bridge. It all must be done using /// other pallets genesis configuration or some other means. - pub opened_bridges: Vec<(Location, InteriorLocation, Option)>, + pub opened_bridges: Vec<(Location, InteriorLocation, Option)>, /// Dummy marker. #[serde(skip)] pub _phantom: sp_std::marker::PhantomData<(T, I)>, @@ -805,14 +808,14 @@ pub mod pallet { /// Universal location of remote bridge endpoint. remote_endpoint: Box, /// Lane identifier. - lane_id: LaneIdBytes, + lane_id: T::LaneId, }, /// Bridge is going to be closed, but not yet fully pruned from the runtime storage. ClosingBridge { /// Bridge identifier. bridge_id: BridgeId, /// Lane identifier. - lane_id: LaneIdBytes, + lane_id: T::LaneId, /// Number of pruned messages during the close call. pruned_messages: MessageNonce, /// Number of enqueued messages that need to be pruned in follow up calls. @@ -824,7 +827,7 @@ pub mod pallet { /// Bridge identifier. bridge_id: BridgeId, /// Lane identifier. - lane_id: LaneIdBytes, + lane_id: T::LaneId, /// Amount of deposit released. bridge_deposit: BalanceOf>, /// Number of pruned messages during the close call. @@ -858,12 +861,11 @@ pub mod pallet { #[cfg(test)] mod tests { use super::*; + use bp_messages::LaneIdType; use mock::*; - use bp_messages::LaneId; use frame_support::{assert_err, assert_noop, assert_ok, traits::fungible::Mutate, BoundedVec}; use frame_system::{EventRecord, Phase}; - use sp_core::H256; use sp_runtime::TryRuntimeError; fn fund_origin_sovereign_account(locations: &BridgeLocations, balance: Balance) -> AccountId { @@ -920,7 +922,7 @@ mod tests { mock_open_bridge_from_with(origin, deposit, bridged_asset_hub_universal_location()) } - fn enqueue_message(lane: LaneId) { + fn enqueue_message(lane: TestLaneIdType) { let lanes_manager = LanesManagerOf::::new(); lanes_manager .active_outbound_lane(lane) @@ -1465,8 +1467,6 @@ mod tests { #[test] fn do_try_state_works() { - use sp_runtime::Either; - let bridge_origin_relative_location = SiblingLocation::get(); let bridge_origin_universal_location = SiblingUniversalLocation::get(); let bridge_destination_universal_location = BridgedUniversalDestination::get(); @@ -1480,8 +1480,8 @@ mod tests { &bridge_destination_universal_location, ); let bridge_id_mismatch = BridgeId::new(&InteriorLocation::Here, &InteriorLocation::Here); - let lane_id = LaneId::from_inner(Either::Left(H256::default())); - let lane_id_mismatch = LaneId::from_inner(Either::Left(H256::from([1u8; 32]))); + let lane_id = TestLaneIdType::new(1, 2); + let lane_id_mismatch = TestLaneIdType::new(3, 4); let test_bridge_state = |id, bridge, diff --git a/bridges/modules/xcm-bridge-hub/src/migration.rs b/bridges/modules/xcm-bridge-hub/src/migration.rs index c9d8b67176a5..ffd5233a917b 100644 --- a/bridges/modules/xcm-bridge-hub/src/migration.rs +++ b/bridges/modules/xcm-bridge-hub/src/migration.rs @@ -17,7 +17,6 @@ //! A module that is responsible for migration of storage. use crate::{Config, Pallet, LOG_TARGET}; -use bp_messages::LaneId; use frame_support::{ traits::{Get, OnRuntimeUpgrade, StorageVersion}, weights::Weight, @@ -52,7 +51,7 @@ pub struct OpenBridgeForLane< impl< T: Config, I: 'static, - Lane: Get, + Lane: Get, CreateLane: Get, SourceRelativeLocation: Get, BridgedUniversalLocation: Get, diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 4d76b56aeb4c..db13f70d69b4 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -20,7 +20,7 @@ use crate as pallet_xcm_bridge_hub; use bp_messages::{ target_chain::{DispatchMessage, MessageDispatch}, - ChainWithMessages, LaneId, MessageNonce, + ChainWithMessages, HashedLaneId, MessageNonce, }; use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, HashOf}; use bp_xcm_bridge_hub::{BridgeId, LocalXcmChannelManager}; @@ -49,6 +49,8 @@ use xcm_executor::XcmExecutor; pub type AccountId = AccountId32; pub type Balance = u64; type Block = frame_system::mocking::MockBlock; +/// Lane identifier type used for tests. +pub type TestLaneIdType = HashedLaneId; pub const SIBLING_ASSET_HUB_ID: u32 = 2001; pub const THIS_BRIDGE_HUB_ID: u32 = 2002; @@ -92,6 +94,7 @@ impl pallet_bridge_messages::Config for TestRuntime { type OutboundPayload = Vec; type InboundPayload = Vec; + type LaneId = HashedLaneId; type DeliveryPayments = (); type DeliveryConfirmationPayments = (); @@ -523,7 +526,7 @@ impl bp_header_chain::HeaderChain for BridgedHeaderChain pub struct TestMessageDispatch; impl TestMessageDispatch { - pub fn deactivate(lane: LaneId) { + pub fn deactivate(lane: TestLaneIdType) { frame_support::storage::unhashed::put(&(b"inactive", lane).encode()[..], &false); } } @@ -531,18 +534,21 @@ impl TestMessageDispatch { impl MessageDispatch for TestMessageDispatch { type DispatchPayload = Vec; type DispatchLevelResult = (); + type LaneId = TestLaneIdType; - fn is_active(lane: LaneId) -> bool { + fn is_active(lane: TestLaneIdType) -> bool { frame_support::storage::unhashed::take::(&(b"inactive", lane).encode()[..]) != Some(false) } - fn dispatch_weight(_message: &mut DispatchMessage) -> Weight { + fn dispatch_weight( + _message: &mut DispatchMessage, + ) -> Weight { Weight::zero() } fn dispatch( - _: DispatchMessage, + _: DispatchMessage, ) -> MessageDispatchResult { MessageDispatchResult { unspent_weight: Weight::zero(), dispatch_level_result: () } } diff --git a/bridges/primitives/messages/src/lane.rs b/bridges/primitives/messages/src/lane.rs index 9ced85b3fa32..f7c0bafd909a 100644 --- a/bridges/primitives/messages/src/lane.rs +++ b/bridges/primitives/messages/src/lane.rs @@ -32,6 +32,7 @@ pub trait LaneIdType: + Debug + PartialEq + Eq + + Ord + TypeInfo + MaxEncodedLen + Serialize diff --git a/bridges/primitives/xcm-bridge-hub/src/lib.rs b/bridges/primitives/xcm-bridge-hub/src/lib.rs index 45e3090f8289..729c1374bafc 100644 --- a/bridges/primitives/xcm-bridge-hub/src/lib.rs +++ b/bridges/primitives/xcm-bridge-hub/src/lib.rs @@ -154,7 +154,7 @@ pub enum BridgeState { #[derive( CloneNoBound, Decode, Encode, Eq, PartialEqNoBound, TypeInfo, MaxEncodedLen, RuntimeDebugNoBound, )] -#[scale_info(skip_type_params(ThisChain))] +#[scale_info(skip_type_params(ThisChain, LaneId))] pub struct Bridge { /// Relative location of the bridge origin chain. This is expected to be **convertible** to the /// `latest` XCM, so the check and migration needs to be ensured. From 17d36815afcccf48e046d29cec863669cde18c84 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Mon, 16 Sep 2024 15:39:03 +0200 Subject: [PATCH 12/38] Generic `LaneId` for `pallet_bridge_relayers` --- .../chains/chain-bridge-hub-kusama/src/lib.rs | 2 +- .../chain-bridge-hub-polkadot/src/lib.rs | 2 +- .../chains/chain-bridge-hub-rococo/src/lib.rs | 2 +- .../chain-bridge-hub-westend/src/lib.rs | 2 +- .../chains/chain-polkadot-bulletin/src/lib.rs | 2 +- bridges/modules/messages/src/lib.rs | 4 +- .../relayers/src/extension/grandpa_adapter.rs | 10 +- .../src/extension/messages_adapter.rs | 8 +- bridges/modules/relayers/src/extension/mod.rs | 141 ++++++++------ .../src/extension/parachain_adapter.rs | 10 +- bridges/modules/relayers/src/lib.rs | 34 ++-- bridges/modules/relayers/src/mock.rs | 36 ++-- .../modules/relayers/src/payment_adapter.rs | 11 +- bridges/modules/relayers/src/stake_adapter.rs | 8 +- bridges/primitives/messages/src/call_info.rs | 10 +- bridges/primitives/relayers/src/extension.rs | 28 +-- bridges/primitives/relayers/src/lib.rs | 178 ++++++++++++++---- .../primitives/relayers/src/registration.rs | 18 +- bridges/primitives/runtime/src/chain.rs | 24 ++- bridges/primitives/runtime/src/lib.rs | 2 +- 20 files changed, 345 insertions(+), 187 deletions(-) diff --git a/bridges/chains/chain-bridge-hub-kusama/src/lib.rs b/bridges/chains/chain-bridge-hub-kusama/src/lib.rs index c990e8a12f36..485fb3d31f20 100644 --- a/bridges/chains/chain-bridge-hub-kusama/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-kusama/src/lib.rs @@ -93,4 +93,4 @@ pub const WITH_BRIDGE_HUB_KUSAMA_MESSAGES_PALLET_NAME: &str = "BridgeKusamaMessa pub const WITH_BRIDGE_HUB_KUSAMA_RELAYERS_PALLET_NAME: &str = "BridgeRelayers"; decl_bridge_finality_runtime_apis!(bridge_hub_kusama); -decl_bridge_messages_runtime_apis!(bridge_hub_kusama); +decl_bridge_messages_runtime_apis!(bridge_hub_kusama, LegacyLaneId); diff --git a/bridges/chains/chain-bridge-hub-polkadot/src/lib.rs b/bridges/chains/chain-bridge-hub-polkadot/src/lib.rs index 7379b8863b1d..7a1793b4da4a 100644 --- a/bridges/chains/chain-bridge-hub-polkadot/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-polkadot/src/lib.rs @@ -85,4 +85,4 @@ pub const WITH_BRIDGE_HUB_POLKADOT_MESSAGES_PALLET_NAME: &str = "BridgePolkadotM pub const WITH_BRIDGE_HUB_POLKADOT_RELAYERS_PALLET_NAME: &str = "BridgeRelayers"; decl_bridge_finality_runtime_apis!(bridge_hub_polkadot); -decl_bridge_messages_runtime_apis!(bridge_hub_polkadot); +decl_bridge_messages_runtime_apis!(bridge_hub_polkadot, LegacyLaneId); diff --git a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs index 7920eb934033..538bc44019f5 100644 --- a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs @@ -99,7 +99,7 @@ pub const WITH_BRIDGE_ROCOCO_TO_WESTEND_MESSAGES_PALLET_INDEX: u8 = 51; pub const WITH_BRIDGE_ROCOCO_TO_BULLETIN_MESSAGES_PALLET_INDEX: u8 = 61; decl_bridge_finality_runtime_apis!(bridge_hub_rococo); -decl_bridge_messages_runtime_apis!(bridge_hub_rococo); +decl_bridge_messages_runtime_apis!(bridge_hub_rococo, LegacyLaneId); frame_support::parameter_types! { /// The XCM fee that is paid for executing XCM program (with `ExportMessage` instruction) at the Rococo diff --git a/bridges/chains/chain-bridge-hub-westend/src/lib.rs b/bridges/chains/chain-bridge-hub-westend/src/lib.rs index 644fa64c687b..7a213fdb28c8 100644 --- a/bridges/chains/chain-bridge-hub-westend/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-westend/src/lib.rs @@ -88,7 +88,7 @@ pub const WITH_BRIDGE_HUB_WESTEND_RELAYERS_PALLET_NAME: &str = "BridgeRelayers"; pub const WITH_BRIDGE_WESTEND_TO_ROCOCO_MESSAGES_PALLET_INDEX: u8 = 44; decl_bridge_finality_runtime_apis!(bridge_hub_westend); -decl_bridge_messages_runtime_apis!(bridge_hub_westend); +decl_bridge_messages_runtime_apis!(bridge_hub_westend, LegacyLaneId); frame_support::parameter_types! { /// The XCM fee that is paid for executing XCM program (with `ExportMessage` instruction) at the Westend diff --git a/bridges/chains/chain-polkadot-bulletin/src/lib.rs b/bridges/chains/chain-polkadot-bulletin/src/lib.rs index 88980a957501..18cc0462109d 100644 --- a/bridges/chains/chain-polkadot-bulletin/src/lib.rs +++ b/bridges/chains/chain-polkadot-bulletin/src/lib.rs @@ -228,4 +228,4 @@ impl ChainWithMessages for PolkadotBulletin { } decl_bridge_finality_runtime_apis!(polkadot_bulletin, grandpa); -decl_bridge_messages_runtime_apis!(polkadot_bulletin); +decl_bridge_messages_runtime_apis!(polkadot_bulletin, LegacyLaneId); diff --git a/bridges/modules/messages/src/lib.rs b/bridges/modules/messages/src/lib.rs index 657c3b902be3..af14257db99c 100644 --- a/bridges/modules/messages/src/lib.rs +++ b/bridges/modules/messages/src/lib.rs @@ -123,7 +123,7 @@ pub mod pallet { type OutboundPayload: Parameter + Size; /// Payload type of inbound messages. This payload is dispatched on this chain. type InboundPayload: Decode; - /// Type of a lane identifier. + /// Lane identifier type. type LaneId: LaneIdType; /// Handler for relayer payments that happen during message delivery transaction. @@ -150,6 +150,8 @@ pub mod pallet { pub type BridgedChainOf = >::BridgedChain; /// Shortcut to bridged header chain type for Config. pub type BridgedHeaderChainOf = >::BridgedHeaderChain; + /// Shortcut to lane identifier type for Config. + pub type LaneIdOf = >::LaneId; #[pallet::pallet] #[pallet::storage_version(migration::STORAGE_VERSION)] diff --git a/bridges/modules/relayers/src/extension/grandpa_adapter.rs b/bridges/modules/relayers/src/extension/grandpa_adapter.rs index 6c9ae1c2968c..a0f2f7d815e0 100644 --- a/bridges/modules/relayers/src/extension/grandpa_adapter.rs +++ b/bridges/modules/relayers/src/extension/grandpa_adapter.rs @@ -30,7 +30,7 @@ use pallet_bridge_grandpa::{ SubmitFinalityProofHelper, }; use pallet_bridge_messages::{ - CallSubType as BridgeMessagesCallSubType, Config as BridgeMessagesConfig, + CallSubType as BridgeMessagesCallSubType, Config as BridgeMessagesConfig, LaneIdOf, }; use sp_runtime::{ traits::{Dispatchable, Get}, @@ -86,13 +86,13 @@ where type Runtime = R; type BridgeMessagesPalletInstance = MI; type PriorityBoostPerMessage = P; - type Reward = R::Reward; type RemoteGrandpaChainBlockNumber = pallet_bridge_grandpa::BridgedBlockNumber; + type LaneId = LaneIdOf; fn parse_and_check_for_obsolete_call( call: &R::RuntimeCall, ) -> Result< - Option>, + Option>, TransactionValidityError, > { let calls = BCU::unpack(call, 2); @@ -120,7 +120,7 @@ where } fn check_call_result( - call_info: &ExtensionCallInfo, + call_info: &ExtensionCallInfo, call_data: &mut ExtensionCallData, relayer: &R::AccountId, ) -> bool { @@ -134,7 +134,7 @@ where /// /// Only returns false when GRANDPA chain state update call has failed. pub(crate) fn verify_submit_finality_proof_succeeded( - call_info: &ExtensionCallInfo, + call_info: &ExtensionCallInfo, call_data: &mut ExtensionCallData, relayer: &::AccountId, ) -> bool diff --git a/bridges/modules/relayers/src/extension/messages_adapter.rs b/bridges/modules/relayers/src/extension/messages_adapter.rs index ecb575524bb0..29002f94ab2b 100644 --- a/bridges/modules/relayers/src/extension/messages_adapter.rs +++ b/bridges/modules/relayers/src/extension/messages_adapter.rs @@ -23,7 +23,7 @@ use bp_relayers::{ExtensionCallData, ExtensionCallInfo, ExtensionConfig}; use bp_runtime::StaticStrProvider; use frame_support::dispatch::{DispatchInfo, PostDispatchInfo}; use pallet_bridge_messages::{ - CallSubType as BridgeMessagesCallSubType, Config as BridgeMessagesConfig, + CallSubType as BridgeMessagesCallSubType, Config as BridgeMessagesConfig, LaneIdOf, }; use sp_runtime::{ traits::{Dispatchable, Get}, @@ -64,13 +64,13 @@ where type Runtime = R; type BridgeMessagesPalletInstance = MI; type PriorityBoostPerMessage = P; - type Reward = R::Reward; type RemoteGrandpaChainBlockNumber = (); + type LaneId = LaneIdOf; fn parse_and_check_for_obsolete_call( call: &R::RuntimeCall, ) -> Result< - Option>, + Option>, TransactionValidityError, > { let call = Self::check_obsolete_parsed_call(call)?; @@ -85,7 +85,7 @@ where } fn check_call_result( - call_info: &ExtensionCallInfo, + call_info: &ExtensionCallInfo, call_data: &mut ExtensionCallData, relayer: &R::AccountId, ) -> bool { diff --git a/bridges/modules/relayers/src/extension/mod.rs b/bridges/modules/relayers/src/extension/mod.rs index e1a7abd0ad1c..8f9b7e567776 100644 --- a/bridges/modules/relayers/src/extension/mod.rs +++ b/bridges/modules/relayers/src/extension/mod.rs @@ -36,7 +36,9 @@ use frame_support::{ CloneNoBound, DefaultNoBound, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound, }; use frame_system::Config as SystemConfig; -use pallet_bridge_messages::{CallHelper as MessagesCallHelper, Config as BridgeMessagesConfig}; +use pallet_bridge_messages::{ + CallHelper as MessagesCallHelper, Config as BridgeMessagesConfig, LaneIdOf, +}; use pallet_transaction_payment::{ Config as TransactionPaymentConfig, OnChargeTransaction, Pallet as TransactionPaymentPallet, }; @@ -62,15 +64,19 @@ mod priority; /// Data that is crafted in `pre_dispatch` method and used at `post_dispatch`. #[cfg_attr(test, derive(Debug, PartialEq))] -pub struct PreDispatchData { +pub struct PreDispatchData< + AccountId, + RemoteGrandpaChainBlockNumber: Debug, + LaneId: Clone + Copy + Debug, +> { /// Transaction submitter (relayer) account. relayer: AccountId, /// Type of the call. - call_info: ExtensionCallInfo, + call_info: ExtensionCallInfo, } -impl - PreDispatchData +impl + PreDispatchData { /// Returns mutable reference to pre-dispatch `finality_target` sent to the /// `SubmitFinalityProof` call. @@ -88,13 +94,13 @@ impl /// The actions on relayer account that need to be performed because of his actions. #[derive(RuntimeDebug, PartialEq)] -pub enum RelayerAccountAction { +pub enum RelayerAccountAction { /// Do nothing with relayer account. None, /// Reward the relayer. - Reward(AccountId, RewardsAccountParams, Reward), + Reward(AccountId, RewardsAccountParams, Reward), /// Slash the relayer. - Slash(AccountId, RewardsAccountParams), + Slash(AccountId, RewardsAccountParams), } /// A signed extension, built around `pallet-bridge-relayers`. @@ -112,19 +118,22 @@ pub enum RelayerAccountAction { RuntimeDebugNoBound, TypeInfo, )] -#[scale_info(skip_type_params(Runtime, Config))] -pub struct BridgeRelayersSignedExtension(PhantomData<(Runtime, Config)>); +#[scale_info(skip_type_params(Runtime, Config, LaneId))] +pub struct BridgeRelayersSignedExtension( + PhantomData<(Runtime, Config, LaneId)>, +); -impl BridgeRelayersSignedExtension +impl BridgeRelayersSignedExtension where Self: 'static + Send + Sync, - R: RelayersConfig - + BridgeMessagesConfig + R: RelayersConfig + + BridgeMessagesConfig + TransactionPaymentConfig, - C: ExtensionConfig, + C: ExtensionConfig, R::RuntimeCall: Dispatchable, ::OnChargeTransaction: OnChargeTransaction, + LaneId: Clone + Copy + Decode + Encode + Debug + TypeInfo, { /// Returns number of bundled messages `Some(_)`, if the given call info is a: /// @@ -136,7 +145,7 @@ where /// virtually boosted. The relayer registration (we only boost priority for registered /// relayer transactions) must be checked outside. fn bundled_messages_for_priority_boost( - call_info: Option<&ExtensionCallInfo>, + call_info: Option<&ExtensionCallInfo>, ) -> Option { // we only boost priority of message delivery transactions let parsed_call = match call_info { @@ -160,18 +169,22 @@ where /// Given post-dispatch information, analyze the outcome of relayer call and return /// actions that need to be performed on relayer account. fn analyze_call_result( - pre: Option>>, + pre: Option< + Option>, + >, info: &DispatchInfo, post_info: &PostDispatchInfo, len: usize, result: &DispatchResult, - ) -> RelayerAccountAction { + ) -> RelayerAccountAction { // We don't refund anything for transactions that we don't support. let (relayer, call_info) = match pre { Some(Some(pre)) => (pre.relayer, pre.call_info), _ => return RelayerAccountAction::None, }; + // lane_id.as_32-byte stuff to trait + // now we know that the call is supported and we may need to reward or slash relayer // => let's prepare the correspondent account that pays reward/receives slashed amount let lane_id = call_info.messages_call_info().lane_id(); @@ -263,22 +276,23 @@ where } } -impl SignedExtension for BridgeRelayersSignedExtension +impl SignedExtension for BridgeRelayersSignedExtension where Self: 'static + Send + Sync, - R: RelayersConfig - + BridgeMessagesConfig + R: RelayersConfig + + BridgeMessagesConfig + TransactionPaymentConfig, - C: ExtensionConfig, + C: ExtensionConfig, R::RuntimeCall: Dispatchable, ::OnChargeTransaction: OnChargeTransaction, + LaneId: Clone + Copy + Decode + Encode + Debug + TypeInfo, { const IDENTIFIER: &'static str = C::IdProvider::STR; type AccountId = R::AccountId; type Call = R::RuntimeCall; type AdditionalSigned = (); - type Pre = Option>; + type Pre = Option>; fn additional_signed(&self) -> Result<(), TransactionValidityError> { Ok(()) @@ -363,7 +377,7 @@ where let lane_id = pre .as_ref() .and_then(|p| p.as_ref()) - .map(|p| p.call_info.messages_call_info().lane_id()); + .map(|p| p.call_info.messages_call_info().lane_id().clone()); let call_result = Self::analyze_call_result(pre, info, post_info, len, result); match call_result { @@ -393,17 +407,19 @@ where /// Verify that the messages pallet call, supported by extension has succeeded. pub(crate) fn verify_messages_call_succeeded( - call_info: &ExtensionCallInfo, + call_info: &ExtensionCallInfo>, _call_data: &mut ExtensionCallData, relayer: &::AccountId, ) -> bool where C: ExtensionConfig, + // TODO: pouit z C::BridgeInstance MI: 'static, C::Runtime: BridgeMessagesConfig, { let messages_call = call_info.messages_call_info(); + // TODO: if !MessagesCallHelper::::was_successful(messages_call) { log::trace!( target: LOG_TARGET, @@ -427,9 +443,9 @@ mod tests { use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, target_chain::FromBridgedChainMessagesProof, BaseMessagesProofInfo, DeliveredMessages, - InboundLaneData, LaneId, MessageNonce, MessagesCallInfo, MessagesOperatingMode, - OutboundLaneData, ReceiveMessagesDeliveryProofInfo, ReceiveMessagesProofInfo, - UnrewardedRelayer, UnrewardedRelayerOccupation, UnrewardedRelayersState, + InboundLaneData, MessageNonce, MessagesCallInfo, MessagesOperatingMode, OutboundLaneData, + ReceiveMessagesDeliveryProofInfo, ReceiveMessagesProofInfo, UnrewardedRelayer, + UnrewardedRelayerOccupation, UnrewardedRelayersState, }; use bp_parachains::{BestParaHeadHash, ParaInfo, SubmitParachainHeadsInfo}; use bp_polkadot_core::parachains::{ParaHeadsProof, ParaId}; @@ -454,17 +470,16 @@ mod tests { parameter_types! { TestParachain: u32 = BridgedUnderlyingParachain::PARACHAIN_ID; - pub MsgProofsRewardsAccount: RewardsAccountParams = RewardsAccountParams::new( + pub MsgProofsRewardsAccount: RewardsAccountParams = RewardsAccountParams::new( test_lane_id(), TEST_BRIDGED_CHAIN_ID, RewardsAccountOwner::ThisChain, ); - pub MsgDeliveryProofsRewardsAccount: RewardsAccountParams = RewardsAccountParams::new( + pub MsgDeliveryProofsRewardsAccount: RewardsAccountParams = RewardsAccountParams::new( test_lane_id(), TEST_BRIDGED_CHAIN_ID, RewardsAccountOwner::BridgedChain, ); - pub TestLaneId: LaneId = test_lane_id(); } bp_runtime::generate_static_str_provider!(TestGrandpaExtension); @@ -480,7 +495,7 @@ mod tests { ConstU64<1>, >; type TestGrandpaExtension = - BridgeRelayersSignedExtension; + BridgeRelayersSignedExtension; type TestExtensionConfig = parachain_adapter::WithParachainExtensionConfig< StrTestExtension, TestRuntime, @@ -489,7 +504,8 @@ mod tests { (), ConstU64<1>, >; - type TestExtension = BridgeRelayersSignedExtension; + type TestExtension = + BridgeRelayersSignedExtension; type TestMessagesExtensionConfig = messages_adapter::WithMessagesExtensionConfig< StrTestMessagesExtension, TestRuntime, @@ -497,11 +513,7 @@ mod tests { ConstU64<1>, >; type TestMessagesExtension = - BridgeRelayersSignedExtension; - - fn test_lane_id() -> LaneId { - LaneId::new(1, 2) - } + BridgeRelayersSignedExtension; fn initial_balance_of_relayer_account_at_this_chain() -> ThisChainBalance { let test_stake: ThisChainBalance = Stake::get(); @@ -795,7 +807,7 @@ mod tests { } fn all_finality_pre_dispatch_data( - ) -> PreDispatchData { + ) -> PreDispatchData { PreDispatchData { relayer: relayer_account_at_this_chain(), call_info: ExtensionCallInfo::AllFinalityAndMsgs( @@ -832,14 +844,14 @@ mod tests { #[cfg(test)] fn all_finality_pre_dispatch_data_ex( - ) -> PreDispatchData { + ) -> PreDispatchData { let mut data = all_finality_pre_dispatch_data(); data.submit_finality_proof_info_mut().unwrap().current_set_id = Some(TEST_GRANDPA_SET_ID); data } fn all_finality_confirmation_pre_dispatch_data( - ) -> PreDispatchData { + ) -> PreDispatchData { PreDispatchData { relayer: relayer_account_at_this_chain(), call_info: ExtensionCallInfo::AllFinalityAndMsgs( @@ -869,14 +881,14 @@ mod tests { } fn all_finality_confirmation_pre_dispatch_data_ex( - ) -> PreDispatchData { + ) -> PreDispatchData { let mut data = all_finality_confirmation_pre_dispatch_data(); data.submit_finality_proof_info_mut().unwrap().current_set_id = Some(TEST_GRANDPA_SET_ID); data } fn relay_finality_pre_dispatch_data( - ) -> PreDispatchData { + ) -> PreDispatchData { PreDispatchData { relayer: relayer_account_at_this_chain(), call_info: ExtensionCallInfo::RelayFinalityAndMsgs( @@ -906,14 +918,14 @@ mod tests { } fn relay_finality_pre_dispatch_data_ex( - ) -> PreDispatchData { + ) -> PreDispatchData { let mut data = relay_finality_pre_dispatch_data(); data.submit_finality_proof_info_mut().unwrap().current_set_id = Some(TEST_GRANDPA_SET_ID); data } fn relay_finality_confirmation_pre_dispatch_data( - ) -> PreDispatchData { + ) -> PreDispatchData { PreDispatchData { relayer: relayer_account_at_this_chain(), call_info: ExtensionCallInfo::RelayFinalityAndMsgs( @@ -937,14 +949,14 @@ mod tests { } fn relay_finality_confirmation_pre_dispatch_data_ex( - ) -> PreDispatchData { + ) -> PreDispatchData { let mut data = relay_finality_confirmation_pre_dispatch_data(); data.submit_finality_proof_info_mut().unwrap().current_set_id = Some(TEST_GRANDPA_SET_ID); data } fn parachain_finality_pre_dispatch_data( - ) -> PreDispatchData { + ) -> PreDispatchData { PreDispatchData { relayer: relayer_account_at_this_chain(), call_info: ExtensionCallInfo::ParachainFinalityAndMsgs( @@ -972,7 +984,7 @@ mod tests { } fn parachain_finality_confirmation_pre_dispatch_data( - ) -> PreDispatchData { + ) -> PreDispatchData { PreDispatchData { relayer: relayer_account_at_this_chain(), call_info: ExtensionCallInfo::ParachainFinalityAndMsgs( @@ -994,7 +1006,7 @@ mod tests { } fn delivery_pre_dispatch_data( - ) -> PreDispatchData { + ) -> PreDispatchData { PreDispatchData { relayer: relayer_account_at_this_chain(), call_info: ExtensionCallInfo::Msgs(MessagesCallInfo::ReceiveMessagesProof( @@ -1016,7 +1028,7 @@ mod tests { } fn confirmation_pre_dispatch_data( - ) -> PreDispatchData { + ) -> PreDispatchData { PreDispatchData { relayer: relayer_account_at_this_chain(), call_info: ExtensionCallInfo::Msgs(MessagesCallInfo::ReceiveMessagesDeliveryProof( @@ -1030,9 +1042,13 @@ mod tests { } fn set_bundled_range_end( - mut pre_dispatch_data: PreDispatchData, + mut pre_dispatch_data: PreDispatchData< + ThisChainAccountId, + BridgedChainBlockNumber, + TestLaneIdType, + >, end: MessageNonce, - ) -> PreDispatchData { + ) -> PreDispatchData { let msg_info = match pre_dispatch_data.call_info { ExtensionCallInfo::AllFinalityAndMsgs(_, _, ref mut info) => info, ExtensionCallInfo::RelayFinalityAndMsgs(_, ref mut info) => info, @@ -1072,7 +1088,7 @@ mod tests { fn run_pre_dispatch( call: RuntimeCall, ) -> Result< - Option>, + Option>, TransactionValidityError, > { sp_tracing::try_init_simple(); @@ -1083,7 +1099,7 @@ mod tests { fn run_grandpa_pre_dispatch( call: RuntimeCall, ) -> Result< - Option>, + Option>, TransactionValidityError, > { let extension: TestGrandpaExtension = BridgeRelayersSignedExtension(PhantomData); @@ -1092,7 +1108,10 @@ mod tests { fn run_messages_pre_dispatch( call: RuntimeCall, - ) -> Result>, TransactionValidityError> { + ) -> Result< + Option>, + TransactionValidityError, + > { let extension: TestMessagesExtension = BridgeRelayersSignedExtension(PhantomData); extension.pre_dispatch(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0) } @@ -1113,7 +1132,9 @@ mod tests { } fn run_post_dispatch( - pre_dispatch_data: Option>, + pre_dispatch_data: Option< + PreDispatchData, + >, dispatch_result: DispatchResult, ) { let post_dispatch_result = TestExtension::post_dispatch( @@ -1886,9 +1907,13 @@ mod tests { } fn run_analyze_call_result( - pre_dispatch_data: PreDispatchData, + pre_dispatch_data: PreDispatchData< + ThisChainAccountId, + BridgedChainBlockNumber, + TestLaneIdType, + >, dispatch_result: DispatchResult, - ) -> RelayerAccountAction { + ) -> RelayerAccountAction { TestExtension::analyze_call_result( Some(Some(pre_dispatch_data)), &dispatch_info(), @@ -2318,7 +2343,7 @@ mod tests { .unwrap(); // allow empty message delivery transactions - let lane_id = TestLaneId::get(); + let lane_id = test_lane_id(); let in_lane_data = InboundLaneData { last_confirmed_nonce: 0, relayers: vec![UnrewardedRelayer { diff --git a/bridges/modules/relayers/src/extension/parachain_adapter.rs b/bridges/modules/relayers/src/extension/parachain_adapter.rs index b6f57cebc309..e9013e535fee 100644 --- a/bridges/modules/relayers/src/extension/parachain_adapter.rs +++ b/bridges/modules/relayers/src/extension/parachain_adapter.rs @@ -32,7 +32,7 @@ use pallet_bridge_grandpa::{ CallSubType as BridgeGrandpaCallSubtype, Config as BridgeGrandpaConfig, }; use pallet_bridge_messages::{ - CallSubType as BridgeMessagesCallSubType, Config as BridgeMessagesConfig, + CallSubType as BridgeMessagesCallSubType, Config as BridgeMessagesConfig, LaneIdOf, }; use pallet_bridge_parachains::{ CallSubType as BridgeParachainsCallSubtype, Config as BridgeParachainsConfig, @@ -92,14 +92,14 @@ where type Runtime = R; type BridgeMessagesPalletInstance = MI; type PriorityBoostPerMessage = P; - type Reward = R::Reward; type RemoteGrandpaChainBlockNumber = pallet_bridge_grandpa::BridgedBlockNumber; + type LaneId = LaneIdOf; fn parse_and_check_for_obsolete_call( call: &R::RuntimeCall, ) -> Result< - Option>, + Option>, TransactionValidityError, > { let calls = BCU::unpack(call, 3); @@ -139,7 +139,7 @@ where } fn check_call_result( - call_info: &ExtensionCallInfo, + call_info: &ExtensionCallInfo, call_data: &mut ExtensionCallData, relayer: &R::AccountId, ) -> bool { @@ -155,7 +155,7 @@ where /// /// Only returns false when parachain state update call has failed. pub(crate) fn verify_submit_parachain_head_succeeded( - call_info: &ExtensionCallInfo, + call_info: &ExtensionCallInfo, _call_data: &mut ExtensionCallData, relayer: &::AccountId, ) -> bool diff --git a/bridges/modules/relayers/src/lib.rs b/bridges/modules/relayers/src/lib.rs index b9627774db1e..2adc2b6c292e 100644 --- a/bridges/modules/relayers/src/lib.rs +++ b/bridges/modules/relayers/src/lib.rs @@ -51,12 +51,16 @@ pub const LOG_TARGET: &str = "runtime::bridge-relayers"; #[frame_support::pallet] pub mod pallet { use super::*; + use bp_messages::LaneIdType; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; /// `RelayerRewardsKeyProvider` for given configuration. - type RelayerRewardsKeyProviderOf = - RelayerRewardsKeyProvider<::AccountId, ::Reward>; + type RelayerRewardsKeyProviderOf = RelayerRewardsKeyProvider< + ::AccountId, + ::Reward, + ::LaneId, + >; #[pallet::config] pub trait Config: frame_system::Config { @@ -65,11 +69,17 @@ pub mod pallet { /// Type of relayer reward. type Reward: AtLeast32BitUnsigned + Copy + Member + Parameter + MaxEncodedLen; /// Pay rewards scheme. - type PaymentProcedure: PaymentProcedure; + type PaymentProcedure: PaymentProcedure< + Self::AccountId, + Self::Reward, + LaneId = Self::LaneId, + >; /// Stake and slash scheme. type StakeAndSlash: StakeAndSlash, Self::Reward>; /// Pallet call weights. type WeightInfo: WeightInfoExt; + /// Lane identifier type. + type LaneId: LaneIdType + Send + Sync; } #[pallet::pallet] @@ -82,7 +92,7 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::claim_rewards())] pub fn claim_rewards( origin: OriginFor, - rewards_account_params: RewardsAccountParams, + rewards_account_params: RewardsAccountParams, ) -> DispatchResult { let relayer = ensure_signed(origin)?; @@ -243,7 +253,7 @@ pub mod pallet { /// It may fail inside, but error is swallowed and we only log it. pub fn slash_and_deregister( relayer: &T::AccountId, - slash_destination: ExplicitOrAccountParams, + slash_destination: ExplicitOrAccountParams, ) { let registration = match RegisteredRelayers::::take(relayer) { Some(registration) => registration, @@ -304,7 +314,7 @@ pub mod pallet { /// Register reward for given relayer. pub fn register_relayer_reward( - rewards_account_params: RewardsAccountParams, + rewards_account_params: RewardsAccountParams, relayer: &T::AccountId, reward: T::Reward, ) { @@ -381,7 +391,7 @@ pub mod pallet { /// Relayer account that can claim reward. relayer: T::AccountId, /// Relayer can claim reward from this account. - rewards_account_params: RewardsAccountParams, + rewards_account_params: RewardsAccountParams, /// Reward amount. reward: T::Reward, }, @@ -390,7 +400,7 @@ pub mod pallet { /// Relayer account that has been rewarded. relayer: T::AccountId, /// Relayer has received reward from this account. - rewards_account_params: RewardsAccountParams, + rewards_account_params: RewardsAccountParams, /// Reward amount. reward: T::Reward, }, @@ -469,10 +479,10 @@ pub mod pallet { #[cfg(test)] mod tests { use super::*; + use bp_messages::LaneIdType; use mock::{RuntimeEvent as TestEvent, *}; use crate::Event::{RewardPaid, RewardRegistered}; - use bp_messages::LaneId; use bp_relayers::RewardsAccountOwner; use frame_support::{ assert_noop, assert_ok, @@ -596,16 +606,16 @@ mod tests { fn pay_reward_from_account_actually_pays_reward() { type Balances = pallet_balances::Pallet; type PayLaneRewardFromAccount = - bp_relayers::PayRewardFromAccount; + bp_relayers::PayRewardFromAccount; run_test(|| { let in_lane_0 = RewardsAccountParams::new( - LaneId::new(1, 2), + TestLaneIdType::new(1, 2), *b"test", RewardsAccountOwner::ThisChain, ); let out_lane_1 = RewardsAccountParams::new( - LaneId::new(1, 3), + TestLaneIdType::new(1, 3), *b"test", RewardsAccountOwner::BridgedChain, ); diff --git a/bridges/modules/relayers/src/mock.rs b/bridges/modules/relayers/src/mock.rs index de1d292b7c0f..f535aa4c62f1 100644 --- a/bridges/modules/relayers/src/mock.rs +++ b/bridges/modules/relayers/src/mock.rs @@ -21,7 +21,7 @@ use crate as pallet_bridge_relayers; use bp_header_chain::ChainWithGrandpa; use bp_messages::{ target_chain::{DispatchMessage, MessageDispatch}, - ChainWithMessages, LaneId, MessageNonce, + ChainWithMessages, HashedLaneId, LaneIdType, MessageNonce, }; use bp_parachains::SingleParaStoredHeaderDataBuilder; use bp_relayers::{ @@ -74,6 +74,13 @@ pub type BridgedChainHeader = pub const TEST_BRIDGED_CHAIN_ID: ChainId = *b"brdg"; /// Maximal extrinsic size at the `BridgedChain`. pub const BRIDGED_CHAIN_MAX_EXTRINSIC_SIZE: u32 = 1024; +/// Lane identifier type used for tests. +pub type TestLaneIdType = HashedLaneId; + +/// Lane that we're using in tests. +pub fn test_lane_id() -> TestLaneIdType { + TestLaneIdType::new(1, 2) +} /// Underlying chain of `ThisChain`. pub struct ThisUnderlyingChain; @@ -253,10 +260,10 @@ impl pallet_bridge_messages::Config for TestRuntime { type WeightInfo = pallet_bridge_messages::weights::BridgeWeight; type OutboundPayload = Vec; - type InboundPayload = Vec; - type DeliveryPayments = (); + type LaneId = TestLaneIdType; + type DeliveryPayments = (); type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< TestRuntime, (), @@ -276,6 +283,7 @@ impl pallet_bridge_relayers::Config for TestRuntime { type PaymentProcedure = TestPaymentProcedure; type StakeAndSlash = TestStakeAndSlash; type WeightInfo = (); + type LaneId = TestLaneIdType; } #[cfg(feature = "runtime-benchmarks")] @@ -306,17 +314,18 @@ pub const REGISTER_RELAYER: ThisChainAccountId = 42; pub struct TestPaymentProcedure; impl TestPaymentProcedure { - pub fn rewards_account(params: RewardsAccountParams) -> ThisChainAccountId { - PayRewardFromAccount::<(), ThisChainAccountId>::rewards_account(params) + pub fn rewards_account(params: RewardsAccountParams) -> ThisChainAccountId { + PayRewardFromAccount::<(), ThisChainAccountId, TestLaneIdType>::rewards_account(params) } } impl PaymentProcedure for TestPaymentProcedure { type Error = (); + type LaneId = TestLaneIdType; fn pay_reward( relayer: &ThisChainAccountId, - _lane_id: RewardsAccountParams, + _lane_id: RewardsAccountParams, _reward: ThisChainBalance, ) -> Result<(), Self::Error> { match *relayer { @@ -330,7 +339,7 @@ impl PaymentProcedure for TestPaymentProce pub struct DummyMessageDispatch; impl DummyMessageDispatch { - pub fn deactivate(lane: LaneId) { + pub fn deactivate(lane: TestLaneIdType) { frame_support::storage::unhashed::put(&(b"inactive", lane).encode()[..], &false); } } @@ -338,26 +347,29 @@ impl DummyMessageDispatch { impl MessageDispatch for DummyMessageDispatch { type DispatchPayload = Vec; type DispatchLevelResult = (); + type LaneId = TestLaneIdType; - fn is_active(lane: LaneId) -> bool { + fn is_active(lane: TestLaneIdType) -> bool { frame_support::storage::unhashed::take::(&(b"inactive", lane).encode()[..]) != Some(false) } - fn dispatch_weight(_message: &mut DispatchMessage) -> Weight { + fn dispatch_weight( + _message: &mut DispatchMessage, + ) -> Weight { Weight::zero() } fn dispatch( - _: DispatchMessage, + _: DispatchMessage, ) -> MessageDispatchResult { MessageDispatchResult { unspent_weight: Weight::zero(), dispatch_level_result: () } } } /// Reward account params that we are using in tests. -pub fn test_reward_account_param() -> RewardsAccountParams { - RewardsAccountParams::new(LaneId::new(1, 2), *b"test", RewardsAccountOwner::ThisChain) +pub fn test_reward_account_param() -> RewardsAccountParams { + RewardsAccountParams::new(TestLaneIdType::new(1, 2), *b"test", RewardsAccountOwner::ThisChain) } /// Return test externalities to use in tests. diff --git a/bridges/modules/relayers/src/payment_adapter.rs b/bridges/modules/relayers/src/payment_adapter.rs index 3693793a3e5c..5383cba5ecbd 100644 --- a/bridges/modules/relayers/src/payment_adapter.rs +++ b/bridges/modules/relayers/src/payment_adapter.rs @@ -20,11 +20,12 @@ use crate::{Config, Pallet}; use bp_messages::{ source_chain::{DeliveryConfirmationPayments, RelayersRewards}, - LaneId, MessageNonce, + MessageNonce, }; use bp_relayers::{RewardsAccountOwner, RewardsAccountParams}; use bp_runtime::Chain; use frame_support::{sp_runtime::SaturatedConversion, traits::Get}; +use pallet_bridge_messages::LaneIdOf; use sp_arithmetic::traits::{Saturating, Zero}; use sp_std::{collections::vec_deque::VecDeque, marker::PhantomData, ops::RangeInclusive}; @@ -34,17 +35,17 @@ pub struct DeliveryConfirmationPaymentsAdapter( PhantomData<(T, MI, DeliveryReward)>, ); -impl DeliveryConfirmationPayments +impl DeliveryConfirmationPayments> for DeliveryConfirmationPaymentsAdapter where - T: Config + pallet_bridge_messages::Config, + T: Config + pallet_bridge_messages::Config::LaneId>, MI: 'static, DeliveryReward: Get, { type Error = &'static str; fn pay_reward( - lane_id: LaneId, + lane_id: LaneIdOf, messages_relayers: VecDeque>, confirmation_relayer: &T::AccountId, received_range: &RangeInclusive, @@ -72,7 +73,7 @@ where fn register_relayers_rewards( confirmation_relayer: &T::AccountId, relayers_rewards: RelayersRewards, - lane_id: RewardsAccountParams, + lane_id: RewardsAccountParams, delivery_fee: T::Reward, ) { // reward every relayer except `confirmation_relayer` diff --git a/bridges/modules/relayers/src/stake_adapter.rs b/bridges/modules/relayers/src/stake_adapter.rs index 0c965e9e6bff..1792f0be8316 100644 --- a/bridges/modules/relayers/src/stake_adapter.rs +++ b/bridges/modules/relayers/src/stake_adapter.rs @@ -18,7 +18,7 @@ //! mechanism of the relayers pallet. use bp_relayers::{ExplicitOrAccountParams, PayRewardFromAccount, StakeAndSlash}; -use codec::Codec; +use codec::{Codec, Decode, Encode}; use frame_support::traits::{tokens::BalanceStatus, NamedReservableCurrency}; use sp_runtime::{traits::Get, DispatchError, DispatchResult}; use sp_std::{fmt::Debug, marker::PhantomData}; @@ -53,15 +53,15 @@ where Currency::unreserve_named(&ReserveId::get(), relayer, amount) } - fn repatriate_reserved( + fn repatriate_reserved( relayer: &AccountId, - beneficiary: ExplicitOrAccountParams, + beneficiary: ExplicitOrAccountParams, amount: Currency::Balance, ) -> Result { let beneficiary_account = match beneficiary { ExplicitOrAccountParams::Explicit(account) => account, ExplicitOrAccountParams::Params(params) => - PayRewardFromAccount::<(), AccountId>::rewards_account(params), + PayRewardFromAccount::<(), AccountId, LaneId>::rewards_account(params), }; Currency::repatriate_reserved_named( &ReserveId::get(), diff --git a/bridges/primitives/messages/src/call_info.rs b/bridges/primitives/messages/src/call_info.rs index 65f1a9fb783f..dfd076f029b4 100644 --- a/bridges/primitives/messages/src/call_info.rs +++ b/bridges/primitives/messages/src/call_info.rs @@ -138,19 +138,19 @@ impl ReceiveMessagesDeliveryProofInfo { /// Info about a `ReceiveMessagesProof` or a `ReceiveMessagesDeliveryProof` call /// which tries to update a single lane. #[derive(PartialEq, RuntimeDebug)] -pub enum MessagesCallInfo { +pub enum MessagesCallInfo { /// Messages delivery call info. ReceiveMessagesProof(ReceiveMessagesProofInfo), /// Messages delivery confirmation call info. ReceiveMessagesDeliveryProof(ReceiveMessagesDeliveryProofInfo), } -impl MessagesCallInfo { +impl MessagesCallInfo { /// Returns lane, used by the call. - pub fn lane_id(&self) -> &LaneId { + pub fn lane_id(&self) -> LaneId { match *self { - Self::ReceiveMessagesProof(ref info) => &info.base.lane_id, - Self::ReceiveMessagesDeliveryProof(ref info) => &info.0.lane_id, + Self::ReceiveMessagesProof(ref info) => info.base.lane_id, + Self::ReceiveMessagesDeliveryProof(ref info) => info.0.lane_id, } } diff --git a/bridges/primitives/relayers/src/extension.rs b/bridges/primitives/relayers/src/extension.rs index 5ab8e6cde96b..22461fcf9ecf 100644 --- a/bridges/primitives/relayers/src/extension.rs +++ b/bridges/primitives/relayers/src/extension.rs @@ -21,6 +21,7 @@ use bp_header_chain::SubmitFinalityProofInfo; use bp_messages::MessagesCallInfo; use bp_parachains::SubmitParachainHeadsInfo; use bp_runtime::StaticStrProvider; +use codec::{Decode, Encode}; use frame_support::{ dispatch::CallableCallFor, traits::IsSubType, weights::Weight, RuntimeDebugNoBound, }; @@ -35,25 +36,28 @@ use sp_std::{fmt::Debug, marker::PhantomData, vec, vec::Vec}; /// Type of the call that the signed extension recognizes. #[derive(PartialEq, RuntimeDebugNoBound)] -pub enum ExtensionCallInfo { +pub enum ExtensionCallInfo { /// Relay chain finality + parachain finality + message delivery/confirmation calls. AllFinalityAndMsgs( SubmitFinalityProofInfo, SubmitParachainHeadsInfo, - MessagesCallInfo, + MessagesCallInfo, ), /// Relay chain finality + message delivery/confirmation calls. - RelayFinalityAndMsgs(SubmitFinalityProofInfo, MessagesCallInfo), + RelayFinalityAndMsgs( + SubmitFinalityProofInfo, + MessagesCallInfo, + ), /// Parachain finality + message delivery/confirmation calls. /// /// This variant is used only when bridging with parachain. - ParachainFinalityAndMsgs(SubmitParachainHeadsInfo, MessagesCallInfo), + ParachainFinalityAndMsgs(SubmitParachainHeadsInfo, MessagesCallInfo), /// Standalone message delivery/confirmation call. - Msgs(MessagesCallInfo), + Msgs(MessagesCallInfo), } -impl - ExtensionCallInfo +impl + ExtensionCallInfo { /// Returns true if call is a message delivery call (with optional finality calls). pub fn is_receive_messages_proof_call(&self) -> bool { @@ -84,7 +88,7 @@ impl } /// Returns the pre-dispatch `ReceiveMessagesProofInfo`. - pub fn messages_call_info(&self) -> &MessagesCallInfo { + pub fn messages_call_info(&self) -> &MessagesCallInfo { match self { Self::AllFinalityAndMsgs(_, _, info) => info, Self::RelayFinalityAndMsgs(_, info) => info, @@ -124,20 +128,20 @@ pub trait ExtensionConfig { /// Additional priority that is added to base message delivery transaction priority /// for every additional bundled message. type PriorityBoostPerMessage: Get; - /// Type of reward, that the `pallet-bridge-relayers` is using. - type Reward; /// Block number for the remote **GRANDPA chain**. Mind that this chain is not /// necessarily the chain that we are bridging with. If we are bridging with /// parachain, it must be its parent relay chain. If we are bridging with the /// GRANDPA chain, it must be it. type RemoteGrandpaChainBlockNumber: Clone + Copy + Debug; + /// Lane identifier type. + type LaneId: Clone + Copy + Decode + Encode + Debug; /// Given runtime call, check if it is supported by the signed extension. Additionally, /// check if call (or any of batched calls) are obsolete. fn parse_and_check_for_obsolete_call( call: &::RuntimeCall, ) -> Result< - Option>, + Option>, TransactionValidityError, >; @@ -149,7 +153,7 @@ pub trait ExtensionConfig { /// Given runtime call info, check that this call has been successful and has updated /// runtime storage accordingly. fn check_call_result( - call_info: &ExtensionCallInfo, + call_info: &ExtensionCallInfo, call_data: &mut ExtensionCallData, relayer: &::AccountId, ) -> bool; diff --git a/bridges/primitives/relayers/src/lib.rs b/bridges/primitives/relayers/src/lib.rs index e23de3074943..f6cc8e95aada 100644 --- a/bridges/primitives/relayers/src/lib.rs +++ b/bridges/primitives/relayers/src/lib.rs @@ -25,7 +25,6 @@ pub use extension::{ }; pub use registration::{ExplicitOrAccountParams, Registration, StakeAndSlash}; -use bp_messages::LaneId; use bp_runtime::{ChainId, StorageDoubleMapKeyProvider}; use frame_support::{traits::tokens::Preservation, Blake2_128Concat, Identity}; use scale_info::TypeInfo; @@ -61,7 +60,7 @@ pub enum RewardsAccountOwner { /// of the sovereign accounts will pay rewards for different operations. So we need multiple /// parameters to identify the account that pays a reward to the relayer. #[derive(Copy, Clone, Debug, Decode, Encode, Eq, PartialEq, TypeInfo, MaxEncodedLen)] -pub struct RewardsAccountParams { +pub struct RewardsAccountParams { // **IMPORTANT NOTE**: the order of fields here matters - we are using // `into_account_truncating` and lane id is already `32` byte, so if other fields are encoded // after it, they're simply dropped. So lane id shall be the last field. @@ -70,7 +69,7 @@ pub struct RewardsAccountParams { lane_id: LaneId, } -impl RewardsAccountParams { +impl RewardsAccountParams { /// Create a new instance of `RewardsAccountParams`. pub const fn new( lane_id: LaneId, @@ -81,7 +80,7 @@ impl RewardsAccountParams { } } -impl TypeId for RewardsAccountParams { +impl TypeId for RewardsAccountParams { const TYPE_ID: [u8; 4] = *b"brap"; } @@ -89,47 +88,58 @@ impl TypeId for RewardsAccountParams { pub trait PaymentProcedure { /// Error that may be returned by the procedure. type Error: Debug; + /// Lane identifier type. + type LaneId: Decode + Encode; /// Pay reward to the relayer from the account with provided params. fn pay_reward( relayer: &Relayer, - rewards_account_params: RewardsAccountParams, + rewards_account_params: RewardsAccountParams, reward: Reward, ) -> Result<(), Self::Error>; } impl PaymentProcedure for () { type Error = &'static str; + type LaneId = (); - fn pay_reward(_: &Relayer, _: RewardsAccountParams, _: Reward) -> Result<(), Self::Error> { + fn pay_reward( + _: &Relayer, + _: RewardsAccountParams, + _: Reward, + ) -> Result<(), Self::Error> { Ok(()) } } /// Reward payment procedure that does `balances::transfer` call from the account, derived from /// given params. -pub struct PayRewardFromAccount(PhantomData<(T, Relayer)>); +pub struct PayRewardFromAccount(PhantomData<(T, Relayer, LaneId)>); -impl PayRewardFromAccount +impl PayRewardFromAccount where Relayer: Decode + Encode, + LaneId: Decode + Encode, { /// Return account that pays rewards based on the provided parameters. - pub fn rewards_account(params: RewardsAccountParams) -> Relayer { + pub fn rewards_account(params: RewardsAccountParams) -> Relayer { params.into_sub_account_truncating(b"rewards-account") } } -impl PaymentProcedure for PayRewardFromAccount +impl PaymentProcedure + for PayRewardFromAccount where T: frame_support::traits::fungible::Mutate, Relayer: Decode + Encode + Eq, + LaneId: Decode + Encode, { type Error = sp_runtime::DispatchError; + type LaneId = LaneId; fn pay_reward( relayer: &Relayer, - rewards_account_params: RewardsAccountParams, + rewards_account_params: RewardsAccountParams, reward: T::Balance, ) -> Result<(), Self::Error> { T::transfer( @@ -142,49 +152,57 @@ where } } -/// Can be use to access the runtime storage key within the `RelayerRewards` map of the relayers +/// Can be used to access the runtime storage key within the `RelayerRewards` map of the relayers /// pallet. -pub struct RelayerRewardsKeyProvider(PhantomData<(AccountId, Reward)>); +pub struct RelayerRewardsKeyProvider( + PhantomData<(AccountId, Reward, LaneId)>, +); -impl StorageDoubleMapKeyProvider for RelayerRewardsKeyProvider +impl StorageDoubleMapKeyProvider + for RelayerRewardsKeyProvider where AccountId: 'static + Codec + EncodeLike + Send + Sync, Reward: 'static + Codec + EncodeLike + Send + Sync, + LaneId: 'static + Codec + EncodeLike + Send + Sync, { const MAP_NAME: &'static str = "RelayerRewards"; type Hasher1 = Blake2_128Concat; type Key1 = AccountId; type Hasher2 = Identity; - type Key2 = RewardsAccountParams; + type Key2 = RewardsAccountParams; type Value = Reward; } #[cfg(test)] mod tests { use super::*; - use bp_messages::LaneId; - use sp_runtime::testing::H256; + use bp_messages::{HashedLaneId, LaneIdType, LegacyLaneId}; + use sp_runtime::{app_crypto::Ss58Codec, testing::H256}; #[test] fn different_lanes_are_using_different_accounts() { assert_eq!( - PayRewardFromAccount::<(), H256>::rewards_account(RewardsAccountParams::new( - LaneId::new(1, 2), - *b"test", - RewardsAccountOwner::ThisChain - )), - hex_literal::hex!("62726170007465737448615368b1d3dccd8b3c3a012afe265f3e3c4432129b8a") + PayRewardFromAccount::<(), H256, HashedLaneId>::rewards_account( + RewardsAccountParams::new( + HashedLaneId::new(1, 2), + *b"test", + RewardsAccountOwner::ThisChain + ) + ), + hex_literal::hex!("627261700074657374b1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dc") .into(), ); assert_eq!( - PayRewardFromAccount::<(), H256>::rewards_account(RewardsAccountParams::new( - LaneId::new(1, 3), - *b"test", - RewardsAccountOwner::ThisChain - )), - hex_literal::hex!("62726170007465737448615368a43e8951aa302c133beb5f85821a21645f07b4") + PayRewardFromAccount::<(), H256, HashedLaneId>::rewards_account( + RewardsAccountParams::new( + HashedLaneId::new(1, 3), + *b"test", + RewardsAccountOwner::ThisChain + ) + ), + hex_literal::hex!("627261700074657374a43e8951aa302c133beb5f85821a21645f07b487270ef3") .into(), ); } @@ -192,23 +210,101 @@ mod tests { #[test] fn different_directions_are_using_different_accounts() { assert_eq!( - PayRewardFromAccount::<(), H256>::rewards_account(RewardsAccountParams::new( - LaneId::new(1, 2), - *b"test", - RewardsAccountOwner::ThisChain - )), - hex_literal::hex!("62726170007465737448615368b1d3dccd8b3c3a012afe265f3e3c4432129b8a") + PayRewardFromAccount::<(), H256, HashedLaneId>::rewards_account( + RewardsAccountParams::new( + HashedLaneId::new(1, 2), + *b"test", + RewardsAccountOwner::ThisChain + ) + ), + hex_literal::hex!("627261700074657374b1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dc") .into(), ); assert_eq!( - PayRewardFromAccount::<(), H256>::rewards_account(RewardsAccountParams::new( - LaneId::new(1, 2), - *b"test", - RewardsAccountOwner::BridgedChain - )), - hex_literal::hex!("62726170017465737448615368b1d3dccd8b3c3a012afe265f3e3c4432129b8a") + PayRewardFromAccount::<(), H256, HashedLaneId>::rewards_account( + RewardsAccountParams::new( + HashedLaneId::new(1, 2), + *b"test", + RewardsAccountOwner::BridgedChain + ) + ), + hex_literal::hex!("627261700174657374b1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dc") .into(), ); } + + #[test] + fn pay_reward_from_account_for_legacy_lane_id_works() { + let test_data = vec![ + // Note: these accounts are used for integration tests within + // `bridges_rococo_westend.sh` + ( + LegacyLaneId([0, 0, 0, 1]), + b"bhks", + RewardsAccountOwner::ThisChain, + (0_u16, "13E5fui97x6KTwNnSjaEKZ8s7kJNot5F3aUsy3jUtuoMyUec"), + ), + ( + LegacyLaneId([0, 0, 0, 1]), + b"bhks", + RewardsAccountOwner::BridgedChain, + (0_u16, "13E5fui9Ka9Vz4JbGN3xWjmwDNxnxF1N9Hhhbeu3VCqLChuj"), + ), + ( + LegacyLaneId([0, 0, 0, 1]), + b"bhpd", + RewardsAccountOwner::ThisChain, + (2_u16, "EoQBtnwtXqnSnr9cgBEJpKU7NjeC9EnR4D1VjgcvHz9ZYmS"), + ), + ( + LegacyLaneId([0, 0, 0, 1]), + b"bhpd", + RewardsAccountOwner::BridgedChain, + (2_u16, "EoQBtnx69txxumxSJexVzxYD1Q4LWAuWmRq8LrBWb27nhYN"), + ), + // Note: these accounts are used for integration tests within + // `bridges_polkadot_kusama.sh` from fellows. + ( + LegacyLaneId([0, 0, 0, 2]), + b"bhwd", + RewardsAccountOwner::ThisChain, + (4_u16, "SNihsskf7bFhnHH9HJFMjWD3FJ96ESdAQTFZUAtXudRQbaH"), + ), + ( + LegacyLaneId([0, 0, 0, 2]), + b"bhwd", + RewardsAccountOwner::BridgedChain, + (4_u16, "SNihsskrjeSDuD5xumyYv9H8sxZEbNkG7g5C5LT8CfPdaSE"), + ), + ( + LegacyLaneId([0, 0, 0, 2]), + b"bhro", + RewardsAccountOwner::ThisChain, + (4_u16, "SNihsskf7bF2vWogkC6uFoiqPhd3dUX6TGzYZ1ocJdo3xHp"), + ), + ( + LegacyLaneId([0, 0, 0, 2]), + b"bhro", + RewardsAccountOwner::BridgedChain, + (4_u16, "SNihsskrjeRZ3ScWNfq6SSnw2N3BzQeCAVpBABNCbfmHENB"), + ), + ]; + + for (lane_id, bridged_chain_id, owner, (expected_ss58, expected_account)) in test_data { + assert_eq!( + expected_account, + sp_runtime::AccountId32::new(PayRewardFromAccount::< + [u8; 32], + [u8; 32], + LegacyLaneId, + >::rewards_account(RewardsAccountParams::new( + lane_id, + *bridged_chain_id, + owner + ))) + .to_ss58check_with_version(expected_ss58.into()) + ); + } + } } diff --git a/bridges/primitives/relayers/src/registration.rs b/bridges/primitives/relayers/src/registration.rs index 9d9b7e481220..d74ef18cf706 100644 --- a/bridges/primitives/relayers/src/registration.rs +++ b/bridges/primitives/relayers/src/registration.rs @@ -48,15 +48,17 @@ use sp_runtime::{ /// Either explicit account reference or `RewardsAccountParams`. #[derive(Clone, Debug)] -pub enum ExplicitOrAccountParams { +pub enum ExplicitOrAccountParams { /// Explicit account reference. Explicit(AccountId), /// Account, referenced using `RewardsAccountParams`. - Params(RewardsAccountParams), + Params(RewardsAccountParams), } -impl From for ExplicitOrAccountParams { - fn from(params: RewardsAccountParams) -> Self { +impl From> + for ExplicitOrAccountParams +{ + fn from(params: RewardsAccountParams) -> Self { ExplicitOrAccountParams::Params(params) } } @@ -103,9 +105,9 @@ pub trait StakeAndSlash { /// `beneficiary`. /// /// Returns `Ok(_)` with non-zero balance if we have failed to repatriate some portion of stake. - fn repatriate_reserved( + fn repatriate_reserved( relayer: &AccountId, - beneficiary: ExplicitOrAccountParams, + beneficiary: ExplicitOrAccountParams, amount: Balance, ) -> Result; } @@ -126,9 +128,9 @@ where Zero::zero() } - fn repatriate_reserved( + fn repatriate_reserved( _relayer: &AccountId, - _beneficiary: ExplicitOrAccountParams, + _beneficiary: ExplicitOrAccountParams, _amount: Balance, ) -> Result { Ok(Zero::zero()) diff --git a/bridges/primitives/runtime/src/chain.rs b/bridges/primitives/runtime/src/chain.rs index 0db4eac79a75..52933263c991 100644 --- a/bridges/primitives/runtime/src/chain.rs +++ b/bridges/primitives/runtime/src/chain.rs @@ -365,17 +365,23 @@ macro_rules! decl_bridge_finality_runtime_apis { }; } +// Re-export to avoid include tuplex dependency everywhere. +#[doc(hidden)] +pub mod __private { + pub use codec; +} + /// Convenience macro that declares bridge messages runtime apis and related constants for a chain. /// This includes: /// - chain-specific bridge runtime APIs: -/// - `ToOutboundLaneApi` -/// - `FromInboundLaneApi` +/// - `ToOutboundLaneApi` +/// - `FromInboundLaneApi` /// - constants that are stringified names of runtime API methods: /// - `FROM__MESSAGE_DETAILS_METHOD`, /// The name of the chain has to be specified in snake case (e.g. `bridge_hub_polkadot`). #[macro_export] macro_rules! decl_bridge_messages_runtime_apis { - ($chain: ident) => { + ($chain: ident, $lane_id_type:ident) => { bp_runtime::paste::item! { mod [<$chain _messages_api>] { use super::*; @@ -393,14 +399,14 @@ macro_rules! decl_bridge_messages_runtime_apis { /// /// This API is implemented by runtimes that are receiving messages from this chain, not by this /// chain's runtime itself. - pub trait [] { + pub trait []<$lane_id_type> where $lane_id_type: $crate::__private::codec::Encode { /// Returns dispatch weight, encoded payload size and delivery+dispatch fee of all /// messages in given inclusive range. /// /// If some (or all) messages are missing from the storage, they'll also will /// be missing from the resulting vector. The vector is ordered by the nonce. fn message_details( - lane: bp_messages::LaneId, + lane: $lane_id_type, begin: bp_messages::MessageNonce, end: bp_messages::MessageNonce, ) -> sp_std::vec::Vec; @@ -413,10 +419,10 @@ macro_rules! decl_bridge_messages_runtime_apis { /// /// Entries of the resulting vector are matching entries of the `messages` vector. Entries of the /// `messages` vector may (and need to) be read using `ToOutboundLaneApi::message_details`. - pub trait [] { + pub trait []<$lane_id_type> where $lane_id_type: $crate::__private::codec::Encode { /// Return details of given inbound messages. fn message_details( - lane: bp_messages::LaneId, + lane: $lane_id_type, messages: sp_std::vec::Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>, ) -> sp_std::vec::Vec; } @@ -433,8 +439,8 @@ macro_rules! decl_bridge_messages_runtime_apis { /// The name of the chain has to be specified in snake case (e.g. `bridge_hub_polkadot`). #[macro_export] macro_rules! decl_bridge_runtime_apis { - ($chain: ident $(, $consensus: ident)?) => { + ($chain: ident $(, $consensus: ident, $lane_id_type:ident)?) => { bp_runtime::decl_bridge_finality_runtime_apis!($chain $(, $consensus)?); - bp_runtime::decl_bridge_messages_runtime_apis!($chain); + bp_runtime::decl_bridge_messages_runtime_apis!($chain, $lane_id_type); }; } diff --git a/bridges/primitives/runtime/src/lib.rs b/bridges/primitives/runtime/src/lib.rs index 8f5040ad9a1b..94ce333a5c78 100644 --- a/bridges/primitives/runtime/src/lib.rs +++ b/bridges/primitives/runtime/src/lib.rs @@ -36,7 +36,7 @@ use sp_std::{fmt::Debug, ops::RangeInclusive, vec, vec::Vec}; pub use chain::{ AccountIdOf, AccountPublicOf, BalanceOf, BlockNumberOf, Chain, EncodedOrDecodedCall, HashOf, HasherOf, HeaderOf, NonceOf, Parachain, ParachainIdOf, SignatureOf, TransactionEraOf, - UnderlyingChainOf, UnderlyingChainProvider, + UnderlyingChainOf, UnderlyingChainProvider, __private, }; pub use frame_support::storage::storage_prefix as storage_value_final_key; use num_traits::{CheckedAdd, CheckedSub, One, SaturatingAdd, Zero}; From 387f5ea11fc2032c4478acfae09880f688a2e634 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 17 Sep 2024 23:24:36 +0200 Subject: [PATCH 13/38] Generic `LaneId` for `bridge-runtime-common` --- bridges/bin/runtime-common/src/extensions.rs | 11 +-- .../bin/runtime-common/src/messages_api.rs | 8 +- .../src/messages_benchmarking.rs | 78 ++++++++++--------- bridges/bin/runtime-common/src/mock.rs | 29 ++++--- bridges/modules/messages/src/benchmarking.rs | 4 +- bridges/modules/messages/src/tests/mock.rs | 4 +- bridges/modules/relayers/src/benchmarking.rs | 16 ++-- bridges/modules/relayers/src/mock.rs | 18 +++-- bridges/modules/xcm-bridge-hub/src/mock.rs | 5 +- bridges/primitives/messages/src/lane.rs | 27 +++++++ bridges/primitives/relayers/src/lib.rs | 2 +- 11 files changed, 123 insertions(+), 79 deletions(-) diff --git a/bridges/bin/runtime-common/src/extensions.rs b/bridges/bin/runtime-common/src/extensions.rs index dc7e14de28f3..dced50239471 100644 --- a/bridges/bin/runtime-common/src/extensions.rs +++ b/bridges/bin/runtime-common/src/extensions.rs @@ -374,7 +374,7 @@ mod tests { use super::*; use crate::mock::*; use bp_header_chain::StoredHeaderDataBuilder; - use bp_messages::{InboundLaneData, LaneId, MessageNonce, OutboundLaneData}; + use bp_messages::{InboundLaneData, MessageNonce, OutboundLaneData}; use bp_parachains::{BestParaHeadHash, ParaInfo}; use bp_polkadot_core::parachains::{ParaHeadsProof, ParaId}; use bp_relayers::{RewardsAccountOwner, RewardsAccountParams}; @@ -390,17 +390,16 @@ mod tests { }; parameter_types! { - pub MsgProofsRewardsAccount: RewardsAccountParams = RewardsAccountParams::new( + pub MsgProofsRewardsAccount: RewardsAccountParams = RewardsAccountParams::new( test_lane_id(), TEST_BRIDGED_CHAIN_ID, RewardsAccountOwner::ThisChain, ); - pub MsgDeliveryProofsRewardsAccount: RewardsAccountParams = RewardsAccountParams::new( + pub MsgDeliveryProofsRewardsAccount: RewardsAccountParams = RewardsAccountParams::new( test_lane_id(), TEST_BRIDGED_CHAIN_ID, RewardsAccountOwner::BridgedChain, ); - pub TestLaneId: LaneId = test_lane_id(); } pub struct MockCall { @@ -476,10 +475,6 @@ mod tests { } } - fn test_lane_id() -> LaneId { - LaneId::new(1, 2) - } - fn initial_balance_of_relayer_account_at_this_chain() -> ThisChainBalance { let test_stake: ThisChainBalance = TestStake::get(); ExistentialDeposit::get().saturating_add(test_stake * 100) diff --git a/bridges/bin/runtime-common/src/messages_api.rs b/bridges/bin/runtime-common/src/messages_api.rs index 7fbdeb366124..c8522d4d1f27 100644 --- a/bridges/bin/runtime-common/src/messages_api.rs +++ b/bridges/bin/runtime-common/src/messages_api.rs @@ -16,14 +16,12 @@ //! Helpers for implementing various message-related runtime API methods. -use bp_messages::{ - InboundMessageDetails, LaneId, MessageNonce, MessagePayload, OutboundMessageDetails, -}; +use bp_messages::{InboundMessageDetails, MessageNonce, MessagePayload, OutboundMessageDetails}; use sp_std::vec::Vec; /// Implementation of the `To*OutboundLaneApi::message_details`. pub fn outbound_message_details( - lane: LaneId, + lane: Runtime::LaneId, begin: MessageNonce, end: MessageNonce, ) -> Vec @@ -48,7 +46,7 @@ where /// Implementation of the `To*InboundLaneApi::message_details`. pub fn inbound_message_details( - lane: LaneId, + lane: Runtime::LaneId, messages: Vec<(MessagePayload, OutboundMessageDetails)>, ) -> Vec where diff --git a/bridges/bin/runtime-common/src/messages_benchmarking.rs b/bridges/bin/runtime-common/src/messages_benchmarking.rs index 1880e65547fe..acbdbcda8dea 100644 --- a/bridges/bin/runtime-common/src/messages_benchmarking.rs +++ b/bridges/bin/runtime-common/src/messages_benchmarking.rs @@ -33,15 +33,15 @@ use pallet_bridge_messages::{ encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof, prepare_messages_storage_proof, }, - BridgedChainOf, ThisChainOf, + BridgedChainOf, LaneIdOf, ThisChainOf, }; use sp_runtime::traits::{Header, Zero}; use sp_std::prelude::*; use xcm::latest::prelude::*; /// Prepare inbound bridge message according to given message proof parameters. -fn prepare_inbound_message( - params: &MessageProofParams, +fn prepare_inbound_message( + params: &MessageProofParams, successful_dispatch_message_generator: impl Fn(usize) -> MessagePayload, ) -> MessagePayload { let expected_size = params.proof_params.db_size.unwrap_or(0) as usize; @@ -71,9 +71,9 @@ fn prepare_inbound_message( /// uses GRANDPA finality. For parachains, please use the `prepare_message_proof_from_parachain` /// function. pub fn prepare_message_proof_from_grandpa_chain( - params: MessageProofParams, + params: MessageProofParams>, message_generator: impl Fn(usize) -> MessagePayload, -) -> (FromBridgedChainMessagesProof>>, Weight) +) -> (FromBridgedChainMessagesProof>, LaneIdOf>, Weight) where R: pallet_bridge_grandpa::Config> + pallet_bridge_messages::Config< @@ -84,18 +84,21 @@ where MI: 'static, { // prepare storage proof - let (state_root, storage_proof) = - prepare_messages_storage_proof::, ThisChainOf>( - params.lane, - params.message_nonces.clone(), - params.outbound_lane_data.clone(), - params.proof_params, - |_| prepare_inbound_message(¶ms, &message_generator), - encode_all_messages, - encode_lane_data, - false, - false, - ); + let (state_root, storage_proof) = prepare_messages_storage_proof::< + BridgedChainOf, + ThisChainOf, + LaneIdOf, + >( + params.lane, + params.message_nonces.clone(), + params.outbound_lane_data.clone(), + params.proof_params, + |_| prepare_inbound_message(¶ms, &message_generator), + encode_all_messages, + encode_lane_data, + false, + false, + ); // update runtime storage let (_, bridged_header_hash) = insert_header_to_grandpa_pallet::(state_root); @@ -121,9 +124,9 @@ where /// uses parachain finality. For GRANDPA chains, please use the /// `prepare_message_proof_from_grandpa_chain` function. pub fn prepare_message_proof_from_parachain( - params: MessageProofParams, + params: MessageProofParams>, message_generator: impl Fn(usize) -> MessagePayload, -) -> (FromBridgedChainMessagesProof>>, Weight) +) -> (FromBridgedChainMessagesProof>, LaneIdOf>, Weight) where R: pallet_bridge_parachains::Config + pallet_bridge_messages::Config, PI: 'static, @@ -131,18 +134,21 @@ where BridgedChainOf: Chain + Parachain, { // prepare storage proof - let (state_root, storage_proof) = - prepare_messages_storage_proof::, ThisChainOf>( - params.lane, - params.message_nonces.clone(), - params.outbound_lane_data.clone(), - params.proof_params, - |_| prepare_inbound_message(¶ms, &message_generator), - encode_all_messages, - encode_lane_data, - false, - false, - ); + let (state_root, storage_proof) = prepare_messages_storage_proof::< + BridgedChainOf, + ThisChainOf, + LaneIdOf, + >( + params.lane, + params.message_nonces.clone(), + params.outbound_lane_data.clone(), + params.proof_params, + |_| prepare_inbound_message(¶ms, &message_generator), + encode_all_messages, + encode_lane_data, + false, + false, + ); // update runtime storage let (_, bridged_header_hash) = @@ -166,8 +172,8 @@ where /// uses GRANDPA finality. For parachains, please use the /// `prepare_message_delivery_proof_from_parachain` function. pub fn prepare_message_delivery_proof_from_grandpa_chain( - params: MessageDeliveryProofParams>>, -) -> FromBridgedChainMessagesDeliveryProof>> + params: MessageDeliveryProofParams>, LaneIdOf>, +) -> FromBridgedChainMessagesDeliveryProof>, LaneIdOf> where R: pallet_bridge_grandpa::Config> + pallet_bridge_messages::Config< @@ -182,6 +188,7 @@ where let (state_root, storage_proof) = prepare_message_delivery_storage_proof::< BridgedChainOf, ThisChainOf, + LaneIdOf, >(params.lane, params.inbound_lane_data, params.proof_params); // update runtime storage @@ -200,8 +207,8 @@ where /// uses parachain finality. For GRANDPA chains, please use the /// `prepare_message_delivery_proof_from_grandpa_chain` function. pub fn prepare_message_delivery_proof_from_parachain( - params: MessageDeliveryProofParams>>, -) -> FromBridgedChainMessagesDeliveryProof>> + params: MessageDeliveryProofParams>, LaneIdOf>, +) -> FromBridgedChainMessagesDeliveryProof>, LaneIdOf> where R: pallet_bridge_parachains::Config + pallet_bridge_messages::Config, PI: 'static, @@ -213,6 +220,7 @@ where let (state_root, storage_proof) = prepare_message_delivery_storage_proof::< BridgedChainOf, ThisChainOf, + LaneIdOf, >(params.lane, params.inbound_lane_data, params.proof_params); // update runtime storage diff --git a/bridges/bin/runtime-common/src/mock.rs b/bridges/bin/runtime-common/src/mock.rs index fed0d15cc080..35a8b5cccab9 100644 --- a/bridges/bin/runtime-common/src/mock.rs +++ b/bridges/bin/runtime-common/src/mock.rs @@ -21,7 +21,7 @@ use bp_header_chain::ChainWithGrandpa; use bp_messages::{ target_chain::{DispatchMessage, MessageDispatch}, - ChainWithMessages, LaneId, MessageNonce, + ChainWithMessages, HashedLaneId, LaneIdType, MessageNonce, }; use bp_parachains::SingleParaStoredHeaderDataBuilder; use bp_relayers::PayRewardFromAccount; @@ -70,7 +70,7 @@ pub type BridgedChainHeader = sp_runtime::generic::Header; /// Rewards payment procedure. -pub type TestPaymentProcedure = PayRewardFromAccount; +pub type TestPaymentProcedure = PayRewardFromAccount; /// Stake that we are using in tests. pub type TestStake = ConstU64<5_000>; /// Stake and slash mechanism to use in tests. @@ -83,10 +83,11 @@ pub type TestStakeAndSlash = pallet_bridge_relayers::StakeAndSlashNamed< ConstU32<8>, >; -/// Message lane used in tests. -#[allow(unused)] -pub fn test_lane_id() -> LaneId { - LaneId::new(1, 2) +/// Lane identifier type used for tests. +pub type TestLaneIdType = HashedLaneId; +/// Lane that we're using in tests. +pub fn test_lane_id() -> TestLaneIdType { + TestLaneIdType::new(1, 2) } /// Bridged chain id used in tests. @@ -189,10 +190,10 @@ impl pallet_bridge_messages::Config for TestRuntime { type WeightInfo = pallet_bridge_messages::weights::BridgeWeight; type OutboundPayload = Vec; - type InboundPayload = Vec; - type DeliveryPayments = (); + type LaneId = TestLaneIdType; + type DeliveryPayments = (); type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< TestRuntime, (), @@ -213,13 +214,14 @@ impl pallet_bridge_relayers::Config for TestRuntime { type PaymentProcedure = TestPaymentProcedure; type StakeAndSlash = TestStakeAndSlash; type WeightInfo = (); + type LaneId = TestLaneIdType; } /// Dummy message dispatcher. pub struct DummyMessageDispatch; impl DummyMessageDispatch { - pub fn deactivate(lane: LaneId) { + pub fn deactivate(lane: TestLaneIdType) { frame_support::storage::unhashed::put(&(b"inactive", lane).encode()[..], &false); } } @@ -227,18 +229,21 @@ impl DummyMessageDispatch { impl MessageDispatch for DummyMessageDispatch { type DispatchPayload = Vec; type DispatchLevelResult = (); + type LaneId = TestLaneIdType; - fn is_active(lane: LaneId) -> bool { + fn is_active(lane: Self::LaneId) -> bool { frame_support::storage::unhashed::take::(&(b"inactive", lane).encode()[..]) != Some(false) } - fn dispatch_weight(_message: &mut DispatchMessage) -> Weight { + fn dispatch_weight( + _message: &mut DispatchMessage, + ) -> Weight { Weight::zero() } fn dispatch( - _: DispatchMessage, + _: DispatchMessage, ) -> MessageDispatchResult { MessageDispatchResult { unspent_weight: Weight::zero(), dispatch_level_result: () } } diff --git a/bridges/modules/messages/src/benchmarking.rs b/bridges/modules/messages/src/benchmarking.rs index 7c723e567315..355fb08ab28a 100644 --- a/bridges/modules/messages/src/benchmarking.rs +++ b/bridges/modules/messages/src/benchmarking.rs @@ -26,7 +26,7 @@ use crate::{ use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, target_chain::FromBridgedChainMessagesProof, ChainWithMessages, DeliveredMessages, - InboundLaneData, LaneIdType, LaneState, MessageNonce, OutboundLaneData, UnrewardedRelayer, + InboundLaneData, LaneState, MessageNonce, OutboundLaneData, UnrewardedRelayer, UnrewardedRelayersState, }; use bp_runtime::{AccountIdOf, HashOf, UnverifiedStorageProofParams}; @@ -75,7 +75,7 @@ pub struct MessageDeliveryProofParams { pub trait Config: crate::Config { /// Lane id to use in benchmarks. fn bench_lane_id() -> Self::LaneId { - Self::LaneId::new(1, 2) + Self::LaneId::default() } /// Return id of relayer account at the bridged chain. diff --git a/bridges/modules/messages/src/tests/mock.rs b/bridges/modules/messages/src/tests/mock.rs index d09f612aa0c0..095319ef0556 100644 --- a/bridges/modules/messages/src/tests/mock.rs +++ b/bridges/modules/messages/src/tests/mock.rs @@ -75,8 +75,6 @@ pub struct TestPayload { pub type TestMessageFee = u64; pub type TestRelayer = u64; pub type TestDispatchLevelResult = (); -/// Lane identifier type used for tests. -pub type TestLaneIdType = HashedLaneId; pub struct ThisChain; @@ -261,6 +259,8 @@ pub const TEST_RELAYER_B: AccountId = 101; /// Account id of additional test relayer - C. pub const TEST_RELAYER_C: AccountId = 102; +/// Lane identifier type used for tests. +pub type TestLaneIdType = HashedLaneId; /// Lane that we're using in tests. pub fn test_lane_id() -> TestLaneIdType { TestLaneIdType::new(1, 2) diff --git a/bridges/modules/relayers/src/benchmarking.rs b/bridges/modules/relayers/src/benchmarking.rs index 8a3f905a8f29..f8e292d038f8 100644 --- a/bridges/modules/relayers/src/benchmarking.rs +++ b/bridges/modules/relayers/src/benchmarking.rs @@ -20,7 +20,6 @@ use crate::*; -use bp_messages::LaneId; use bp_relayers::RewardsAccountOwner; use frame_benchmarking::{benchmarks, whitelisted_caller}; use frame_system::RawOrigin; @@ -34,8 +33,15 @@ pub struct Pallet(crate::Pallet); /// Trait that must be implemented by runtime. pub trait Config: crate::Config { + /// Lane id to use in benchmarks. + fn bench_lane_id() -> Self::LaneId { + Self::LaneId::default() + } /// Prepare environment for paying given reward for serving given lane. - fn prepare_rewards_account(account_params: RewardsAccountParams, reward: Self::Reward); + fn prepare_rewards_account( + account_params: RewardsAccountParams, + reward: Self::Reward, + ); /// Give enough balance to given account. fn deposit_account(account: Self::AccountId, balance: Self::Reward); } @@ -43,7 +49,7 @@ pub trait Config: crate::Config { benchmarks! { // Benchmark `claim_rewards` call. claim_rewards { - let lane = LaneId::new(1, 2); + let lane = T::bench_lane_id(); let account_params = RewardsAccountParams::new(lane, *b"test", RewardsAccountOwner::ThisChain); let relayer: T::AccountId = whitelisted_caller(); @@ -102,7 +108,7 @@ benchmarks! { crate::Pallet::::register(RawOrigin::Signed(relayer.clone()).into(), valid_till).unwrap(); // create slash destination account - let lane = LaneId::new(1, 2); + let lane = T::bench_lane_id(); let slash_destination = RewardsAccountParams::new(lane, *b"test", RewardsAccountOwner::ThisChain); T::prepare_rewards_account(slash_destination, Zero::zero()); }: { @@ -116,7 +122,7 @@ benchmarks! { // the weight of message delivery call if `RefundBridgedParachainMessages` signed extension // is deployed at runtime level. register_relayer_reward { - let lane = LaneId::new(1, 2); + let lane = T::bench_lane_id(); let relayer: T::AccountId = whitelisted_caller(); let account_params = RewardsAccountParams::new(lane, *b"test", RewardsAccountOwner::ThisChain); diff --git a/bridges/modules/relayers/src/mock.rs b/bridges/modules/relayers/src/mock.rs index f535aa4c62f1..3d718154c16a 100644 --- a/bridges/modules/relayers/src/mock.rs +++ b/bridges/modules/relayers/src/mock.rs @@ -74,9 +74,9 @@ pub type BridgedChainHeader = pub const TEST_BRIDGED_CHAIN_ID: ChainId = *b"brdg"; /// Maximal extrinsic size at the `BridgedChain`. pub const BRIDGED_CHAIN_MAX_EXTRINSIC_SIZE: u32 = 1024; + /// Lane identifier type used for tests. pub type TestLaneIdType = HashedLaneId; - /// Lane that we're using in tests. pub fn test_lane_id() -> TestLaneIdType { TestLaneIdType::new(1, 2) @@ -288,11 +288,15 @@ impl pallet_bridge_relayers::Config for TestRuntime { #[cfg(feature = "runtime-benchmarks")] impl pallet_bridge_relayers::benchmarking::Config for TestRuntime { - fn prepare_rewards_account(account_params: RewardsAccountParams, reward: ThisChainBalance) { - let rewards_account = - bp_relayers::PayRewardFromAccount::::rewards_account( - account_params, - ); + fn prepare_rewards_account( + account_params: RewardsAccountParams, + reward: Self::Reward, + ) { + let rewards_account = bp_relayers::PayRewardFromAccount::< + Balances, + ThisChainAccountId, + Self::LaneId, + >::rewards_account(account_params); Self::deposit_account(rewards_account, reward); } @@ -349,7 +353,7 @@ impl MessageDispatch for DummyMessageDispatch { type DispatchLevelResult = (); type LaneId = TestLaneIdType; - fn is_active(lane: TestLaneIdType) -> bool { + fn is_active(lane: Self::LaneId) -> bool { frame_support::storage::unhashed::take::(&(b"inactive", lane).encode()[..]) != Some(false) } diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index db13f70d69b4..ece5006e86d3 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -49,6 +49,7 @@ use xcm_executor::XcmExecutor; pub type AccountId = AccountId32; pub type Balance = u64; type Block = frame_system::mocking::MockBlock; + /// Lane identifier type used for tests. pub type TestLaneIdType = HashedLaneId; @@ -94,7 +95,7 @@ impl pallet_bridge_messages::Config for TestRuntime { type OutboundPayload = Vec; type InboundPayload = Vec; - type LaneId = HashedLaneId; + type LaneId = TestLaneIdType; type DeliveryPayments = (); type DeliveryConfirmationPayments = (); @@ -536,7 +537,7 @@ impl MessageDispatch for TestMessageDispatch { type DispatchLevelResult = (); type LaneId = TestLaneIdType; - fn is_active(lane: TestLaneIdType) -> bool { + fn is_active(lane: Self::LaneId) -> bool { frame_support::storage::unhashed::take::(&(b"inactive", lane).encode()[..]) != Some(false) } diff --git a/bridges/primitives/messages/src/lane.rs b/bridges/primitives/messages/src/lane.rs index f7c0bafd909a..44cb8180e52d 100644 --- a/bridges/primitives/messages/src/lane.rs +++ b/bridges/primitives/messages/src/lane.rs @@ -30,6 +30,7 @@ pub trait LaneIdType: + Codec + EncodeLike + Debug + + Default + PartialEq + Eq + Ord @@ -62,6 +63,18 @@ pub trait LaneIdType: )] pub struct LegacyLaneId(pub [u8; 4]); +#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))] +impl TryFrom> for LegacyLaneId { + type Error = (); + + fn try_from(value: Vec) -> Result { + if value.len() == 4 { + return <[u8; 4]>::try_from(value).map(Self).map_err(|_| ()); + } + Err(()) + } +} + impl core::fmt::Debug for LegacyLaneId { fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { self.0.fmt(fmt) @@ -100,6 +113,7 @@ impl TypeId for LegacyLaneId { Clone, Copy, Decode, + Default, Encode, Eq, Ord, @@ -118,6 +132,7 @@ impl HashedLaneId { /// There's no `From` implementation for the `LaneId`, because using this conversion /// in a wrong way (i.e. computing hash of endpoints manually) may lead to issues. So we /// want the call to be explicit. + #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))] pub const fn from_inner(inner: H256) -> Self { Self(inner) } @@ -161,6 +176,18 @@ impl LaneIdType for HashedLaneId { } } +#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))] +impl TryFrom> for HashedLaneId { + type Error = (); + + fn try_from(value: Vec) -> Result { + if value.len() == 32 { + return <[u8; 32]>::try_from(value).map(|v| Self(H256::from(v))).map_err(|_| ()); + } + Err(()) + } +} + /// Lane state. #[derive(Clone, Copy, Decode, Encode, Eq, PartialEq, TypeInfo, MaxEncodedLen, RuntimeDebug)] pub enum LaneState { diff --git a/bridges/primitives/relayers/src/lib.rs b/bridges/primitives/relayers/src/lib.rs index f6cc8e95aada..c81e074dfa48 100644 --- a/bridges/primitives/relayers/src/lib.rs +++ b/bridges/primitives/relayers/src/lib.rs @@ -163,7 +163,7 @@ impl StorageDoubleMapKeyProvider where AccountId: 'static + Codec + EncodeLike + Send + Sync, Reward: 'static + Codec + EncodeLike + Send + Sync, - LaneId: 'static + Codec + EncodeLike + Send + Sync, + LaneId: Codec + EncodeLike + Send + Sync, { const MAP_NAME: &'static str = "RelayerRewards"; From cdbddfa308038255a34315332d9f9583e24686ce Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 17 Sep 2024 23:57:06 +0200 Subject: [PATCH 14/38] Generic `LaneId` for relayer code --- Cargo.lock | 1 - .../lib-substrate-relay/src/cli/bridge.rs | 23 ++++- .../relays/lib-substrate-relay/src/cli/mod.rs | 43 +++------ .../src/cli/relay_headers_and_messages/mod.rs | 61 +++++++----- .../src/cli/relay_messages.rs | 16 +++- .../src/messages/metrics.rs | 20 ++-- .../lib-substrate-relay/src/messages/mod.rs | 94 +++++++++++++------ .../src/messages/source.rs | 27 ++++-- .../src/messages/target.rs | 12 +-- bridges/relays/messages/Cargo.toml | 1 - bridges/relays/messages/src/lib.rs | 2 +- bridges/relays/messages/src/message_lane.rs | 4 + .../relays/messages/src/message_lane_loop.rs | 49 +++++++--- bridges/relays/messages/src/metrics.rs | 29 ++++-- 14 files changed, 248 insertions(+), 134 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e07b20517b99..166525c5e5a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9555,7 +9555,6 @@ dependencies = [ "relay-utils", "sp-arithmetic 23.0.0", "sp-core 28.0.0", - "sp-runtime 31.0.1", ] [[package]] diff --git a/bridges/relays/lib-substrate-relay/src/cli/bridge.rs b/bridges/relays/lib-substrate-relay/src/cli/bridge.rs index 28b0eb0ad526..2e15562f6c2e 100644 --- a/bridges/relays/lib-substrate-relay/src/cli/bridge.rs +++ b/bridges/relays/lib-substrate-relay/src/cli/bridge.rs @@ -23,9 +23,12 @@ use crate::{ parachains::SubstrateParachainsPipeline, }; use bp_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber}; +use codec::{Codec, EncodeLike}; +use messages_relay::Labeled; use relay_substrate_client::{ Chain, ChainWithRuntimeVersion, ChainWithTransactions, Parachain, RelayChain, }; +use std::fmt::Debug; /// Minimal bridge representation that can be used from the CLI. /// It connects a source chain to a target chain. @@ -99,7 +102,22 @@ where /// Bridge representation that can be used from the CLI for relaying messages. pub trait MessagesCliBridge: CliBridgeBase { /// The Source -> Destination messages synchronization pipeline. - type MessagesLane: SubstrateMessageLane; + type MessagesLane: SubstrateMessageLane< + SourceChain = Self::Source, + TargetChain = Self::Target, + LaneId = Self::LaneId, + >; + /// Lane identifier type. + type LaneId: Clone + + Copy + + Debug + + Codec + + EncodeLike + + Send + + Sync + + Labeled + + TryFrom> + + Default; /// Optional messages delivery transaction limits that the messages relay is going /// to use. If it returns `None`, limits are estimated using `TransactionPayment` API @@ -108,3 +126,6 @@ pub trait MessagesCliBridge: CliBridgeBase { None } } + +/// An alias for lane identifier type. +pub type MessagesLaneIdOf = ::LaneId; diff --git a/bridges/relays/lib-substrate-relay/src/cli/mod.rs b/bridges/relays/lib-substrate-relay/src/cli/mod.rs index ef8403ff68ee..ee5aec67511b 100644 --- a/bridges/relays/lib-substrate-relay/src/cli/mod.rs +++ b/bridges/relays/lib-substrate-relay/src/cli/mod.rs @@ -16,10 +16,8 @@ //! Deal with CLI args of substrate-to-substrate relay. -use bp_messages::LaneId; use rbtag::BuildInfo; -use sp_core::H256; -use sp_runtime::Either; +use sp_runtime::traits::TryConvert; use std::str::FromStr; use structopt::StructOpt; use strum::{EnumString, VariantNames}; @@ -43,36 +41,19 @@ pub type DefaultClient = relay_substrate_client::RpcWithCachingClient; /// Lane id. #[derive(Debug, Clone, PartialEq, Eq)] -pub struct HexLaneId(Either); +pub struct HexLaneId(Vec); -impl From for LaneId { - fn from(lane_id: HexLaneId) -> LaneId { - LaneId::from_inner(lane_id.0) +impl>> TryConvert for HexLaneId { + fn try_convert(a: HexLaneId) -> Result { + T::try_from(a.0.clone()).map_err(|_| a) } } impl FromStr for HexLaneId { - type Err = rustc_hex::FromHexError; + type Err = hex::FromHexError; fn from_str(s: &str) -> Result { - // check `H256` variant at first - match H256::from_str(s) { - Ok(hash) => Ok(HexLaneId(Either::Left(hash))), - Err(hash_error) => { - // check backwards compatible - let mut lane_id = [0u8; 4]; - match hex::decode_to_slice(s, &mut lane_id) { - Ok(_) => Ok(HexLaneId(Either::Right(lane_id))), - Err(array_error) => { - log::error!( - target: "bridge", - "Failed to parse `HexLaneId` as hex string: {s:?} - hash_error: {hash_error:?}, array_error: {array_error:?}", - ); - Err(hash_error) - }, - } - }, - } + hex::decode(s).map(Self) } } @@ -172,6 +153,8 @@ pub enum RuntimeVersionType { #[cfg(test)] mod tests { use super::*; + use bp_messages::{HashedLaneId, LegacyLaneId}; + use sp_core::H256; #[test] fn hex_lane_id_from_str_works() { @@ -185,21 +168,21 @@ mod tests { ) .is_err()); assert_eq!( - LaneId::from( + HexLaneId::try_convert( HexLaneId::from_str( "0101010101010101010101010101010101010101010101010101010101010101" ) .unwrap() ), - LaneId::from_inner(Either::Left(H256::from([1u8; 32]))) + Ok(HashedLaneId::from_inner(H256::from([1u8; 32]))) ); // array variant assert!(HexLaneId::from_str("0000001").is_err()); assert!(HexLaneId::from_str("000000001").is_err()); assert_eq!( - LaneId::from(HexLaneId::from_str("00000001").unwrap()), - LaneId::from_inner(Either::Right([0, 0, 0, 1])) + HexLaneId::try_convert(HexLaneId::from_str("00000001").unwrap()), + Ok(LegacyLaneId([0, 0, 0, 1])) ); } } diff --git a/bridges/relays/lib-substrate-relay/src/cli/relay_headers_and_messages/mod.rs b/bridges/relays/lib-substrate-relay/src/cli/relay_headers_and_messages/mod.rs index 3786976bed9b..9261dc437536 100644 --- a/bridges/relays/lib-substrate-relay/src/cli/relay_headers_and_messages/mod.rs +++ b/bridges/relays/lib-substrate-relay/src/cli/relay_headers_and_messages/mod.rs @@ -31,25 +31,30 @@ pub mod relay_to_relay; pub mod relay_to_parachain; use async_trait::async_trait; -use std::{marker::PhantomData, sync::Arc}; +use codec::{Codec, EncodeLike}; +use std::{fmt::Debug, marker::PhantomData, sync::Arc}; use structopt::StructOpt; use futures::{FutureExt, TryFutureExt}; use crate::{ - cli::{bridge::MessagesCliBridge, DefaultClient, HexLaneId, PrometheusParams}, + cli::{ + bridge::{MessagesCliBridge, MessagesLaneIdOf}, + DefaultClient, HexLaneId, PrometheusParams, + }, messages::{MessagesRelayLimits, MessagesRelayParams}, on_demand::OnDemandRelay, HeadersToRelay, TaggedAccount, TransactionParams, }; -use bp_messages::LaneId; use bp_runtime::BalanceOf; +use messages_relay::Labeled; use relay_substrate_client::{ AccountIdOf, AccountKeyPairOf, Chain, ChainWithBalances, ChainWithMessages, ChainWithRuntimeVersion, ChainWithTransactions, }; use relay_utils::metrics::MetricsParams; use sp_core::Pair; +use sp_runtime::traits::TryConvert; /// Parameters that have the same names across all bridges. #[derive(Debug, PartialEq, StructOpt)] @@ -163,7 +168,7 @@ where &self, source_to_target_headers_relay: Arc>, target_to_source_headers_relay: Arc>, - lane_id: LaneId, + lane_id: MessagesLaneIdOf, maybe_limits: Option, ) -> MessagesRelayParams, DefaultClient> { MessagesRelayParams { @@ -234,9 +239,20 @@ where + ChainWithRuntimeVersion; /// Left to Right bridge. - type L2R: MessagesCliBridge; + type L2R: MessagesCliBridge; /// Right to Left bridge - type R2L: MessagesCliBridge; + type R2L: MessagesCliBridge; + /// Lane identifier type. + type LaneId: Clone + + Copy + + Debug + + Codec + + EncodeLike + + Send + + Sync + + Labeled + + TryFrom> + + Default; /// Construct new bridge. fn new(params: ::Params) -> anyhow::Result; @@ -287,30 +303,29 @@ where self.mut_base().start_on_demand_headers_relayers().await?; // add balance-related metrics - let lanes = self + let lanes: Vec = self .base() .common() .shared .lane .iter() .cloned() - .map(Into::into) - .collect::>(); + .map(HexLaneId::try_convert) + .collect::, HexLaneId>>() + .expect(""); { let common = self.mut_base().mut_common(); - crate::messages::metrics::add_relay_balances_metrics::<_, Self::Right>( - common.left.client.clone(), - &common.metrics_params, - &common.left.accounts, - &lanes, - ) + crate::messages::metrics::add_relay_balances_metrics::< + _, + Self::Right, + MessagesLaneIdOf, + >(common.left.client.clone(), &common.metrics_params, &common.left.accounts, &lanes) .await?; - crate::messages::metrics::add_relay_balances_metrics::<_, Self::Left>( - common.right.client.clone(), - &common.metrics_params, - &common.right.accounts, - &lanes, - ) + crate::messages::metrics::add_relay_balances_metrics::< + _, + Self::Left, + MessagesLaneIdOf, + >(common.right.client.clone(), &common.metrics_params, &common.right.accounts, &lanes) .await?; } @@ -359,8 +374,6 @@ mod tests { use crate::{cli::chain_schema::RuntimeVersionType, declare_chain_cli_schema}; use relay_substrate_client::{ChainRuntimeVersion, Parachain, SimpleRuntimeVersion}; - use sp_core::H256; - use sp_runtime::Either; #[test] // We need `#[allow(dead_code)]` because some of the methods generated by the macros @@ -434,7 +447,7 @@ mod tests { res, BridgeHubKusamaBridgeHubPolkadotHeadersAndMessages { shared: HeadersAndMessagesSharedParams { - lane: vec![HexLaneId(Either::Left(H256::from([0x00u8; 32])))], + lane: vec![HexLaneId(vec![0x00u8; 32])], only_mandatory_headers: false, only_free_headers: false, prometheus_params: PrometheusParams { diff --git a/bridges/relays/lib-substrate-relay/src/cli/relay_messages.rs b/bridges/relays/lib-substrate-relay/src/cli/relay_messages.rs index 34d5226e90c5..3878b081d6c3 100644 --- a/bridges/relays/lib-substrate-relay/src/cli/relay_messages.rs +++ b/bridges/relays/lib-substrate-relay/src/cli/relay_messages.rs @@ -33,6 +33,7 @@ use relay_substrate_client::{ ChainWithTransactions, Client, }; use relay_utils::UniqueSaturatedInto; +use sp_runtime::traits::TryConvert; /// Messages relaying params. #[derive(StructOpt)] @@ -116,6 +117,9 @@ where let target_client = data.target.into_client::().await?; let target_sign = data.target_sign.to_keypair::()?; let target_transactions_mortality = data.target_sign.transactions_mortality()?; + let lane_id = HexLaneId::try_convert(data.lane).map_err(|invalid_lane_id| { + anyhow::format_err!("Invalid laneId: {:?}!", invalid_lane_id) + })?; crate::messages::run::(MessagesRelayParams { source_client, @@ -130,7 +134,7 @@ where }, source_to_target_headers_relay: None, target_to_source_headers_relay: None, - lane_id: data.lane.into(), + lane_id, limits: Self::maybe_messages_limits(), metrics_params: data.prometheus_params.into_metrics_params()?, }) @@ -146,6 +150,9 @@ where let source_transactions_mortality = data.source_sign.transactions_mortality()?; let target_sign = data.target_sign.to_keypair::()?; let target_transactions_mortality = data.target_sign.transactions_mortality()?; + let lane_id = HexLaneId::try_convert(data.lane).map_err(|invalid_lane_id| { + anyhow::format_err!("Invalid laneId: {:?}!", invalid_lane_id) + })?; let at_source_block = source_client .header_by_number(data.at_source_block.unique_saturated_into()) @@ -167,7 +174,7 @@ where TransactionParams { signer: source_sign, mortality: source_transactions_mortality }, TransactionParams { signer: target_sign, mortality: target_transactions_mortality }, at_source_block, - data.lane.into(), + lane_id, data.messages_start..=data.messages_end, data.outbound_state_proof_required, ) @@ -182,6 +189,9 @@ where let target_client = data.target.into_client::().await?; let source_sign = data.source_sign.to_keypair::()?; let source_transactions_mortality = data.source_sign.transactions_mortality()?; + let lane_id = HexLaneId::try_convert(data.lane).map_err(|invalid_lane_id| { + anyhow::format_err!("Invalid laneId: {:?}!", invalid_lane_id) + })?; let at_target_block = target_client .header_by_number(data.at_target_block.unique_saturated_into()) @@ -202,7 +212,7 @@ where target_client, TransactionParams { signer: source_sign, mortality: source_transactions_mortality }, at_target_block, - data.lane.into(), + lane_id, ) .await } diff --git a/bridges/relays/lib-substrate-relay/src/messages/metrics.rs b/bridges/relays/lib-substrate-relay/src/messages/metrics.rs index 201fee0b1c1c..9d45a4b3d668 100644 --- a/bridges/relays/lib-substrate-relay/src/messages/metrics.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/metrics.rs @@ -18,12 +18,11 @@ use crate::TaggedAccount; -use bp_messages::LaneId; use bp_relayers::{RewardsAccountOwner, RewardsAccountParams}; use bp_runtime::StorageDoubleMapKeyProvider; -use codec::Decode; +use codec::{Decode, EncodeLike}; use frame_system::AccountInfo; -use messages_relay::lane_to_label; +use messages_relay::Labeled; use pallet_balances::AccountData; use relay_substrate_client::{ metrics::{FloatStorageValue, FloatStorageValueMetric}, @@ -36,7 +35,7 @@ use sp_runtime::{FixedPointNumber, FixedU128}; use std::{fmt::Debug, marker::PhantomData}; /// Add relay accounts balance metrics. -pub async fn add_relay_balances_metrics( +pub async fn add_relay_balances_metrics( client: impl Client, metrics: &MetricsParams, relay_accounts: &Vec>>, @@ -44,6 +43,7 @@ pub async fn add_relay_balances_metrics anyhow::Result<()> where BalanceOf: Into + std::fmt::Debug, + LaneId: Clone + Copy + Decode + EncodeLike + Send + Sync + Labeled, { if relay_accounts.is_empty() { return Ok(()) @@ -87,25 +87,25 @@ where FloatStorageValueMetric::new( AccountBalance:: { token_decimals, _phantom: Default::default() }, client.clone(), - bp_relayers::RelayerRewardsKeyProvider::, BalanceOf>::final_key( + bp_relayers::RelayerRewardsKeyProvider::, BalanceOf, LaneId>::final_key( relayers_pallet_name, account.id(), &RewardsAccountParams::new(*lane, BC::ID, RewardsAccountOwner::ThisChain), ), - format!("at_{}_relay_{}_reward_for_msgs_from_{}_on_lane_{}", C::NAME, account.tag(), BC::NAME, lane_to_label(lane)), - format!("Reward of the {} relay account at {} for delivering messages from {} on lane {:?}", account.tag(), C::NAME, BC::NAME, lane), + format!("at_{}_relay_{}_reward_for_msgs_from_{}_on_lane_{}", C::NAME, account.tag(), BC::NAME, lane.label()), + format!("Reward of the {} relay account at {} for delivering messages from {} on lane {:?}", account.tag(), C::NAME, BC::NAME, lane.label()), )?.register_and_spawn(&metrics.registry)?; FloatStorageValueMetric::new( AccountBalance:: { token_decimals, _phantom: Default::default() }, client.clone(), - bp_relayers::RelayerRewardsKeyProvider::, BalanceOf>::final_key( + bp_relayers::RelayerRewardsKeyProvider::, BalanceOf, LaneId>::final_key( relayers_pallet_name, account.id(), &RewardsAccountParams::new(*lane, BC::ID, RewardsAccountOwner::BridgedChain), ), - format!("at_{}_relay_{}_reward_for_msgs_to_{}_on_lane_{}", C::NAME, account.tag(), BC::NAME, lane_to_label(lane)), - format!("Reward of the {} relay account at {} for delivering messages confirmations from {} on lane {:?}", account.tag(), C::NAME, BC::NAME, lane), + format!("at_{}_relay_{}_reward_for_msgs_to_{}_on_lane_{}", C::NAME, account.tag(), BC::NAME, lane.label()), + format!("Reward of the {} relay account at {} for delivering messages confirmations from {} on lane {:?}", account.tag(), C::NAME, BC::NAME, lane.label()), )?.register_and_spawn(&metrics.registry)?; } } diff --git a/bridges/relays/lib-substrate-relay/src/messages/mod.rs b/bridges/relays/lib-substrate-relay/src/messages/mod.rs index 28bc5c7f5e8e..08e9163a2211 100644 --- a/bridges/relays/lib-substrate-relay/src/messages/mod.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/mod.rs @@ -27,19 +27,18 @@ use crate::{ use async_std::sync::Arc; use bp_messages::{ - target_chain::FromBridgedChainMessagesProof, ChainWithMessages as _, LaneId, MessageNonce, + source_chain::FromBridgedChainMessagesDeliveryProof, + target_chain::FromBridgedChainMessagesProof, ChainWithMessages as _, MessageNonce, }; -use bp_runtime::{ - AccountIdOf, Chain as _, EncodedOrDecodedCall, HeaderIdOf, TransactionEra, WeightExtraOps, -}; -use codec::Encode; +use bp_runtime::{AccountIdOf, EncodedOrDecodedCall, HeaderIdOf, TransactionEra, WeightExtraOps}; +use codec::{Codec, Encode, EncodeLike}; use frame_support::{dispatch::GetDispatchInfo, weights::Weight}; -use messages_relay::{message_lane::MessageLane, message_lane_loop::BatchTransaction}; +use messages_relay::{message_lane::MessageLane, message_lane_loop::BatchTransaction, Labeled}; use pallet_bridge_messages::{Call as BridgeMessagesCall, Config as BridgeMessagesConfig}; use relay_substrate_client::{ transaction_stall_timeout, AccountKeyPairOf, BalanceOf, BlockNumberOf, CallOf, Chain, - ChainWithMessages, ChainWithTransactions, Client, Error as SubstrateError, HashOf, SignParam, - UnsignedTransaction, + ChainBase, ChainWithMessages, ChainWithTransactions, Client, Error as SubstrateError, HashOf, + SignParam, UnsignedTransaction, }; use relay_utils::{ metrics::{GlobalMetrics, MetricsParams, StandaloneMetric}, @@ -60,6 +59,18 @@ pub trait SubstrateMessageLane: 'static + Clone + Debug + Send + Sync { /// Messages from the `SourceChain` are dispatched on this chain. type TargetChain: ChainWithMessages + ChainWithTransactions; + /// Lane identifier type. + type LaneId: Clone + + Copy + + Debug + + Codec + + EncodeLike + + Send + + Sync + + Labeled + + TryFrom> + + Default; + /// How receive messages proof call is built? type ReceiveMessagesProofCallBuilder: ReceiveMessagesProofCallBuilder; /// How receive messages delivery proof call is built? @@ -81,8 +92,10 @@ impl MessageLane for MessageLaneAdapter

{ const SOURCE_NAME: &'static str = P::SourceChain::NAME; const TARGET_NAME: &'static str = P::TargetChain::NAME; - type MessagesProof = SubstrateMessagesProof; - type MessagesReceivingProof = SubstrateMessagesDeliveryProof; + type LaneId = P::LaneId; + + type MessagesProof = SubstrateMessagesProof; + type MessagesReceivingProof = SubstrateMessagesDeliveryProof; type SourceChainBalance = BalanceOf; type SourceHeaderNumber = BlockNumberOf; @@ -109,7 +122,7 @@ pub struct MessagesRelayParams pub target_to_source_headers_relay: Option>>, /// Identifier of lane that needs to be served. - pub lane_id: LaneId, + pub lane_id: P::LaneId, /// Messages relay limits. If not provided, the relay tries to determine it automatically, /// using `TransactionPayment` pallet runtime API. pub limits: Option, @@ -293,7 +306,7 @@ pub async fn relay_messages_range( source_transaction_params: TransactionParams>, target_transaction_params: TransactionParams>, at_source_block: HeaderIdOf, - lane_id: LaneId, + lane_id: P::LaneId, range: RangeInclusive, outbound_state_proof_required: bool, ) -> anyhow::Result<()> @@ -335,7 +348,7 @@ pub async fn relay_messages_delivery_confirmation( target_client: impl Client, source_transaction_params: TransactionParams>, at_target_block: HeaderIdOf, - lane_id: LaneId, + lane_id: P::LaneId, ) -> anyhow::Result<()> where AccountIdOf: From< as Pair>::Public>, @@ -372,7 +385,7 @@ pub trait ReceiveMessagesProofCallBuilder { /// messages module at the target chain. fn build_receive_messages_proof_call( relayer_id_at_source: AccountIdOf, - proof: SubstrateMessagesProof, + proof: SubstrateMessagesProof, messages_count: u32, dispatch_weight: Weight, trace_call: bool, @@ -393,10 +406,21 @@ where R::BridgedChain: bp_runtime::Chain, Hash = HashOf>, CallOf: From> + GetDispatchInfo, + Box< + bp_messages::target_chain::FromBridgedChainMessagesProof< + <

::SourceChain as ChainBase>::Hash, + >::LaneId, + >, + >: From< + bp_messages::target_chain::FromBridgedChainMessagesProof< + <

::SourceChain as ChainBase>::Hash, +

::LaneId, + >, + >, { fn build_receive_messages_proof_call( relayer_id_at_source: AccountIdOf, - proof: SubstrateMessagesProof, + proof: SubstrateMessagesProof, messages_count: u32, dispatch_weight: Weight, trace_call: bool, @@ -444,7 +468,8 @@ macro_rules! generate_receive_message_proof_call_builder { <$pipeline as $crate::messages::SubstrateMessageLane>::SourceChain >, proof: $crate::messages::source::SubstrateMessagesProof< - <$pipeline as $crate::messages::SubstrateMessageLane>::SourceChain + <$pipeline as $crate::messages::SubstrateMessageLane>::SourceChain, + <$pipeline as $crate::messages::SubstrateMessageLane>::LaneId >, messages_count: u32, dispatch_weight: bp_messages::Weight, @@ -470,7 +495,7 @@ pub trait ReceiveMessagesDeliveryProofCallBuilder { /// Given messages delivery proof, build call of `receive_messages_delivery_proof` function of /// bridge messages module at the source chain. fn build_receive_messages_delivery_proof_call( - proof: SubstrateMessagesDeliveryProof, + proof: SubstrateMessagesDeliveryProof, trace_call: bool, ) -> CallOf; } @@ -489,9 +514,18 @@ where I: 'static, R::BridgedChain: bp_runtime::Chain>, CallOf: From> + GetDispatchInfo, + FromBridgedChainMessagesDeliveryProof< + <

::TargetChain as ChainBase>::Hash, + >::LaneId, + >: From< + FromBridgedChainMessagesDeliveryProof< + <

::TargetChain as ChainBase>::Hash, +

::LaneId, + >, + >, { fn build_receive_messages_delivery_proof_call( - proof: SubstrateMessagesDeliveryProof, + proof: SubstrateMessagesDeliveryProof, trace_call: bool, ) -> CallOf { let call: CallOf = @@ -533,7 +567,8 @@ macro_rules! generate_receive_message_delivery_proof_call_builder { { fn build_receive_messages_delivery_proof_call( proof: $crate::messages::target::SubstrateMessagesDeliveryProof< - <$pipeline as $crate::messages::SubstrateMessageLane>::TargetChain + <$pipeline as $crate::messages::SubstrateMessageLane>::TargetChain, + <$pipeline as $crate::messages::SubstrateMessageLane>::LaneId >, _trace_call: bool, ) -> relay_substrate_client::CallOf< @@ -644,7 +679,7 @@ where FromBridgedChainMessagesProof { bridged_header_hash: Default::default(), storage_proof: Default::default(), - lane: LaneId::new(1, 2), + lane: P::LaneId::default(), nonces_start: 1, nonces_end: messages as u64, }, @@ -674,7 +709,7 @@ where mod tests { use super::*; use bp_messages::{ - source_chain::FromBridgedChainMessagesDeliveryProof, UnrewardedRelayersState, + source_chain::FromBridgedChainMessagesDeliveryProof, LaneIdType, UnrewardedRelayersState, }; use relay_substrate_client::calls::{UtilityCall as MockUtilityCall, UtilityCall}; @@ -687,8 +722,8 @@ mod tests { } pub type CodegenBridgeMessagesCall = bp_messages::BridgeMessagesCall< u64, - Box>, - FromBridgedChainMessagesDeliveryProof, + Box>, + FromBridgedChainMessagesDeliveryProof, >; impl From> for RuntimeCall { @@ -706,7 +741,7 @@ mod tests { let receive_messages_proof = FromBridgedChainMessagesProof { bridged_header_hash: Default::default(), storage_proof: Default::default(), - lane: LaneId::new(1, 2), + lane: mock::TestLaneIdType::new(1, 2), nonces_start: 0, nonces_end: 0, }; @@ -761,7 +796,7 @@ mod tests { let receive_messages_delivery_proof = FromBridgedChainMessagesDeliveryProof { bridged_header_hash: Default::default(), storage_proof: Default::default(), - lane: LaneId::new(1, 2), + lane: mock::TestLaneIdType::new(1, 2), }; let relayers_state = UnrewardedRelayersState { unrewarded_relayer_entries: 0, @@ -808,7 +843,7 @@ mod tests { // mock runtime with `pallet_bridge_messages` mod mock { use super::super::*; - use bp_messages::target_chain::ForbidInboundMessages; + use bp_messages::{target_chain::ForbidInboundMessages, HashedLaneId}; use bp_runtime::ChainId; use frame_support::derive_impl; use sp_core::H256; @@ -819,6 +854,9 @@ mod tests { type Block = frame_system::mocking::MockBlock; pub type SignedBlock = generic::SignedBlock; + /// Lane identifier type used for tests. + pub type TestLaneIdType = HashedLaneId; + frame_support::construct_runtime! { pub enum TestRuntime { @@ -840,10 +878,11 @@ mod tests { type BridgedHeaderChain = BridgedHeaderChain; type OutboundPayload = Vec; type InboundPayload = Vec; + type LaneId = TestLaneIdType; type DeliveryPayments = (); type DeliveryConfirmationPayments = (); type OnMessagesDelivered = (); - type MessageDispatch = ForbidInboundMessages>; + type MessageDispatch = ForbidInboundMessages, Self::LaneId>; } pub struct ThisUnderlyingChain; @@ -1005,6 +1044,7 @@ mod tests { impl SubstrateMessageLane for ThisChainToBridgedChainMessageLane { type SourceChain = ThisChain; type TargetChain = BridgedChain; + type LaneId = mock::TestLaneIdType; type ReceiveMessagesProofCallBuilder = ThisChainToBridgedChainMessageLaneReceiveMessagesProofCallBuilder; type ReceiveMessagesDeliveryProofCallBuilder = diff --git a/bridges/relays/lib-substrate-relay/src/messages/source.rs b/bridges/relays/lib-substrate-relay/src/messages/source.rs index 2c49df3452ab..8359b053309f 100644 --- a/bridges/relays/lib-substrate-relay/src/messages/source.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/source.rs @@ -34,7 +34,7 @@ use async_trait::async_trait; use bp_messages::{ storage_keys::{operating_mode_key, outbound_lane_data_key}, target_chain::FromBridgedChainMessagesProof, - ChainWithMessages as _, InboundMessageDetails, LaneId, MessageNonce, MessagePayload, + ChainWithMessages as _, InboundMessageDetails, MessageNonce, MessagePayload, MessagesOperatingMode, OutboundLaneData, OutboundMessageDetails, }; use bp_runtime::{BasicOperatingMode, HeaderIdProvider, RangeInclusiveExt}; @@ -60,14 +60,14 @@ use std::ops::RangeInclusive; /// Intermediate message proof returned by the source Substrate node. Includes everything /// required to submit to the target node: cumulative dispatch weight of bundled messages and /// the proof itself. -pub type SubstrateMessagesProof = (Weight, FromBridgedChainMessagesProof>); +pub type SubstrateMessagesProof = (Weight, FromBridgedChainMessagesProof, L>); type MessagesToRefine<'a> = Vec<(MessagePayload, &'a mut OutboundMessageDetails)>; /// Substrate client as Substrate messages source. pub struct SubstrateMessagesSource { source_client: SourceClnt, target_client: TargetClnt, - lane_id: LaneId, + lane_id: P::LaneId, transaction_params: TransactionParams>, target_to_source_headers_relay: Option>>, } @@ -79,7 +79,7 @@ impl, TargetClnt> pub fn new( source_client: SourceClnt, target_client: TargetClnt, - lane_id: LaneId, + lane_id: P::LaneId, transaction_params: TransactionParams>, target_to_source_headers_relay: Option< Arc>, @@ -256,8 +256,11 @@ where } let best_target_header_hash = self.target_client.best_header_hash().await?; - for mut msgs_to_refine_batch in - split_msgs_to_refine::(self.lane_id, msgs_to_refine)? + for mut msgs_to_refine_batch in split_msgs_to_refine::< + P::SourceChain, + P::TargetChain, + P::LaneId, + >(self.lane_id, msgs_to_refine)? { let in_msgs_details = self .target_client @@ -542,7 +545,7 @@ fn validate_out_msgs_details( Ok(()) } -fn split_msgs_to_refine( +fn split_msgs_to_refine( lane_id: LaneId, msgs_to_refine: MessagesToRefine, ) -> Result, SubstrateError> { @@ -578,8 +581,12 @@ fn split_msgs_to_refine( #[cfg(test)] mod tests { use super::*; + use bp_messages::{HashedLaneId, LaneIdType}; use relay_substrate_client::test_chain::TestChain; + /// Lane identifier type used for tests. + type TestLaneIdType = HashedLaneId; + fn message_details_from_rpc( nonces: RangeInclusive, ) -> Vec { @@ -660,8 +667,10 @@ mod tests { msgs_to_refine.push((payload, out_msg_details)); } - let maybe_batches = - split_msgs_to_refine::(LaneId::new(1, 2), msgs_to_refine); + let maybe_batches = split_msgs_to_refine::( + TestLaneIdType::new(1, 2), + msgs_to_refine, + ); match expected_batches { Ok(expected_batches) => { let batches = maybe_batches.unwrap(); diff --git a/bridges/relays/lib-substrate-relay/src/messages/target.rs b/bridges/relays/lib-substrate-relay/src/messages/target.rs index a6bf169cffb6..0d1aac88a32a 100644 --- a/bridges/relays/lib-substrate-relay/src/messages/target.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/target.rs @@ -36,7 +36,7 @@ use async_std::sync::Arc; use async_trait::async_trait; use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, storage_keys::inbound_lane_data_key, - ChainWithMessages as _, InboundLaneData, LaneId, MessageNonce, UnrewardedRelayersState, + ChainWithMessages as _, InboundLaneData, MessageNonce, UnrewardedRelayersState, }; use messages_relay::{ message_lane::{MessageLane, SourceHeaderIdOf, TargetHeaderIdOf}, @@ -51,14 +51,14 @@ use sp_core::Pair; use std::{convert::TryFrom, ops::RangeInclusive}; /// Message receiving proof returned by the target Substrate node. -pub type SubstrateMessagesDeliveryProof = - (UnrewardedRelayersState, FromBridgedChainMessagesDeliveryProof>); +pub type SubstrateMessagesDeliveryProof = + (UnrewardedRelayersState, FromBridgedChainMessagesDeliveryProof, L>); /// Substrate client as Substrate messages target. pub struct SubstrateMessagesTarget { target_client: TargetClnt, source_client: SourceClnt, - lane_id: LaneId, + lane_id: P::LaneId, relayer_id_at_source: AccountIdOf, transaction_params: Option>>, source_to_target_headers_relay: Option>>, @@ -73,7 +73,7 @@ where pub fn new( target_client: TargetClnt, source_client: SourceClnt, - lane_id: LaneId, + lane_id: P::LaneId, relayer_id_at_source: AccountIdOf, transaction_params: Option>>, source_to_target_headers_relay: Option< @@ -308,7 +308,7 @@ where fn make_messages_delivery_call( relayer_id_at_source: AccountIdOf, nonces: RangeInclusive, - proof: SubstrateMessagesProof, + proof: SubstrateMessagesProof, trace_call: bool, ) -> CallOf { let messages_count = nonces.end() - nonces.start() + 1; diff --git a/bridges/relays/messages/Cargo.toml b/bridges/relays/messages/Cargo.toml index 7708a494d1c7..5e71851f7385 100644 --- a/bridges/relays/messages/Cargo.toml +++ b/bridges/relays/messages/Cargo.toml @@ -26,7 +26,6 @@ finality-relay = { workspace = true } relay-utils = { workspace = true } sp-arithmetic = { workspace = true, default-features = true } -sp-runtime = { workspace = true } [dev-dependencies] sp-core = { workspace = true } \ No newline at end of file diff --git a/bridges/relays/messages/src/lib.rs b/bridges/relays/messages/src/lib.rs index 2b834d424361..f5e09f4d4684 100644 --- a/bridges/relays/messages/src/lib.rs +++ b/bridges/relays/messages/src/lib.rs @@ -38,4 +38,4 @@ mod message_race_strategy; pub use message_race_delivery::relay_messages_range; pub use message_race_receiving::relay_messages_delivery_confirmation; -pub use metrics::lane_to_label; +pub use metrics::Labeled; diff --git a/bridges/relays/messages/src/message_lane.rs b/bridges/relays/messages/src/message_lane.rs index 5c9728ad93ab..84c1e57ba4eb 100644 --- a/bridges/relays/messages/src/message_lane.rs +++ b/bridges/relays/messages/src/message_lane.rs @@ -19,6 +19,7 @@ //! 1) relay new messages from source to target node; //! 2) relay proof-of-delivery from target to source node. +use crate::metrics::Labeled; use num_traits::{SaturatingAdd, Zero}; use relay_utils::{BlockNumberBase, HeaderId}; use sp_arithmetic::traits::AtLeast32BitUnsigned; @@ -31,6 +32,9 @@ pub trait MessageLane: 'static + Clone + Send + Sync { /// Name of the messages target. const TARGET_NAME: &'static str; + /// Lane identifier type. + type LaneId: Clone + Send + Sync + Labeled; + /// Messages proof. type MessagesProof: Clone + Debug + Send + Sync; /// Messages receiving proof. diff --git a/bridges/relays/messages/src/message_lane_loop.rs b/bridges/relays/messages/src/message_lane_loop.rs index ccad334dcb56..2ee302a9259e 100644 --- a/bridges/relays/messages/src/message_lane_loop.rs +++ b/bridges/relays/messages/src/message_lane_loop.rs @@ -29,7 +29,7 @@ use std::{collections::BTreeMap, fmt::Debug, future::Future, ops::RangeInclusive use async_trait::async_trait; use futures::{channel::mpsc::unbounded, future::FutureExt, stream::StreamExt}; -use bp_messages::{LaneId, MessageNonce, UnrewardedRelayersState, Weight}; +use bp_messages::{MessageNonce, UnrewardedRelayersState, Weight}; use relay_utils::{ interval, metrics::MetricsParams, process_future_result, relay_loop::Client as RelayClient, retry_backoff, FailedClient, TransactionTracker, @@ -39,12 +39,12 @@ use crate::{ message_lane::{MessageLane, SourceHeaderIdOf, TargetHeaderIdOf}, message_race_delivery::run as run_message_delivery_race, message_race_receiving::run as run_message_receiving_race, - metrics::{lane_to_label, MessageLaneLoopMetrics}, + metrics::{Labeled, MessageLaneLoopMetrics}, }; /// Message lane loop configuration params. #[derive(Debug, Clone)] -pub struct Params { +pub struct Params { /// Id of lane this loop is servicing. pub lane: LaneId, /// Interval at which we ask target node about its updates. @@ -275,13 +275,13 @@ pub struct ClientsState { /// Return prefix that will be used by default to expose Prometheus metrics of the finality proofs /// sync loop. -pub fn metrics_prefix(lane: &LaneId) -> String { - format!("{}_to_{}_MessageLane_{}", P::SOURCE_NAME, P::TARGET_NAME, lane_to_label(lane)) +pub fn metrics_prefix(lane: &P::LaneId) -> String { + format!("{}_to_{}_MessageLane_{}", P::SOURCE_NAME, P::TARGET_NAME, lane.label()) } /// Run message lane service loop. pub async fn run( - params: Params, + params: Params, source_client: impl SourceClient

, target_client: impl TargetClient

, metrics_params: MetricsParams, @@ -309,7 +309,7 @@ pub async fn run( /// Run one-way message delivery loop until connection with target or source node is lost, or exit /// signal is received. async fn run_until_connection_lost, TC: TargetClient

>( - params: Params, + params: Params, source_client: SC, target_client: TC, metrics_msg: Option, @@ -471,9 +471,9 @@ async fn run_until_connection_lost, TC: Targ pub(crate) mod tests { use std::sync::Arc; + use bp_messages::{HashedLaneId, LaneIdType, LegacyLaneId}; use futures::stream::StreamExt; use parking_lot::Mutex; - use relay_utils::{HeaderId, MaybeConnectionError, TrackedTransactionStatus}; use super::*; @@ -504,6 +504,9 @@ pub(crate) mod tests { } } + /// Lane identifier type used for tests. + pub type TestLaneIdType = HashedLaneId; + #[derive(Clone)] pub struct TestMessageLane; @@ -520,6 +523,8 @@ pub(crate) mod tests { type TargetHeaderNumber = TestTargetHeaderNumber; type TargetHeaderHash = TestTargetHeaderHash; + + type LaneId = TestLaneIdType; } #[derive(Clone, Debug)] @@ -957,7 +962,7 @@ pub(crate) mod tests { }; let _ = run( Params { - lane: LaneId::new(1, 2), + lane: TestLaneIdType::new(1, 2), source_tick: Duration::from_millis(100), target_tick: Duration::from_millis(100), reconnect_delay: Duration::from_millis(0), @@ -1278,11 +1283,31 @@ pub(crate) mod tests { #[test] fn metrics_prefix_is_valid() { assert!(MessageLaneLoopMetrics::new(Some(&metrics_prefix::( - &LaneId::new(1, 2) + &HashedLaneId::new(1, 2) ))) .is_ok()); - assert!(MessageLaneLoopMetrics::new(Some(&metrics_prefix::( - &LaneId::from_inner(sp_runtime::Either::Right([0, 0, 0, 1])) + + // with LegacyLaneId + #[derive(Clone)] + pub struct LegacyTestMessageLane; + impl MessageLane for LegacyTestMessageLane { + const SOURCE_NAME: &'static str = "LegacyTestSource"; + const TARGET_NAME: &'static str = "LegacyTestTarget"; + + type MessagesProof = TestMessagesProof; + type MessagesReceivingProof = TestMessagesReceivingProof; + + type SourceChainBalance = TestSourceChainBalance; + type SourceHeaderNumber = TestSourceHeaderNumber; + type SourceHeaderHash = TestSourceHeaderHash; + + type TargetHeaderNumber = TestTargetHeaderNumber; + type TargetHeaderHash = TestTargetHeaderHash; + + type LaneId = LegacyLaneId; + } + assert!(MessageLaneLoopMetrics::new(Some(&metrics_prefix::( + &LegacyLaneId([0, 0, 0, 1]) ))) .is_ok()); } diff --git a/bridges/relays/messages/src/metrics.rs b/bridges/relays/messages/src/metrics.rs index d1ae1bb989dc..2ca10e56d74a 100644 --- a/bridges/relays/messages/src/metrics.rs +++ b/bridges/relays/messages/src/metrics.rs @@ -21,12 +21,11 @@ use crate::{ message_lane_loop::{SourceClientState, TargetClientState}, }; -use bp_messages::{LaneId, MessageNonce}; +use bp_messages::{HashedLaneId, LegacyLaneId, MessageNonce}; use finality_relay::SyncLoopMetrics; use relay_utils::metrics::{ metric_name, register, GaugeVec, Metric, Opts, PrometheusError, Registry, U64, }; -use sp_runtime::Either; /// Message lane relay metrics. /// @@ -148,11 +147,23 @@ impl Metric for MessageLaneLoopMetrics { } } -/// Unified label for `LaneId`. -pub fn lane_to_label(lane: &LaneId) -> String { - match lane.inner() { - Either::Left(hash) => format!("{:?}", hash), - Either::Right(array) => hex::encode(array), +/// Provides a label for metrics. +pub trait Labeled { + /// Returns a label. + fn label(&self) -> String; +} + +/// `Labeled` implementation for `LegacyLaneId`. +impl Labeled for LegacyLaneId { + fn label(&self) -> String { + hex::encode(self.0) + } +} + +/// `Labeled` implementation for `HashedLaneId`. +impl Labeled for HashedLaneId { + fn label(&self) -> String { + format!("{:?}", self.inner()) } } @@ -160,7 +171,7 @@ pub fn lane_to_label(lane: &LaneId) -> String { fn lane_to_label_works() { assert_eq!( "0x0101010101010101010101010101010101010101010101010101010101010101", - lane_to_label(&LaneId::from_inner(Either::Left(sp_core::H256::from([1u8; 32])))), + HashedLaneId::from_inner(sp_core::H256::from([1u8; 32])).label(), ); - assert_eq!("00000001", lane_to_label(&LaneId::from_inner(Either::Right([0, 0, 0, 1])))); + assert_eq!("00000001", LegacyLaneId([0, 0, 0, 1]).label()); } From 387ae67cc1cc1ae484fc043eebee303fcc2e77e9 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 18 Sep 2024 10:53:27 +0200 Subject: [PATCH 15/38] Add multi-instance support for `pallet_bridge_relayers` --- bridges/modules/relayers/src/lib.rs | 186 +++++++++++++++------------- 1 file changed, 97 insertions(+), 89 deletions(-) diff --git a/bridges/modules/relayers/src/lib.rs b/bridges/modules/relayers/src/lib.rs index 2adc2b6c292e..ebd3a59f13c3 100644 --- a/bridges/modules/relayers/src/lib.rs +++ b/bridges/modules/relayers/src/lib.rs @@ -56,16 +56,17 @@ pub mod pallet { use frame_system::pallet_prelude::*; /// `RelayerRewardsKeyProvider` for given configuration. - type RelayerRewardsKeyProviderOf = RelayerRewardsKeyProvider< + type RelayerRewardsKeyProviderOf = RelayerRewardsKeyProvider< ::AccountId, - ::Reward, - ::LaneId, + >::Reward, + >::LaneId, >; #[pallet::config] - pub trait Config: frame_system::Config { + pub trait Config: frame_system::Config { /// The overarching event type. - type RuntimeEvent: From> + IsType<::RuntimeEvent>; + type RuntimeEvent: From> + + IsType<::RuntimeEvent>; /// Type of relayer reward. type Reward: AtLeast32BitUnsigned + Copy + Member + Parameter + MaxEncodedLen; /// Pay rewards scheme. @@ -83,10 +84,10 @@ pub mod pallet { } #[pallet::pallet] - pub struct Pallet(PhantomData); + pub struct Pallet(PhantomData<(T, I)>); #[pallet::call] - impl Pallet { + impl, I: 'static> Pallet { /// Claim accumulated rewards. #[pallet::call_index(0)] #[pallet::weight(T::WeightInfo::claim_rewards())] @@ -96,11 +97,11 @@ pub mod pallet { ) -> DispatchResult { let relayer = ensure_signed(origin)?; - RelayerRewards::::try_mutate_exists( + RelayerRewards::::try_mutate_exists( &relayer, rewards_account_params, |maybe_reward| -> DispatchResult { - let reward = maybe_reward.take().ok_or(Error::::NoRewardForRelayer)?; + let reward = maybe_reward.take().ok_or(Error::::NoRewardForRelayer)?; T::PaymentProcedure::pay_reward(&relayer, rewards_account_params, reward) .map_err(|e| { log::trace!( @@ -110,10 +111,10 @@ pub mod pallet { relayer, e, ); - Error::::FailedToPayReward + Error::::FailedToPayReward })?; - Self::deposit_event(Event::::RewardPaid { + Self::deposit_event(Event::::RewardPaid { relayer: relayer.clone(), rewards_account_params, reward, @@ -135,53 +136,57 @@ pub mod pallet { // than the `RequiredRegistrationLease` let lease = valid_till.saturating_sub(frame_system::Pallet::::block_number()); ensure!( - lease > Pallet::::required_registration_lease(), - Error::::InvalidRegistrationLease + lease > Self::required_registration_lease(), + Error::::InvalidRegistrationLease ); - RegisteredRelayers::::try_mutate(&relayer, |maybe_registration| -> DispatchResult { - let mut registration = maybe_registration - .unwrap_or_else(|| Registration { valid_till, stake: Zero::zero() }); + RegisteredRelayers::::try_mutate( + &relayer, + |maybe_registration| -> DispatchResult { + let mut registration = maybe_registration + .unwrap_or_else(|| Registration { valid_till, stake: Zero::zero() }); + + // new `valid_till` must be larger (or equal) than the old one + ensure!( + valid_till >= registration.valid_till, + Error::::CannotReduceRegistrationLease, + ); + registration.valid_till = valid_till; + + // regarding stake, there are three options: + // - if relayer stake is larger than required stake, we may do unreserve + // - if relayer stake equals to required stake, we do nothing + // - if relayer stake is smaller than required stake, we do additional reserve + let required_stake = Self::required_stake(); + if let Some(to_unreserve) = registration.stake.checked_sub(&required_stake) { + Self::do_unreserve(&relayer, to_unreserve)?; + } else if let Some(to_reserve) = required_stake.checked_sub(®istration.stake) + { + T::StakeAndSlash::reserve(&relayer, to_reserve).map_err(|e| { + log::trace!( + target: LOG_TARGET, + "Failed to reserve {:?} on relayer {:?} account: {:?}", + to_reserve, + relayer, + e, + ); - // new `valid_till` must be larger (or equal) than the old one - ensure!( - valid_till >= registration.valid_till, - Error::::CannotReduceRegistrationLease, - ); - registration.valid_till = valid_till; - - // regarding stake, there are three options: - // - if relayer stake is larger than required stake, we may do unreserve - // - if relayer stake equals to required stake, we do nothing - // - if relayer stake is smaller than required stake, we do additional reserve - let required_stake = Pallet::::required_stake(); - if let Some(to_unreserve) = registration.stake.checked_sub(&required_stake) { - Self::do_unreserve(&relayer, to_unreserve)?; - } else if let Some(to_reserve) = required_stake.checked_sub(®istration.stake) { - T::StakeAndSlash::reserve(&relayer, to_reserve).map_err(|e| { - log::trace!( - target: LOG_TARGET, - "Failed to reserve {:?} on relayer {:?} account: {:?}", - to_reserve, - relayer, - e, - ); - - Error::::FailedToReserve - })?; - } - registration.stake = required_stake; - - log::trace!(target: LOG_TARGET, "Successfully registered relayer: {:?}", relayer); - Self::deposit_event(Event::::RegistrationUpdated { - relayer: relayer.clone(), - registration, - }); - - *maybe_registration = Some(registration); - - Ok(()) - }) + Error::::FailedToReserve + })?; + } + registration.stake = required_stake; + + log::trace!(target: LOG_TARGET, "Successfully registered relayer: {:?}", relayer); + Self::deposit_event(Event::::RegistrationUpdated { + relayer: relayer.clone(), + registration, + }); + + *maybe_registration = Some(registration); + + Ok(()) + }, + ) } /// `Deregister` relayer. @@ -193,34 +198,37 @@ pub mod pallet { pub fn deregister(origin: OriginFor) -> DispatchResult { let relayer = ensure_signed(origin)?; - RegisteredRelayers::::try_mutate(&relayer, |maybe_registration| -> DispatchResult { - let registration = match maybe_registration.take() { - Some(registration) => registration, - None => fail!(Error::::NotRegistered), - }; - - // we can't deregister until `valid_till + 1` - ensure!( - registration.valid_till < frame_system::Pallet::::block_number(), - Error::::RegistrationIsStillActive, - ); + RegisteredRelayers::::try_mutate( + &relayer, + |maybe_registration| -> DispatchResult { + let registration = match maybe_registration.take() { + Some(registration) => registration, + None => fail!(Error::::NotRegistered), + }; + + // we can't deregister until `valid_till + 1` + ensure!( + registration.valid_till < frame_system::Pallet::::block_number(), + Error::::RegistrationIsStillActive, + ); - // if stake is non-zero, we should do unreserve - if !registration.stake.is_zero() { - Self::do_unreserve(&relayer, registration.stake)?; - } + // if stake is non-zero, we should do unreserve + if !registration.stake.is_zero() { + Self::do_unreserve(&relayer, registration.stake)?; + } - log::trace!(target: LOG_TARGET, "Successfully deregistered relayer: {:?}", relayer); - Self::deposit_event(Event::::Deregistered { relayer: relayer.clone() }); + log::trace!(target: LOG_TARGET, "Successfully deregistered relayer: {:?}", relayer); + Self::deposit_event(Event::::Deregistered { relayer: relayer.clone() }); - *maybe_registration = None; + *maybe_registration = None; - Ok(()) - }) + Ok(()) + }, + ) } } - impl Pallet { + impl, I: 'static> Pallet { /// Returns true if given relayer registration is active at current block. /// /// This call respects both `RequiredStake` and `RequiredRegistrationLease`, meaning that @@ -255,7 +263,7 @@ pub mod pallet { relayer: &T::AccountId, slash_destination: ExplicitOrAccountParams, ) { - let registration = match RegisteredRelayers::::take(relayer) { + let registration = match RegisteredRelayers::::take(relayer) { Some(registration) => registration, None => { log::trace!( @@ -322,7 +330,7 @@ pub mod pallet { return } - RelayerRewards::::mutate( + RelayerRewards::::mutate( relayer, rewards_account_params, |old_reward: &mut Option| { @@ -337,7 +345,7 @@ pub mod pallet { new_reward, ); - Self::deposit_event(Event::::RewardRegistered { + Self::deposit_event(Event::::RewardRegistered { relayer: relayer.clone(), rewards_account_params, reward, @@ -376,7 +384,7 @@ pub mod pallet { relayer, ); - fail!(Error::::FailedToUnreserve) + fail!(Error::::FailedToUnreserve) } Ok(()) @@ -385,7 +393,7 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] - pub enum Event { + pub enum Event, I: 'static = ()> { /// Relayer reward has been registered and may be claimed later. RewardRegistered { /// Relayer account that can claim reward. @@ -426,7 +434,7 @@ pub mod pallet { } #[pallet::error] - pub enum Error { + pub enum Error { /// No reward can be claimed by given relayer. NoRewardForRelayer, /// Reward payment procedure has failed. @@ -449,13 +457,13 @@ pub mod pallet { /// Map of the relayer => accumulated reward. #[pallet::storage] #[pallet::getter(fn relayer_reward)] - pub type RelayerRewards = StorageDoubleMap< + pub type RelayerRewards, I: 'static = ()> = StorageDoubleMap< _, - as StorageDoubleMapKeyProvider>::Hasher1, - as StorageDoubleMapKeyProvider>::Key1, - as StorageDoubleMapKeyProvider>::Hasher2, - as StorageDoubleMapKeyProvider>::Key2, - as StorageDoubleMapKeyProvider>::Value, + as StorageDoubleMapKeyProvider>::Hasher1, + as StorageDoubleMapKeyProvider>::Key1, + as StorageDoubleMapKeyProvider>::Hasher2, + as StorageDoubleMapKeyProvider>::Key2, + as StorageDoubleMapKeyProvider>::Value, OptionQuery, >; @@ -467,7 +475,7 @@ pub mod pallet { /// relayer is present. #[pallet::storage] #[pallet::getter(fn registered_relayer)] - pub type RegisteredRelayers = StorageMap< + pub type RegisteredRelayers, I: 'static = ()> = StorageMap< _, Blake2_128Concat, T::AccountId, From c1ec789716a8126e424dd37286d513eadc47d0f4 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 18 Sep 2024 16:06:18 +0200 Subject: [PATCH 16/38] Rewards migraiton for `pallet_bridge_relayers` --- bridges/modules/relayers/src/benchmarking.rs | 38 +-- bridges/modules/relayers/src/lib.rs | 2 + bridges/modules/relayers/src/migration.rs | 243 +++++++++++++++++++ bridges/modules/xcm-bridge-hub/src/lib.rs | 2 +- bridges/primitives/messages/src/lane.rs | 10 +- bridges/primitives/relayers/src/lib.rs | 5 + bridges/primitives/runtime/src/lib.rs | 2 +- 7 files changed, 280 insertions(+), 22 deletions(-) create mode 100644 bridges/modules/relayers/src/migration.rs diff --git a/bridges/modules/relayers/src/benchmarking.rs b/bridges/modules/relayers/src/benchmarking.rs index f8e292d038f8..17f1bd826581 100644 --- a/bridges/modules/relayers/src/benchmarking.rs +++ b/bridges/modules/relayers/src/benchmarking.rs @@ -21,7 +21,7 @@ use crate::*; use bp_relayers::RewardsAccountOwner; -use frame_benchmarking::{benchmarks, whitelisted_caller}; +use frame_benchmarking::{benchmarks_instance_pallet, whitelisted_caller}; use frame_system::RawOrigin; use sp_runtime::traits::One; @@ -29,10 +29,10 @@ use sp_runtime::traits::One; const REWARD_AMOUNT: u32 = u32::MAX; /// Pallet we're benchmarking here. -pub struct Pallet(crate::Pallet); +pub struct Pallet, I: 'static = ()>(crate::Pallet); /// Trait that must be implemented by runtime. -pub trait Config: crate::Config { +pub trait Config: crate::Config { /// Lane id to use in benchmarks. fn bench_lane_id() -> Self::LaneId { Self::LaneId::default() @@ -46,7 +46,7 @@ pub trait Config: crate::Config { fn deposit_account(account: Self::AccountId, balance: Self::Reward); } -benchmarks! { +benchmarks_instance_pallet! { // Benchmark `claim_rewards` call. claim_rewards { let lane = T::bench_lane_id(); @@ -56,7 +56,7 @@ benchmarks! { let reward = T::Reward::from(REWARD_AMOUNT); T::prepare_rewards_account(account_params, reward); - RelayerRewards::::insert(&relayer, account_params, reward); + RelayerRewards::::insert(&relayer, account_params, reward); }: _(RawOrigin::Signed(relayer), account_params) verify { // we can't check anything here, because `PaymentProcedure` is responsible for @@ -68,30 +68,30 @@ benchmarks! { register { let relayer: T::AccountId = whitelisted_caller(); let valid_till = frame_system::Pallet::::block_number() - .saturating_add(crate::Pallet::::required_registration_lease()) + .saturating_add(crate::Pallet::::required_registration_lease()) .saturating_add(One::one()) .saturating_add(One::one()); - T::deposit_account(relayer.clone(), crate::Pallet::::required_stake()); + T::deposit_account(relayer.clone(), crate::Pallet::::required_stake()); }: _(RawOrigin::Signed(relayer.clone()), valid_till) verify { - assert!(crate::Pallet::::is_registration_active(&relayer)); + assert!(crate::Pallet::::is_registration_active(&relayer)); } // Benchmark `deregister` call. deregister { let relayer: T::AccountId = whitelisted_caller(); let valid_till = frame_system::Pallet::::block_number() - .saturating_add(crate::Pallet::::required_registration_lease()) + .saturating_add(crate::Pallet::::required_registration_lease()) .saturating_add(One::one()) .saturating_add(One::one()); - T::deposit_account(relayer.clone(), crate::Pallet::::required_stake()); - crate::Pallet::::register(RawOrigin::Signed(relayer.clone()).into(), valid_till).unwrap(); + T::deposit_account(relayer.clone(), crate::Pallet::::required_stake()); + crate::Pallet::::register(RawOrigin::Signed(relayer.clone()).into(), valid_till).unwrap(); frame_system::Pallet::::set_block_number(valid_till.saturating_add(One::one())); }: _(RawOrigin::Signed(relayer.clone())) verify { - assert!(!crate::Pallet::::is_registration_active(&relayer)); + assert!(!crate::Pallet::::is_registration_active(&relayer)); } // Benchmark `slash_and_deregister` method of the pallet. We are adding this weight to @@ -101,21 +101,21 @@ benchmarks! { // prepare and register relayer account let relayer: T::AccountId = whitelisted_caller(); let valid_till = frame_system::Pallet::::block_number() - .saturating_add(crate::Pallet::::required_registration_lease()) + .saturating_add(crate::Pallet::::required_registration_lease()) .saturating_add(One::one()) .saturating_add(One::one()); - T::deposit_account(relayer.clone(), crate::Pallet::::required_stake()); - crate::Pallet::::register(RawOrigin::Signed(relayer.clone()).into(), valid_till).unwrap(); + T::deposit_account(relayer.clone(), crate::Pallet::::required_stake()); + crate::Pallet::::register(RawOrigin::Signed(relayer.clone()).into(), valid_till).unwrap(); // create slash destination account let lane = T::bench_lane_id(); let slash_destination = RewardsAccountParams::new(lane, *b"test", RewardsAccountOwner::ThisChain); T::prepare_rewards_account(slash_destination, Zero::zero()); }: { - crate::Pallet::::slash_and_deregister(&relayer, slash_destination.into()) + crate::Pallet::::slash_and_deregister(&relayer, slash_destination.into()) } verify { - assert!(!crate::Pallet::::is_registration_active(&relayer)); + assert!(!crate::Pallet::::is_registration_active(&relayer)); } // Benchmark `register_relayer_reward` method of the pallet. We are adding this weight to @@ -127,10 +127,10 @@ benchmarks! { let account_params = RewardsAccountParams::new(lane, *b"test", RewardsAccountOwner::ThisChain); }: { - crate::Pallet::::register_relayer_reward(account_params, &relayer, One::one()); + crate::Pallet::::register_relayer_reward(account_params, &relayer, One::one()); } verify { - assert_eq!(RelayerRewards::::get(relayer, &account_params), Some(One::one())); + assert_eq!(RelayerRewards::::get(relayer, &account_params), Some(One::one())); } impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::TestRuntime) diff --git a/bridges/modules/relayers/src/lib.rs b/bridges/modules/relayers/src/lib.rs index ebd3a59f13c3..7cc4154ac180 100644 --- a/bridges/modules/relayers/src/lib.rs +++ b/bridges/modules/relayers/src/lib.rs @@ -43,6 +43,7 @@ mod weights_ext; pub mod benchmarking; pub mod extension; +pub mod migration; pub mod weights; /// The target that will be used when publishing logs related to this pallet. @@ -84,6 +85,7 @@ pub mod pallet { } #[pallet::pallet] + #[pallet::storage_version(migration::STORAGE_VERSION)] pub struct Pallet(PhantomData<(T, I)>); #[pallet::call] diff --git a/bridges/modules/relayers/src/migration.rs b/bridges/modules/relayers/src/migration.rs new file mode 100644 index 000000000000..7c995ed65e10 --- /dev/null +++ b/bridges/modules/relayers/src/migration.rs @@ -0,0 +1,243 @@ +// Copyright (C) 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 . + +//! A module that is responsible for migration of storage. + +use frame_support::{ + traits::{Get, StorageVersion}, + weights::Weight, +}; + +/// The in-code storage version. +pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); + +/// This module contains data structures that are valid for the initial state of `0`. +/// (used with v1 migration). +pub mod v0 { + use crate::{Config, Pallet}; + use bp_relayers::RewardsAccountOwner; + use bp_runtime::{ChainId, StorageDoubleMapKeyProvider}; + use codec::{Codec, Decode, Encode, EncodeLike, MaxEncodedLen}; + use frame_support::{pallet_prelude::OptionQuery, Blake2_128Concat, Identity}; + use scale_info::TypeInfo; + use sp_runtime::traits::AccountIdConversion; + use sp_std::marker::PhantomData; + + /// Structure used to identify the account that pays a reward to the relayer. + #[derive(Copy, Clone, Debug, Decode, Encode, Eq, PartialEq, TypeInfo, MaxEncodedLen)] + pub struct RewardsAccountParams { + /// lane_id + pub lane_id: LaneId, + /// bridged_chain_id + pub bridged_chain_id: ChainId, + /// owner + pub owner: RewardsAccountOwner, + } + + impl RewardsAccountParams { + /// Create a new instance of `RewardsAccountParams`. + pub const fn new( + lane_id: LaneId, + bridged_chain_id: ChainId, + owner: RewardsAccountOwner, + ) -> Self { + Self { lane_id, bridged_chain_id, owner } + } + } + + impl sp_runtime::TypeId for RewardsAccountParams { + const TYPE_ID: [u8; 4] = *b"brap"; + } + + pub(crate) struct RelayerRewardsKeyProvider( + PhantomData<(AccountId, Reward, LaneId)>, + ); + + impl StorageDoubleMapKeyProvider + for RelayerRewardsKeyProvider + where + AccountId: 'static + Codec + EncodeLike + Send + Sync, + Reward: 'static + Codec + EncodeLike + Send + Sync, + LaneId: Codec + EncodeLike + Send + Sync, + { + const MAP_NAME: &'static str = "RelayerRewards"; + + type Hasher1 = Blake2_128Concat; + type Key1 = AccountId; + type Hasher2 = Identity; + type Key2 = RewardsAccountParams; + type Value = Reward; + } + + pub(crate) type RelayerRewardsKeyProviderOf = RelayerRewardsKeyProvider< + ::AccountId, + >::Reward, + >::LaneId, + >; + + #[frame_support::storage_alias] + pub(crate) type RelayerRewards, I: 'static> = StorageDoubleMap< + Pallet, + as StorageDoubleMapKeyProvider>::Hasher1, + as StorageDoubleMapKeyProvider>::Key1, + as StorageDoubleMapKeyProvider>::Hasher2, + as StorageDoubleMapKeyProvider>::Key2, + as StorageDoubleMapKeyProvider>::Value, + OptionQuery, + >; + + /// Reward account generator for `v0`. + pub struct PayRewardFromAccount(PhantomData<(Account, LaneId)>); + impl PayRewardFromAccount + where + Account: Decode + Encode, + LaneId: Decode + Encode, + { + /// Return account that pays rewards based on the provided parameters. + pub fn rewards_account(params: RewardsAccountParams) -> Account { + params.into_sub_account_truncating(b"rewards-account") + } + } +} + +/// This migration updates `RelayerRewards` where `RewardsAccountParams` was used as the key with +/// `lane_id` as the first attribute, which affects `into_sub_account_truncating`. We are migrating +/// this key to use the new `RewardsAccountParams` where `lane_id` is the last attribute. +pub mod v1 { + use super::*; + use crate::{Config, Pallet}; + use bp_relayers::RewardsAccountParams; + use frame_support::traits::UncheckedOnRuntimeUpgrade; + use sp_std::marker::PhantomData; + + #[cfg(feature = "try-runtime")] + use crate::RelayerRewards; + + /// Migrates the pallet storage to v1. + pub struct UncheckedMigrationV0ToV1(PhantomData<(T, I)>); + + #[cfg(feature = "try-runtime")] + const LOG_TARGET: &str = "runtime::bridge-relayers-migration"; + + impl, I: 'static> UncheckedOnRuntimeUpgrade for UncheckedMigrationV0ToV1 { + fn on_runtime_upgrade() -> Weight { + let mut weight = T::DbWeight::get().reads(1); + + // list all rewards (we cannot do this as one step because of `drain` limitation) + let mut rewards_to_migrate = + sp_std::vec::Vec::with_capacity(v0::RelayerRewards::::iter().count()); + for (key1, key2, reward) in v0::RelayerRewards::::drain() { + rewards_to_migrate.push((key1, key2, reward)); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + } + + // re-register rewards with new format of `RewardsAccountParams`. + for (key1, key2, reward) in rewards_to_migrate { + // expand old key + let v0::RewardsAccountParams { owner, lane_id, bridged_chain_id } = key2.clone(); + + // re-register reward + Pallet::::register_relayer_reward( + v1::RewardsAccountParams::new(lane_id, bridged_chain_id, owner), + &key1, + reward, + ); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + } + + weight + } + + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, sp_runtime::DispatchError> { + use codec::Encode; + use frame_support::BoundedBTreeMap; + use sp_runtime::traits::ConstU32; + + // collect actual rewards + let mut rewards: BoundedBTreeMap< + (T::AccountId, T::LaneId), + T::Reward, + ConstU32<{ u32::MAX }>, + > = BoundedBTreeMap::new(); + for (key1, key2, reward) in v0::RelayerRewards::::iter() { + log::info!(target: LOG_TARGET, "Reward to migrate: {key1:?}::{key2:?} - {reward:?}"); + rewards = rewards + .try_mutate(|inner| { + inner + .entry((key1.clone(), key2.lane_id.clone())) + .and_modify(|value| *value += reward) + .or_insert(reward); + }) + .unwrap(); + } + log::info!(target: LOG_TARGET, "Found total rewards to migrate: {rewards:?}"); + + Ok(rewards.encode()) + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(state: sp_std::vec::Vec) -> Result<(), sp_runtime::DispatchError> { + use codec::Decode; + use frame_support::BoundedBTreeMap; + use sp_runtime::traits::ConstU32; + + let rewards_before: BoundedBTreeMap< + (T::AccountId, T::LaneId), + T::Reward, + ConstU32<{ u32::MAX }>, + > = Decode::decode(&mut &state[..]).unwrap(); + + // collect migrated rewards + let mut rewards_after: BoundedBTreeMap< + (T::AccountId, T::LaneId), + T::Reward, + ConstU32<{ u32::MAX }>, + > = BoundedBTreeMap::new(); + for (key1, key2, reward) in v1::RelayerRewards::::iter() { + log::info!(target: LOG_TARGET, "Migrated rewards: {key1:?}::{key2:?} - {reward:?}"); + rewards_after = rewards_after + .try_mutate(|inner| { + inner + .entry((key1.clone(), key2.lane_id().clone())) + .and_modify(|value| *value += reward) + .or_insert(reward); + }) + .unwrap(); + } + log::info!(target: LOG_TARGET, "Found total migrated rewards: {rewards_after:?}"); + + frame_support::ensure!( + rewards_before == rewards_after, + "The rewards were not migrated correctly!." + ); + + log::info!(target: LOG_TARGET, "migrated all."); + Ok(()) + } + } + + /// [`UncheckedMigrationV0ToV1`] wrapped in a + /// [`VersionedMigration`](frame_support::migrations::VersionedMigration), ensuring the + /// migration is only performed when on-chain version is 0. + pub type MigrationToV1 = frame_support::migrations::VersionedMigration< + 0, + 1, + UncheckedMigrationV0ToV1, + Pallet, + ::DbWeight, + >; +} diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 8e7632f9eabd..33f9c90334a6 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -252,7 +252,7 @@ pub mod pallet { pub type ThisChainOf = pallet_bridge_messages::ThisChainOf>::BridgeMessagesPalletInstance>; /// An alias for lane identifier type. - type LaneIdOf = + pub type LaneIdOf = >::BridgeMessagesPalletInstance>>::LaneId; /// An alias for the associated lanes manager. pub type LanesManagerOf = diff --git a/bridges/primitives/messages/src/lane.rs b/bridges/primitives/messages/src/lane.rs index 44cb8180e52d..dab6c7b13d54 100644 --- a/bridges/primitives/messages/src/lane.rs +++ b/bridges/primitives/messages/src/lane.rs @@ -63,6 +63,14 @@ pub trait LaneIdType: )] pub struct LegacyLaneId(pub [u8; 4]); +impl LaneIdType for LegacyLaneId { + /// Create lane identifier from two locations. + fn new(_endpoint1: T, _endpoint2: T) -> Self { + // we don't support this for `LegacyLaneId`, because it was hard-coded before + unimplemented!(); + } +} + #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))] impl TryFrom> for LegacyLaneId { type Error = (); @@ -164,7 +172,7 @@ impl LaneIdType for HashedLaneId { fn new(endpoint1: T, endpoint2: T) -> Self { const VALUES_SEPARATOR: [u8; 31] = *b"bridges-lane-id-value-separator"; - HashedLaneId( + Self( if endpoint1 < endpoint2 { (endpoint1, VALUES_SEPARATOR, endpoint2) } else { diff --git a/bridges/primitives/relayers/src/lib.rs b/bridges/primitives/relayers/src/lib.rs index c81e074dfa48..91eab3cb687d 100644 --- a/bridges/primitives/relayers/src/lib.rs +++ b/bridges/primitives/relayers/src/lib.rs @@ -78,6 +78,11 @@ impl RewardsAccountParams { ) -> Self { Self { lane_id, bridged_chain_id, owner } } + + /// Getter for `lane_id`. + pub const fn lane_id(&self) -> &LaneId { + &self.lane_id + } } impl TypeId for RewardsAccountParams { diff --git a/bridges/primitives/runtime/src/lib.rs b/bridges/primitives/runtime/src/lib.rs index 94ce333a5c78..90eb72922bea 100644 --- a/bridges/primitives/runtime/src/lib.rs +++ b/bridges/primitives/runtime/src/lib.rs @@ -272,7 +272,7 @@ pub trait StorageMapKeyProvider { } } -/// Can be use to access the runtime storage key of a `StorageDoubleMap`. +/// Can be used to access the runtime storage key of a `StorageDoubleMap`. pub trait StorageDoubleMapKeyProvider { /// The name of the variable that holds the `StorageDoubleMap`. const MAP_NAME: &'static str; From e1f09f3e85bc51bef40c808755dd491a7d48e6f3 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 19 Sep 2024 10:01:10 +0200 Subject: [PATCH 17/38] Adjust testnet runtimes to the latest vogue --- .../src/bridge_common_config.rs | 12 +- .../src/bridge_to_bulletin_config.rs | 54 ++++----- .../src/bridge_to_westend_config.rs | 61 +++++----- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 65 +++++++---- .../bridge-hub-rococo/tests/tests.rs | 4 + .../src/bridge_common_config.rs | 12 +- .../src/bridge_to_rococo_config.rs | 59 +++++----- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 37 +++--- .../bridge-hub-westend/tests/tests.rs | 6 +- .../src/test_cases/from_grandpa_chain.rs | 97 +++++++++------- .../src/test_cases/from_parachain.rs | 106 ++++++++++-------- .../test-utils/src/test_cases/helpers.rs | 30 ++--- .../test-utils/src/test_cases/mod.rs | 7 +- .../src/test_data/from_grandpa_chain.rs | 31 +++-- .../src/test_data/from_parachain.rs | 24 ++-- .../test-utils/src/test_data/mod.rs | 6 +- 16 files changed, 357 insertions(+), 254 deletions(-) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_common_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_common_config.rs index 779cc537ee96..28112d061ce0 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_common_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_common_config.rs @@ -22,6 +22,7 @@ //! GRANDPA tracking pallet only needs to be aware of one chain. use super::{weights, AccountId, Balance, Balances, BlockNumber, Runtime, RuntimeEvent}; +use bp_messages::LegacyLaneId; use bp_parachains::SingleParaStoredHeaderDataBuilder; use frame_support::{parameter_types, traits::ConstU32}; @@ -64,11 +65,15 @@ impl pallet_bridge_parachains::Config for Runtim } /// Allows collect and claim rewards for relayers -impl pallet_bridge_relayers::Config for Runtime { +pub type RelayersForLegacyLaneIdsMessagesInstance = (); +impl pallet_bridge_relayers::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Reward = Balance; - type PaymentProcedure = - bp_relayers::PayRewardFromAccount, AccountId>; + type PaymentProcedure = bp_relayers::PayRewardFromAccount< + pallet_balances::Pallet, + AccountId, + Self::LaneId, + >; type StakeAndSlash = pallet_bridge_relayers::StakeAndSlashNamed< AccountId, BlockNumber, @@ -78,6 +83,7 @@ impl pallet_bridge_relayers::Config for Runtime { RelayerStakeLease, >; type WeightInfo = weights::pallet_bridge_relayers::WeightInfo; + type LaneId = LegacyLaneId; } /// Add GRANDPA bridge pallet to track Rococo Bulletin chain. diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs index d426e27cea9f..8f706d2214d1 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs @@ -26,7 +26,7 @@ use crate::{ }; use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, - target_chain::FromBridgedChainMessagesProof, + target_chain::FromBridgedChainMessagesProof, LegacyLaneId, }; use bridge_hub_common::xcm_version::XcmVersionOfDestAndRemoteBridge; @@ -34,11 +34,11 @@ use frame_support::{ parameter_types, traits::{Equals, PalletInfoAccess}, }; -use frame_system::EnsureRoot; +use frame_system::{EnsureNever, EnsureRoot}; +use pallet_bridge_messages::LaneIdOf; use pallet_bridge_relayers::extension::{ BridgeRelayersSignedExtension, WithMessagesExtensionConfig, }; -use pallet_xcm::EnsureXcm; use pallet_xcm_bridge_hub::XcmAsPlainPayload; use polkadot_parachain_primitives::primitives::Sibling; use testnet_parachains_constants::rococo::currency::UNITS as ROC; @@ -78,11 +78,11 @@ parameter_types! { } /// Proof of messages, coming from Rococo Bulletin chain. -pub type FromRococoBulletinMessagesProof = - FromBridgedChainMessagesProof; +pub type FromRococoBulletinMessagesProof = + FromBridgedChainMessagesProof>; /// Messages delivery proof for Rococo Bridge Hub -> Rococo Bulletin messages. -pub type ToRococoBulletinMessagesDeliveryProof = - FromBridgedChainMessagesDeliveryProof; +pub type ToRococoBulletinMessagesDeliveryProof = + FromBridgedChainMessagesDeliveryProof>; /// Dispatches received XCM messages from other bridge. type FromRococoBulletinMessageBlobDispatcher = BridgeBlobDispatcher< @@ -101,6 +101,7 @@ pub type OnBridgeHubRococoRefundRococoBulletinMessages = BridgeRelayersSignedExt WithRococoBulletinMessagesInstance, PriorityBoostPerMessage, >, + LaneIdOf, >; bp_runtime::generate_static_str_provider!(OnBridgeHubRococoRefundRococoBulletinMessages); @@ -116,10 +117,10 @@ impl pallet_bridge_messages::Config for Runt type BridgedHeaderChain = BridgeRococoBulletinGrandpa; type OutboundPayload = XcmAsPlainPayload; - type InboundPayload = XcmAsPlainPayload; - type DeliveryPayments = (); + type LaneId = LegacyLaneId; + type DeliveryPayments = (); type DeliveryConfirmationPayments = (); type MessageDispatch = XcmOverRococoBulletin; @@ -140,8 +141,8 @@ impl pallet_xcm_bridge_hub::Config for Runtime XcmVersionOfDestAndRemoteBridge; type ForceOrigin = EnsureRoot; - // Only allow calls from sibling People parachain to directly open the bridge. - type OpenBridgeOrigin = EnsureXcm>; + // We don't want to allow creating bridges for this instance with `LegacyLaneId`. + type OpenBridgeOrigin = EnsureNever; // Converter aligned with `OpenBridgeOrigin`. type BridgeOriginAccountIdConverter = (ParentIsPreset, SiblingParachainConvertsVia); @@ -230,14 +231,20 @@ mod tests { } #[cfg(feature = "runtime-benchmarks")] -pub(crate) fn open_bridge_for_benchmarks( - with: bp_messages::LaneId, +pub(crate) fn open_bridge_for_benchmarks( + with: pallet_xcm_bridge_hub::LaneIdOf, sibling_para_id: u32, -) -> InteriorLocation { +) -> InteriorLocation +where + R: pallet_xcm_bridge_hub::Config, + XBHI: 'static, + C: xcm_executor::traits::ConvertLocation< + bp_runtime::AccountIdOf>, + >, +{ use pallet_xcm_bridge_hub::{Bridge, BridgeId, BridgeState}; use sp_runtime::traits::Zero; use xcm::VersionedInteriorLocation; - use xcm_executor::traits::ConvertLocation; // insert bridge metadata let lane_id = with; @@ -248,7 +255,7 @@ pub(crate) fn open_bridge_for_benchmarks( let bridge_id = BridgeId::new(&universal_source, &universal_destination); // insert only bridge metadata, because the benchmarks create lanes - pallet_xcm_bridge_hub::Bridges::::insert( + pallet_xcm_bridge_hub::Bridges::::insert( bridge_id, Bridge { bridge_origin_relative_location: alloc::boxed::Box::new( @@ -261,17 +268,12 @@ pub(crate) fn open_bridge_for_benchmarks( VersionedInteriorLocation::from(universal_destination), ), state: BridgeState::Opened, - bridge_owner_account: crate::xcm_config::LocationToAccountId::convert_location( - &sibling_parachain, - ) - .expect("valid AccountId"), - deposit: Balance::zero(), + bridge_owner_account: C::convert_location(&sibling_parachain).expect("valid AccountId"), + deposit: Zero::zero(), lane_id, }, ); - pallet_xcm_bridge_hub::LaneToBridge::::insert( - lane_id, bridge_id, - ); + pallet_xcm_bridge_hub::LaneToBridge::::insert(lane_id, bridge_id); universal_source } @@ -279,12 +281,10 @@ pub(crate) fn open_bridge_for_benchmarks( /// Contains the migration for the PeopleRococo<>RococoBulletin bridge. pub mod migration { use super::*; - use bp_messages::LaneId; use frame_support::traits::ConstBool; - use sp_runtime::Either; parameter_types! { - pub RococoPeopleToRococoBulletinMessagesLane: LaneId = LaneId::from_inner(Either::Right([0, 0, 0, 0])); + pub RococoPeopleToRococoBulletinMessagesLane: LegacyLaneId = LegacyLaneId([0, 0, 0, 0]); pub BulletinRococoLocation: InteriorLocation = [GlobalConsensus(RococoBulletinGlobalConsensusNetwork::get())].into(); } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index bce05034ea99..a8007020f63e 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -25,20 +25,18 @@ use crate::{ }; use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, - target_chain::FromBridgedChainMessagesProof, + target_chain::FromBridgedChainMessagesProof, LegacyLaneId, }; use bridge_hub_common::xcm_version::XcmVersionOfDestAndRemoteBridge; use pallet_xcm_bridge_hub::XcmAsPlainPayload; use frame_support::{parameter_types, traits::PalletInfoAccess}; -use frame_system::EnsureRoot; +use frame_system::{EnsureNever, EnsureRoot}; +use pallet_bridge_messages::LaneIdOf; use pallet_bridge_relayers::extension::{ BridgeRelayersSignedExtension, WithMessagesExtensionConfig, }; -use pallet_xcm::EnsureXcm; -use parachains_common::xcm_config::{ - AllSiblingSystemParachains, ParentRelayOrSiblingParachains, RelayOrOtherSystemParachains, -}; +use parachains_common::xcm_config::{AllSiblingSystemParachains, RelayOrOtherSystemParachains}; use polkadot_parachain_primitives::primitives::Sibling; use testnet_parachains_constants::rococo::currency::UNITS as ROC; use xcm::{ @@ -73,11 +71,11 @@ parameter_types! { } /// Proof of messages, coming from Westend. -pub type FromWestendBridgeHubMessagesProof = - FromBridgedChainMessagesProof; +pub type FromWestendBridgeHubMessagesProof = + FromBridgedChainMessagesProof>; /// Messages delivery proof for Rococo Bridge Hub -> Westend Bridge Hub messages. -pub type ToWestendBridgeHubMessagesDeliveryProof = - FromBridgedChainMessagesDeliveryProof; +pub type ToWestendBridgeHubMessagesDeliveryProof = + FromBridgedChainMessagesDeliveryProof>; /// Dispatches received XCM messages from other bridge type FromWestendMessageBlobDispatcher = @@ -92,6 +90,7 @@ pub type OnBridgeHubRococoRefundBridgeHubWestendMessages = BridgeRelayersSignedE WithBridgeHubWestendMessagesInstance, PriorityBoostPerMessage, >, + LaneIdOf, >; bp_runtime::generate_static_str_provider!(OnBridgeHubRococoRefundBridgeHubWestendMessages); @@ -110,10 +109,10 @@ impl pallet_bridge_messages::Config for Ru >; type OutboundPayload = XcmAsPlainPayload; - type InboundPayload = XcmAsPlainPayload; - type DeliveryPayments = (); + type LaneId = LegacyLaneId; + type DeliveryPayments = (); type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< Runtime, WithBridgeHubWestendMessagesInstance, @@ -124,7 +123,8 @@ impl pallet_bridge_messages::Config for Ru type OnMessagesDelivered = XcmOverBridgeHubWestend; } -/// Add support for the export and dispatch of XCM programs. +/// Add support for the export and dispatch of XCM programs withing +/// `WithBridgeHubWestendMessagesInstance`. pub type XcmOverBridgeHubWestendInstance = pallet_xcm_bridge_hub::Instance1; impl pallet_xcm_bridge_hub::Config for Runtime { type RuntimeEvent = RuntimeEvent; @@ -138,8 +138,8 @@ impl pallet_xcm_bridge_hub::Config for Runtime XcmVersionOfDestAndRemoteBridge; type ForceOrigin = EnsureRoot; - // Only allow calls from relay chains and sibling parachains to directly open the bridge. - type OpenBridgeOrigin = EnsureXcm; + // We don't want to allow creating bridges for this instance with `LegacyLaneId`. + type OpenBridgeOrigin = EnsureNever; // Converter aligned with `OpenBridgeOrigin`. type BridgeOriginAccountIdConverter = (ParentIsPreset, SiblingParachainConvertsVia); @@ -157,14 +157,20 @@ impl pallet_xcm_bridge_hub::Config for Runtime } #[cfg(feature = "runtime-benchmarks")] -pub(crate) fn open_bridge_for_benchmarks( - with: bp_messages::LaneId, +pub(crate) fn open_bridge_for_benchmarks( + with: pallet_xcm_bridge_hub::LaneIdOf, sibling_para_id: u32, -) -> InteriorLocation { +) -> InteriorLocation +where + R: pallet_xcm_bridge_hub::Config, + XBHI: 'static, + C: xcm_executor::traits::ConvertLocation< + bp_runtime::AccountIdOf>, + >, +{ use pallet_xcm_bridge_hub::{Bridge, BridgeId, BridgeState}; use sp_runtime::traits::Zero; use xcm::VersionedInteriorLocation; - use xcm_executor::traits::ConvertLocation; // insert bridge metadata let lane_id = with; @@ -174,7 +180,7 @@ pub(crate) fn open_bridge_for_benchmarks( let bridge_id = BridgeId::new(&universal_source, &universal_destination); // insert only bridge metadata, because the benchmarks create lanes - pallet_xcm_bridge_hub::Bridges::::insert( + pallet_xcm_bridge_hub::Bridges::::insert( bridge_id, Bridge { bridge_origin_relative_location: alloc::boxed::Box::new( @@ -187,17 +193,12 @@ pub(crate) fn open_bridge_for_benchmarks( VersionedInteriorLocation::from(universal_destination), ), state: BridgeState::Opened, - bridge_owner_account: crate::xcm_config::LocationToAccountId::convert_location( - &sibling_parachain, - ) - .expect("valid AccountId"), - deposit: Balance::zero(), + bridge_owner_account: C::convert_location(&sibling_parachain).expect("valid AccountId"), + deposit: Zero::zero(), lane_id, }, ); - pallet_xcm_bridge_hub::LaneToBridge::::insert( - lane_id, bridge_id, - ); + pallet_xcm_bridge_hub::LaneToBridge::::insert(lane_id, bridge_id); universal_source } @@ -297,12 +298,10 @@ mod tests { /// Contains the migration for the AssetHubRococo<>AssetHubWestend bridge. pub mod migration { use super::*; - use bp_messages::LaneId; use frame_support::traits::ConstBool; - use sp_runtime::Either; parameter_types! { - pub AssetHubRococoToAssetHubWestendMessagesLane: LaneId = LaneId::from_inner(Either::Right([0, 0, 0, 2])); + pub AssetHubRococoToAssetHubWestendMessagesLane: LegacyLaneId = LegacyLaneId([0, 0, 0, 2]); pub AssetHubRococoLocation: Location = Location::new(1, [Parachain(bp_asset_hub_rococo::ASSET_HUB_ROCOCO_PARACHAIN_ID)]); pub AssetHubWestendUniversalLocation: InteriorLocation = [GlobalConsensus(WestendGlobalConsensusNetwork::get()), Parachain(bp_asset_hub_westend::ASSET_HUB_WESTEND_PARACHAIN_ID)].into(); } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 6c6e2ec7efdd..a1de3d4ecccc 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -42,6 +42,7 @@ use bridge_runtime_common::extensions::{ CheckAndBoostBridgeGrandpaTransactions, CheckAndBoostBridgeParachainsTransactions, }; use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; +use pallet_bridge_messages::LaneIdOf; use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; use sp_runtime::{ @@ -174,6 +175,7 @@ pub type Migrations = ( OutboundLanesCongestedSignalsKey, RocksDbWeight, >, + pallet_bridge_relayers::migration::v1::MigrationToV1, // permanent pallet_xcm::migration::MigrateToLatestXcmVersion, ); @@ -904,9 +906,9 @@ impl_runtime_apis! { } // This is exposed by BridgeHubRococo - impl bp_bridge_hub_westend::FromBridgeHubWestendInboundLaneApi for Runtime { + impl bp_bridge_hub_westend::FromBridgeHubWestendInboundLaneApi> for Runtime { fn message_details( - lane: bp_messages::LaneId, + lane: LaneIdOf, messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>, ) -> Vec { bridge_runtime_common::messages_api::inbound_message_details::< @@ -917,9 +919,9 @@ impl_runtime_apis! { } // This is exposed by BridgeHubRococo - impl bp_bridge_hub_westend::ToBridgeHubWestendOutboundLaneApi for Runtime { + impl bp_bridge_hub_westend::ToBridgeHubWestendOutboundLaneApi> for Runtime { fn message_details( - lane: bp_messages::LaneId, + lane: LaneIdOf, begin: bp_messages::MessageNonce, end: bp_messages::MessageNonce, ) -> Vec { @@ -947,9 +949,9 @@ impl_runtime_apis! { } } - impl bp_polkadot_bulletin::FromPolkadotBulletinInboundLaneApi for Runtime { + impl bp_polkadot_bulletin::FromPolkadotBulletinInboundLaneApi> for Runtime { fn message_details( - lane: bp_messages::LaneId, + lane: LaneIdOf, messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>, ) -> Vec { bridge_runtime_common::messages_api::inbound_message_details::< @@ -959,9 +961,9 @@ impl_runtime_apis! { } } - impl bp_polkadot_bulletin::ToPolkadotBulletinOutboundLaneApi for Runtime { + impl bp_polkadot_bulletin::ToPolkadotBulletinOutboundLaneApi> for Runtime { fn message_details( - lane: bp_messages::LaneId, + lane: LaneIdOf, begin: bp_messages::MessageNonce, end: bp_messages::MessageNonce, ) -> Vec { @@ -1305,12 +1307,16 @@ impl_runtime_apis! { } fn prepare_message_proof( - params: MessageProofParams, - ) -> (bridge_to_westend_config::FromWestendBridgeHubMessagesProof, Weight) { + params: MessageProofParams>, + ) -> (bridge_to_westend_config::FromWestendBridgeHubMessagesProof, Weight) { use cumulus_primitives_core::XcmpMessageSource; assert!(XcmpQueue::take_outbound_messages(usize::MAX).is_empty()); ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(42.into()); - let universal_source = bridge_to_westend_config::open_bridge_for_benchmarks(params.lane, 42); + let universal_source = bridge_to_westend_config::open_bridge_for_benchmarks::< + Runtime, + bridge_to_westend_config::XcmOverBridgeHubWestendInstance, + xcm_config::LocationToAccountId, + >(params.lane, 42); prepare_message_proof_from_parachain::< Runtime, bridge_common_config::BridgeGrandpaWestendInstance, @@ -1319,9 +1325,13 @@ impl_runtime_apis! { } fn prepare_message_delivery_proof( - params: MessageDeliveryProofParams, - ) -> bridge_to_westend_config::ToWestendBridgeHubMessagesDeliveryProof { - let _ = bridge_to_westend_config::open_bridge_for_benchmarks(params.lane, 42); + params: MessageDeliveryProofParams>, + ) -> bridge_to_westend_config::ToWestendBridgeHubMessagesDeliveryProof { + let _ = bridge_to_westend_config::open_bridge_for_benchmarks::< + Runtime, + bridge_to_westend_config::XcmOverBridgeHubWestendInstance, + xcm_config::LocationToAccountId, + >(params.lane, 42); prepare_message_delivery_proof_from_parachain::< Runtime, bridge_common_config::BridgeGrandpaWestendInstance, @@ -1342,12 +1352,16 @@ impl_runtime_apis! { } fn prepare_message_proof( - params: MessageProofParams, - ) -> (bridge_to_bulletin_config::FromRococoBulletinMessagesProof, Weight) { + params: MessageProofParams>, + ) -> (bridge_to_bulletin_config::FromRococoBulletinMessagesProof, Weight) { use cumulus_primitives_core::XcmpMessageSource; assert!(XcmpQueue::take_outbound_messages(usize::MAX).is_empty()); ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(42.into()); - let universal_source = bridge_to_bulletin_config::open_bridge_for_benchmarks(params.lane, 42); + let universal_source = bridge_to_bulletin_config::open_bridge_for_benchmarks::< + Runtime, + bridge_to_bulletin_config::XcmOverPolkadotBulletinInstance, + xcm_config::LocationToAccountId, + >(params.lane, 42); prepare_message_proof_from_grandpa_chain::< Runtime, bridge_common_config::BridgeGrandpaRococoBulletinInstance, @@ -1356,9 +1370,13 @@ impl_runtime_apis! { } fn prepare_message_delivery_proof( - params: MessageDeliveryProofParams, - ) -> bridge_to_bulletin_config::ToRococoBulletinMessagesDeliveryProof { - let _ = bridge_to_bulletin_config::open_bridge_for_benchmarks(params.lane, 42); + params: MessageDeliveryProofParams>, + ) -> bridge_to_bulletin_config::ToRococoBulletinMessagesDeliveryProof { + let _ = bridge_to_bulletin_config::open_bridge_for_benchmarks::< + Runtime, + bridge_to_bulletin_config::XcmOverPolkadotBulletinInstance, + xcm_config::LocationToAccountId, + >(params.lane, 42); prepare_message_delivery_proof_from_grandpa_chain::< Runtime, bridge_common_config::BridgeGrandpaRococoBulletinInstance, @@ -1403,14 +1421,15 @@ impl_runtime_apis! { } } - impl BridgeRelayersConfig for Runtime { + impl BridgeRelayersConfig for Runtime { fn prepare_rewards_account( - account_params: bp_relayers::RewardsAccountParams, + account_params: bp_relayers::RewardsAccountParams<>::LaneId>, reward: Balance, ) { let rewards_account = bp_relayers::PayRewardFromAccount::< Balances, - AccountId + AccountId, + >::LaneId, >::rewards_account(account_params); Self::deposit_account(rewards_account, reward); } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs index 982c9fec6634..9e84317f42d4 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs @@ -147,6 +147,7 @@ mod bridge_hub_westend_tests { use super::*; use bridge_common_config::{ BridgeGrandpaWestendInstance, BridgeParachainWestendInstance, DeliveryRewardInBalance, + RelayersForLegacyLaneIdsMessagesInstance, }; use bridge_hub_test_utils::test_cases::from_parachain; use bridge_to_westend_config::{ @@ -174,6 +175,7 @@ mod bridge_hub_westend_tests { BridgeGrandpaWestendInstance, BridgeParachainWestendInstance, WithBridgeHubWestendMessagesInstance, + RelayersForLegacyLaneIdsMessagesInstance, >; #[test] @@ -506,6 +508,7 @@ mod bridge_hub_westend_tests { mod bridge_hub_bulletin_tests { use super::*; use bridge_common_config::BridgeGrandpaRococoBulletinInstance; + use bridge_hub_rococo_runtime::bridge_common_config::RelayersForLegacyLaneIdsMessagesInstance; use bridge_hub_test_utils::test_cases::from_grandpa_chain; use bridge_to_bulletin_config::{ RococoBulletinGlobalConsensusNetwork, RococoBulletinGlobalConsensusNetworkLocation, @@ -527,6 +530,7 @@ mod bridge_hub_bulletin_tests { AllPalletsWithoutSystem, BridgeGrandpaRococoBulletinInstance, WithRococoBulletinMessagesInstance, + RelayersForLegacyLaneIdsMessagesInstance, >; #[test] diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_common_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_common_config.rs index 9bae106395a6..0872d0498f85 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_common_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_common_config.rs @@ -22,6 +22,7 @@ //! GRANDPA tracking pallet only needs to be aware of one chain. use super::{weights, AccountId, Balance, Balances, BlockNumber, Runtime, RuntimeEvent}; +use bp_messages::LegacyLaneId; use frame_support::parameter_types; parameter_types! { @@ -33,11 +34,15 @@ parameter_types! { } /// Allows collect and claim rewards for relayers -impl pallet_bridge_relayers::Config for Runtime { +pub type RelayersForLegacyLaneIdsMessagesInstance = (); +impl pallet_bridge_relayers::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Reward = Balance; - type PaymentProcedure = - bp_relayers::PayRewardFromAccount, AccountId>; + type PaymentProcedure = bp_relayers::PayRewardFromAccount< + pallet_balances::Pallet, + AccountId, + Self::LaneId, + >; type StakeAndSlash = pallet_bridge_relayers::StakeAndSlashNamed< AccountId, BlockNumber, @@ -47,4 +52,5 @@ impl pallet_bridge_relayers::Config for Runtime { RelayerStakeLease, >; type WeightInfo = weights::pallet_bridge_relayers::WeightInfo; + type LaneId = LegacyLaneId; } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index 694ad4efa792..ddeb6d0a9a76 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -23,7 +23,7 @@ use crate::{ }; use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, - target_chain::FromBridgedChainMessagesProof, + target_chain::FromBridgedChainMessagesProof, LegacyLaneId, }; use bp_parachains::SingleParaStoredHeaderDataBuilder; use bridge_hub_common::xcm_version::XcmVersionOfDestAndRemoteBridge; @@ -33,14 +33,12 @@ use frame_support::{ parameter_types, traits::{ConstU32, PalletInfoAccess}, }; -use frame_system::EnsureRoot; +use frame_system::{EnsureNever, EnsureRoot}; +use pallet_bridge_messages::LaneIdOf; use pallet_bridge_relayers::extension::{ BridgeRelayersSignedExtension, WithMessagesExtensionConfig, }; -use pallet_xcm::EnsureXcm; -use parachains_common::xcm_config::{ - AllSiblingSystemParachains, ParentRelayOrSiblingParachains, RelayOrOtherSystemParachains, -}; +use parachains_common::xcm_config::{AllSiblingSystemParachains, RelayOrOtherSystemParachains}; use polkadot_parachain_primitives::primitives::Sibling; use testnet_parachains_constants::westend::currency::UNITS as WND; use xcm::{ @@ -81,11 +79,11 @@ parameter_types! { } /// Proof of messages, coming from Rococo. -pub type FromRococoBridgeHubMessagesProof = - FromBridgedChainMessagesProof; +pub type FromRococoBridgeHubMessagesProof = + FromBridgedChainMessagesProof>; /// Messages delivery proof for Rococo Bridge Hub -> Westend Bridge Hub messages. -pub type ToRococoBridgeHubMessagesDeliveryProof = - FromBridgedChainMessagesDeliveryProof; +pub type ToRococoBridgeHubMessagesDeliveryProof = + FromBridgedChainMessagesDeliveryProof>; /// Dispatches received XCM messages from other bridge type FromRococoMessageBlobDispatcher = @@ -100,6 +98,7 @@ pub type OnBridgeHubWestendRefundBridgeHubRococoMessages = BridgeRelayersSignedE WithBridgeHubRococoMessagesInstance, PriorityBoostPerMessage, >, + LaneIdOf, >; bp_runtime::generate_static_str_provider!(OnBridgeHubWestendRefundBridgeHubRococoMessages); @@ -142,10 +141,10 @@ impl pallet_bridge_messages::Config for Run >; type OutboundPayload = XcmAsPlainPayload; - type InboundPayload = XcmAsPlainPayload; - type DeliveryPayments = (); + type LaneId = LegacyLaneId; + type DeliveryPayments = (); type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< Runtime, WithBridgeHubRococoMessagesInstance, @@ -169,8 +168,8 @@ impl pallet_xcm_bridge_hub::Config for Runtime { type DestinationVersion = XcmVersionOfDestAndRemoteBridge; type ForceOrigin = EnsureRoot; - // Only allow calls from relay chains and sibling parachains to directly open the bridge. - type OpenBridgeOrigin = EnsureXcm; + // We don't want to allow creating bridges for this instance with `LegacyLaneId`. + type OpenBridgeOrigin = EnsureNever; // Converter aligned with `OpenBridgeOrigin`. type BridgeOriginAccountIdConverter = (ParentIsPreset, SiblingParachainConvertsVia); @@ -188,14 +187,20 @@ impl pallet_xcm_bridge_hub::Config for Runtime { } #[cfg(feature = "runtime-benchmarks")] -pub(crate) fn open_bridge_for_benchmarks( - with: bp_messages::LaneId, +pub(crate) fn open_bridge_for_benchmarks( + with: pallet_xcm_bridge_hub::LaneIdOf, sibling_para_id: u32, -) -> InteriorLocation { +) -> InteriorLocation +where + R: pallet_xcm_bridge_hub::Config, + XBHI: 'static, + C: xcm_executor::traits::ConvertLocation< + bp_runtime::AccountIdOf>, + >, +{ use pallet_xcm_bridge_hub::{Bridge, BridgeId, BridgeState}; use sp_runtime::traits::Zero; use xcm::VersionedInteriorLocation; - use xcm_executor::traits::ConvertLocation; // insert bridge metadata let lane_id = with; @@ -205,7 +210,7 @@ pub(crate) fn open_bridge_for_benchmarks( let bridge_id = BridgeId::new(&universal_source, &universal_destination); // insert only bridge metadata, because the benchmarks create lanes - pallet_xcm_bridge_hub::Bridges::::insert( + pallet_xcm_bridge_hub::Bridges::::insert( bridge_id, Bridge { bridge_origin_relative_location: alloc::boxed::Box::new( @@ -218,17 +223,12 @@ pub(crate) fn open_bridge_for_benchmarks( VersionedInteriorLocation::from(universal_destination), ), state: BridgeState::Opened, - bridge_owner_account: crate::xcm_config::LocationToAccountId::convert_location( - &sibling_parachain, - ) - .expect("valid AccountId"), - deposit: Balance::zero(), + bridge_owner_account: C::convert_location(&sibling_parachain).expect("valid AccountId"), + deposit: Zero::zero(), lane_id, }, ); - pallet_xcm_bridge_hub::LaneToBridge::::insert( - lane_id, bridge_id, - ); + pallet_xcm_bridge_hub::LaneToBridge::::insert(lane_id, bridge_id); universal_source } @@ -327,12 +327,11 @@ mod tests { /// Contains the migration for the AssetHubWestend<>AssetHubRococo bridge. pub mod migration { use super::*; - use bp_messages::LaneId; + use bp_messages::LegacyLaneId; use frame_support::traits::ConstBool; - use sp_runtime::Either; parameter_types! { - pub AssetHubWestendToAssetHubRococoMessagesLane: LaneId = LaneId::from_inner(Either::Right([0, 0, 0, 2])); + pub AssetHubWestendToAssetHubRococoMessagesLane: LegacyLaneId = LegacyLaneId([0, 0, 0, 2]); pub AssetHubWestendLocation: Location = Location::new(1, [Parachain(bp_asset_hub_westend::ASSET_HUB_WESTEND_PARACHAIN_ID)]); pub AssetHubRococoUniversalLocation: InteriorLocation = [GlobalConsensus(RococoGlobalConsensusNetwork::get()), Parachain(bp_asset_hub_rococo::ASSET_HUB_ROCOCO_PARACHAIN_ID)].into(); } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index bdac664ee431..2643ecd0dc6e 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -81,6 +81,7 @@ use xcm_runtime_apis::{ }; use bp_runtime::HeaderId; +use pallet_bridge_messages::LaneIdOf; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; @@ -152,6 +153,7 @@ pub type Migrations = ( OutboundLanesCongestedSignalsKey, RocksDbWeight, >, + pallet_bridge_relayers::migration::v1::MigrationToV1, // permanent pallet_xcm::migration::MigrateToLatestXcmVersion, snowbridge_pallet_system::migration::v0::InitializeOnUpgrade< @@ -841,9 +843,9 @@ impl_runtime_apis! { } } - impl bp_bridge_hub_rococo::FromBridgeHubRococoInboundLaneApi for Runtime { + impl bp_bridge_hub_rococo::FromBridgeHubRococoInboundLaneApi> for Runtime { fn message_details( - lane: bp_messages::LaneId, + lane: LaneIdOf, messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>, ) -> Vec { bridge_runtime_common::messages_api::inbound_message_details::< @@ -853,9 +855,9 @@ impl_runtime_apis! { } } - impl bp_bridge_hub_rococo::ToBridgeHubRococoOutboundLaneApi for Runtime { + impl bp_bridge_hub_rococo::ToBridgeHubRococoOutboundLaneApi> for Runtime { fn message_details( - lane: bp_messages::LaneId, + lane: LaneIdOf, begin: bp_messages::MessageNonce, end: bp_messages::MessageNonce, ) -> Vec { @@ -1195,12 +1197,16 @@ impl_runtime_apis! { } fn prepare_message_proof( - params: MessageProofParams, - ) -> (bridge_to_rococo_config::FromRococoBridgeHubMessagesProof, Weight) { + params: MessageProofParams>, + ) -> (bridge_to_rococo_config::FromRococoBridgeHubMessagesProof, Weight) { use cumulus_primitives_core::XcmpMessageSource; assert!(XcmpQueue::take_outbound_messages(usize::MAX).is_empty()); ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(42.into()); - let universal_source = bridge_to_rococo_config::open_bridge_for_benchmarks(params.lane, 42); + let universal_source = bridge_to_rococo_config::open_bridge_for_benchmarks::< + Runtime, + bridge_to_rococo_config::XcmOverBridgeHubRococoInstance, + xcm_config::LocationToAccountId, + >(params.lane, 42); prepare_message_proof_from_parachain::< Runtime, bridge_to_rococo_config::BridgeGrandpaRococoInstance, @@ -1209,9 +1215,13 @@ impl_runtime_apis! { } fn prepare_message_delivery_proof( - params: MessageDeliveryProofParams, - ) -> bridge_to_rococo_config::ToRococoBridgeHubMessagesDeliveryProof { - let _ = bridge_to_rococo_config::open_bridge_for_benchmarks(params.lane, 42); + params: MessageDeliveryProofParams>, + ) -> bridge_to_rococo_config::ToRococoBridgeHubMessagesDeliveryProof { + let _ = bridge_to_rococo_config::open_bridge_for_benchmarks::< + Runtime, + bridge_to_rococo_config::XcmOverBridgeHubRococoInstance, + xcm_config::LocationToAccountId, + >(params.lane, 42); prepare_message_delivery_proof_from_parachain::< Runtime, bridge_to_rococo_config::BridgeGrandpaRococoInstance, @@ -1256,14 +1266,15 @@ impl_runtime_apis! { } } - impl BridgeRelayersConfig for Runtime { + impl BridgeRelayersConfig for Runtime { fn prepare_rewards_account( - account_params: bp_relayers::RewardsAccountParams, + account_params: bp_relayers::RewardsAccountParams<>::LaneId>, reward: Balance, ) { let rewards_account = bp_relayers::PayRewardFromAccount::< Balances, - AccountId + AccountId, + >::LaneId, >::rewards_account(account_params); Self::deposit_account(rewards_account, reward); } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs index 4391b069cf09..55f2d7869bf6 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs @@ -17,7 +17,10 @@ #![cfg(test)] use bp_polkadot_core::Signature; -use bridge_common_config::{DeliveryRewardInBalance, RequiredStakeForStakeAndSlash}; +use bridge_common_config::{ + DeliveryRewardInBalance, RelayersForLegacyLaneIdsMessagesInstance, + RequiredStakeForStakeAndSlash, +}; use bridge_hub_test_utils::{test_cases::from_parachain, SlotDurations}; use bridge_hub_westend_runtime::{ bridge_common_config, bridge_to_rococo_config, @@ -63,6 +66,7 @@ type RuntimeTestsAdapter = from_parachain::WithRemoteParachainHelperAdapter< BridgeGrandpaRococoInstance, BridgeParachainRococoInstance, WithBridgeHubRococoMessagesInstance, + RelayersForLegacyLaneIdsMessagesInstance, >; parameter_types! { diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs index 72743eaa41db..ce8eaa270392 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs @@ -24,12 +24,12 @@ use crate::{ use alloc::{boxed::Box, vec}; use bp_header_chain::ChainWithGrandpa; -use bp_messages::{LaneId, UnrewardedRelayersState}; +use bp_messages::UnrewardedRelayersState; use bp_relayers::{RewardsAccountOwner, RewardsAccountParams}; use bp_xcm_bridge_hub::XcmAsPlainPayload; use frame_support::traits::{OnFinalize, OnInitialize}; use frame_system::pallet_prelude::BlockNumberFor; -use pallet_bridge_messages::{BridgedChainOf, ThisChainOf}; +use pallet_bridge_messages::{BridgedChainOf, LaneIdOf, ThisChainOf}; use parachains_runtimes_test_utils::{ AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, SlotDurations, }; @@ -50,7 +50,7 @@ pub trait WithRemoteGrandpaChainHelper { Self::MPI, InboundPayload = XcmAsPlainPayload, OutboundPayload = XcmAsPlainPayload, - > + pallet_bridge_relayers::Config; + > + pallet_bridge_relayers::Config>; /// All pallets of this chain, excluding system pallet. type AllPalletsWithoutSystem: OnInitialize> + OnFinalize>; @@ -58,15 +58,18 @@ pub trait WithRemoteGrandpaChainHelper { type GPI: 'static; /// Instance of the `pallet-bridge-messages`, used to bridge with remote GRANDPA chain. type MPI: 'static; + /// Instance of the `pallet-bridge-relayers`, used to collect rewards from messages `MPI` + /// instance. + type RPI: 'static; } /// Adapter struct that implements [`WithRemoteGrandpaChainHelper`]. -pub struct WithRemoteGrandpaChainHelperAdapter( - core::marker::PhantomData<(Runtime, AllPalletsWithoutSystem, GPI, MPI)>, +pub struct WithRemoteGrandpaChainHelperAdapter( + core::marker::PhantomData<(Runtime, AllPalletsWithoutSystem, GPI, MPI, RPI)>, ); -impl WithRemoteGrandpaChainHelper - for WithRemoteGrandpaChainHelperAdapter +impl WithRemoteGrandpaChainHelper + for WithRemoteGrandpaChainHelperAdapter where Runtime: BasicParachainRuntime + cumulus_pallet_xcmp_queue::Config @@ -75,16 +78,18 @@ where MPI, InboundPayload = XcmAsPlainPayload, OutboundPayload = XcmAsPlainPayload, - > + pallet_bridge_relayers::Config, + > + pallet_bridge_relayers::Config>, AllPalletsWithoutSystem: OnInitialize> + OnFinalize>, GPI: 'static, MPI: 'static, + RPI: 'static, { type Runtime = Runtime; type AllPalletsWithoutSystem = AllPalletsWithoutSystem; type GPI = GPI; type MPI = MPI; + type RPI = RPI; } /// Test-case makes sure that Runtime can dispatch XCM messages submitted by relayer, @@ -96,7 +101,7 @@ pub fn relayed_incoming_message_works( runtime_para_id: u32, sibling_parachain_id: u32, local_relay_chain_id: NetworkId, - prepare_configuration: impl Fn() -> LaneId, + prepare_configuration: impl Fn() -> LaneIdOf, construct_and_apply_extrinsic: fn( sp_keyring::AccountKeyring, RuntimeCallOf, @@ -140,6 +145,7 @@ pub fn relayed_incoming_message_works( test_data::from_grandpa_chain::make_complex_relayer_delivery_proofs::< BridgedChainOf, ThisChainOf, + LaneIdOf, >( lane_id, xcm.into(), @@ -172,7 +178,7 @@ pub fn relayed_incoming_message_works( lane_id, 1, ), - helpers::VerifyRelayerRewarded::::expect_relayer_reward( + helpers::VerifyRelayerRewarded::::expect_relayer_reward( relayer_id_at_this_chain, RewardsAccountParams::new( lane_id, @@ -197,7 +203,7 @@ pub fn free_relay_extrinsic_works( runtime_para_id: u32, sibling_parachain_id: u32, local_relay_chain_id: NetworkId, - prepare_configuration: impl Fn() -> LaneId, + prepare_configuration: impl Fn() -> LaneIdOf, construct_and_apply_extrinsic: fn( sp_keyring::AccountKeyring, RuntimeCallOf, @@ -263,6 +269,7 @@ pub fn free_relay_extrinsic_works( test_data::from_grandpa_chain::make_complex_relayer_delivery_proofs::< BridgedChainOf, ThisChainOf, + LaneIdOf, >( lane_id, xcm.into(), @@ -301,7 +308,7 @@ pub fn free_relay_extrinsic_works( lane_id, 1, ), - helpers::VerifyRelayerRewarded::::expect_relayer_reward( + helpers::VerifyRelayerRewarded::::expect_relayer_reward( relayer_id_at_this_chain, RewardsAccountParams::new( lane_id, @@ -325,7 +332,7 @@ pub fn complex_relay_extrinsic_works( runtime_para_id: u32, sibling_parachain_id: u32, local_relay_chain_id: NetworkId, - prepare_configuration: impl Fn() -> LaneId, + prepare_configuration: impl Fn() -> LaneIdOf, construct_and_apply_extrinsic: fn( sp_keyring::AccountKeyring, RuntimeCallOf, @@ -372,6 +379,7 @@ pub fn complex_relay_extrinsic_works( test_data::from_grandpa_chain::make_complex_relayer_delivery_proofs::< BridgedChainOf, ThisChainOf, + LaneIdOf, >( lane_id, xcm.into(), @@ -382,9 +390,10 @@ pub fn complex_relay_extrinsic_works( ); let relay_chain_header_hash = relay_chain_header.hash(); - vec![( - pallet_utility::Call::::batch_all { - calls: vec![ + vec![ + ( + pallet_utility::Call::::batch_all { + calls: vec![ BridgeGrandpaCall::::submit_finality_proof { finality_target: Box::new(relay_chain_header), justification: grandpa_justification, @@ -396,27 +405,33 @@ pub fn complex_relay_extrinsic_works( dispatch_weight: Weight::from_parts(1000000000, 0), }.into(), ], - } - .into(), - Box::new(( - helpers::VerifySubmitGrandpaFinalityProofOutcome::< - RuntimeHelper::Runtime, - RuntimeHelper::GPI, - >::expect_best_header_hash(relay_chain_header_hash), - helpers::VerifySubmitMessagesProofOutcome::< - RuntimeHelper::Runtime, - RuntimeHelper::MPI, - >::expect_last_delivered_nonce(lane_id, 1), - helpers::VerifyRelayerRewarded::::expect_relayer_reward( - relayer_id_at_this_chain, - RewardsAccountParams::new( - lane_id, - bridged_chain_id, - RewardsAccountOwner::ThisChain, + } + .into(), + Box::new( + ( + helpers::VerifySubmitGrandpaFinalityProofOutcome::< + RuntimeHelper::Runtime, + RuntimeHelper::GPI, + >::expect_best_header_hash(relay_chain_header_hash), + helpers::VerifySubmitMessagesProofOutcome::< + RuntimeHelper::Runtime, + RuntimeHelper::MPI, + >::expect_last_delivered_nonce(lane_id, 1), + helpers::VerifyRelayerRewarded::< + RuntimeHelper::Runtime, + RuntimeHelper::RPI, + >::expect_relayer_reward( + relayer_id_at_this_chain, + RewardsAccountParams::new( + lane_id, + bridged_chain_id, + RewardsAccountOwner::ThisChain, + ), + ), ), ), - )), - )] + ), + ] }, ); } @@ -446,8 +461,9 @@ where test_data::from_grandpa_chain::make_complex_relayer_delivery_proofs::< BridgedChainOf, ThisChainOf, + LaneIdOf, >( - LaneId::new(1, 2), + LaneIdOf::::default(), vec![Instruction::<()>::ClearOrigin; 1_024].into(), 1, [GlobalConsensus(Polkadot), Parachain(1_000)].into(), @@ -502,8 +518,9 @@ where BridgedChainOf, ThisChainOf, (), + LaneIdOf, >( - LaneId::new(1, 2), + LaneIdOf::::default(), 1u32.into(), AccountId32::from(Alice.public()).into(), unrewarded_relayers.clone(), @@ -550,8 +567,9 @@ where test_data::from_grandpa_chain::make_complex_relayer_delivery_proofs::< BridgedChainOf, ThisChainOf, + LaneIdOf, >( - LaneId::new(1, 2), + LaneIdOf::::default(), vec![Instruction::<()>::ClearOrigin; 1_024].into(), 1, [GlobalConsensus(Polkadot), Parachain(1_000)].into(), @@ -602,8 +620,9 @@ where BridgedChainOf, ThisChainOf, (), + LaneIdOf, >( - LaneId::new(1, 2), + LaneIdOf::::default(), 1u32.into(), AccountId32::from(Alice.public()).into(), unrewarded_relayers.clone(), diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs index 82edcacdcab5..4a1d7470e839 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs @@ -24,14 +24,14 @@ use crate::{ use alloc::{boxed::Box, vec}; use bp_header_chain::ChainWithGrandpa; -use bp_messages::{LaneId, UnrewardedRelayersState}; +use bp_messages::UnrewardedRelayersState; use bp_polkadot_core::parachains::ParaHash; use bp_relayers::{RewardsAccountOwner, RewardsAccountParams}; use bp_runtime::{Chain, Parachain}; use bp_xcm_bridge_hub::XcmAsPlainPayload; use frame_support::traits::{OnFinalize, OnInitialize}; use frame_system::pallet_prelude::BlockNumberFor; -use pallet_bridge_messages::{BridgedChainOf, ThisChainOf}; +use pallet_bridge_messages::{BridgedChainOf, LaneIdOf, ThisChainOf}; use parachains_runtimes_test_utils::{ AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, SlotDurations, }; @@ -53,7 +53,7 @@ pub trait WithRemoteParachainHelper { Self::MPI, InboundPayload = XcmAsPlainPayload, OutboundPayload = XcmAsPlainPayload, - > + pallet_bridge_relayers::Config; + > + pallet_bridge_relayers::Config>; /// All pallets of this chain, excluding system pallet. type AllPalletsWithoutSystem: OnInitialize> + OnFinalize>; @@ -63,15 +63,18 @@ pub trait WithRemoteParachainHelper { type PPI: 'static; /// Instance of the `pallet-bridge-messages`, used to bridge with remote parachain. type MPI: 'static; + /// Instance of the `pallet-bridge-relayers`, used to collect rewards from messages `MPI` + /// instance. + type RPI: 'static; } /// Adapter struct that implements `WithRemoteParachainHelper`. -pub struct WithRemoteParachainHelperAdapter( - core::marker::PhantomData<(Runtime, AllPalletsWithoutSystem, GPI, PPI, MPI)>, +pub struct WithRemoteParachainHelperAdapter( + core::marker::PhantomData<(Runtime, AllPalletsWithoutSystem, GPI, PPI, MPI, RPI)>, ); -impl WithRemoteParachainHelper - for WithRemoteParachainHelperAdapter +impl WithRemoteParachainHelper + for WithRemoteParachainHelperAdapter where Runtime: BasicParachainRuntime + cumulus_pallet_xcmp_queue::Config @@ -81,19 +84,20 @@ where MPI, InboundPayload = XcmAsPlainPayload, OutboundPayload = XcmAsPlainPayload, - > + pallet_bridge_relayers::Config, + > + pallet_bridge_relayers::Config>, AllPalletsWithoutSystem: OnInitialize> + OnFinalize>, GPI: 'static, PPI: 'static, MPI: 'static, - // MB: MessageBridge, + RPI: 'static, { type Runtime = Runtime; type AllPalletsWithoutSystem = AllPalletsWithoutSystem; type GPI = GPI; type PPI = PPI; type MPI = MPI; + type RPI = RPI; } /// Test-case makes sure that Runtime can dispatch XCM messages submitted by relayer, @@ -106,7 +110,7 @@ pub fn relayed_incoming_message_works( bridged_para_id: u32, sibling_parachain_id: u32, local_relay_chain_id: NetworkId, - prepare_configuration: impl Fn() -> LaneId, + prepare_configuration: impl Fn() -> LaneIdOf, construct_and_apply_extrinsic: fn( sp_keyring::AccountKeyring, ::RuntimeCall, @@ -161,6 +165,7 @@ pub fn relayed_incoming_message_works( >::BridgedChain, BridgedChainOf, ThisChainOf, + LaneIdOf, >( lane_id, xcm.into(), @@ -208,7 +213,7 @@ pub fn relayed_incoming_message_works( lane_id, 1, ), - helpers::VerifyRelayerRewarded::::expect_relayer_reward( + helpers::VerifyRelayerRewarded::::expect_relayer_reward( relayer_id_at_this_chain, RewardsAccountParams::new( lane_id, @@ -234,7 +239,7 @@ pub fn free_relay_extrinsic_works( bridged_para_id: u32, sibling_parachain_id: u32, local_relay_chain_id: NetworkId, - prepare_configuration: impl Fn() -> LaneId, + prepare_configuration: impl Fn() -> LaneIdOf, construct_and_apply_extrinsic: fn( sp_keyring::AccountKeyring, ::RuntimeCall, @@ -312,6 +317,7 @@ pub fn free_relay_extrinsic_works( >::BridgedChain, BridgedChainOf, ThisChainOf, + LaneIdOf, >( lane_id, xcm.into(), @@ -371,7 +377,7 @@ pub fn free_relay_extrinsic_works( lane_id, 1, ), - helpers::VerifyRelayerRewarded::::expect_relayer_reward( + helpers::VerifyRelayerRewarded::::expect_relayer_reward( relayer_id_at_this_chain, RewardsAccountParams::new( lane_id, @@ -396,7 +402,7 @@ pub fn complex_relay_extrinsic_works( bridged_para_id: u32, sibling_parachain_id: u32, local_relay_chain_id: NetworkId, - prepare_configuration: impl Fn() -> LaneId, + prepare_configuration: impl Fn() -> LaneIdOf, construct_and_apply_extrinsic: fn( sp_keyring::AccountKeyring, ::RuntimeCall, @@ -454,6 +460,7 @@ pub fn complex_relay_extrinsic_works( >::BridgedChain, BridgedChainOf, ThisChainOf, + LaneIdOf, >( lane_id, xcm.into(), @@ -468,9 +475,10 @@ pub fn complex_relay_extrinsic_works( let parachain_head_hash = parachain_head.hash(); let relay_chain_header_hash = relay_chain_header.hash(); let relay_chain_header_number = *relay_chain_header.number(); - vec![( - pallet_utility::Call::::batch_all { - calls: vec![ + vec![ + ( + pallet_utility::Call::::batch_all { + calls: vec![ BridgeGrandpaCall::::submit_finality_proof { finality_target: Box::new(relay_chain_header), justification: grandpa_justification, @@ -487,31 +495,37 @@ pub fn complex_relay_extrinsic_works( dispatch_weight: Weight::from_parts(1000000000, 0), }.into(), ], - } - .into(), - Box::new(( - helpers::VerifySubmitGrandpaFinalityProofOutcome::< - RuntimeHelper::Runtime, - RuntimeHelper::GPI, - >::expect_best_header_hash(relay_chain_header_hash), - helpers::VerifySubmitParachainHeaderProofOutcome::< - RuntimeHelper::Runtime, - RuntimeHelper::PPI, - >::expect_best_header_hash(bridged_para_id, parachain_head_hash), - helpers::VerifySubmitMessagesProofOutcome::< - RuntimeHelper::Runtime, - RuntimeHelper::MPI, - >::expect_last_delivered_nonce(lane_id, 1), - helpers::VerifyRelayerRewarded::::expect_relayer_reward( - relayer_id_at_this_chain, - RewardsAccountParams::new( - lane_id, - bridged_chain_id, - RewardsAccountOwner::ThisChain, + } + .into(), + Box::new( + ( + helpers::VerifySubmitGrandpaFinalityProofOutcome::< + RuntimeHelper::Runtime, + RuntimeHelper::GPI, + >::expect_best_header_hash(relay_chain_header_hash), + helpers::VerifySubmitParachainHeaderProofOutcome::< + RuntimeHelper::Runtime, + RuntimeHelper::PPI, + >::expect_best_header_hash(bridged_para_id, parachain_head_hash), + helpers::VerifySubmitMessagesProofOutcome::< + RuntimeHelper::Runtime, + RuntimeHelper::MPI, + >::expect_last_delivered_nonce(lane_id, 1), + helpers::VerifyRelayerRewarded::< + RuntimeHelper::Runtime, + RuntimeHelper::RPI, + >::expect_relayer_reward( + relayer_id_at_this_chain, + RewardsAccountParams::new( + lane_id, + bridged_chain_id, + RewardsAccountOwner::ThisChain, + ), + ), ), ), - )), - )] + ), + ] }, ); } @@ -551,8 +565,9 @@ where >::BridgedChain, BridgedChainOf, ThisChainOf, + LaneIdOf >( - LaneId::new(1, 2), + LaneIdOf::::default(), vec![Instruction::<()>::ClearOrigin; 1_024].into(), 1, [GlobalConsensus(Polkadot), Parachain(1_000)].into(), @@ -621,8 +636,9 @@ where >::BridgedChain, BridgedChainOf, ThisChainOf, + LaneIdOf, >( - LaneId::new(1, 2), + LaneIdOf::::default(), 1, 5, 1_000, @@ -683,8 +699,9 @@ where >::BridgedChain, BridgedChainOf, ThisChainOf, + LaneIdOf, >( - LaneId::new(1, 2), + LaneIdOf::::default(), vec![Instruction::<()>::ClearOrigin; 1_024].into(), 1, [GlobalConsensus(Polkadot), Parachain(1_000)].into(), @@ -738,8 +755,9 @@ where >::BridgedChain, BridgedChainOf, ThisChainOf, + LaneIdOf, >( - LaneId::new(1, 2), + LaneIdOf::::default(), 1, 5, 1_000, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs index c343e9b3e09a..4605b7cf9b22 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs @@ -19,7 +19,7 @@ use crate::test_cases::{bridges_prelude::*, run_test, RuntimeHelper}; use asset_test_utils::BasicParachainRuntime; -use bp_messages::{LaneId, MessageNonce}; +use bp_messages::MessageNonce; use bp_polkadot_core::parachains::{ParaHash, ParaId}; use bp_relayers::RewardsAccountParams; use bp_runtime::Chain; @@ -33,7 +33,7 @@ use frame_support::{ }; use frame_system::pallet_prelude::BlockNumberFor; use pallet_bridge_grandpa::{BridgedBlockHash, BridgedHeader}; -use pallet_bridge_messages::BridgedChainOf; +use pallet_bridge_messages::{BridgedChainOf, LaneIdOf}; use parachains_common::AccountId; use parachains_runtimes_test_utils::{ mock_open_hrmp_channel, AccountIdOf, CollatorSessionKeys, RuntimeCallOf, SlotDurations, @@ -132,8 +132,8 @@ where } /// Checks that the latest delivered nonce in the bridge messages pallet equals to given one. -pub struct VerifySubmitMessagesProofOutcome { - lane: LaneId, +pub struct VerifySubmitMessagesProofOutcome, MPI: 'static> { + lane: LaneIdOf, expected_nonce: MessageNonce, _marker: PhantomData<(Runtime, MPI)>, } @@ -145,7 +145,7 @@ where { /// Expect given delivered nonce to be the latest after transaction. pub fn expect_last_delivered_nonce( - lane: LaneId, + lane: LaneIdOf, expected_nonce: MessageNonce, ) -> Box { Box::new(Self { lane, expected_nonce, _marker: PhantomData }) @@ -167,30 +167,32 @@ where } /// Verifies that relayer is rewarded at this chain. -pub struct VerifyRelayerRewarded { +pub struct VerifyRelayerRewarded, RPI: 'static> { relayer: Runtime::AccountId, - reward_params: RewardsAccountParams, + reward_params: RewardsAccountParams, } -impl VerifyRelayerRewarded +impl VerifyRelayerRewarded where - Runtime: pallet_bridge_relayers::Config, + Runtime: pallet_bridge_relayers::Config, + RPI: 'static, { /// Expect given delivered nonce to be the latest after transaction. pub fn expect_relayer_reward( relayer: Runtime::AccountId, - reward_params: RewardsAccountParams, + reward_params: RewardsAccountParams, ) -> Box { Box::new(Self { relayer, reward_params }) } } -impl VerifyTransactionOutcome for VerifyRelayerRewarded +impl VerifyTransactionOutcome for VerifyRelayerRewarded where - Runtime: pallet_bridge_relayers::Config, + Runtime: pallet_bridge_relayers::Config, + RPI: 'static, { fn verify_outcome(&self) { - assert!(pallet_bridge_relayers::RelayerRewards::::get( + assert!(pallet_bridge_relayers::RelayerRewards::::get( &self.relayer, &self.reward_params, ) @@ -388,7 +390,7 @@ fn execute_and_verify_calls( /// Helper function to open the bridge/lane for `source` and `destination` while ensuring all /// required balances are placed into the SA of the source. -pub fn ensure_opened_bridge(source: Location, destination: InteriorLocation) -> (BridgeLocations, LaneId) +pub fn ensure_opened_bridge(source: Location, destination: InteriorLocation) -> (BridgeLocations, pallet_xcm_bridge_hub::LaneIdOf) where Runtime: BasicParachainRuntime + BridgeXcmOverBridgeConfig, XcmOverBridgePalletInstance: 'static, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs index de117982b26f..4b15db929dee 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs @@ -29,7 +29,7 @@ use crate::{test_cases::bridges_prelude::*, test_data}; use asset_test_utils::BasicParachainRuntime; use bp_messages::{ target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch}, - LaneId, LaneState, MessageKey, MessagesOperatingMode, OutboundLaneData, + LaneState, MessageKey, MessagesOperatingMode, OutboundLaneData, }; use bp_runtime::BasicOperatingMode; use bp_xcm_bridge_hub::{Bridge, BridgeState, XcmAsPlainPayload}; @@ -71,6 +71,7 @@ pub(crate) mod bridges_prelude { // Re-export test_case from assets pub use asset_test_utils::include_teleports_for_native_asset_works; +use pallet_bridge_messages::LaneIdOf; pub type RuntimeHelper = parachains_runtimes_test_utils::RuntimeHelper; @@ -326,7 +327,7 @@ pub fn handle_export_message_from_system_parachain_to_outbound_queue_works< export_message_instruction: fn() -> Instruction, existential_deposit: Option, maybe_paid_export_message: Option, - prepare_configuration: impl Fn() -> LaneId, + prepare_configuration: impl Fn() -> LaneIdOf, ) where Runtime: BasicParachainRuntime + BridgeMessagesConfig, XcmConfig: xcm_executor::Config, @@ -469,7 +470,7 @@ pub fn message_dispatch_routing_works< run_test::(collator_session_key, runtime_para_id, vec![], || { prepare_configuration(); - let dummy_lane_id = LaneId::new(1, 2); + let dummy_lane_id = LaneIdOf::::default(); let mut alice = [0u8; 32]; alice[0] = 1; diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/from_grandpa_chain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/from_grandpa_chain.rs index 2940c4e00f42..7461085330f2 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/from_grandpa_chain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/from_grandpa_chain.rs @@ -20,8 +20,8 @@ use crate::test_data::prepare_inbound_xcm; use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, - target_chain::FromBridgedChainMessagesProof, ChainWithMessages, LaneId, LaneState, - MessageNonce, UnrewardedRelayersState, + target_chain::FromBridgedChainMessagesProof, ChainWithMessages, LaneState, MessageNonce, + UnrewardedRelayersState, }; use bp_runtime::{AccountIdOf, BlockNumberOf, Chain, HeaderOf, UnverifiedStorageProofParams}; use bp_test_utils::make_default_justification; @@ -40,7 +40,7 @@ use pallet_bridge_messages::{ encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof, prepare_messages_storage_proof, }, - BridgedChainOf, + BridgedChainOf, LaneIdOf, }; use sp_runtime::DigestItem; @@ -48,7 +48,10 @@ use sp_runtime::DigestItem; pub fn make_complex_relayer_delivery_batch( bridged_header: BridgedHeader, bridged_justification: GrandpaJustification>, - message_proof: FromBridgedChainMessagesProof>>, + message_proof: FromBridgedChainMessagesProof< + HashOf>, + LaneIdOf, + >, relayer_id_at_bridged_chain: InboundRelayerId, ) -> pallet_utility::Call where @@ -82,6 +85,7 @@ pub fn make_complex_relayer_confirmation_batch( bridged_justification: GrandpaJustification>, message_delivery_proof: FromBridgedChainMessagesDeliveryProof< HashOf>, + LaneIdOf, >, relayers_state: UnrewardedRelayersState, ) -> pallet_utility::Call @@ -111,7 +115,10 @@ where /// Prepare a call with message proof. pub fn make_standalone_relayer_delivery_call( - message_proof: FromBridgedChainMessagesProof>>, + message_proof: FromBridgedChainMessagesProof< + HashOf>, + LaneIdOf, + >, relayer_id_at_bridged_chain: InboundRelayerId, ) -> Runtime::RuntimeCall where @@ -134,6 +141,7 @@ where pub fn make_standalone_relayer_confirmation_call( message_delivery_proof: FromBridgedChainMessagesDeliveryProof< HashOf>, + LaneIdOf, >, relayers_state: UnrewardedRelayersState, ) -> Runtime::RuntimeCall @@ -152,7 +160,7 @@ where } /// Prepare storage proofs of messages, stored at the (bridged) source GRANDPA chain. -pub fn make_complex_relayer_delivery_proofs( +pub fn make_complex_relayer_delivery_proofs( lane_id: LaneId, xcm_message: Xcm<()>, message_nonce: MessageNonce, @@ -162,17 +170,18 @@ pub fn make_complex_relayer_delivery_proofs ) -> ( HeaderOf, GrandpaJustification>, - FromBridgedChainMessagesProof>, + FromBridgedChainMessagesProof, LaneId>, ) where BridgedChain: ChainWithGrandpa, ThisChainWithMessages: ChainWithMessages, + LaneId: Copy + Encode, { // prepare message let message_payload = prepare_inbound_xcm(xcm_message, message_destination); // prepare storage proof containing message let (state_root, storage_proof) = - prepare_messages_storage_proof::( + prepare_messages_storage_proof::( lane_id, message_nonce..=message_nonce, None, @@ -206,6 +215,7 @@ pub fn make_complex_relayer_confirmation_proofs< BridgedChain, ThisChainWithMessages, InnerXcmRuntimeCall, + LaneId, >( lane_id: LaneId, header_number: BlockNumberOf, @@ -214,15 +224,16 @@ pub fn make_complex_relayer_confirmation_proofs< ) -> ( HeaderOf, GrandpaJustification>, - FromBridgedChainMessagesDeliveryProof>, + FromBridgedChainMessagesDeliveryProof, LaneId>, ) where BridgedChain: ChainWithGrandpa, ThisChainWithMessages: ChainWithMessages, + LaneId: Copy + Encode, { // prepare storage proof containing message delivery proof let (state_root, storage_proof) = - prepare_message_delivery_storage_proof::( + prepare_message_delivery_storage_proof::( lane_id, InboundLaneData { state: LaneState::Opened, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/from_parachain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/from_parachain.rs index aefbc0dbd0a7..a6659b8241df 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/from_parachain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/from_parachain.rs @@ -20,7 +20,7 @@ use super::{from_grandpa_chain::make_complex_bridged_grandpa_header_proof, prepa use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, - target_chain::FromBridgedChainMessagesProof, ChainWithMessages, LaneId, LaneState, + target_chain::FromBridgedChainMessagesProof, ChainWithMessages, LaneState, UnrewardedRelayersState, Weight, }; use bp_parachains::{RelayBlockHash, RelayBlockNumber}; @@ -43,7 +43,7 @@ use pallet_bridge_messages::{ encode_all_messages, encode_lane_data, prepare_message_delivery_storage_proof, prepare_messages_storage_proof, }, - BridgedChainOf, + BridgedChainOf, LaneIdOf, }; use sp_runtime::SaturatedConversion; @@ -53,7 +53,7 @@ pub fn make_complex_relayer_delivery_batch( grandpa_justification: GrandpaJustification>, parachain_heads: Vec<(ParaId, ParaHash)>, para_heads_proof: ParaHeadsProof, - message_proof: FromBridgedChainMessagesProof, + message_proof: FromBridgedChainMessagesProof>, relayer_id_at_bridged_chain: InboundRelayerId, ) -> pallet_utility::Call where @@ -106,7 +106,7 @@ pub fn make_complex_relayer_confirmation_batch( grandpa_justification: GrandpaJustification>, parachain_heads: Vec<(ParaId, ParaHash)>, para_heads_proof: ParaHeadsProof, - message_delivery_proof: FromBridgedChainMessagesDeliveryProof, + message_delivery_proof: FromBridgedChainMessagesDeliveryProof>, relayers_state: UnrewardedRelayersState, ) -> pallet_utility::Call where @@ -154,7 +154,7 @@ where /// Prepare a call with message proof. pub fn make_standalone_relayer_delivery_call( - message_proof: FromBridgedChainMessagesProof, + message_proof: FromBridgedChainMessagesProof>, relayer_id_at_bridged_chain: InboundRelayerId, ) -> Runtime::RuntimeCall where @@ -174,7 +174,7 @@ where /// Prepare a call with message delivery proof. pub fn make_standalone_relayer_confirmation_call( - message_delivery_proof: FromBridgedChainMessagesDeliveryProof, + message_delivery_proof: FromBridgedChainMessagesDeliveryProof>, relayers_state: UnrewardedRelayersState, ) -> Runtime::RuntimeCall where @@ -195,6 +195,7 @@ pub fn make_complex_relayer_delivery_proofs< BridgedRelayChain, BridgedParachain, ThisChainWithMessages, + LaneId, >( lane_id: LaneId, xcm_message: Xcm<()>, @@ -210,19 +211,20 @@ pub fn make_complex_relayer_delivery_proofs< ParaHead, Vec<(ParaId, ParaHash)>, ParaHeadsProof, - FromBridgedChainMessagesProof, + FromBridgedChainMessagesProof, ) where BridgedRelayChain: bp_runtime::Chain + ChainWithGrandpa, BridgedParachain: bp_runtime::Chain + Parachain, ThisChainWithMessages: ChainWithMessages, + LaneId: Copy + Encode, { // prepare message let message_payload = prepare_inbound_xcm(xcm_message, message_destination); // prepare para storage proof containing message let (para_state_root, para_storage_proof) = - prepare_messages_storage_proof::( + prepare_messages_storage_proof::( lane_id, message_nonce..=message_nonce, None, @@ -266,6 +268,7 @@ pub fn make_complex_relayer_confirmation_proofs< BridgedRelayChain, BridgedParachain, ThisChainWithMessages, + LaneId, >( lane_id: LaneId, para_header_number: u32, @@ -279,17 +282,18 @@ pub fn make_complex_relayer_confirmation_proofs< ParaHead, Vec<(ParaId, ParaHash)>, ParaHeadsProof, - FromBridgedChainMessagesDeliveryProof, + FromBridgedChainMessagesDeliveryProof, ) where BridgedRelayChain: bp_runtime::Chain + ChainWithGrandpa, BridgedParachain: bp_runtime::Chain + Parachain, ThisChainWithMessages: ChainWithMessages, + LaneId: Copy + Encode, { // prepare para storage proof containing message delivery proof let (para_state_root, para_storage_proof) = - prepare_message_delivery_storage_proof::( + prepare_message_delivery_storage_proof::( lane_id, InboundLaneData { state: LaneState::Opened, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/mod.rs index 106eacd799ca..c34188af5068 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_data/mod.rs @@ -21,7 +21,7 @@ pub mod from_parachain; use bp_messages::{ target_chain::{DispatchMessage, DispatchMessageData}, - LaneId, MessageKey, + MessageKey, }; use codec::Encode; use frame_support::traits::Get; @@ -65,11 +65,11 @@ pub(crate) fn dummy_xcm() -> Xcm<()> { vec![Trap(42)].into() } -pub(crate) fn dispatch_message( +pub(crate) fn dispatch_message( lane_id: LaneId, nonce: MessageNonce, payload: Vec, -) -> DispatchMessage> { +) -> DispatchMessage, LaneId> { DispatchMessage { key: MessageKey { lane_id, nonce }, data: DispatchMessageData { payload: Ok(payload) }, From 483575025f244be4f273c2a683ce185e2d74e10b Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 19 Sep 2024 11:29:43 +0200 Subject: [PATCH 18/38] Adjust tests with latest vogue --- Cargo.lock | 1 + bridges/modules/xcm-bridge-hub/src/lib.rs | 3 +- .../rococo-westend/bridges_rococo_westend.sh | 116 +++++++++--------- .../emulated/common/src/impls.rs | 16 +-- .../bridge-hub-rococo/tests/tests.rs | 68 +++++++++- .../bridge-hub-westend/tests/tests.rs | 25 +++- .../bridge-hubs/test-utils/Cargo.toml | 1 + .../bridge-hubs/test-utils/src/lib.rs | 4 +- .../test-utils/src/test_cases/helpers.rs | 73 ++++++++--- .../test-utils/src/test_cases/mod.rs | 7 +- .../parachains/runtimes/test-utils/src/lib.rs | 2 +- .../src/chain_spec/bridge_hubs.rs | 15 ++- 12 files changed, 230 insertions(+), 101 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 166525c5e5a6..c5b2fed9bf75 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2355,6 +2355,7 @@ dependencies = [ "pallet-bridge-relayers", "pallet-timestamp", "pallet-utility", + "pallet-xcm", "pallet-xcm-bridge-hub", "parachains-common", "parachains-runtimes-test-utils", diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 33f9c90334a6..31b658a4305b 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -451,7 +451,8 @@ pub mod pallet { } impl, I: 'static> Pallet { - pub(crate) fn do_open_bridge( + /// Open bridge for lane. + pub fn do_open_bridge( locations: Box, lane_id: T::LaneId, create_lanes: bool, diff --git a/bridges/testing/environments/rococo-westend/bridges_rococo_westend.sh b/bridges/testing/environments/rococo-westend/bridges_rococo_westend.sh index 54633449134b..e7848fe7163c 100755 --- a/bridges/testing/environments/rococo-westend/bridges_rococo_westend.sh +++ b/bridges/testing/environments/rococo-westend/bridges_rococo_westend.sh @@ -53,66 +53,66 @@ ASSET_HUB_ROCOCO_SOVEREIGN_ACCOUNT_AT_BRIDGE_HUB_ROCOCO="5Eg2fntNprdN3FgH4sfEaaZ # Expected sovereign accounts for rewards on BridgeHubs. # # Generated by: -# #[test] -# fn generate_sovereign_accounts_for_rewards() { -# use bp_messages::LaneId; -# use bp_relayers::{PayRewardFromAccount, RewardsAccountOwner, RewardsAccountParams}; -# use sp_core::crypto::Ss58Codec; +##[test] +#fn generate_sovereign_accounts_for_rewards() { +# use bp_messages::LegacyLaneId; +# use bp_relayers::{PayRewardFromAccount, RewardsAccountOwner, RewardsAccountParams}; +# use sp_core::crypto::Ss58Codec; # -# // SS58=42 -# println!( -# "ON_BRIDGE_HUB_ROCOCO_SOVEREIGN_ACCOUNT_FOR_LANE_00000002_bhwd_ThisChain=\"{}\"", -# frame_support::sp_runtime::AccountId32::new( -# PayRewardFromAccount::<[u8; 32], [u8; 32]>::rewards_account(RewardsAccountParams::new( -# LaneId([0, 0, 0, 2]), -# *b"bhwd", -# RewardsAccountOwner::ThisChain -# )) -# ) -# .to_ss58check_with_version(42_u16.into()) -# ); -# // SS58=42 -# println!( -# "ON_BRIDGE_HUB_ROCOCO_SOVEREIGN_ACCOUNT_FOR_LANE_00000002_bhwd_BridgedChain=\"{}\"", -# frame_support::sp_runtime::AccountId32::new( -# PayRewardFromAccount::<[u8; 32], [u8; 32]>::rewards_account(RewardsAccountParams::new( -# LaneId([0, 0, 0, 2]), -# *b"bhwd", -# RewardsAccountOwner::BridgedChain -# )) -# ) -# .to_ss58check_with_version(42_u16.into()) -# ); +# // SS58=42 +# println!( +# "ON_BRIDGE_HUB_ROCOCO_SOVEREIGN_ACCOUNT_FOR_LANE_00000002_bhwd_ThisChain=\"{}\"", +# frame_support::sp_runtime::AccountId32::new( +# PayRewardFromAccount::<[u8; 32], [u8; 32], LegacyLaneId>::rewards_account(RewardsAccountParams::new( +# LegacyLaneId([0, 0, 0, 2]), +# *b"bhwd", +# RewardsAccountOwner::ThisChain +# )) +# ) +# .to_ss58check_with_version(42_u16.into()) +# ); +# // SS58=42 +# println!( +# "ON_BRIDGE_HUB_ROCOCO_SOVEREIGN_ACCOUNT_FOR_LANE_00000002_bhwd_BridgedChain=\"{}\"", +# frame_support::sp_runtime::AccountId32::new( +# PayRewardFromAccount::<[u8; 32], [u8; 32], LegacyLaneId>::rewards_account(RewardsAccountParams::new( +# LegacyLaneId([0, 0, 0, 2]), +# *b"bhwd", +# RewardsAccountOwner::BridgedChain +# )) +# ) +# .to_ss58check_with_version(42_u16.into()) +# ); # -# // SS58=42 -# println!( -# "ON_BRIDGE_HUB_WESTEND_SOVEREIGN_ACCOUNT_FOR_LANE_00000002_bhro_ThisChain=\"{}\"", -# frame_support::sp_runtime::AccountId32::new( -# PayRewardFromAccount::<[u8; 32], [u8; 32]>::rewards_account(RewardsAccountParams::new( -# LaneId([0, 0, 0, 2]), -# *b"bhro", -# RewardsAccountOwner::ThisChain -# )) -# ) -# .to_ss58check_with_version(42_u16.into()) -# ); -# // SS58=42 -# println!( -# "ON_BRIDGE_HUB_WESTEND_SOVEREIGN_ACCOUNT_FOR_LANE_00000002_bhro_BridgedChain=\"{}\"", -# frame_support::sp_runtime::AccountId32::new( -# PayRewardFromAccount::<[u8; 32], [u8; 32]>::rewards_account(RewardsAccountParams::new( -# LaneId([0, 0, 0, 2]), -# *b"bhro", -# RewardsAccountOwner::BridgedChain -# )) -# ) -# .to_ss58check_with_version(42_u16.into()) -# ); -# } -ON_BRIDGE_HUB_ROCOCO_SOVEREIGN_ACCOUNT_FOR_LANE_00000002_bhwd_ThisChain="5EHnXaT5BhiSGP5hbdsoVGtzi2sQVgpDNToTxLYeQvKoMPEm" -ON_BRIDGE_HUB_ROCOCO_SOVEREIGN_ACCOUNT_FOR_LANE_00000002_bhwd_BridgedChain="5EHnXaT5BhiSGP5hbdt5EJSapXYbxEv678jyWHEUskCXcjqo" -ON_BRIDGE_HUB_WESTEND_SOVEREIGN_ACCOUNT_FOR_LANE_00000002_bhro_ThisChain="5EHnXaT5BhiSGP5h9Rg8sgUJqoLym3iEaWUiboT8S9AT5xFh" -ON_BRIDGE_HUB_WESTEND_SOVEREIGN_ACCOUNT_FOR_LANE_00000002_bhro_BridgedChain="5EHnXaT5BhiSGP5h9RgQci1txJ2BDbp7KBRE9k8xty3BMUSi" +# // SS58=42 +# println!( +# "ON_BRIDGE_HUB_WESTEND_SOVEREIGN_ACCOUNT_FOR_LANE_00000002_bhro_ThisChain=\"{}\"", +# frame_support::sp_runtime::AccountId32::new( +# PayRewardFromAccount::<[u8; 32], [u8; 32], LegacyLaneId>::rewards_account(RewardsAccountParams::new( +# LegacyLaneId([0, 0, 0, 2]), +# *b"bhro", +# RewardsAccountOwner::ThisChain +# )) +# ) +# .to_ss58check_with_version(42_u16.into()) +# ); +# // SS58=42 +# println!( +# "ON_BRIDGE_HUB_WESTEND_SOVEREIGN_ACCOUNT_FOR_LANE_00000002_bhro_BridgedChain=\"{}\"", +# frame_support::sp_runtime::AccountId32::new( +# PayRewardFromAccount::<[u8; 32], [u8; 32], LegacyLaneId>::rewards_account(RewardsAccountParams::new( +# LegacyLaneId([0, 0, 0, 2]), +# *b"bhro", +# RewardsAccountOwner::BridgedChain +# )) +# ) +# .to_ss58check_with_version(42_u16.into()) +# ); +#} +ON_BRIDGE_HUB_ROCOCO_SOVEREIGN_ACCOUNT_FOR_LANE_00000002_bhwd_ThisChain="5EHnXaT5GApse1euZWj9hycMbgjKBCNQL9WEwScL8QDx6mhK" +ON_BRIDGE_HUB_ROCOCO_SOVEREIGN_ACCOUNT_FOR_LANE_00000002_bhwd_BridgedChain="5EHnXaT5Tnt4A8aiP9CsuAFRhKPjKZJXRrj4a3mtihFvKpTi" +ON_BRIDGE_HUB_WESTEND_SOVEREIGN_ACCOUNT_FOR_LANE_00000002_bhro_ThisChain="5EHnXaT5GApry9tS6yd1FVusPq8o8bQJGCKyvXTFCoEKk5Z9" +ON_BRIDGE_HUB_WESTEND_SOVEREIGN_ACCOUNT_FOR_LANE_00000002_bhro_BridgedChain="5EHnXaT5Tnt3VGpEvc6jSgYwVToDGxLRMuYoZ8coo6GHyWbR" LANE_ID="00000002" XCM_VERSION=3 diff --git a/cumulus/parachains/integration-tests/emulated/common/src/impls.rs b/cumulus/parachains/integration-tests/emulated/common/src/impls.rs index 559a16379bb4..c0d42cf2758e 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/impls.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/impls.rs @@ -61,10 +61,10 @@ pub use xcm_emulator::{ // Bridges use bp_messages::{ target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch}, - LaneId, MessageKey, OutboundLaneData, + MessageKey, OutboundLaneData, }; pub use bp_xcm_bridge_hub::XcmBridgeHubCall; -use pallet_bridge_messages::{Config as BridgeMessagesConfig, OutboundLanes, Pallet}; +use pallet_bridge_messages::{Config as BridgeMessagesConfig, LaneIdOf, OutboundLanes, Pallet}; pub use pallet_bridge_messages::{ Instance1 as BridgeMessagesInstance1, Instance2 as BridgeMessagesInstance2, Instance3 as BridgeMessagesInstance3, @@ -75,14 +75,14 @@ pub struct BridgeHubMessageHandler { _marker: std::marker::PhantomData<(S, SI, T, TI)>, } -struct LaneIdWrapper(LaneId); -impl From for BridgeLaneId { - fn from(lane_id: LaneIdWrapper) -> BridgeLaneId { +struct LaneIdWrapper(LaneId); +impl From> for BridgeLaneId { + fn from(lane_id: LaneIdWrapper) -> BridgeLaneId { lane_id.0.encode() } } -impl From for LaneIdWrapper { - fn from(id: BridgeLaneId) -> LaneIdWrapper { +impl From for LaneIdWrapper { + fn from(id: BridgeLaneId) -> LaneIdWrapper { LaneIdWrapper(LaneId::decode(&mut &id[..]).expect("decodable")) } } @@ -154,7 +154,7 @@ where } fn notify_source_message_delivery(lane_id: BridgeLaneId) { - let lane_id = LaneIdWrapper::from(lane_id).0; + let lane_id: LaneIdOf = LaneIdWrapper::from(lane_id).0; let data = OutboundLanes::::get(lane_id).unwrap(); let new_data = OutboundLaneData { oldest_unpruned_nonce: data.oldest_unpruned_nonce + 1, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs index 9e84317f42d4..29a0111d2a87 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs @@ -145,6 +145,7 @@ fn change_required_stake_by_governance_works() { mod bridge_hub_westend_tests { use super::*; + use bp_messages::LegacyLaneId; use bridge_common_config::{ BridgeGrandpaWestendInstance, BridgeParachainWestendInstance, DeliveryRewardInBalance, RelayersForLegacyLaneIdsMessagesInstance, @@ -340,7 +341,16 @@ mod bridge_hub_westend_tests { XcmOverBridgeHubWestendInstance, LocationToAccountId, TokenLocation, - >(SiblingParachainLocation::get(), BridgedUniversalLocation::get()).1 + >( + SiblingParachainLocation::get(), + BridgedUniversalLocation::get(), + |locations, fee| { + bridge_hub_test_utils::open_bridge_with_storage::< + Runtime, + XcmOverBridgeHubWestendInstance + >(locations, fee, LegacyLaneId([0, 0, 0, 1])) + } + ).1 }, ) } @@ -395,7 +405,16 @@ mod bridge_hub_westend_tests { XcmOverBridgeHubWestendInstance, LocationToAccountId, TokenLocation, - >(SiblingParachainLocation::get(), BridgedUniversalLocation::get()) + >( + SiblingParachainLocation::get(), + BridgedUniversalLocation::get(), + |locations, fee| { + bridge_hub_test_utils::open_bridge_with_storage::< + Runtime, + XcmOverBridgeHubWestendInstance, + >(locations, fee, LegacyLaneId([0, 0, 0, 1])) + }, + ) .1 }, construct_and_apply_extrinsic, @@ -419,7 +438,16 @@ mod bridge_hub_westend_tests { XcmOverBridgeHubWestendInstance, LocationToAccountId, TokenLocation, - >(SiblingParachainLocation::get(), BridgedUniversalLocation::get()) + >( + SiblingParachainLocation::get(), + BridgedUniversalLocation::get(), + |locations, fee| { + bridge_hub_test_utils::open_bridge_with_storage::< + Runtime, + XcmOverBridgeHubWestendInstance, + >(locations, fee, LegacyLaneId([0, 0, 0, 1])) + }, + ) .1 }, construct_and_apply_extrinsic, @@ -507,6 +535,7 @@ mod bridge_hub_westend_tests { mod bridge_hub_bulletin_tests { use super::*; + use bp_messages::LegacyLaneId; use bridge_common_config::BridgeGrandpaRococoBulletinInstance; use bridge_hub_rococo_runtime::bridge_common_config::RelayersForLegacyLaneIdsMessagesInstance; use bridge_hub_test_utils::test_cases::from_grandpa_chain; @@ -593,7 +622,16 @@ mod bridge_hub_bulletin_tests { XcmOverPolkadotBulletinInstance, LocationToAccountId, TokenLocation, - >(SiblingPeopleParachainLocation::get(), BridgedBulletinLocation::get()).1 + >( + SiblingPeopleParachainLocation::get(), + BridgedBulletinLocation::get(), + |locations, fee| { + bridge_hub_test_utils::open_bridge_with_storage::< + Runtime, + XcmOverPolkadotBulletinInstance + >(locations, fee, LegacyLaneId([0, 0, 0, 2])) + } + ).1 }, ) } @@ -647,7 +685,16 @@ mod bridge_hub_bulletin_tests { XcmOverPolkadotBulletinInstance, LocationToAccountId, TokenLocation, - >(SiblingPeopleParachainLocation::get(), BridgedBulletinLocation::get()) + >( + SiblingPeopleParachainLocation::get(), + BridgedBulletinLocation::get(), + |locations, fee| { + bridge_hub_test_utils::open_bridge_with_storage::< + Runtime, + XcmOverPolkadotBulletinInstance, + >(locations, fee, LegacyLaneId([0, 0, 0, 2])) + }, + ) .1 }, construct_and_apply_extrinsic, @@ -670,7 +717,16 @@ mod bridge_hub_bulletin_tests { XcmOverPolkadotBulletinInstance, LocationToAccountId, TokenLocation, - >(SiblingPeopleParachainLocation::get(), BridgedBulletinLocation::get()) + >( + SiblingPeopleParachainLocation::get(), + BridgedBulletinLocation::get(), + |locations, fee| { + bridge_hub_test_utils::open_bridge_with_storage::< + Runtime, + XcmOverPolkadotBulletinInstance, + >(locations, fee, LegacyLaneId([0, 0, 0, 2])) + }, + ) .1 }, construct_and_apply_extrinsic, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs index 55f2d7869bf6..0432fb60813b 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs @@ -16,6 +16,7 @@ #![cfg(test)] +use bp_messages::LegacyLaneId; use bp_polkadot_core::Signature; use bridge_common_config::{ DeliveryRewardInBalance, RelayersForLegacyLaneIdsMessagesInstance, @@ -239,7 +240,15 @@ fn handle_export_message_from_system_parachain_add_to_outbound_queue_works() { XcmOverBridgeHubRococoInstance, LocationToAccountId, WestendLocation, - >(SiblingParachainLocation::get(), BridgedUniversalLocation::get()).1 + >( + SiblingParachainLocation::get(), + BridgedUniversalLocation::get(), + |locations, fee| { + bridge_hub_test_utils::open_bridge_with_storage::< + Runtime, XcmOverBridgeHubRococoInstance + >(locations, fee, LegacyLaneId([0, 0, 0, 1])) + } + ).1 }, ) } @@ -292,7 +301,12 @@ fn relayed_incoming_message_works() { XcmOverBridgeHubRococoInstance, LocationToAccountId, WestendLocation, - >(SiblingParachainLocation::get(), BridgedUniversalLocation::get()) + >(SiblingParachainLocation::get(), BridgedUniversalLocation::get(), |locations, fee| { + bridge_hub_test_utils::open_bridge_with_storage::< + Runtime, + XcmOverBridgeHubRococoInstance, + >(locations, fee, LegacyLaneId([0, 0, 0, 1])) + }) .1 }, construct_and_apply_extrinsic, @@ -316,7 +330,12 @@ fn free_relay_extrinsic_works() { XcmOverBridgeHubRococoInstance, LocationToAccountId, WestendLocation, - >(SiblingParachainLocation::get(), BridgedUniversalLocation::get()) + >(SiblingParachainLocation::get(), BridgedUniversalLocation::get(), |locations, fee| { + bridge_hub_test_utils::open_bridge_with_storage::< + Runtime, + XcmOverBridgeHubRococoInstance, + >(locations, fee, LegacyLaneId([0, 0, 0, 1])) + }) .1 }, construct_and_apply_extrinsic, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml index 8c048a0d2dbd..009a65522f32 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml @@ -37,6 +37,7 @@ parachains-runtimes-test-utils = { workspace = true } xcm = { workspace = true } xcm-builder = { workspace = true } xcm-executor = { workspace = true } +pallet-xcm = { workspace = true } # Bridges bp-header-chain = { workspace = true } diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/lib.rs index b8d6d87051c7..bc28df0eb829 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/lib.rs @@ -24,7 +24,9 @@ extern crate alloc; pub use bp_test_utils::test_header; pub use parachains_runtimes_test_utils::*; use sp_runtime::Perbill; -pub use test_cases::helpers::ensure_opened_bridge; +pub use test_cases::helpers::{ + ensure_opened_bridge, open_bridge_with_extrinsic, open_bridge_with_storage, +}; /// A helper function for comparing the actual value of a fee constant with its estimated value. The /// estimated value can be overestimated (`overestimate_in_percent`), and if the difference to the diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs index 4605b7cf9b22..aac60bba0b53 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs @@ -390,7 +390,12 @@ fn execute_and_verify_calls( /// Helper function to open the bridge/lane for `source` and `destination` while ensuring all /// required balances are placed into the SA of the source. -pub fn ensure_opened_bridge(source: Location, destination: InteriorLocation) -> (BridgeLocations, pallet_xcm_bridge_hub::LaneIdOf) +pub fn ensure_opened_bridge< + Runtime, + XcmOverBridgePalletInstance, + LocationToAccountId, + TokenLocation> +(source: Location, destination: InteriorLocation, bridge_opener: impl Fn(BridgeLocations, Asset)) -> (BridgeLocations, pallet_xcm_bridge_hub::LaneIdOf) where Runtime: BasicParachainRuntime + BridgeXcmOverBridgeConfig, XcmOverBridgePalletInstance: 'static, @@ -427,34 +432,74 @@ TokenLocation: Get{ let _ = >::mint_into(&source_account_id, balance_needed) .expect("mint_into passes"); + // call the bridge opener + bridge_opener(*locations.clone(), buy_execution_fee); + + // check opened bridge + let bridge = pallet_xcm_bridge_hub::Bridges::::get( + locations.bridge_id(), + ) + .expect("opened bridge"); + + // check state + assert_ok!( + pallet_xcm_bridge_hub::Pallet::::do_try_state() + ); + + // return locations + (*locations, bridge.lane_id) +} + +/// Utility for opening bridge with dedicated `pallet_xcm_bridge_hub`'s extrinsic. +pub fn open_bridge_with_extrinsic( + locations: BridgeLocations, + buy_execution_fee: Asset, +) where + Runtime: frame_system::Config + + pallet_xcm_bridge_hub::Config + + cumulus_pallet_parachain_system::Config + + pallet_xcm::Config, + XcmOverBridgePalletInstance: 'static, + ::RuntimeCall: + GetDispatchInfo + From>, +{ // open bridge with `Transact` call let open_bridge_call = RuntimeCallOf::::from(BridgeXcmOverBridgeCall::< Runtime, XcmOverBridgePalletInstance, >::open_bridge { - bridge_destination_universal_location: Box::new(destination.into()), + bridge_destination_universal_location: Box::new( + locations.bridge_destination_universal_location().clone().into(), + ), }); // execute XCM as source origin would do with `Transact -> Origin::Xcm` assert_ok!(RuntimeHelper::::execute_as_origin_xcm( + locations.bridge_origin_relative_location().clone(), open_bridge_call, - source.clone(), buy_execution_fee ) .ensure_complete()); +} - let bridge = pallet_xcm_bridge_hub::Bridges::::get( - locations.bridge_id(), - ) - .expect("opened bridge"); - - // check state +/// Utility for opening bridge directly inserting data to the storage (used only for legacy +/// purposes). +pub fn open_bridge_with_storage( + locations: BridgeLocations, + _buy_execution_fee: Asset, + lane_id: pallet_xcm_bridge_hub::LaneIdOf, +) where + Runtime: pallet_xcm_bridge_hub::Config, + XcmOverBridgePalletInstance: 'static, +{ + // insert bridge data directly to the storage assert_ok!( - pallet_xcm_bridge_hub::Pallet::::do_try_state() + pallet_xcm_bridge_hub::Pallet::::do_open_bridge( + Box::new(locations), + lane_id, + true + ) ); - - // return locations - (*locations, bridge.lane_id) } /// Helper function to close the bridge/lane for `source` and `destination`. @@ -506,8 +551,8 @@ TokenLocation: Get{ // execute XCM as source origin would do with `Transact -> Origin::Xcm` assert_ok!(RuntimeHelper::::execute_as_origin_xcm( - close_bridge_call, source.clone(), + close_bridge_call, buy_execution_fee ) .ensure_complete()); diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs index 4b15db929dee..663558f5fd5c 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs @@ -77,6 +77,7 @@ pub type RuntimeHelper = parachains_runtimes_test_utils::RuntimeHelper; // Re-export test_case from `parachains-runtimes-test-utils` +use crate::test_cases::helpers::open_bridge_with_extrinsic; pub use parachains_runtimes_test_utils::test_cases::{ change_storage_constant_by_governance_works, set_storage_keys_by_governance_works, }; @@ -715,7 +716,11 @@ pub fn open_and_close_bridge_works(source.clone(), destination.clone()) + >( + source.clone(), + destination.clone(), + open_bridge_with_extrinsic:: + ) .0 .bridge_id(), locations.bridge_id() diff --git a/cumulus/parachains/runtimes/test-utils/src/lib.rs b/cumulus/parachains/runtimes/test-utils/src/lib.rs index fe75b2b6e72f..3b38eee244f1 100644 --- a/cumulus/parachains/runtimes/test-utils/src/lib.rs +++ b/cumulus/parachains/runtimes/test-utils/src/lib.rs @@ -465,8 +465,8 @@ impl< } pub fn execute_as_origin_xcm( - call: Call, origin: Location, + call: Call, buy_execution_fee: Asset, ) -> Outcome { // prepare `Transact` xcm diff --git a/cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs b/cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs index 16bbca416579..bdfbe7f4a6c9 100644 --- a/cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs +++ b/cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs @@ -15,13 +15,12 @@ // along with Cumulus. If not, see . use crate::chain_spec::{get_account_id_from_seed, get_collator_keys_from_seed}; -use bp_messages::LaneId; +use bp_messages::LegacyLaneId; use cumulus_primitives_core::ParaId; use parachains_common::Balance as BridgeHubBalance; use polkadot_parachain_lib::chain_spec::GenericChainSpec; use sc_chain_spec::ChainSpec; use sp_core::sr25519; -use sp_runtime::Either; use std::str::FromStr; use xcm::latest::prelude::*; @@ -88,7 +87,7 @@ impl BridgeHubRuntimeType { vec![( Location::new(1, [Parachain(1000)]), Junctions::from([Rococo.into(), Parachain(1000)]), - Some(LaneId::from_inner(Either::Right([0, 0, 0, 2]))), + Some(LegacyLaneId([0, 0, 0, 2])), )], ))), BridgeHubRuntimeType::WestendDevelopment => Ok(Box::new(westend::local_config( @@ -111,7 +110,7 @@ impl BridgeHubRuntimeType { vec![( Location::new(1, [Parachain(1000)]), Junctions::from([Westend.into(), Parachain(1000)]), - Some(LaneId::from_inner(Either::Right([0, 0, 0, 2]))), + Some(LegacyLaneId([0, 0, 0, 2])), )], |_| (), ))), @@ -162,7 +161,7 @@ pub mod rococo { relay_chain: &str, para_id: ParaId, bridges_pallet_owner_seed: Option, - opened_bridges: Vec<(Location, InteriorLocation, Option)>, + opened_bridges: Vec<(Location, InteriorLocation, Option)>, modify_props: ModifyProperties, ) -> GenericChainSpec { // Rococo defaults @@ -221,7 +220,7 @@ pub mod rococo { endowed_accounts: Vec, id: ParaId, bridges_pallet_owner: Option, - opened_bridges: Vec<(Location, InteriorLocation, Option)>, + opened_bridges: Vec<(Location, InteriorLocation, Option)>, ) -> serde_json::Value { serde_json::json!({ "balances": { @@ -292,7 +291,7 @@ pub mod westend { relay_chain: &str, para_id: ParaId, bridges_pallet_owner_seed: Option, - opened_bridges: Vec<(Location, InteriorLocation, Option)>, + opened_bridges: Vec<(Location, InteriorLocation, Option)>, ) -> GenericChainSpec { let mut properties = sc_chain_spec::Properties::new(); properties.insert("tokenSymbol".into(), "WND".into()); @@ -347,7 +346,7 @@ pub mod westend { endowed_accounts: Vec, id: ParaId, bridges_pallet_owner: Option, - opened_bridges: Vec<(Location, InteriorLocation, Option)>, + opened_bridges: Vec<(Location, InteriorLocation, Option)>, ) -> serde_json::Value { serde_json::json!({ "balances": { From bebaba15c7112ecfd43696a717f3b4ae5894e54f Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Fri, 20 Sep 2024 09:56:06 +0200 Subject: [PATCH 19/38] Testing nits --- bridges/modules/relayers/src/benchmarking.rs | 2 +- bridges/modules/relayers/src/extension/mod.rs | 2 +- bridges/modules/relayers/src/migration.rs | 2 +- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 17 +++++++++++------ .../bridge-hubs/bridge-hub-westend/src/lib.rs | 17 +++++++++++------ .../bridges_zombienet_tests_injected.Dockerfile | 2 +- 6 files changed, 26 insertions(+), 16 deletions(-) diff --git a/bridges/modules/relayers/src/benchmarking.rs b/bridges/modules/relayers/src/benchmarking.rs index 17f1bd826581..8fe3fc11d6ae 100644 --- a/bridges/modules/relayers/src/benchmarking.rs +++ b/bridges/modules/relayers/src/benchmarking.rs @@ -32,7 +32,7 @@ const REWARD_AMOUNT: u32 = u32::MAX; pub struct Pallet, I: 'static = ()>(crate::Pallet); /// Trait that must be implemented by runtime. -pub trait Config: crate::Config { +pub trait Config: crate::Config { /// Lane id to use in benchmarks. fn bench_lane_id() -> Self::LaneId { Self::LaneId::default() diff --git a/bridges/modules/relayers/src/extension/mod.rs b/bridges/modules/relayers/src/extension/mod.rs index 8f9b7e567776..06390d37e89f 100644 --- a/bridges/modules/relayers/src/extension/mod.rs +++ b/bridges/modules/relayers/src/extension/mod.rs @@ -377,7 +377,7 @@ where let lane_id = pre .as_ref() .and_then(|p| p.as_ref()) - .map(|p| p.call_info.messages_call_info().lane_id().clone()); + .map(|p| p.call_info.messages_call_info().lane_id()); let call_result = Self::analyze_call_result(pre, info, post_info, len, result); match call_result { diff --git a/bridges/modules/relayers/src/migration.rs b/bridges/modules/relayers/src/migration.rs index 7c995ed65e10..12f1234ee6ce 100644 --- a/bridges/modules/relayers/src/migration.rs +++ b/bridges/modules/relayers/src/migration.rs @@ -147,7 +147,7 @@ pub mod v1 { // re-register rewards with new format of `RewardsAccountParams`. for (key1, key2, reward) in rewards_to_migrate { // expand old key - let v0::RewardsAccountParams { owner, lane_id, bridged_chain_id } = key2.clone(); + let v0::RewardsAccountParams { owner, lane_id, bridged_chain_id } = key2; // re-register reward Pallet::::register_relayer_reward( diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index a1de3d4ecccc..435fdb6653bb 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -1242,15 +1242,20 @@ impl_runtime_apis! { ); // open bridge - let origin = RuntimeOrigin::from(pallet_xcm::Origin::Xcm(sibling_parachain_location.clone())); - XcmOverBridgeHubWestend::open_bridge( - origin.clone(), - Box::new(VersionedInteriorLocation::from([GlobalConsensus(NetworkId::Westend), Parachain(8765)])), + let bridge_destination_universal_location: InteriorLocation = [GlobalConsensus(NetworkId::Westend), Parachain(8765)].into(); + let locations = XcmOverBridgeHubWestend::bridge_locations( + sibling_parachain_location.clone(), + bridge_destination_universal_location.clone(), + )?; + XcmOverBridgeHubWestend::do_open_bridge( + locations, + bp_messages::LegacyLaneId([1, 2, 3, 4]), + true, ).map_err(|e| { log::error!( "Failed to `XcmOverBridgeHubWestend::open_bridge`({:?}, {:?})`, error: {:?}", - origin, - [GlobalConsensus(NetworkId::Westend), Parachain(8765)], + sibling_parachain_location, + bridge_destination_universal_location, e ); BenchmarkError::Stop("Bridge was not opened!") diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 2643ecd0dc6e..15060da28a27 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -1135,15 +1135,20 @@ impl_runtime_apis! { ); // open bridge - let origin = RuntimeOrigin::from(pallet_xcm::Origin::Xcm(sibling_parachain_location.clone())); - XcmOverBridgeHubRococo::open_bridge( - origin.clone(), - alloc::boxed::Box::new(VersionedInteriorLocation::from([GlobalConsensus(NetworkId::Rococo), Parachain(8765)])), + let bridge_destination_universal_location: InteriorLocation = [GlobalConsensus(NetworkId::Rococo), Parachain(8765)].into(); + let locations = XcmOverBridgeHubRococo::bridge_locations( + sibling_parachain_location.clone(), + bridge_destination_universal_location.clone(), + )?; + XcmOverBridgeHubRococo::do_open_bridge( + locations, + bp_messages::LegacyLaneId([1, 2, 3, 4]), + true, ).map_err(|e| { log::error!( "Failed to `XcmOverBridgeHubRococo::open_bridge`({:?}, {:?})`, error: {:?}", - origin, - [GlobalConsensus(NetworkId::Rococo), Parachain(8765)], + sibling_parachain_location, + bridge_destination_universal_location, e ); BenchmarkError::Stop("Bridge was not opened!") diff --git a/docker/dockerfiles/bridges_zombienet_tests_injected.Dockerfile b/docker/dockerfiles/bridges_zombienet_tests_injected.Dockerfile index 55b9156e6a0a..2198da13a4b7 100644 --- a/docker/dockerfiles/bridges_zombienet_tests_injected.Dockerfile +++ b/docker/dockerfiles/bridges_zombienet_tests_injected.Dockerfile @@ -1,7 +1,7 @@ # this image is built on top of existing Zombienet image ARG ZOMBIENET_IMAGE # this image uses substrate-relay image built elsewhere -ARG SUBSTRATE_RELAY_IMAGE=docker.io/paritytech/substrate-relay:v1.6.8 +ARG SUBSTRATE_RELAY_IMAGE=docker.io/paritytech/substrate-relay:v1.6.10 # metadata ARG VCS_REF From ded26ef78f6003e7482cecd3cda0f203faa67f33 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Fri, 20 Sep 2024 10:24:16 +0200 Subject: [PATCH 20/38] zepter+taplo --- bridges/relays/messages/Cargo.toml | 2 +- cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/bridges/relays/messages/Cargo.toml b/bridges/relays/messages/Cargo.toml index 5e71851f7385..f9df73507c75 100644 --- a/bridges/relays/messages/Cargo.toml +++ b/bridges/relays/messages/Cargo.toml @@ -28,4 +28,4 @@ relay-utils = { workspace = true } sp-arithmetic = { workspace = true, default-features = true } [dev-dependencies] -sp-core = { workspace = true } \ No newline at end of file +sp-core = { workspace = true } diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml index 009a65522f32..915b3090092f 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/Cargo.toml @@ -82,6 +82,7 @@ std = [ "pallet-timestamp/std", "pallet-utility/std", "pallet-xcm-bridge-hub/std", + "pallet-xcm/std", "parachains-common/std", "parachains-runtimes-test-utils/std", "sp-core/std", From 8de9f0ce5a759913fe0b7f6bcff802f010d712db Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Fri, 20 Sep 2024 12:02:20 +0200 Subject: [PATCH 21/38] prdoc draft --- prdoc/pr_5649.prdoc | 47 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 prdoc/pr_5649.prdoc diff --git a/prdoc/pr_5649.prdoc b/prdoc/pr_5649.prdoc new file mode 100644 index 000000000000..a7ada9dc1d94 --- /dev/null +++ b/prdoc/pr_5649.prdoc @@ -0,0 +1,47 @@ +title: "Bridges lane id agnostic for backwards compatibility" + +doc: +- audience: Runtime Dev + description: | + This PR improves support for handling `LaneId` backwards compatibility with the previously merged [PR](https://github.com/paritytech/polkadot-sdk/pull/4949). + If `pallet_bridge_messages` or `pallet_bridge_relayers` used `LaneId([u8; 4])` previously, they should now set `type LaneId = LegacyLaneId;`. + +crates: +- name: bridge-runtime-common + bump: major +- name: bp-runtime + bump: minor +- name: staging-xcm-executor + bump: none +- name: parachains-runtimes-test-utils + bump: major +- name: bp-messages + bump: major +- name: bp-relayers + bump: major +- name: bp-xcm-bridge-hub + bump: major +- name: pallet-bridge-messages + bump: minor +- name: pallet-bridge-relayers + bump: major +- name: pallet-xcm-bridge-hub + bump: major +- name: emulated-integration-tests-common + bump: patch +- name: bp-bridge-hub-kusama + bump: patch +- name: bp-bridge-hub-polkadot + bump: patch +- name: bp-bridge-hub-rococo + bump: patch +- name: bp-bridge-hub-westend + bump: patch +- name: bp-polkadot-bulletin + bump: patch +- name: bridge-hub-rococo-runtime + bump: patch +- name: bridge-hub-westend-runtime + bump: patch +- name: polkadot-parachain-bin + bump: patch From 9d74ecb5665afe8fc02aec63e30a256cdeeaf90a Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Fri, 20 Sep 2024 13:14:38 +0200 Subject: [PATCH 22/38] prdoc --- prdoc/pr_5649.prdoc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/prdoc/pr_5649.prdoc b/prdoc/pr_5649.prdoc index a7ada9dc1d94..67ce882b3a13 100644 --- a/prdoc/pr_5649.prdoc +++ b/prdoc/pr_5649.prdoc @@ -8,23 +8,23 @@ doc: crates: - name: bridge-runtime-common - bump: major + bump: patch - name: bp-runtime - bump: minor + bump: patch - name: staging-xcm-executor bump: none - name: parachains-runtimes-test-utils - bump: major + bump: patch - name: bp-messages bump: major - name: bp-relayers bump: major - name: bp-xcm-bridge-hub - bump: major + bump: patch - name: pallet-bridge-messages - bump: minor + bump: patch - name: pallet-bridge-relayers - bump: major + bump: patch - name: pallet-xcm-bridge-hub bump: major - name: emulated-integration-tests-common @@ -45,3 +45,5 @@ crates: bump: patch - name: polkadot-parachain-bin bump: patch +- name: bridge-hub-test-utils + bump: patch From 69357e63d866ea4e8615ba6d3b846bb2403261c0 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Fri, 20 Sep 2024 13:53:40 +0200 Subject: [PATCH 23/38] Deduplicate functionality --- bridges/modules/xcm-bridge-hub/src/lib.rs | 36 +++-------------------- 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 31b658a4305b..1ce10f2935c9 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -753,43 +753,15 @@ pub mod pallet { bridge_destination_universal_location.clone().into(), ) .expect("Invalid genesis configuration"); + let lane_id = match maybe_lane_id { - Some(lane_id) => lane_id.clone(), + Some(lane_id) => *lane_id, None => locations.calculate_lane_id(xcm::latest::VERSION).expect("Valid locations"), }; - let bridge_owner_account = T::BridgeOriginAccountIdConverter::convert_location( - locations.bridge_origin_relative_location(), - ) - .expect("Invalid genesis configuration"); - - Bridges::::insert( - locations.bridge_id(), - Bridge { - bridge_origin_relative_location: Box::new( - locations.bridge_origin_relative_location().clone().into(), - ), - bridge_origin_universal_location: Box::new( - locations.bridge_origin_universal_location().clone().into(), - ), - bridge_destination_universal_location: Box::new( - locations.bridge_destination_universal_location().clone().into(), - ), - state: BridgeState::Opened, - bridge_owner_account, - deposit: Zero::zero(), - lane_id, - }, - ); - LaneToBridge::::insert(lane_id, locations.bridge_id()); - let lanes_manager = LanesManagerOf::::new(); - lanes_manager - .create_inbound_lane(lane_id) - .expect("Invalid genesis configuration"); - lanes_manager - .create_outbound_lane(lane_id) - .expect("Invalid genesis configuration"); + Pallet::::do_open_bridge(locations, lane_id, true) + .expect("Valid opened bridge!"); } } } From ba33d241e9296711fa7992bb080f8b804317e89c Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Sun, 22 Sep 2024 20:39:28 +0200 Subject: [PATCH 24/38] Fix for zombienet-bridges-0001-asset-transfer-works --- .../chains/chain-polkadot-bulletin/src/lib.rs | 2 +- bridges/primitives/messages/src/lib.rs | 18 +++++++++--------- bridges/primitives/runtime/src/chain.rs | 6 +++--- bridges/relays/client-substrate/src/chain.rs | 3 --- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 8 ++++---- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 4 ++-- 6 files changed, 19 insertions(+), 22 deletions(-) diff --git a/bridges/chains/chain-polkadot-bulletin/src/lib.rs b/bridges/chains/chain-polkadot-bulletin/src/lib.rs index 18cc0462109d..df1dad0cc4c2 100644 --- a/bridges/chains/chain-polkadot-bulletin/src/lib.rs +++ b/bridges/chains/chain-polkadot-bulletin/src/lib.rs @@ -228,4 +228,4 @@ impl ChainWithMessages for PolkadotBulletin { } decl_bridge_finality_runtime_apis!(polkadot_bulletin, grandpa); -decl_bridge_messages_runtime_apis!(polkadot_bulletin, LegacyLaneId); +decl_bridge_messages_runtime_apis!(polkadot_bulletin, bp_messages::LegacyLaneId); diff --git a/bridges/primitives/messages/src/lib.rs b/bridges/primitives/messages/src/lib.rs index a6cc7c88f8a9..2776b806cc16 100644 --- a/bridges/primitives/messages/src/lib.rs +++ b/bridges/primitives/messages/src/lib.rs @@ -200,11 +200,6 @@ pub struct Message { /// Inbound lane data. #[derive(Encode, Decode, Clone, RuntimeDebug, PartialEq, Eq, TypeInfo)] pub struct InboundLaneData { - /// Inbound lane state. - /// - /// If state is `Closed`, then all attempts to deliver messages to this end will fail. - pub state: LaneState, - /// Identifiers of relayers and messages that they have delivered to this lane (ordered by /// message nonce). /// @@ -233,6 +228,11 @@ pub struct InboundLaneData { /// This value is updated indirectly when an `OutboundLane` state of the source /// chain is received alongside with new messages delivery. pub last_confirmed_nonce: MessageNonce, + + /// Inbound lane state. + /// + /// If state is `Closed`, then all attempts to deliver messages to this end will fail. + pub state: LaneState, } impl Default for InboundLaneData { @@ -449,10 +449,6 @@ impl From<&InboundLaneData> for UnrewardedRelayersState { /// Outbound lane data. #[derive(Encode, Decode, Clone, RuntimeDebug, PartialEq, Eq, TypeInfo, MaxEncodedLen)] pub struct OutboundLaneData { - /// Lane state. - /// - /// If state is `Closed`, then all attempts to send messages messages at this end will fail. - pub state: LaneState, /// Nonce of the oldest message that we haven't yet pruned. May point to not-yet-generated /// message if all sent messages are already pruned. pub oldest_unpruned_nonce: MessageNonce, @@ -460,6 +456,10 @@ pub struct OutboundLaneData { pub latest_received_nonce: MessageNonce, /// Nonce of the latest message, generated by us. pub latest_generated_nonce: MessageNonce, + /// Lane state. + /// + /// If state is `Closed`, then all attempts to send messages at this end will fail. + pub state: LaneState, } impl OutboundLaneData { diff --git a/bridges/primitives/runtime/src/chain.rs b/bridges/primitives/runtime/src/chain.rs index 52933263c991..eba3bcadfead 100644 --- a/bridges/primitives/runtime/src/chain.rs +++ b/bridges/primitives/runtime/src/chain.rs @@ -381,7 +381,7 @@ pub mod __private { /// The name of the chain has to be specified in snake case (e.g. `bridge_hub_polkadot`). #[macro_export] macro_rules! decl_bridge_messages_runtime_apis { - ($chain: ident, $lane_id_type:ident) => { + ($chain: ident, $lane_id_type:ty) => { bp_runtime::paste::item! { mod [<$chain _messages_api>] { use super::*; @@ -399,7 +399,7 @@ macro_rules! decl_bridge_messages_runtime_apis { /// /// This API is implemented by runtimes that are receiving messages from this chain, not by this /// chain's runtime itself. - pub trait []<$lane_id_type> where $lane_id_type: $crate::__private::codec::Encode { + pub trait [] { /// Returns dispatch weight, encoded payload size and delivery+dispatch fee of all /// messages in given inclusive range. /// @@ -419,7 +419,7 @@ macro_rules! decl_bridge_messages_runtime_apis { /// /// Entries of the resulting vector are matching entries of the `messages` vector. Entries of the /// `messages` vector may (and need to) be read using `ToOutboundLaneApi::message_details`. - pub trait []<$lane_id_type> where $lane_id_type: $crate::__private::codec::Encode { + pub trait [] { /// Return details of given inbound messages. fn message_details( lane: $lane_id_type, diff --git a/bridges/relays/client-substrate/src/chain.rs b/bridges/relays/client-substrate/src/chain.rs index 227e9c31c5bf..9856f0d0237e 100644 --- a/bridges/relays/client-substrate/src/chain.rs +++ b/bridges/relays/client-substrate/src/chain.rs @@ -113,9 +113,6 @@ impl Parachain for T where T: UnderlyingChainProvider + Chain + ParachainBase /// Substrate-based chain with messaging support from minimal relay-client point of view. pub trait ChainWithMessages: Chain + ChainWithMessagesBase { - // TODO (https://github.com/paritytech/parity-bridges-common/issues/1692): check all the names - // after the issue is fixed - all names must be changed - /// Name of the bridge relayers pallet (used in `construct_runtime` macro call) that is deployed /// at some other chain to bridge with this `ChainWithMessages`. /// diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 435fdb6653bb..8c188a7551a1 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -906,7 +906,7 @@ impl_runtime_apis! { } // This is exposed by BridgeHubRococo - impl bp_bridge_hub_westend::FromBridgeHubWestendInboundLaneApi> for Runtime { + impl bp_bridge_hub_westend::FromBridgeHubWestendInboundLaneApi for Runtime { fn message_details( lane: LaneIdOf, messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>, @@ -919,7 +919,7 @@ impl_runtime_apis! { } // This is exposed by BridgeHubRococo - impl bp_bridge_hub_westend::ToBridgeHubWestendOutboundLaneApi> for Runtime { + impl bp_bridge_hub_westend::ToBridgeHubWestendOutboundLaneApi for Runtime { fn message_details( lane: LaneIdOf, begin: bp_messages::MessageNonce, @@ -949,7 +949,7 @@ impl_runtime_apis! { } } - impl bp_polkadot_bulletin::FromPolkadotBulletinInboundLaneApi> for Runtime { + impl bp_polkadot_bulletin::FromPolkadotBulletinInboundLaneApi for Runtime { fn message_details( lane: LaneIdOf, messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>, @@ -961,7 +961,7 @@ impl_runtime_apis! { } } - impl bp_polkadot_bulletin::ToPolkadotBulletinOutboundLaneApi> for Runtime { + impl bp_polkadot_bulletin::ToPolkadotBulletinOutboundLaneApi for Runtime { fn message_details( lane: LaneIdOf, begin: bp_messages::MessageNonce, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 15060da28a27..6176c651bb31 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -843,7 +843,7 @@ impl_runtime_apis! { } } - impl bp_bridge_hub_rococo::FromBridgeHubRococoInboundLaneApi> for Runtime { + impl bp_bridge_hub_rococo::FromBridgeHubRococoInboundLaneApi for Runtime { fn message_details( lane: LaneIdOf, messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>, @@ -855,7 +855,7 @@ impl_runtime_apis! { } } - impl bp_bridge_hub_rococo::ToBridgeHubRococoOutboundLaneApi> for Runtime { + impl bp_bridge_hub_rococo::ToBridgeHubRococoOutboundLaneApi for Runtime { fn message_details( lane: LaneIdOf, begin: bp_messages::MessageNonce, From fad96d909796b30c33c023ba2d4f663aacb1af07 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Sun, 22 Sep 2024 21:59:30 +0200 Subject: [PATCH 25/38] clippy --- cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs b/cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs index 07d0d9311d3e..af399be9eacf 100644 --- a/cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs +++ b/cumulus/polkadot-parachain/src/chain_spec/bridge_hubs.rs @@ -18,7 +18,6 @@ use cumulus_primitives_core::ParaId; use polkadot_parachain_lib::chain_spec::GenericChainSpec; use sc_chain_spec::{ChainSpec, ChainType}; use std::str::FromStr; -use xcm::latest::prelude::*; /// Collects all supported BridgeHub configurations #[derive(Debug, PartialEq)] From 268a7a76d5d50732b36e0f5e0f176c76f7b402f7 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Sun, 22 Sep 2024 22:25:43 +0200 Subject: [PATCH 26/38] clippy --- bridges/modules/relayers/src/migration.rs | 4 +- .../bridge-hub-rococo/tests/tests.rs | 38 ------------------- .../bridge-hub-westend/tests/tests.rs | 19 ---------- 3 files changed, 2 insertions(+), 59 deletions(-) diff --git a/bridges/modules/relayers/src/migration.rs b/bridges/modules/relayers/src/migration.rs index 12f1234ee6ce..8bf473b300c2 100644 --- a/bridges/modules/relayers/src/migration.rs +++ b/bridges/modules/relayers/src/migration.rs @@ -178,7 +178,7 @@ pub mod v1 { rewards = rewards .try_mutate(|inner| { inner - .entry((key1.clone(), key2.lane_id.clone())) + .entry((key1.clone(), key2.lane_id)) .and_modify(|value| *value += reward) .or_insert(reward); }) @@ -212,7 +212,7 @@ pub mod v1 { rewards_after = rewards_after .try_mutate(|inner| { inner - .entry((key1.clone(), key2.lane_id().clone())) + .entry((key1.clone(), *key2.lane_id())) .and_modify(|value| *value += reward) .or_insert(reward); }) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs index 29a0111d2a87..830305883c21 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs @@ -512,25 +512,6 @@ mod bridge_hub_westend_tests { ), ) } - - #[test] - fn open_and_close_bridge_works() { - let origins = [SiblingParachainLocation::get(), SiblingSystemParachainLocation::get()]; - - for origin in origins { - bridge_hub_test_utils::test_cases::open_and_close_bridge_works::< - Runtime, - XcmOverBridgeHubWestendInstance, - LocationToAccountId, - TokenLocation, - >( - collator_session_keys(), - bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, - origin, - BridgedUniversalLocation::get(), - ) - } - } } mod bridge_hub_bulletin_tests { @@ -732,23 +713,4 @@ mod bridge_hub_bulletin_tests { construct_and_apply_extrinsic, ) } - - #[test] - fn open_and_close_bridge_works() { - let origins = [SiblingPeopleParachainLocation::get()]; - - for origin in origins { - bridge_hub_test_utils::test_cases::open_and_close_bridge_works::< - Runtime, - XcmOverPolkadotBulletinInstance, - LocationToAccountId, - TokenLocation, - >( - collator_session_keys(), - bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, - origin, - BridgedBulletinLocation::get(), - ) - } - } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs index 0432fb60813b..5c56459a54bc 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs @@ -400,22 +400,3 @@ pub fn can_calculate_fee_for_standalone_message_confirmation_transaction() { ), ) } - -#[test] -fn open_and_close_bridge_works() { - let origins = [SiblingParachainLocation::get(), SiblingSystemParachainLocation::get()]; - - for origin in origins { - bridge_hub_test_utils::test_cases::open_and_close_bridge_works::< - Runtime, - XcmOverBridgeHubRococoInstance, - LocationToAccountId, - WestendLocation, - >( - collator_session_keys(), - bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID, - origin, - BridgedUniversalLocation::get(), - ) - } -} From f89581f4ed422cf3f567b03edfc63f7039804d38 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Sun, 22 Sep 2024 23:21:51 +0200 Subject: [PATCH 27/38] Fix bridges integration tests - open AHR<>AHW lanes for genesis --- Cargo.lock | 4 ++++ .../bridges/bridge-hub-rococo/Cargo.toml | 6 +++++ .../bridges/bridge-hub-rococo/src/genesis.rs | 12 ++++++++++ .../bridges/bridge-hub-westend/Cargo.toml | 6 +++++ .../bridges/bridge-hub-westend/src/genesis.rs | 12 ++++++++++ .../bridge-hub-rococo/src/tests/mod.rs | 22 ------------------- .../bridge-hub-westend/src/tests/mod.rs | 22 ------------------- prdoc/pr_5649.prdoc | 4 ++-- 8 files changed, 42 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fbab6ef3dfd5..3689a7819964 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2188,12 +2188,14 @@ dependencies = [ name = "bridge-hub-rococo-emulated-chain" version = "0.0.0" dependencies = [ + "bp-messages", "bridge-hub-common", "bridge-hub-rococo-runtime", "emulated-integration-tests-common", "frame-support", "parachains-common", "sp-core 28.0.0", + "staging-xcm", "testnet-parachains-constants", ] @@ -2376,12 +2378,14 @@ dependencies = [ name = "bridge-hub-westend-emulated-chain" version = "0.0.0" dependencies = [ + "bp-messages", "bridge-hub-common", "bridge-hub-westend-runtime", "emulated-integration-tests-common", "frame-support", "parachains-common", "sp-core 28.0.0", + "staging-xcm", "testnet-parachains-constants", ] diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/Cargo.toml index f3c0799ad0f6..266d743ca0c2 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/Cargo.toml @@ -16,6 +16,12 @@ workspace = true sp-core = { workspace = true } frame-support = { workspace = true } +# Polkadot Dependencies +xcm = { workspace = true } + +# Bridge dependencies +bp-messages = { workspace = true } + # Cumulus parachains-common = { workspace = true, default-features = true } emulated-integration-tests-common = { workspace = true } diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/src/genesis.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/src/genesis.rs index 3786d529ea65..b9c0c01101c6 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/src/genesis.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/src/genesis.rs @@ -21,6 +21,7 @@ use emulated_integration_tests_common::{ accounts, build_genesis_storage, collators, get_account_id_from_seed, SAFE_XCM_VERSION, }; use parachains_common::Balance; +use xcm::latest::prelude::*; pub const ASSETHUB_PARA_ID: u32 = 1000; pub const PARA_ID: u32 = 1013; @@ -66,6 +67,17 @@ pub fn genesis() -> Storage { owner: Some(get_account_id_from_seed::(accounts::BOB)), ..Default::default() }, + xcm_over_bridge_hub_westend: bridge_hub_rococo_runtime::XcmOverBridgeHubWestendConfig { + opened_bridges: vec![ + // open AHR -> AHW bridge + ( + Location::new(1, [Parachain(1000)]), + Junctions::from([Westend.into(), Parachain(1000)]), + Some(bp_messages::LegacyLaneId([0, 0, 0, 2])), + ), + ], + ..Default::default() + }, ethereum_system: bridge_hub_rococo_runtime::EthereumSystemConfig { para_id: PARA_ID.into(), asset_hub_para_id: ASSETHUB_PARA_ID.into(), diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-westend/Cargo.toml b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-westend/Cargo.toml index ebcec9641e7d..88d7348f50f2 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-westend/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-westend/Cargo.toml @@ -16,6 +16,12 @@ workspace = true sp-core = { workspace = true } frame-support = { workspace = true } +# Polkadot Dependencies +xcm = { workspace = true } + +# Bridge dependencies +bp-messages = { workspace = true } + # Cumulus parachains-common = { workspace = true, default-features = true } emulated-integration-tests-common = { workspace = true } diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-westend/src/genesis.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-westend/src/genesis.rs index f38f385db650..3ffe3d86b2ac 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-westend/src/genesis.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-westend/src/genesis.rs @@ -21,6 +21,7 @@ use emulated_integration_tests_common::{ accounts, build_genesis_storage, collators, get_account_id_from_seed, SAFE_XCM_VERSION, }; use parachains_common::Balance; +use xcm::latest::prelude::*; pub const PARA_ID: u32 = 1002; pub const ASSETHUB_PARA_ID: u32 = 1000; @@ -66,6 +67,17 @@ pub fn genesis() -> Storage { owner: Some(get_account_id_from_seed::(accounts::BOB)), ..Default::default() }, + xcm_over_bridge_hub_rococo: bridge_hub_westend_runtime::XcmOverBridgeHubRococoConfig { + opened_bridges: vec![ + // open AHW -> AHR bridge + ( + Location::new(1, [Parachain(1000)]), + Junctions::from([Rococo.into(), Parachain(1000)]), + Some(bp_messages::LegacyLaneId([0, 0, 0, 2])), + ), + ], + ..Default::default() + }, ethereum_system: bridge_hub_westend_runtime::EthereumSystemConfig { para_id: PARA_ID.into(), asset_hub_para_id: ASSETHUB_PARA_ID.into(), diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs index b540f55642a5..a989881fef09 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs @@ -231,17 +231,6 @@ pub(crate) fn open_bridge_between_asset_hub_rococo_and_asset_hub_westend() { )), )), ); - BridgeHubRococo::execute_with(|| { - type RuntimeEvent = ::RuntimeEvent; - assert_expected_events!( - BridgeHubRococo, - vec![ - RuntimeEvent::XcmOverBridgeHubWestend( - pallet_xcm_bridge_hub::Event::BridgeOpened { .. } - ) => {}, - ] - ); - }); // open AHW -> AHR BridgeHubWestend::fund_para_sovereign(AssetHubWestend::para_id(), WND * 5); @@ -255,15 +244,4 @@ pub(crate) fn open_bridge_between_asset_hub_rococo_and_asset_hub_westend() { )), )), ); - BridgeHubWestend::execute_with(|| { - type RuntimeEvent = ::RuntimeEvent; - assert_expected_events!( - BridgeHubWestend, - vec![ - RuntimeEvent::XcmOverBridgeHubRococo( - pallet_xcm_bridge_hub::Event::BridgeOpened { .. } - ) => {}, - ] - ); - }); } diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs index 699641d3328f..f037a05a8276 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs @@ -246,17 +246,6 @@ pub(crate) fn open_bridge_between_asset_hub_rococo_and_asset_hub_westend() { )), )), ); - BridgeHubRococo::execute_with(|| { - type RuntimeEvent = ::RuntimeEvent; - assert_expected_events!( - BridgeHubRococo, - vec![ - RuntimeEvent::XcmOverBridgeHubWestend( - pallet_xcm_bridge_hub::Event::BridgeOpened { .. } - ) => {}, - ] - ); - }); // open AHW -> AHR BridgeHubWestend::fund_para_sovereign(AssetHubWestend::para_id(), WND * 5); @@ -270,15 +259,4 @@ pub(crate) fn open_bridge_between_asset_hub_rococo_and_asset_hub_westend() { )), )), ); - BridgeHubWestend::execute_with(|| { - type RuntimeEvent = ::RuntimeEvent; - assert_expected_events!( - BridgeHubWestend, - vec![ - RuntimeEvent::XcmOverBridgeHubRococo( - pallet_xcm_bridge_hub::Event::BridgeOpened { .. } - ) => {}, - ] - ); - }); } diff --git a/prdoc/pr_5649.prdoc b/prdoc/pr_5649.prdoc index 67ce882b3a13..ec16d96c6016 100644 --- a/prdoc/pr_5649.prdoc +++ b/prdoc/pr_5649.prdoc @@ -44,6 +44,6 @@ crates: - name: bridge-hub-westend-runtime bump: patch - name: polkadot-parachain-bin - bump: patch + bump: none - name: bridge-hub-test-utils - bump: patch + bump: major From c2989e09a93e909e58e4294dd15978462477cdf4 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Sun, 22 Sep 2024 23:54:50 +0200 Subject: [PATCH 28/38] Fixed migration for BridgeHubRococo/Westend --- .../src/bridge_to_westend_config.rs | 71 +++++++++++++++++++ .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 4 ++ .../src/bridge_to_rococo_config.rs | 71 +++++++++++++++++++ .../bridge-hubs/bridge-hub-westend/src/lib.rs | 4 ++ 4 files changed, 150 insertions(+) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index a8007020f63e..8b9164562a4d 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -317,4 +317,75 @@ pub mod migration { AssetHubRococoLocation, AssetHubWestendUniversalLocation, >; + + mod v1_wrong { + use bp_messages::{LaneState, MessageNonce, UnrewardedRelayer}; + use bp_runtime::AccountIdOf; + use codec::{Decode, Encode}; + use pallet_bridge_messages::BridgedChainOf; + use sp_std::collections::vec_deque::VecDeque; + + #[derive(Encode, Decode, Clone, PartialEq, Eq)] + pub(crate) struct StoredInboundLaneData, I: 'static>( + pub(crate) InboundLaneData>>, + ); + #[derive(Encode, Decode, Clone, PartialEq, Eq)] + pub(crate) struct InboundLaneData { + pub state: LaneState, + pub(crate) relayers: VecDeque>, + pub(crate) last_confirmed_nonce: MessageNonce, + } + #[derive(Encode, Decode, Clone, PartialEq, Eq)] + pub(crate) struct OutboundLaneData { + pub state: LaneState, + pub(crate) oldest_unpruned_nonce: MessageNonce, + pub(crate) latest_received_nonce: MessageNonce, + pub(crate) latest_generated_nonce: MessageNonce, + } + } + + mod v1 { + pub use bp_messages::{InboundLaneData, LaneState, OutboundLaneData}; + pub use pallet_bridge_messages::{InboundLanes, OutboundLanes, StoredInboundLaneData}; + } + + /// Fix for v1 migration - corrects data for OutboundLaneData/InboundLaneData (it is needed only + /// for Rococo/Westend). + pub struct FixMessagesV1Migration(sp_std::marker::PhantomData<(T, I)>); + + impl, I: 'static> frame_support::traits::OnRuntimeUpgrade + for FixMessagesV1Migration + { + fn on_runtime_upgrade() -> Weight { + use sp_core::Get; + let mut weight = T::DbWeight::get().reads(1); + + // `InboundLanes` - add state to the old structs + let translate_inbound = + |pre: v1_wrong::StoredInboundLaneData| -> Option> { + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + Some(v1::StoredInboundLaneData(v1::InboundLaneData { + state: v1::LaneState::Opened, + relayers: pre.0.relayers, + last_confirmed_nonce: pre.0.last_confirmed_nonce, + })) + }; + v1::InboundLanes::::translate_values(translate_inbound); + + // `OutboundLanes` - add state to the old structs + let translate_outbound = + |pre: v1_wrong::OutboundLaneData| -> Option { + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + Some(v1::OutboundLaneData { + state: v1::LaneState::Opened, + oldest_unpruned_nonce: pre.oldest_unpruned_nonce, + latest_received_nonce: pre.latest_received_nonce, + latest_generated_nonce: pre.latest_generated_nonce, + }) + }; + v1::OutboundLanes::::translate_values(translate_outbound); + + weight + } + } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 9ab4e07b6c55..f542354e2144 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -164,6 +164,10 @@ pub type Migrations = ( Runtime, bridge_to_bulletin_config::WithRococoBulletinMessagesInstance, >, + bridge_to_westend_config::migration::FixMessagesV1Migration< + Runtime, + bridge_to_westend_config::WithBridgeHubWestendMessagesInstance, + >, bridge_to_westend_config::migration::StaticToDynamicLanes, bridge_to_bulletin_config::migration::StaticToDynamicLanes, frame_support::migrations::RemoveStorage< diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index ddeb6d0a9a76..806d904486f1 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -347,4 +347,75 @@ pub mod migration { AssetHubWestendLocation, AssetHubRococoUniversalLocation, >; + + mod v1_wrong { + use bp_messages::{LaneState, MessageNonce, UnrewardedRelayer}; + use bp_runtime::AccountIdOf; + use codec::{Decode, Encode}; + use pallet_bridge_messages::BridgedChainOf; + use sp_std::collections::vec_deque::VecDeque; + + #[derive(Encode, Decode, Clone, PartialEq, Eq)] + pub(crate) struct StoredInboundLaneData, I: 'static>( + pub(crate) InboundLaneData>>, + ); + #[derive(Encode, Decode, Clone, PartialEq, Eq)] + pub(crate) struct InboundLaneData { + pub state: LaneState, + pub(crate) relayers: VecDeque>, + pub(crate) last_confirmed_nonce: MessageNonce, + } + #[derive(Encode, Decode, Clone, PartialEq, Eq)] + pub(crate) struct OutboundLaneData { + pub state: LaneState, + pub(crate) oldest_unpruned_nonce: MessageNonce, + pub(crate) latest_received_nonce: MessageNonce, + pub(crate) latest_generated_nonce: MessageNonce, + } + } + + mod v1 { + pub use bp_messages::{InboundLaneData, LaneState, OutboundLaneData}; + pub use pallet_bridge_messages::{InboundLanes, OutboundLanes, StoredInboundLaneData}; + } + + /// Fix for v1 migration - corrects data for OutboundLaneData/InboundLaneData (it is needed only + /// for Rococo/Westend). + pub struct FixMessagesV1Migration(sp_std::marker::PhantomData<(T, I)>); + + impl, I: 'static> frame_support::traits::OnRuntimeUpgrade + for FixMessagesV1Migration + { + fn on_runtime_upgrade() -> Weight { + use sp_core::Get; + let mut weight = T::DbWeight::get().reads(1); + + // `InboundLanes` - add state to the old structs + let translate_inbound = + |pre: v1_wrong::StoredInboundLaneData| -> Option> { + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + Some(v1::StoredInboundLaneData(v1::InboundLaneData { + state: v1::LaneState::Opened, + relayers: pre.0.relayers, + last_confirmed_nonce: pre.0.last_confirmed_nonce, + })) + }; + v1::InboundLanes::::translate_values(translate_inbound); + + // `OutboundLanes` - add state to the old structs + let translate_outbound = + |pre: v1_wrong::OutboundLaneData| -> Option { + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + Some(v1::OutboundLaneData { + state: v1::LaneState::Opened, + oldest_unpruned_nonce: pre.oldest_unpruned_nonce, + latest_received_nonce: pre.latest_received_nonce, + latest_generated_nonce: pre.latest_generated_nonce, + }) + }; + v1::OutboundLanes::::translate_values(translate_outbound); + + weight + } + } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 76649d0ef7b3..79c154c605f0 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -148,6 +148,10 @@ pub type Migrations = ( Runtime, bridge_to_rococo_config::WithBridgeHubRococoMessagesInstance, >, + bridge_to_rococo_config::migration::FixMessagesV1Migration< + Runtime, + bridge_to_rococo_config::WithBridgeHubRococoMessagesInstance, + >, bridge_to_rococo_config::migration::StaticToDynamicLanes, frame_support::migrations::RemoveStorage< BridgeRococoMessagesPalletName, From 93a789affcd0f55bdbb5c6cf65492cb70a9635df Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Mon, 23 Sep 2024 06:59:56 +0200 Subject: [PATCH 29/38] Exporter nits --- .../modules/xcm-bridge-hub/src/exporter.rs | 123 +++++++++++++++--- bridges/modules/xcm-bridge-hub/src/mock.rs | 2 +- 2 files changed, 109 insertions(+), 16 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index bc91c966e4d6..c59c74f02958 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -94,7 +94,7 @@ where "Destination: {dest:?} is already universal, checking dest_network: {dest_network:?} and network: {network:?} if matches: {:?}", dest_network == network ); - ensure!(dest_network == network, SendError::Unroutable); + ensure!(dest_network == network, SendError::NotApplicable); // ok, `dest` looks like a universal location, so let's use it dest }, @@ -108,23 +108,12 @@ where error_data.0, error_data.1, ); - SendError::Unroutable + SendError::NotApplicable })? }, } }; - // check if we are able to route the message. We use existing `HaulBlobExporter` for that. - // It will make all required changes and will encode message properly, so that the - // `DispatchBlob` at the bridged bridge hub will be able to decode it - let ((blob, id), price) = PalletAsHaulBlobExporter::::validate( - network, - channel, - universal_source, - destination, - message, - )?; - // prepare the origin relative location let bridge_origin_relative_location = bridge_origin_universal_location.relative_to(&T::UniversalLocation::get()); @@ -139,7 +128,7 @@ where target: LOG_TARGET, "Validate `bridge_locations` with error: {e:?}", ); - SendError::Unroutable + SendError::NotApplicable })?; let Some(bridge) = Self::bridge(locations.bridge_id()) else { log::error!( @@ -148,9 +137,20 @@ where locations.bridge_origin_relative_location(), locations.bridge_destination_universal_location(), ); - return Err(SendError::Unroutable) + return Err(SendError::NotApplicable) }; + // check if we are able to route the message. We use existing `HaulBlobExporter` for that. + // It will make all required changes and will encode message properly, so that the + // `DispatchBlob` at the bridged bridge hub will be able to decode it + let ((blob, id), price) = PalletAsHaulBlobExporter::::validate( + network, + channel, + universal_source, + destination, + message, + )?; + let bridge_message = MessagesPallet::::validate_message(bridge.lane_id, &blob) .map_err(|e| { match e { @@ -687,4 +687,97 @@ mod tests { ); }) } + + #[test] + fn not_applicable_if_destination_is_within_other_network() { + run_test(|| { + let xcm: Xcm<()> = vec![ClearOrigin].into(); + + // check that router does not consume when `NotApplicable` + let mut xcm_wrapper = Some(xcm.clone()); + let mut universal_source_wrapper = Some(universal_source()); + + // wrong `NetworkId` + let mut dest_wrapper = Some(bridged_relative_destination()); + assert_eq!( + XcmOverBridge::validate( + NetworkId::ByGenesis([0; 32]), + 0, + &mut universal_source_wrapper, + &mut dest_wrapper, + &mut xcm_wrapper, + ), + Err(SendError::NotApplicable), + ); + // dest and xcm is NOT consumed and untouched + assert_eq!(&Some(xcm.clone()), &xcm_wrapper); + assert_eq!(&Some(universal_source()), &universal_source_wrapper); + assert_eq!(&Some(bridged_relative_destination()), &dest_wrapper); + + // dest starts with wrong `NetworkId` + let mut invalid_dest_wrapper = Some( + [GlobalConsensus(NetworkId::ByGenesis([0; 32])), Parachain(BRIDGED_ASSET_HUB_ID)] + .into(), + ); + assert_eq!( + XcmOverBridge::validate( + BridgedRelayNetwork::get(), + 0, + &mut Some(universal_source()), + &mut invalid_dest_wrapper, + &mut xcm_wrapper, + ), + Err(SendError::NotApplicable), + ); + // dest and xcm is NOT consumed and untouched + assert_eq!(&Some(xcm.clone()), &xcm_wrapper); + assert_eq!(&Some(universal_source()), &universal_source_wrapper); + assert_eq!( + &Some( + [ + GlobalConsensus(NetworkId::ByGenesis([0; 32]),), + Parachain(BRIDGED_ASSET_HUB_ID) + ] + .into() + ), + &invalid_dest_wrapper + ); + + // no opened lane for dest + let mut dest_without_lane_wrapper = + Some([GlobalConsensus(BridgedRelayNetwork::get()), Parachain(5679)].into()); + assert_eq!( + XcmOverBridge::validate( + BridgedRelayNetwork::get(), + 0, + &mut Some(universal_source()), + &mut dest_without_lane_wrapper, + &mut xcm_wrapper, + ), + Err(SendError::NotApplicable), + ); + // dest and xcm is NOT consumed and untouched + assert_eq!(&Some(xcm.clone()), &xcm_wrapper); + assert_eq!(&Some(universal_source()), &universal_source_wrapper); + assert_eq!( + &Some([GlobalConsensus(BridgedRelayNetwork::get(),), Parachain(5679)].into()), + &dest_without_lane_wrapper + ); + + // ok + let _ = open_lane(); + let mut dest_wrapper = Some(bridged_relative_destination()); + assert_ok!(XcmOverBridge::validate( + BridgedRelayNetwork::get(), + 0, + &mut Some(universal_source()), + &mut dest_wrapper, + &mut xcm_wrapper, + )); + // dest and xcm IS consumed + assert_eq!(None, xcm_wrapper); + assert_eq!(&Some(universal_source()), &universal_source_wrapper); + assert_eq!(None, dest_wrapper); + }); + } } diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index ece5006e86d3..6511b9fc5b04 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -156,7 +156,7 @@ parameter_types! { pub SiblingLocation: Location = Location::new(1, [Parachain(SIBLING_ASSET_HUB_ID)]); pub SiblingUniversalLocation: InteriorLocation = [GlobalConsensus(RelayNetwork::get()), Parachain(SIBLING_ASSET_HUB_ID)].into(); - pub const BridgedRelayNetwork: NetworkId = NetworkId::Polkadot; + pub const BridgedRelayNetwork: NetworkId = NetworkId::ByGenesis([1; 32]); pub BridgedRelayNetworkLocation: Location = (Parent, GlobalConsensus(BridgedRelayNetwork::get())).into(); pub BridgedRelativeDestination: InteriorLocation = [Parachain(BRIDGED_ASSET_HUB_ID)].into(); pub BridgedUniversalDestination: InteriorLocation = [GlobalConsensus(BridgedRelayNetwork::get()), Parachain(BRIDGED_ASSET_HUB_ID)].into(); From 3ae8d319ae8bf12cc60d05a225b657a849123880 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 24 Sep 2024 09:07:04 +0200 Subject: [PATCH 30/38] Update bridges/modules/relayers/src/extension/mod.rs Co-authored-by: Adrian Catangiu --- bridges/modules/relayers/src/extension/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/bridges/modules/relayers/src/extension/mod.rs b/bridges/modules/relayers/src/extension/mod.rs index 06390d37e89f..298f08cab405 100644 --- a/bridges/modules/relayers/src/extension/mod.rs +++ b/bridges/modules/relayers/src/extension/mod.rs @@ -183,8 +183,6 @@ where _ => return RelayerAccountAction::None, }; - // lane_id.as_32-byte stuff to trait - // now we know that the call is supported and we may need to reward or slash relayer // => let's prepare the correspondent account that pays reward/receives slashed amount let lane_id = call_info.messages_call_info().lane_id(); From 8e6e33aa1b27de5ce8fb9b971d5e2a1a87b6c9fa Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 24 Sep 2024 09:37:15 +0200 Subject: [PATCH 31/38] prdoc major -> minor --- prdoc/pr_5649.prdoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/prdoc/pr_5649.prdoc b/prdoc/pr_5649.prdoc index ec16d96c6016..969fbe35f87d 100644 --- a/prdoc/pr_5649.prdoc +++ b/prdoc/pr_5649.prdoc @@ -16,9 +16,9 @@ crates: - name: parachains-runtimes-test-utils bump: patch - name: bp-messages - bump: major + bump: minor - name: bp-relayers - bump: major + bump: minor - name: bp-xcm-bridge-hub bump: patch - name: pallet-bridge-messages @@ -26,7 +26,7 @@ crates: - name: pallet-bridge-relayers bump: patch - name: pallet-xcm-bridge-hub - bump: major + bump: minor - name: emulated-integration-tests-common bump: patch - name: bp-bridge-hub-kusama @@ -46,4 +46,4 @@ crates: - name: polkadot-parachain-bin bump: none - name: bridge-hub-test-utils - bump: major + bump: minor From 6ccc9c59696a5f5bc4c8bdf4a0ec91ddd737c9a4 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 24 Sep 2024 09:37:41 +0200 Subject: [PATCH 32/38] Removed forgotten TODO --- .../relayers/src/extension/grandpa_adapter.rs | 4 ++-- .../relayers/src/extension/messages_adapter.rs | 4 ++-- bridges/modules/relayers/src/extension/mod.rs | 16 +++++++++------- .../relayers/src/extension/parachain_adapter.rs | 6 +++--- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/bridges/modules/relayers/src/extension/grandpa_adapter.rs b/bridges/modules/relayers/src/extension/grandpa_adapter.rs index a0f2f7d815e0..f60346fcd872 100644 --- a/bridges/modules/relayers/src/extension/grandpa_adapter.rs +++ b/bridges/modules/relayers/src/extension/grandpa_adapter.rs @@ -87,7 +87,7 @@ where type BridgeMessagesPalletInstance = MI; type PriorityBoostPerMessage = P; type RemoteGrandpaChainBlockNumber = pallet_bridge_grandpa::BridgedBlockNumber; - type LaneId = LaneIdOf; + type LaneId = LaneIdOf; fn parse_and_check_for_obsolete_call( call: &R::RuntimeCall, @@ -125,7 +125,7 @@ where relayer: &R::AccountId, ) -> bool { verify_submit_finality_proof_succeeded::(call_info, call_data, relayer) && - verify_messages_call_succeeded::(call_info, call_data, relayer) + verify_messages_call_succeeded::(call_info, call_data, relayer) } } diff --git a/bridges/modules/relayers/src/extension/messages_adapter.rs b/bridges/modules/relayers/src/extension/messages_adapter.rs index 29002f94ab2b..a1c6418ca8d7 100644 --- a/bridges/modules/relayers/src/extension/messages_adapter.rs +++ b/bridges/modules/relayers/src/extension/messages_adapter.rs @@ -65,7 +65,7 @@ where type BridgeMessagesPalletInstance = MI; type PriorityBoostPerMessage = P; type RemoteGrandpaChainBlockNumber = (); - type LaneId = LaneIdOf; + type LaneId = LaneIdOf; fn parse_and_check_for_obsolete_call( call: &R::RuntimeCall, @@ -89,6 +89,6 @@ where call_data: &mut ExtensionCallData, relayer: &R::AccountId, ) -> bool { - verify_messages_call_succeeded::(call_info, call_data, relayer) + verify_messages_call_succeeded::(call_info, call_data, relayer) } } diff --git a/bridges/modules/relayers/src/extension/mod.rs b/bridges/modules/relayers/src/extension/mod.rs index 06390d37e89f..f3532fef29b0 100644 --- a/bridges/modules/relayers/src/extension/mod.rs +++ b/bridges/modules/relayers/src/extension/mod.rs @@ -406,21 +406,23 @@ where } /// Verify that the messages pallet call, supported by extension has succeeded. -pub(crate) fn verify_messages_call_succeeded( - call_info: &ExtensionCallInfo>, +pub(crate) fn verify_messages_call_succeeded( + call_info: &ExtensionCallInfo< + C::RemoteGrandpaChainBlockNumber, + LaneIdOf, + >, _call_data: &mut ExtensionCallData, relayer: &::AccountId, ) -> bool where C: ExtensionConfig, - // TODO: pouit z C::BridgeInstance - MI: 'static, - C::Runtime: BridgeMessagesConfig, + C::Runtime: BridgeMessagesConfig, { let messages_call = call_info.messages_call_info(); - // TODO: - if !MessagesCallHelper::::was_successful(messages_call) { + if !MessagesCallHelper::::was_successful( + messages_call, + ) { log::trace!( target: LOG_TARGET, "{}.{:?}: relayer {:?} has submitted invalid messages call", diff --git a/bridges/modules/relayers/src/extension/parachain_adapter.rs b/bridges/modules/relayers/src/extension/parachain_adapter.rs index e9013e535fee..21439dce3592 100644 --- a/bridges/modules/relayers/src/extension/parachain_adapter.rs +++ b/bridges/modules/relayers/src/extension/parachain_adapter.rs @@ -94,7 +94,7 @@ where type PriorityBoostPerMessage = P; type RemoteGrandpaChainBlockNumber = pallet_bridge_grandpa::BridgedBlockNumber; - type LaneId = LaneIdOf; + type LaneId = LaneIdOf; fn parse_and_check_for_obsolete_call( call: &R::RuntimeCall, @@ -109,7 +109,7 @@ where let msgs_call = calls.next().transpose()?.and_then(|c| c.call_info()); let para_finality_call = calls.next().transpose()?.and_then(|c| { let r = c.submit_parachain_heads_info_for( - >::BridgedChain::PARACHAIN_ID, + >::BridgedChain::PARACHAIN_ID, ); r }); @@ -146,7 +146,7 @@ where verify_submit_finality_proof_succeeded::( call_info, call_data, relayer, ) && verify_submit_parachain_head_succeeded::(call_info, call_data, relayer) && - verify_messages_call_succeeded::(call_info, call_data, relayer) + verify_messages_call_succeeded::(call_info, call_data, relayer) } } From 98aedb2dffdb7bc103df2f4aa4934d6dd8e799df Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 24 Sep 2024 12:20:41 +0200 Subject: [PATCH 33/38] Missing instance support for rewards + Bulletin without rewards + HashedLaneId --- .../chains/chain-polkadot-bulletin/src/lib.rs | 2 +- .../relayers/src/extension/grandpa_adapter.rs | 11 +++-- .../src/extension/messages_adapter.rs | 9 +++- bridges/modules/relayers/src/extension/mod.rs | 3 ++ .../src/extension/parachain_adapter.rs | 10 +++- bridges/primitives/relayers/src/extension.rs | 2 + .../src/bridge_common_config.rs | 25 +++++++++- .../src/bridge_to_bulletin_config.rs | 21 ++++++--- .../src/bridge_to_westend_config.rs | 6 ++- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 47 ++++++++++++++----- .../bridge-hub-rococo/tests/snowbridge.rs | 6 +-- .../bridge-hub-rococo/tests/tests.rs | 21 +++++---- .../src/bridge_to_rococo_config.rs | 5 +- .../bridge-hub-westend/tests/tests.rs | 2 + .../src/test_cases/from_grandpa_chain.rs | 42 ++++++++++------- .../src/test_cases/from_parachain.rs | 46 +++++++++++------- 16 files changed, 178 insertions(+), 80 deletions(-) diff --git a/bridges/chains/chain-polkadot-bulletin/src/lib.rs b/bridges/chains/chain-polkadot-bulletin/src/lib.rs index df1dad0cc4c2..d00936919721 100644 --- a/bridges/chains/chain-polkadot-bulletin/src/lib.rs +++ b/bridges/chains/chain-polkadot-bulletin/src/lib.rs @@ -228,4 +228,4 @@ impl ChainWithMessages for PolkadotBulletin { } decl_bridge_finality_runtime_apis!(polkadot_bulletin, grandpa); -decl_bridge_messages_runtime_apis!(polkadot_bulletin, bp_messages::LegacyLaneId); +decl_bridge_messages_runtime_apis!(polkadot_bulletin, bp_messages::HashedLaneId); diff --git a/bridges/modules/relayers/src/extension/grandpa_adapter.rs b/bridges/modules/relayers/src/extension/grandpa_adapter.rs index f60346fcd872..2a8a6e78ef9c 100644 --- a/bridges/modules/relayers/src/extension/grandpa_adapter.rs +++ b/bridges/modules/relayers/src/extension/grandpa_adapter.rs @@ -54,6 +54,8 @@ pub struct WithGrandpaChainExtensionConfig< BridgeGrandpaPalletInstance, // instance of BridgedChain `pallet-bridge-messages`, tracked by this extension BridgeMessagesPalletInstance, + // instance of `pallet-bridge-relayers`, tracked by this extension + BridgeRelayersPalletInstance, // message delivery transaction priority boost for every additional message PriorityBoostPerMessage, >( @@ -63,20 +65,22 @@ pub struct WithGrandpaChainExtensionConfig< BatchCallUnpacker, BridgeGrandpaPalletInstance, BridgeMessagesPalletInstance, + BridgeRelayersPalletInstance, PriorityBoostPerMessage, )>, ); -impl ExtensionConfig - for WithGrandpaChainExtensionConfig +impl ExtensionConfig + for WithGrandpaChainExtensionConfig where ID: StaticStrProvider, - R: BridgeRelayersConfig + R: BridgeRelayersConfig + BridgeMessagesConfig> + BridgeGrandpaConfig, BCU: BatchCallUnpacker, GI: 'static, MI: 'static, + RI: 'static, P: Get, R::RuntimeCall: Dispatchable + BridgeGrandpaCallSubtype @@ -85,6 +89,7 @@ where type IdProvider = ID; type Runtime = R; type BridgeMessagesPalletInstance = MI; + type BridgeRelayersPalletInstance = RI; type PriorityBoostPerMessage = P; type RemoteGrandpaChainBlockNumber = pallet_bridge_grandpa::BridgedBlockNumber; type LaneId = LaneIdOf; diff --git a/bridges/modules/relayers/src/extension/messages_adapter.rs b/bridges/modules/relayers/src/extension/messages_adapter.rs index a1c6418ca8d7..e8c2088b7f2d 100644 --- a/bridges/modules/relayers/src/extension/messages_adapter.rs +++ b/bridges/modules/relayers/src/extension/messages_adapter.rs @@ -37,6 +37,7 @@ pub struct WithMessagesExtensionConfig< IdProvider, Runtime, BridgeMessagesPalletInstance, + BridgeRelayersPalletInstance, PriorityBoostPerMessage, >( PhantomData<( @@ -46,16 +47,19 @@ pub struct WithMessagesExtensionConfig< Runtime, // instance of BridgedChain `pallet-bridge-messages`, tracked by this extension BridgeMessagesPalletInstance, + // instance of `pallet-bridge-relayers`, tracked by this extension + BridgeRelayersPalletInstance, // message delivery transaction priority boost for every additional message PriorityBoostPerMessage, )>, ); -impl ExtensionConfig for WithMessagesExtensionConfig +impl ExtensionConfig for WithMessagesExtensionConfig where ID: StaticStrProvider, - R: BridgeRelayersConfig + BridgeMessagesConfig, + R: BridgeRelayersConfig + BridgeMessagesConfig, MI: 'static, + RI: 'static, P: Get, R::RuntimeCall: Dispatchable + BridgeMessagesCallSubType, @@ -63,6 +67,7 @@ where type IdProvider = ID; type Runtime = R; type BridgeMessagesPalletInstance = MI; + type BridgeRelayersPalletInstance = RI; type PriorityBoostPerMessage = P; type RemoteGrandpaChainBlockNumber = (); type LaneId = LaneIdOf; diff --git a/bridges/modules/relayers/src/extension/mod.rs b/bridges/modules/relayers/src/extension/mod.rs index f3532fef29b0..b19cc90020e9 100644 --- a/bridges/modules/relayers/src/extension/mod.rs +++ b/bridges/modules/relayers/src/extension/mod.rs @@ -494,6 +494,7 @@ mod tests { RuntimeWithUtilityPallet, (), (), + (), ConstU64<1>, >; type TestGrandpaExtension = @@ -504,6 +505,7 @@ mod tests { RuntimeWithUtilityPallet, (), (), + (), ConstU64<1>, >; type TestExtension = @@ -512,6 +514,7 @@ mod tests { StrTestMessagesExtension, TestRuntime, (), + (), ConstU64<1>, >; type TestMessagesExtension = diff --git a/bridges/modules/relayers/src/extension/parachain_adapter.rs b/bridges/modules/relayers/src/extension/parachain_adapter.rs index 21439dce3592..69cf766dd674 100644 --- a/bridges/modules/relayers/src/extension/parachain_adapter.rs +++ b/bridges/modules/relayers/src/extension/parachain_adapter.rs @@ -58,6 +58,8 @@ pub struct WithParachainExtensionConfig< BridgeParachainsPalletInstance, // instance of BridgedChain `pallet-bridge-messages`, tracked by this extension BridgeMessagesPalletInstance, + // instance of `pallet-bridge-relayers`, tracked by this extension + BridgeRelayersPalletInstance, // message delivery transaction priority boost for every additional message PriorityBoostPerMessage, >( @@ -67,20 +69,23 @@ pub struct WithParachainExtensionConfig< BatchCallUnpacker, BridgeParachainsPalletInstance, BridgeMessagesPalletInstance, + BridgeRelayersPalletInstance, PriorityBoostPerMessage, )>, ); -impl ExtensionConfig for WithParachainExtensionConfig +impl ExtensionConfig + for WithParachainExtensionConfig where ID: StaticStrProvider, - R: BridgeRelayersConfig + R: BridgeRelayersConfig + BridgeMessagesConfig + BridgeParachainsConfig + BridgeGrandpaConfig, BCU: BatchCallUnpacker, PI: 'static, MI: 'static, + RI: 'static, P: Get, R::RuntimeCall: Dispatchable + BridgeGrandpaCallSubtype @@ -91,6 +96,7 @@ where type IdProvider = ID; type Runtime = R; type BridgeMessagesPalletInstance = MI; + type BridgeRelayersPalletInstance = RI; type PriorityBoostPerMessage = P; type RemoteGrandpaChainBlockNumber = pallet_bridge_grandpa::BridgedBlockNumber; diff --git a/bridges/primitives/relayers/src/extension.rs b/bridges/primitives/relayers/src/extension.rs index 22461fcf9ecf..a9fa4df27ead 100644 --- a/bridges/primitives/relayers/src/extension.rs +++ b/bridges/primitives/relayers/src/extension.rs @@ -123,6 +123,8 @@ pub trait ExtensionConfig { /// Runtime that optionally supports batched calls. We assume that batched call /// succeeds if and only if all of its nested calls succeed. type Runtime: frame_system::Config; + /// Relayers pallet instance. + type BridgeRelayersPalletInstance: 'static; /// Messages pallet instance. type BridgeMessagesPalletInstance: 'static; /// Additional priority that is added to base message delivery transaction priority diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_common_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_common_config.rs index 28112d061ce0..5dca45d326b8 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_common_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_common_config.rs @@ -22,7 +22,6 @@ //! GRANDPA tracking pallet only needs to be aware of one chain. use super::{weights, AccountId, Balance, Balances, BlockNumber, Runtime, RuntimeEvent}; -use bp_messages::LegacyLaneId; use bp_parachains::SingleParaStoredHeaderDataBuilder; use frame_support::{parameter_types, traits::ConstU32}; @@ -83,7 +82,29 @@ impl pallet_bridge_relayers::Config fo RelayerStakeLease, >; type WeightInfo = weights::pallet_bridge_relayers::WeightInfo; - type LaneId = LegacyLaneId; + type LaneId = bp_messages::LegacyLaneId; +} + +/// Allows collect and claim rewards for relayers +pub type RelayersForPermissionlessLanesInstance = pallet_bridge_relayers::Instance2; +impl pallet_bridge_relayers::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Reward = Balance; + type PaymentProcedure = bp_relayers::PayRewardFromAccount< + pallet_balances::Pallet, + AccountId, + Self::LaneId, + >; + type StakeAndSlash = pallet_bridge_relayers::StakeAndSlashNamed< + AccountId, + BlockNumber, + Balances, + RelayerStakeReserveId, + RequiredStakeForStakeAndSlash, + RelayerStakeLease, + >; + type WeightInfo = weights::pallet_bridge_relayers::WeightInfo; + type LaneId = bp_messages::HashedLaneId; } /// Add GRANDPA bridge pallet to track Rococo Bulletin chain. diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs index 8f706d2214d1..c971fa59c68d 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs @@ -20,13 +20,14 @@ //! are reusing Polkadot Bulletin chain primitives everywhere here. use crate::{ - weights, xcm_config::UniversalLocation, AccountId, Balance, Balances, - BridgeRococoBulletinGrandpa, BridgeRococoBulletinMessages, PolkadotXcm, Runtime, RuntimeEvent, - RuntimeHoldReason, XcmOverRococoBulletin, XcmRouter, + bridge_common_config::RelayersForPermissionlessLanesInstance, weights, + xcm_config::UniversalLocation, AccountId, Balance, Balances, BridgeRococoBulletinGrandpa, + BridgeRococoBulletinMessages, PolkadotXcm, Runtime, RuntimeEvent, RuntimeHoldReason, + XcmOverRococoBulletin, XcmRouter, }; use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, - target_chain::FromBridgedChainMessagesProof, LegacyLaneId, + target_chain::FromBridgedChainMessagesProof, HashedLaneId, }; use bridge_hub_common::xcm_version::XcmVersionOfDestAndRemoteBridge; @@ -99,6 +100,7 @@ pub type OnBridgeHubRococoRefundRococoBulletinMessages = BridgeRelayersSignedExt StrOnBridgeHubRococoRefundRococoBulletinMessages, Runtime, WithRococoBulletinMessagesInstance, + RelayersForPermissionlessLanesInstance, PriorityBoostPerMessage, >, LaneIdOf, @@ -118,7 +120,7 @@ impl pallet_bridge_messages::Config for Runt type OutboundPayload = XcmAsPlainPayload; type InboundPayload = XcmAsPlainPayload; - type LaneId = LegacyLaneId; + type LaneId = HashedLaneId; type DeliveryPayments = (); type DeliveryConfirmationPayments = (); @@ -141,7 +143,7 @@ impl pallet_xcm_bridge_hub::Config for Runtime XcmVersionOfDestAndRemoteBridge; type ForceOrigin = EnsureRoot; - // We don't want to allow creating bridges for this instance with `LegacyLaneId`. + // We don't want to allow creating bridges for this instance. type OpenBridgeOrigin = EnsureNever; // Converter aligned with `OpenBridgeOrigin`. type BridgeOriginAccountIdConverter = @@ -284,8 +286,13 @@ pub mod migration { use frame_support::traits::ConstBool; parameter_types! { - pub RococoPeopleToRococoBulletinMessagesLane: LegacyLaneId = LegacyLaneId([0, 0, 0, 0]); pub BulletinRococoLocation: InteriorLocation = [GlobalConsensus(RococoBulletinGlobalConsensusNetwork::get())].into(); + pub RococoPeopleToRococoBulletinMessagesLane: HashedLaneId = pallet_xcm_bridge_hub::Pallet::< Runtime, XcmOverPolkadotBulletinInstance >::bridge_locations( + PeopleRococoLocation::get(), + BulletinRococoLocation::get() + ) + .unwrap() + .calculate_lane_id(xcm::latest::VERSION).expect("Valid locations"); } /// Ensure that the existing lanes for the People<>Bulletin bridge are correctly configured. diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index 8b9164562a4d..8fe045723107 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -17,7 +17,10 @@ //! Bridge definitions used on BridgeHubRococo for bridging to BridgeHubWestend. use crate::{ - bridge_common_config::{BridgeParachainWestendInstance, DeliveryRewardInBalance}, + bridge_common_config::{ + BridgeParachainWestendInstance, DeliveryRewardInBalance, + RelayersForLegacyLaneIdsMessagesInstance, + }, weights, xcm_config::UniversalLocation, AccountId, Balance, Balances, BridgeWestendMessages, PolkadotXcm, Runtime, RuntimeEvent, @@ -88,6 +91,7 @@ pub type OnBridgeHubRococoRefundBridgeHubWestendMessages = BridgeRelayersSignedE StrOnBridgeHubRococoRefundBridgeHubWestendMessages, Runtime, WithBridgeHubWestendMessagesInstance, + RelayersForLegacyLaneIdsMessagesInstance, PriorityBoostPerMessage, >, LaneIdOf, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index c64ea3b8237f..bf9bd58669b4 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -131,10 +131,7 @@ pub type SignedExtra = ( frame_system::CheckWeight, pallet_transaction_payment::ChargeTransactionPayment, BridgeRejectObsoleteHeadersAndMessages, - ( - bridge_to_westend_config::OnBridgeHubRococoRefundBridgeHubWestendMessages, - bridge_to_bulletin_config::OnBridgeHubRococoRefundRococoBulletinMessages, - ), + (bridge_to_westend_config::OnBridgeHubRococoRefundBridgeHubWestendMessages,), cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim, frame_metadata_hash_extension::CheckMetadataHash, ); @@ -599,6 +596,9 @@ construct_runtime!( // With-Rococo Bulletin bridge hub pallet. XcmOverPolkadotBulletin: pallet_xcm_bridge_hub:: = 62, + // Bridge relayers pallet, used by several bridges here (another instance). + BridgeRelayersForPermissionlessLanes: pallet_bridge_relayers:: = 63, + EthereumInboundQueue: snowbridge_pallet_inbound_queue = 80, EthereumOutboundQueue: snowbridge_pallet_outbound_queue = 81, EthereumBeaconClient: snowbridge_pallet_ethereum_client = 82, @@ -668,7 +668,8 @@ mod benches { [pallet_bridge_parachains, WithinWestend] [pallet_bridge_messages, RococoToWestend] [pallet_bridge_messages, RococoToRococoBulletin] - [pallet_bridge_relayers, BridgeRelayersBench::] + [pallet_bridge_relayers, Legacy] + [pallet_bridge_relayers, PermissionlessLanes] // Ethereum Bridge [snowbridge_pallet_inbound_queue, EthereumInboundQueue] [snowbridge_pallet_outbound_queue, EthereumOutboundQueue] @@ -677,6 +678,11 @@ mod benches { ); } +cumulus_pallet_parachain_system::register_validate_block! { + Runtime = Runtime, + BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::, +} + impl_runtime_apis! { impl sp_consensus_aura::AuraApi for Runtime { fn slot_duration() -> sp_consensus_aura::SlotDuration { @@ -1045,6 +1051,8 @@ impl_runtime_apis! { type WithinWestend = pallet_bridge_parachains::benchmarking::Pallet::; type RococoToWestend = pallet_bridge_messages::benchmarking::Pallet ::; type RococoToRococoBulletin = pallet_bridge_messages::benchmarking::Pallet ::; + type Legacy = BridgeRelayersBench::; + type PermissionlessLanes = BridgeRelayersBench::; let mut list = Vec::::new(); list_benchmarks!(list, extra); @@ -1294,6 +1302,8 @@ impl_runtime_apis! { type WithinWestend = pallet_bridge_parachains::benchmarking::Pallet::; type RococoToWestend = pallet_bridge_messages::benchmarking::Pallet ::; type RococoToRococoBulletin = pallet_bridge_messages::benchmarking::Pallet ::; + type Legacy = BridgeRelayersBench::; + type PermissionlessLanes = BridgeRelayersBench::; use bridge_runtime_common::messages_benchmarking::{ prepare_message_delivery_proof_from_grandpa_chain, @@ -1448,7 +1458,26 @@ impl_runtime_apis! { AccountId, >::LaneId, >::rewards_account(account_params); - Self::deposit_account(rewards_account, reward); + >::deposit_account(rewards_account, reward); + } + + fn deposit_account(account: AccountId, balance: Balance) { + use frame_support::traits::fungible::Mutate; + Balances::mint_into(&account, balance.saturating_add(ExistentialDeposit::get())).unwrap(); + } + } + + impl BridgeRelayersConfig for Runtime { + fn prepare_rewards_account( + account_params: bp_relayers::RewardsAccountParams<>::LaneId>, + reward: Balance, + ) { + let rewards_account = bp_relayers::PayRewardFromAccount::< + Balances, + AccountId, + >::LaneId, + >::rewards_account(account_params); + >::deposit_account(rewards_account, reward); } fn deposit_account(account: AccountId, balance: Balance) { @@ -1493,11 +1522,6 @@ impl_runtime_apis! { } } -cumulus_pallet_parachain_system::register_validate_block! { - Runtime = Runtime, - BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::, -} - #[cfg(test)] mod tests { use super::*; @@ -1525,7 +1549,6 @@ mod tests { BridgeRejectObsoleteHeadersAndMessages, ( bridge_to_westend_config::OnBridgeHubRococoRefundBridgeHubWestendMessages::default(), - bridge_to_bulletin_config::OnBridgeHubRococoRefundRococoBulletinMessages::default(), ), cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim::new(), frame_metadata_hash_extension::CheckMetadataHash::new(false), diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs index c7b5850f9ffe..7a0f1462e7a7 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs @@ -18,7 +18,6 @@ use bp_polkadot_core::Signature; use bridge_hub_rococo_runtime::{ - bridge_to_bulletin_config::OnBridgeHubRococoRefundRococoBulletinMessages, bridge_to_westend_config::OnBridgeHubRococoRefundBridgeHubWestendMessages, xcm_config::XcmConfig, AllPalletsWithoutSystem, BridgeRejectObsoleteHeadersAndMessages, Executive, MessageQueueServiceWeight, Runtime, RuntimeCall, RuntimeEvent, SessionKeys, @@ -183,10 +182,7 @@ fn construct_extrinsic( frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(0), BridgeRejectObsoleteHeadersAndMessages::default(), - ( - OnBridgeHubRococoRefundBridgeHubWestendMessages::default(), - OnBridgeHubRococoRefundRococoBulletinMessages::default(), - ), + (OnBridgeHubRococoRefundBridgeHubWestendMessages::default(),), cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim::new(), frame_metadata_hash_extension::CheckMetadataHash::::new(false), ); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs index 830305883c21..e45117322fa3 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs @@ -62,10 +62,7 @@ fn construct_extrinsic( frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(0), BridgeRejectObsoleteHeadersAndMessages::default(), - ( - bridge_to_westend_config::OnBridgeHubRococoRefundBridgeHubWestendMessages::default(), - bridge_to_bulletin_config::OnBridgeHubRococoRefundRococoBulletinMessages::default(), - ), + (bridge_to_westend_config::OnBridgeHubRococoRefundBridgeHubWestendMessages::default(),), cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim::new(), frame_metadata_hash_extension::CheckMetadataHash::new(false), ); @@ -418,6 +415,7 @@ mod bridge_hub_westend_tests { .1 }, construct_and_apply_extrinsic, + true, ) } @@ -451,6 +449,7 @@ mod bridge_hub_westend_tests { .1 }, construct_and_apply_extrinsic, + false, ) } @@ -516,9 +515,9 @@ mod bridge_hub_westend_tests { mod bridge_hub_bulletin_tests { use super::*; - use bp_messages::LegacyLaneId; + use bp_messages::{HashedLaneId, LaneIdType}; use bridge_common_config::BridgeGrandpaRococoBulletinInstance; - use bridge_hub_rococo_runtime::bridge_common_config::RelayersForLegacyLaneIdsMessagesInstance; + use bridge_hub_rococo_runtime::bridge_common_config::RelayersForPermissionlessLanesInstance; use bridge_hub_test_utils::test_cases::from_grandpa_chain; use bridge_to_bulletin_config::{ RococoBulletinGlobalConsensusNetwork, RococoBulletinGlobalConsensusNetworkLocation, @@ -540,7 +539,7 @@ mod bridge_hub_bulletin_tests { AllPalletsWithoutSystem, BridgeGrandpaRococoBulletinInstance, WithRococoBulletinMessagesInstance, - RelayersForLegacyLaneIdsMessagesInstance, + RelayersForPermissionlessLanesInstance, >; #[test] @@ -610,7 +609,7 @@ mod bridge_hub_bulletin_tests { bridge_hub_test_utils::open_bridge_with_storage::< Runtime, XcmOverPolkadotBulletinInstance - >(locations, fee, LegacyLaneId([0, 0, 0, 2])) + >(locations, fee, HashedLaneId::new(1, 2)) } ).1 }, @@ -673,12 +672,13 @@ mod bridge_hub_bulletin_tests { bridge_hub_test_utils::open_bridge_with_storage::< Runtime, XcmOverPolkadotBulletinInstance, - >(locations, fee, LegacyLaneId([0, 0, 0, 2])) + >(locations, fee, HashedLaneId::new(1, 2)) }, ) .1 }, construct_and_apply_extrinsic, + false, ) } @@ -705,12 +705,13 @@ mod bridge_hub_bulletin_tests { bridge_hub_test_utils::open_bridge_with_storage::< Runtime, XcmOverPolkadotBulletinInstance, - >(locations, fee, LegacyLaneId([0, 0, 0, 2])) + >(locations, fee, HashedLaneId::new(1, 2)) }, ) .1 }, construct_and_apply_extrinsic, + false, ) } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index 806d904486f1..e45654bc62bd 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -17,7 +17,9 @@ //! Bridge definitions used on BridgeHub with the Westend flavor. use crate::{ - bridge_common_config::DeliveryRewardInBalance, weights, xcm_config::UniversalLocation, + bridge_common_config::{DeliveryRewardInBalance, RelayersForLegacyLaneIdsMessagesInstance}, + weights, + xcm_config::UniversalLocation, AccountId, Balance, Balances, BridgeRococoMessages, PolkadotXcm, Runtime, RuntimeEvent, RuntimeHoldReason, XcmOverBridgeHubRococo, XcmRouter, }; @@ -96,6 +98,7 @@ pub type OnBridgeHubWestendRefundBridgeHubRococoMessages = BridgeRelayersSignedE StrOnBridgeHubWestendRefundBridgeHubRococoMessages, Runtime, WithBridgeHubRococoMessagesInstance, + RelayersForLegacyLaneIdsMessagesInstance, PriorityBoostPerMessage, >, LaneIdOf, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs index 5c56459a54bc..4ff388f4ba2b 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs @@ -310,6 +310,7 @@ fn relayed_incoming_message_works() { .1 }, construct_and_apply_extrinsic, + true, ) } @@ -339,6 +340,7 @@ fn free_relay_extrinsic_works() { .1 }, construct_and_apply_extrinsic, + true, ) } diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs index ce8eaa270392..320f3030b60a 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs @@ -106,6 +106,7 @@ pub fn relayed_incoming_message_works( sp_keyring::AccountKeyring, RuntimeCallOf, ) -> sp_runtime::DispatchOutcome, + expect_rewards: bool, ) where RuntimeHelper: WithRemoteGrandpaChainHelper, AccountIdOf: From, @@ -178,14 +179,18 @@ pub fn relayed_incoming_message_works( lane_id, 1, ), - helpers::VerifyRelayerRewarded::::expect_relayer_reward( - relayer_id_at_this_chain, - RewardsAccountParams::new( - lane_id, - bridged_chain_id, - RewardsAccountOwner::ThisChain, - ), - ), + if expect_rewards { + helpers::VerifyRelayerRewarded::::expect_relayer_reward( + relayer_id_at_this_chain, + RewardsAccountParams::new( + lane_id, + bridged_chain_id, + RewardsAccountOwner::ThisChain, + ), + ) + } else { + Box::new(()) + } )), ), ] @@ -208,6 +213,7 @@ pub fn free_relay_extrinsic_works( sp_keyring::AccountKeyring, RuntimeCallOf, ) -> sp_runtime::DispatchOutcome, + expect_rewards: bool, ) where RuntimeHelper: WithRemoteGrandpaChainHelper, RuntimeHelper::Runtime: pallet_balances::Config, @@ -308,14 +314,18 @@ pub fn free_relay_extrinsic_works( lane_id, 1, ), - helpers::VerifyRelayerRewarded::::expect_relayer_reward( - relayer_id_at_this_chain, - RewardsAccountParams::new( - lane_id, - bridged_chain_id, - RewardsAccountOwner::ThisChain, - ), - ), + if expect_rewards { + helpers::VerifyRelayerRewarded::::expect_relayer_reward( + relayer_id_at_this_chain, + RewardsAccountParams::new( + lane_id, + bridged_chain_id, + RewardsAccountOwner::ThisChain, + ), + ) + } else { + Box::new(()) + } )), ), ] diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs index 4a1d7470e839..1da901e0bcdf 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs @@ -115,6 +115,7 @@ pub fn relayed_incoming_message_works( sp_keyring::AccountKeyring, ::RuntimeCall, ) -> sp_runtime::DispatchOutcome, + expect_rewards: bool, ) where RuntimeHelper: WithRemoteParachainHelper, AccountIdOf: From, @@ -213,14 +214,18 @@ pub fn relayed_incoming_message_works( lane_id, 1, ), - helpers::VerifyRelayerRewarded::::expect_relayer_reward( - relayer_id_at_this_chain, - RewardsAccountParams::new( - lane_id, - bridged_chain_id, - RewardsAccountOwner::ThisChain, - ), - ), + if expect_rewards { + helpers::VerifyRelayerRewarded::::expect_relayer_reward( + relayer_id_at_this_chain, + RewardsAccountParams::new( + lane_id, + bridged_chain_id, + RewardsAccountOwner::ThisChain, + ), + ) + } else { + Box::new(()) + } )), ), ] @@ -244,6 +249,7 @@ pub fn free_relay_extrinsic_works( sp_keyring::AccountKeyring, ::RuntimeCall, ) -> sp_runtime::DispatchOutcome, + expect_rewards: bool, ) where RuntimeHelper: WithRemoteParachainHelper, RuntimeHelper::Runtime: pallet_balances::Config, @@ -359,10 +365,10 @@ pub fn free_relay_extrinsic_works( bridged_para_id, parachain_head_hash, ), - /*helpers::VerifyRelayerBalance::::expect_relayer_balance( + helpers::VerifyRelayerBalance::::expect_relayer_balance( relayer_id_at_this_chain.clone(), initial_relayer_balance, - ),*/ + ), )), ), ( @@ -377,14 +383,18 @@ pub fn free_relay_extrinsic_works( lane_id, 1, ), - helpers::VerifyRelayerRewarded::::expect_relayer_reward( - relayer_id_at_this_chain, - RewardsAccountParams::new( - lane_id, - bridged_chain_id, - RewardsAccountOwner::ThisChain, - ), - ), + if expect_rewards { + helpers::VerifyRelayerRewarded::::expect_relayer_reward( + relayer_id_at_this_chain, + RewardsAccountParams::new( + lane_id, + bridged_chain_id, + RewardsAccountOwner::ThisChain, + ), + ) + } else { + Box::new(()) + } )), ), ] From 2f8a0fc9387bb7376b5837ca1f6e0a29f78da133 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 24 Sep 2024 13:19:51 +0200 Subject: [PATCH 34/38] prdoc --- prdoc/pr_5649.prdoc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/prdoc/pr_5649.prdoc b/prdoc/pr_5649.prdoc index 969fbe35f87d..390632bdac19 100644 --- a/prdoc/pr_5649.prdoc +++ b/prdoc/pr_5649.prdoc @@ -16,9 +16,9 @@ crates: - name: parachains-runtimes-test-utils bump: patch - name: bp-messages - bump: minor + bump: major - name: bp-relayers - bump: minor + bump: major - name: bp-xcm-bridge-hub bump: patch - name: pallet-bridge-messages @@ -26,7 +26,7 @@ crates: - name: pallet-bridge-relayers bump: patch - name: pallet-xcm-bridge-hub - bump: minor + bump: major - name: emulated-integration-tests-common bump: patch - name: bp-bridge-hub-kusama @@ -40,10 +40,10 @@ crates: - name: bp-polkadot-bulletin bump: patch - name: bridge-hub-rococo-runtime - bump: patch + bump: major - name: bridge-hub-westend-runtime bump: patch - name: polkadot-parachain-bin bump: none - name: bridge-hub-test-utils - bump: minor + bump: major From b545648bfb3a6c579caaacca6be86f6e8e2e86fe Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 24 Sep 2024 13:35:50 +0200 Subject: [PATCH 35/38] prdoc --- prdoc/pr_5649.prdoc | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/prdoc/pr_5649.prdoc b/prdoc/pr_5649.prdoc index 390632bdac19..c7f1e0216e71 100644 --- a/prdoc/pr_5649.prdoc +++ b/prdoc/pr_5649.prdoc @@ -16,9 +16,11 @@ crates: - name: parachains-runtimes-test-utils bump: patch - name: bp-messages - bump: major + bump: minor + validate: false - name: bp-relayers - bump: major + bump: minor + validate: false - name: bp-xcm-bridge-hub bump: patch - name: pallet-bridge-messages @@ -26,7 +28,8 @@ crates: - name: pallet-bridge-relayers bump: patch - name: pallet-xcm-bridge-hub - bump: major + bump: minor + validate: false - name: emulated-integration-tests-common bump: patch - name: bp-bridge-hub-kusama @@ -40,10 +43,12 @@ crates: - name: bp-polkadot-bulletin bump: patch - name: bridge-hub-rococo-runtime - bump: major + bump: minor + validate: false - name: bridge-hub-westend-runtime bump: patch - name: polkadot-parachain-bin bump: none - name: bridge-hub-test-utils - bump: major + bump: minor + validate: false From 4daae2163b645a46f763d8e6a418a63dda31b813 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 24 Sep 2024 14:42:34 +0200 Subject: [PATCH 36/38] Review fixes - part1 --- .../modules/xcm-bridge-hub/src/exporter.rs | 8 +++--- .../relays/lib-substrate-relay/src/cli/mod.rs | 4 +-- .../lib-substrate-relay/src/messages/mod.rs | 25 ++----------------- 3 files changed, 8 insertions(+), 29 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index c59c74f02958..5afb9f36bc94 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -130,15 +130,15 @@ where ); SendError::NotApplicable })?; - let Some(bridge) = Self::bridge(locations.bridge_id()) else { + let bridge = Self::bridge(locations.bridge_id()).ok_or_else(|| { log::error!( target: LOG_TARGET, "No opened bridge for requested bridge_origin_relative_location: {:?} and bridge_destination_universal_location: {:?}", locations.bridge_origin_relative_location(), locations.bridge_destination_universal_location(), ); - return Err(SendError::NotApplicable) - }; + SendError::NotApplicable + })?; // check if we are able to route the message. We use existing `HaulBlobExporter` for that. // It will make all required changes and will encode message properly, so that the @@ -689,7 +689,7 @@ mod tests { } #[test] - fn not_applicable_if_destination_is_within_other_network() { + fn validate_works() { run_test(|| { let xcm: Xcm<()> = vec![ClearOrigin].into(); diff --git a/bridges/relays/lib-substrate-relay/src/cli/mod.rs b/bridges/relays/lib-substrate-relay/src/cli/mod.rs index ee5aec67511b..be64866fc14b 100644 --- a/bridges/relays/lib-substrate-relay/src/cli/mod.rs +++ b/bridges/relays/lib-substrate-relay/src/cli/mod.rs @@ -44,8 +44,8 @@ pub type DefaultClient = relay_substrate_client::RpcWithCachingClient; pub struct HexLaneId(Vec); impl>> TryConvert for HexLaneId { - fn try_convert(a: HexLaneId) -> Result { - T::try_from(a.0.clone()).map_err(|_| a) + fn try_convert(lane_id: HexLaneId) -> Result { + T::try_from(lane_id.0.clone()).map_err(|_| lane_id) } } diff --git a/bridges/relays/lib-substrate-relay/src/messages/mod.rs b/bridges/relays/lib-substrate-relay/src/messages/mod.rs index 08e9163a2211..ffa2c2a47db3 100644 --- a/bridges/relays/lib-substrate-relay/src/messages/mod.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/mod.rs @@ -27,7 +27,6 @@ use crate::{ use async_std::sync::Arc; use bp_messages::{ - source_chain::FromBridgedChainMessagesDeliveryProof, target_chain::FromBridgedChainMessagesProof, ChainWithMessages as _, MessageNonce, }; use bp_runtime::{AccountIdOf, EncodedOrDecodedCall, HeaderIdOf, TransactionEra, WeightExtraOps}; @@ -401,22 +400,11 @@ pub struct DirectReceiveMessagesProofCallBuilder { impl ReceiveMessagesProofCallBuilder

for DirectReceiveMessagesProofCallBuilder where P: SubstrateMessageLane, - R: BridgeMessagesConfig, + R: BridgeMessagesConfig, I: 'static, R::BridgedChain: bp_runtime::Chain, Hash = HashOf>, CallOf: From> + GetDispatchInfo, - Box< - bp_messages::target_chain::FromBridgedChainMessagesProof< - <

::SourceChain as ChainBase>::Hash, - >::LaneId, - >, - >: From< - bp_messages::target_chain::FromBridgedChainMessagesProof< - <

::SourceChain as ChainBase>::Hash, -

::LaneId, - >, - >, { fn build_receive_messages_proof_call( relayer_id_at_source: AccountIdOf, @@ -510,19 +498,10 @@ impl ReceiveMessagesDeliveryProofCallBuilder

for DirectReceiveMessagesDeliveryProofCallBuilder where P: SubstrateMessageLane, - R: BridgeMessagesConfig, + R: BridgeMessagesConfig, I: 'static, R::BridgedChain: bp_runtime::Chain>, CallOf: From> + GetDispatchInfo, - FromBridgedChainMessagesDeliveryProof< - <

::TargetChain as ChainBase>::Hash, - >::LaneId, - >: From< - FromBridgedChainMessagesDeliveryProof< - <

::TargetChain as ChainBase>::Hash, -

::LaneId, - >, - >, { fn build_receive_messages_delivery_proof_call( proof: SubstrateMessagesDeliveryProof, From 7a6cc8d40f06e472e4fd9ca0379eb490554de3a0 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 24 Sep 2024 15:00:20 +0200 Subject: [PATCH 37/38] Review nits --- bridges/bin/runtime-common/src/mock.rs | 2 +- bridges/modules/messages/src/tests/mock.rs | 6 ++--- .../messages/src/tests/pallet_tests.rs | 4 ++-- bridges/modules/relayers/src/lib.rs | 4 ++-- bridges/modules/relayers/src/mock.rs | 8 +++++-- .../modules/xcm-bridge-hub/src/dispatcher.rs | 4 ++-- bridges/modules/xcm-bridge-hub/src/lib.rs | 4 ++-- bridges/primitives/messages/src/lane.rs | 22 +++++++++---------- .../primitives/messages/src/storage_keys.rs | 9 +++++--- bridges/primitives/relayers/src/lib.rs | 8 +++---- bridges/primitives/xcm-bridge-hub/src/lib.rs | 7 ++++-- .../lib-substrate-relay/src/messages/mod.rs | 4 ++-- .../src/messages/source.rs | 2 +- .../relays/messages/src/message_lane_loop.rs | 4 ++-- .../bridge-hub-rococo/tests/tests.rs | 6 ++--- 15 files changed, 52 insertions(+), 42 deletions(-) diff --git a/bridges/bin/runtime-common/src/mock.rs b/bridges/bin/runtime-common/src/mock.rs index 35a8b5cccab9..1d4043fc4b61 100644 --- a/bridges/bin/runtime-common/src/mock.rs +++ b/bridges/bin/runtime-common/src/mock.rs @@ -87,7 +87,7 @@ pub type TestStakeAndSlash = pallet_bridge_relayers::StakeAndSlashNamed< pub type TestLaneIdType = HashedLaneId; /// Lane that we're using in tests. pub fn test_lane_id() -> TestLaneIdType { - TestLaneIdType::new(1, 2) + TestLaneIdType::try_new(1, 2).unwrap() } /// Bridged chain id used in tests. diff --git a/bridges/modules/messages/src/tests/mock.rs b/bridges/modules/messages/src/tests/mock.rs index 095319ef0556..2935ebd69610 100644 --- a/bridges/modules/messages/src/tests/mock.rs +++ b/bridges/modules/messages/src/tests/mock.rs @@ -263,17 +263,17 @@ pub const TEST_RELAYER_C: AccountId = 102; pub type TestLaneIdType = HashedLaneId; /// Lane that we're using in tests. pub fn test_lane_id() -> TestLaneIdType { - TestLaneIdType::new(1, 2) + TestLaneIdType::try_new(1, 2).unwrap() } /// Lane that is completely unknown to our runtime. pub fn unknown_lane_id() -> TestLaneIdType { - TestLaneIdType::new(1, 3) + TestLaneIdType::try_new(1, 3).unwrap() } /// Lane that is registered, but it is closed. pub fn closed_lane_id() -> TestLaneIdType { - TestLaneIdType::new(1, 4) + TestLaneIdType::try_new(1, 4).unwrap() } /// Regular message payload. diff --git a/bridges/modules/messages/src/tests/pallet_tests.rs b/bridges/modules/messages/src/tests/pallet_tests.rs index 3bab5e48d6b8..9df103a7cf6f 100644 --- a/bridges/modules/messages/src/tests/pallet_tests.rs +++ b/bridges/modules/messages/src/tests/pallet_tests.rs @@ -632,7 +632,7 @@ fn receive_messages_delivery_proof_rewards_relayers() { fn receive_messages_delivery_proof_rejects_invalid_proof() { run_test(|| { let mut proof = prepare_messages_delivery_proof(test_lane_id(), Default::default()); - proof.lane = TestLaneIdType::new(42, 84); + proof.lane = TestLaneIdType::try_new(42, 84).unwrap(); assert_noop!( Pallet::::receive_messages_delivery_proof( @@ -1087,7 +1087,7 @@ fn inbound_storage_extra_proof_size_bytes_works() { fn storage(relayer_entries: usize) -> RuntimeInboundLaneStorage { RuntimeInboundLaneStorage { - lane_id: TestLaneIdType::new(1, 2), + lane_id: TestLaneIdType::try_new(1, 2).unwrap(), cached_data: InboundLaneData { state: LaneState::Opened, relayers: vec![relayer_entry(); relayer_entries].into(), diff --git a/bridges/modules/relayers/src/lib.rs b/bridges/modules/relayers/src/lib.rs index 7cc4154ac180..f06c2e16ac24 100644 --- a/bridges/modules/relayers/src/lib.rs +++ b/bridges/modules/relayers/src/lib.rs @@ -620,12 +620,12 @@ mod tests { run_test(|| { let in_lane_0 = RewardsAccountParams::new( - TestLaneIdType::new(1, 2), + TestLaneIdType::try_new(1, 2).unwrap(), *b"test", RewardsAccountOwner::ThisChain, ); let out_lane_1 = RewardsAccountParams::new( - TestLaneIdType::new(1, 3), + TestLaneIdType::try_new(1, 3).unwrap(), *b"test", RewardsAccountOwner::BridgedChain, ); diff --git a/bridges/modules/relayers/src/mock.rs b/bridges/modules/relayers/src/mock.rs index 3d718154c16a..d186e968e648 100644 --- a/bridges/modules/relayers/src/mock.rs +++ b/bridges/modules/relayers/src/mock.rs @@ -79,7 +79,7 @@ pub const BRIDGED_CHAIN_MAX_EXTRINSIC_SIZE: u32 = 1024; pub type TestLaneIdType = HashedLaneId; /// Lane that we're using in tests. pub fn test_lane_id() -> TestLaneIdType { - TestLaneIdType::new(1, 2) + TestLaneIdType::try_new(1, 2).unwrap() } /// Underlying chain of `ThisChain`. @@ -373,7 +373,11 @@ impl MessageDispatch for DummyMessageDispatch { /// Reward account params that we are using in tests. pub fn test_reward_account_param() -> RewardsAccountParams { - RewardsAccountParams::new(TestLaneIdType::new(1, 2), *b"test", RewardsAccountOwner::ThisChain) + RewardsAccountParams::new( + TestLaneIdType::try_new(1, 2).unwrap(), + *b"test", + RewardsAccountOwner::ThisChain, + ) } /// Return test externalities to use in tests. diff --git a/bridges/modules/xcm-bridge-hub/src/dispatcher.rs b/bridges/modules/xcm-bridge-hub/src/dispatcher.rs index ca5c3755778e..dd855c7069aa 100644 --- a/bridges/modules/xcm-bridge-hub/src/dispatcher.rs +++ b/bridges/modules/xcm-bridge-hub/src/dispatcher.rs @@ -196,14 +196,14 @@ mod tests { fn invalid_message() -> DispatchMessage, TestLaneIdType> { DispatchMessage { - key: MessageKey { lane_id: TestLaneIdType::new(1, 2), nonce: 1 }, + key: MessageKey { lane_id: TestLaneIdType::try_new(1, 2).unwrap(), nonce: 1 }, data: DispatchMessageData { payload: Err(codec::Error::from("test")) }, } } fn valid_message() -> DispatchMessage, TestLaneIdType> { DispatchMessage { - key: MessageKey { lane_id: TestLaneIdType::new(1, 2), nonce: 1 }, + key: MessageKey { lane_id: TestLaneIdType::try_new(1, 2).unwrap(), nonce: 1 }, data: DispatchMessageData { payload: Ok(vec![42]) }, } } diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 1ce10f2935c9..22c60fb4ad60 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -1453,8 +1453,8 @@ mod tests { &bridge_destination_universal_location, ); let bridge_id_mismatch = BridgeId::new(&InteriorLocation::Here, &InteriorLocation::Here); - let lane_id = TestLaneIdType::new(1, 2); - let lane_id_mismatch = TestLaneIdType::new(3, 4); + let lane_id = TestLaneIdType::try_new(1, 2).unwrap(); + let lane_id_mismatch = TestLaneIdType::try_new(3, 4).unwrap(); let test_bridge_state = |id, bridge, diff --git a/bridges/primitives/messages/src/lane.rs b/bridges/primitives/messages/src/lane.rs index dab6c7b13d54..c835449db27d 100644 --- a/bridges/primitives/messages/src/lane.rs +++ b/bridges/primitives/messages/src/lane.rs @@ -39,8 +39,8 @@ pub trait LaneIdType: + Serialize + DeserializeOwned { - /// Creates a new `LaneId` type. - fn new(endpoint1: E, endpoint2: E) -> Self; + /// Creates a new `LaneId` type (if supported). + fn try_new(endpoint1: E, endpoint2: E) -> Result; } /// Bridge lane identifier (legacy). @@ -65,9 +65,9 @@ pub struct LegacyLaneId(pub [u8; 4]); impl LaneIdType for LegacyLaneId { /// Create lane identifier from two locations. - fn new(_endpoint1: T, _endpoint2: T) -> Self { + fn try_new(_endpoint1: T, _endpoint2: T) -> Result { // we don't support this for `LegacyLaneId`, because it was hard-coded before - unimplemented!(); + Err(()) } } @@ -169,10 +169,10 @@ impl TypeId for HashedLaneId { impl LaneIdType for HashedLaneId { /// Create lane identifier from two locations. - fn new(endpoint1: T, endpoint2: T) -> Self { + fn try_new(endpoint1: T, endpoint2: T) -> Result { const VALUES_SEPARATOR: [u8; 31] = *b"bridges-lane-id-value-separator"; - Self( + Ok(Self( if endpoint1 < endpoint2 { (endpoint1, VALUES_SEPARATOR, endpoint2) } else { @@ -180,7 +180,7 @@ impl LaneIdType for HashedLaneId { } .using_encoded(blake2_256) .into(), - ) + )) } } @@ -294,12 +294,12 @@ mod tests { #[test] fn hashed_lane_id_is_generated_using_ordered_endpoints() { - assert_eq!(HashedLaneId::new(1, 2), HashedLaneId::new(2, 1)); + assert_eq!(HashedLaneId::try_new(1, 2).unwrap(), HashedLaneId::try_new(2, 1).unwrap()); } #[test] fn hashed_lane_id_is_different_for_different_endpoints() { - assert_ne!(HashedLaneId::new(1, 2), HashedLaneId::new(1, 3)); + assert_ne!(HashedLaneId::try_new(1, 2).unwrap(), HashedLaneId::try_new(1, 3).unwrap()); } #[test] @@ -327,8 +327,8 @@ mod tests { } assert_ne!( - HashedLaneId::new(Either::Two(1, 2), Either::Two(3, 4)), - HashedLaneId::new(Either::Three(1, 2, 3), Either::One(4)), + HashedLaneId::try_new(Either::Two(1, 2), Either::Two(3, 4)).unwrap(), + HashedLaneId::try_new(Either::Three(1, 2, 3), Either::One(4)).unwrap(), ); } } diff --git a/bridges/primitives/messages/src/storage_keys.rs b/bridges/primitives/messages/src/storage_keys.rs index 0db0690447ff..fb3371cb830c 100644 --- a/bridges/primitives/messages/src/storage_keys.rs +++ b/bridges/primitives/messages/src/storage_keys.rs @@ -99,7 +99,8 @@ mod tests { fn storage_message_key_computed_properly() { // If this test fails, then something has been changed in module storage that is breaking // all previously crafted messages proofs. - let storage_key = message_key("BridgeMessages", &HashedLaneId::new(1, 2), 42).0; + let storage_key = + message_key("BridgeMessages", &HashedLaneId::try_new(1, 2).unwrap(), 42).0; assert_eq!( storage_key, hex!("dd16c784ebd3390a9bc0357c7511ed018a395e6242c6813b196ca31ed0547ea70e9bdb8f50c68d12f06eabb57759ee5eb1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dcf87f9793be208e5ea02a00000000000000").to_vec(), @@ -121,7 +122,8 @@ mod tests { fn outbound_lane_data_key_computed_properly() { // If this test fails, then something has been changed in module storage that is breaking // all previously crafted outbound lane state proofs. - let storage_key = outbound_lane_data_key("BridgeMessages", &HashedLaneId::new(1, 2)).0; + let storage_key = + outbound_lane_data_key("BridgeMessages", &HashedLaneId::try_new(1, 2).unwrap()).0; assert_eq!( storage_key, hex!("dd16c784ebd3390a9bc0357c7511ed0196c246acb9b55077390e3ca723a0ca1fd3bef8b00df8ca7b01813b5e2741950db1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dcf87f9793be208e5ea0").to_vec(), @@ -143,7 +145,8 @@ mod tests { fn inbound_lane_data_key_computed_properly() { // If this test fails, then something has been changed in module storage that is breaking // all previously crafted inbound lane state proofs. - let storage_key = inbound_lane_data_key("BridgeMessages", &HashedLaneId::new(1, 2)).0; + let storage_key = + inbound_lane_data_key("BridgeMessages", &HashedLaneId::try_new(1, 2).unwrap()).0; assert_eq!( storage_key, hex!("dd16c784ebd3390a9bc0357c7511ed01e5f83cf83f2127eb47afdc35d6e43fabd3bef8b00df8ca7b01813b5e2741950db1d3dccd8b3c3a012afe265f3e3c4432129b8aee50c9dcf87f9793be208e5ea0").to_vec(), diff --git a/bridges/primitives/relayers/src/lib.rs b/bridges/primitives/relayers/src/lib.rs index 91eab3cb687d..faa4cb177629 100644 --- a/bridges/primitives/relayers/src/lib.rs +++ b/bridges/primitives/relayers/src/lib.rs @@ -190,7 +190,7 @@ mod tests { assert_eq!( PayRewardFromAccount::<(), H256, HashedLaneId>::rewards_account( RewardsAccountParams::new( - HashedLaneId::new(1, 2), + HashedLaneId::try_new(1, 2).unwrap(), *b"test", RewardsAccountOwner::ThisChain ) @@ -202,7 +202,7 @@ mod tests { assert_eq!( PayRewardFromAccount::<(), H256, HashedLaneId>::rewards_account( RewardsAccountParams::new( - HashedLaneId::new(1, 3), + HashedLaneId::try_new(1, 3).unwrap(), *b"test", RewardsAccountOwner::ThisChain ) @@ -217,7 +217,7 @@ mod tests { assert_eq!( PayRewardFromAccount::<(), H256, HashedLaneId>::rewards_account( RewardsAccountParams::new( - HashedLaneId::new(1, 2), + HashedLaneId::try_new(1, 2).unwrap(), *b"test", RewardsAccountOwner::ThisChain ) @@ -229,7 +229,7 @@ mod tests { assert_eq!( PayRewardFromAccount::<(), H256, HashedLaneId>::rewards_account( RewardsAccountParams::new( - HashedLaneId::new(1, 2), + HashedLaneId::try_new(1, 2).unwrap(), *b"test", RewardsAccountOwner::BridgedChain ) diff --git a/bridges/primitives/xcm-bridge-hub/src/lib.rs b/bridges/primitives/xcm-bridge-hub/src/lib.rs index 729c1374bafc..061e7a275063 100644 --- a/bridges/primitives/xcm-bridge-hub/src/lib.rs +++ b/bridges/primitives/xcm-bridge-hub/src/lib.rs @@ -209,6 +209,8 @@ pub enum BridgeLocationsError { UnsupportedDestinationLocation, /// The version of XCM location argument is unsupported. UnsupportedXcmVersion, + /// The `LaneIdType` generator is not supported. + UnsupportedLaneIdType, } impl BridgeLocations { @@ -346,10 +348,11 @@ impl BridgeLocations { .into_version(xcm_version) .map_err(|_| BridgeLocationsError::UnsupportedXcmVersion); - Ok(LaneId::new( + LaneId::try_new( EncodedVersionedInteriorLocation(universal_location1.encode()), EncodedVersionedInteriorLocation(universal_location2.encode()), - )) + ) + .map_err(|_| BridgeLocationsError::UnsupportedLaneIdType) } } diff --git a/bridges/relays/lib-substrate-relay/src/messages/mod.rs b/bridges/relays/lib-substrate-relay/src/messages/mod.rs index ffa2c2a47db3..f7031648bc35 100644 --- a/bridges/relays/lib-substrate-relay/src/messages/mod.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/mod.rs @@ -720,7 +720,7 @@ mod tests { let receive_messages_proof = FromBridgedChainMessagesProof { bridged_header_hash: Default::default(), storage_proof: Default::default(), - lane: mock::TestLaneIdType::new(1, 2), + lane: mock::TestLaneIdType::try_new(1, 2).unwrap(), nonces_start: 0, nonces_end: 0, }; @@ -775,7 +775,7 @@ mod tests { let receive_messages_delivery_proof = FromBridgedChainMessagesDeliveryProof { bridged_header_hash: Default::default(), storage_proof: Default::default(), - lane: mock::TestLaneIdType::new(1, 2), + lane: mock::TestLaneIdType::try_new(1, 2).unwrap(), }; let relayers_state = UnrewardedRelayersState { unrewarded_relayer_entries: 0, diff --git a/bridges/relays/lib-substrate-relay/src/messages/source.rs b/bridges/relays/lib-substrate-relay/src/messages/source.rs index 8359b053309f..b560867a235b 100644 --- a/bridges/relays/lib-substrate-relay/src/messages/source.rs +++ b/bridges/relays/lib-substrate-relay/src/messages/source.rs @@ -668,7 +668,7 @@ mod tests { } let maybe_batches = split_msgs_to_refine::( - TestLaneIdType::new(1, 2), + TestLaneIdType::try_new(1, 2).unwrap(), msgs_to_refine, ); match expected_batches { diff --git a/bridges/relays/messages/src/message_lane_loop.rs b/bridges/relays/messages/src/message_lane_loop.rs index 2ee302a9259e..36de637f04c4 100644 --- a/bridges/relays/messages/src/message_lane_loop.rs +++ b/bridges/relays/messages/src/message_lane_loop.rs @@ -962,7 +962,7 @@ pub(crate) mod tests { }; let _ = run( Params { - lane: TestLaneIdType::new(1, 2), + lane: TestLaneIdType::try_new(1, 2).unwrap(), source_tick: Duration::from_millis(100), target_tick: Duration::from_millis(100), reconnect_delay: Duration::from_millis(0), @@ -1283,7 +1283,7 @@ pub(crate) mod tests { #[test] fn metrics_prefix_is_valid() { assert!(MessageLaneLoopMetrics::new(Some(&metrics_prefix::( - &HashedLaneId::new(1, 2) + &HashedLaneId::try_new(1, 2).unwrap() ))) .is_ok()); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs index e45117322fa3..002e31174cb1 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs @@ -609,7 +609,7 @@ mod bridge_hub_bulletin_tests { bridge_hub_test_utils::open_bridge_with_storage::< Runtime, XcmOverPolkadotBulletinInstance - >(locations, fee, HashedLaneId::new(1, 2)) + >(locations, fee, HashedLaneId::try_new(1, 2).unwrap()) } ).1 }, @@ -672,7 +672,7 @@ mod bridge_hub_bulletin_tests { bridge_hub_test_utils::open_bridge_with_storage::< Runtime, XcmOverPolkadotBulletinInstance, - >(locations, fee, HashedLaneId::new(1, 2)) + >(locations, fee, HashedLaneId::try_new(1, 2).unwrap()) }, ) .1 @@ -705,7 +705,7 @@ mod bridge_hub_bulletin_tests { bridge_hub_test_utils::open_bridge_with_storage::< Runtime, XcmOverPolkadotBulletinInstance, - >(locations, fee, HashedLaneId::new(1, 2)) + >(locations, fee, HashedLaneId::try_new(1, 2).unwrap()) }, ) .1 From 2f24d4846ab04c0642a087727f2e9ab1150284d4 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Tue, 24 Sep 2024 17:32:11 +0200 Subject: [PATCH 38/38] fix prdoc Signed-off-by: Oliver Tale-Yazdi --- prdoc/pr_5649.prdoc | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/prdoc/pr_5649.prdoc b/prdoc/pr_5649.prdoc index c7f1e0216e71..1f4c97aa1753 100644 --- a/prdoc/pr_5649.prdoc +++ b/prdoc/pr_5649.prdoc @@ -16,20 +16,17 @@ crates: - name: parachains-runtimes-test-utils bump: patch - name: bp-messages - bump: minor - validate: false + bump: major - name: bp-relayers - bump: minor - validate: false + bump: major - name: bp-xcm-bridge-hub - bump: patch + bump: major - name: pallet-bridge-messages bump: patch - name: pallet-bridge-relayers bump: patch - name: pallet-xcm-bridge-hub - bump: minor - validate: false + bump: major - name: emulated-integration-tests-common bump: patch - name: bp-bridge-hub-kusama @@ -43,12 +40,10 @@ crates: - name: bp-polkadot-bulletin bump: patch - name: bridge-hub-rococo-runtime - bump: minor - validate: false + bump: major - name: bridge-hub-westend-runtime bump: patch - name: polkadot-parachain-bin bump: none - name: bridge-hub-test-utils - bump: minor - validate: false + bump: major