From 138892d334532ba7d203fd0214ef2499391d7a45 Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Wed, 8 Nov 2023 19:13:38 +0200 Subject: [PATCH] Add commons crate for BridgeHub runtime --- Cargo.toml | 1 + .../runtimes/bridge-hubs/common/Cargo.toml | 35 ++++++ .../runtimes/bridge-hubs/common/src/lib.rs | 19 ++++ .../bridge-hubs/common/src/message_queue.rs | 107 ++++++++++++++++++ 4 files changed, 162 insertions(+) create mode 100644 cumulus/parachains/runtimes/bridge-hubs/common/Cargo.toml create mode 100644 cumulus/parachains/runtimes/bridge-hubs/common/src/lib.rs create mode 100644 cumulus/parachains/runtimes/bridge-hubs/common/src/message_queue.rs diff --git a/Cargo.toml b/Cargo.toml index 2344a24a5d95..60cb556b9fd6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -83,6 +83,7 @@ members = [ "cumulus/parachains/runtimes/bridge-hubs/bridge-hub-polkadot", "cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo", "cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend", + "cumulus/parachains/runtimes/bridge-hubs/common", "cumulus/parachains/runtimes/bridge-hubs/test-utils", "cumulus/parachains/runtimes/collectives/collectives-polkadot", "cumulus/parachains/runtimes/contracts/contracts-rococo", diff --git a/cumulus/parachains/runtimes/bridge-hubs/common/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/common/Cargo.toml new file mode 100644 index 000000000000..d59eaa0d35fc --- /dev/null +++ b/cumulus/parachains/runtimes/bridge-hubs/common/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "bridge-hub-common" +version = "0.1.0" +authors.workspace = true +edition.workspace = true +description = "Bridge hub common utilities" +license = "Apache-2.0" + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } +scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } +frame-support = { path = "../../../../../substrate/frame/support", default-features = false } +sp-std = { path = "../../../../../substrate/primitives/std", default-features = false } +sp-runtime = { path = "../../../../../substrate/primitives/runtime", default-features = false } +cumulus-primitives-core = { path = "../../../../primitives/core", default-features = false } +xcm = { package = "staging-xcm", path = "../../../../../polkadot/xcm", default-features = false} + + +[features] +default = [ "std" ] +std = [ + "codec/std", + "scale-info/std", + "frame-support/std", + "sp-std/std", + "sp-runtime/std", + "cumulus-primitives-core/std", + "xcm/std" +] + +runtime-benchmarks = [ + "frame-support/runtime-benchmarks", + "cumulus-primitives-core/runtime-benchmarks", + "sp-runtime/runtime-benchmarks" +] diff --git a/cumulus/parachains/runtimes/bridge-hubs/common/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/common/src/lib.rs new file mode 100644 index 000000000000..eb02498448a1 --- /dev/null +++ b/cumulus/parachains/runtimes/bridge-hubs/common/src/lib.rs @@ -0,0 +1,19 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#![cfg_attr(not(feature = "std"), no_std)] + +pub mod message_queue; + +pub use message_queue::{AggregateMessageOrigin, BridgeHubMessageRouter}; diff --git a/cumulus/parachains/runtimes/bridge-hubs/common/src/message_queue.rs b/cumulus/parachains/runtimes/bridge-hubs/common/src/message_queue.rs new file mode 100644 index 000000000000..54f54b3e2290 --- /dev/null +++ b/cumulus/parachains/runtimes/bridge-hubs/common/src/message_queue.rs @@ -0,0 +1,107 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//! Runtime configuration for MessageQueue pallet +use sp_std::{prelude::*, marker::PhantomData}; +use codec::{Decode, Encode, MaxEncodedLen}; +use frame_support::{weights::WeightMeter, traits::{ProcessMessage, ProcessMessageError}}; +use scale_info::TypeInfo; +use cumulus_primitives_core::ParaId; +use xcm::v3::{MultiLocation, Junction}; + +/// The aggregate origin of an inbound message. +/// This is specialized for BridgeHub, as the snowbridge-outbound-queue pallet is also using +/// the shared MessageQueue pallet. +#[derive(Encode, Decode, MaxEncodedLen, Clone, Eq, PartialEq, TypeInfo, Debug)] +pub enum AggregateMessageOrigin { + /// The message came from the para-chain itself. + Here, + /// The message came from the relay-chain. + /// + /// This is used by the DMP queue. + Parent, + /// The message came from a sibling para-chain. + /// + /// This is used by the HRMP queue. + Sibling(ParaId), + Snowbridge(SnowbridgeMessageOrigin), +} + +/// The origin of an inbound message for Snowbridge. +#[derive(Encode, Decode, MaxEncodedLen, Clone, Eq, PartialEq, TypeInfo, Debug)] +pub enum SnowbridgeMessageOrigin { + /// The message came from the para-chain itself. + Here, + /// The message came from a sibling para-chain. + Sibling(ParaId), +} + +impl From for MultiLocation { + fn from(origin: AggregateMessageOrigin) -> Self { + use AggregateMessageOrigin::*; + match origin { + Here => MultiLocation::here(), + Parent => MultiLocation::parent(), + Sibling(id) => + MultiLocation::new(1, Junction::Parachain(id.into())), + // NOTE: We don't need this conversion for Snowbridge. However we have to + // implement it anyway as xcm_builder::ProcessXcmMessage requires it. + Snowbridge(_) => MultiLocation::default(), + } + } +} + +#[cfg(feature = "runtime-benchmarks")] +impl From for AggregateMessageOrigin { + fn from(x: u32) -> Self { + match x { + 0 => Self::Here, + 1 => Self::Parent, + p => Self::Sibling(ParaId::from(p)), + } + } +} + +/// Routes messages to either the XCMP or Snowbridge processor. +pub struct BridgeHubMessageRouter(PhantomData<(XcmpProcessor, SnowbridgeProcessor)>) +where + XcmpProcessor: ProcessMessage, + SnowbridgeProcessor: ProcessMessage; + +impl< + XcmpProcessor, + SnowbridgeProcessor +> ProcessMessage for BridgeHubMessageRouter< + XcmpProcessor, + SnowbridgeProcessor +> +where + XcmpProcessor: ProcessMessage, + SnowbridgeProcessor: ProcessMessage +{ + type Origin = AggregateMessageOrigin; + + fn process_message( + message: &[u8], + origin: Self::Origin, + meter: &mut WeightMeter, + id: &mut [u8; 32], + ) -> Result { + use AggregateMessageOrigin::*; + match origin { + Here | Parent | Sibling(_) => XcmpProcessor::process_message(message, origin, meter, id), + Snowbridge(_) => SnowbridgeProcessor::process_message(message, origin, meter, id) + } + } +}