Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ members = [
"cumulus/parachains/runtimes/bridge-hubs/bridge-hub-kusama",
"cumulus/parachains/runtimes/bridge-hubs/bridge-hub-polkadot",
"cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo",
"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",
Expand Down
25 changes: 16 additions & 9 deletions cumulus/parachains/common/src/message_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,40 +16,47 @@

//! Helpers to deal with configuring the message queue in the runtime.

use cumulus_primitives_core::{AggregateMessageOrigin, ParaId};
use cumulus_primitives_core::{AggregateMessageOrigin, MessageOrigin, ParaId};
use frame_support::traits::{QueueFootprint, QueuePausedQuery};
use pallet_message_queue::OnQueueChanged;
use sp_std::marker::PhantomData;

/// Narrow the scope of the `Inner` query from `AggregateMessageOrigin` to `ParaId`.
///
/// All non-`Sibling` variants will be ignored.
pub struct NarrowOriginToSibling<Inner>(PhantomData<Inner>);
pub struct NarrowOriginToXcmSibling<Inner>(PhantomData<Inner>);
impl<Inner: QueuePausedQuery<ParaId>> QueuePausedQuery<AggregateMessageOrigin>
for NarrowOriginToSibling<Inner>
for NarrowOriginToXcmSibling<Inner>
{
fn is_paused(origin: &AggregateMessageOrigin) -> bool {
use AggregateMessageOrigin::*;
use MessageOrigin::*;
match origin {
AggregateMessageOrigin::Sibling(id) => Inner::is_paused(id),
Xcm(Sibling(id)) => Inner::is_paused(id),
_ => false,
}
}
}

impl<Inner: OnQueueChanged<ParaId>> OnQueueChanged<AggregateMessageOrigin>
for NarrowOriginToSibling<Inner>
for NarrowOriginToXcmSibling<Inner>
{
fn on_queue_changed(origin: AggregateMessageOrigin, fp: QueueFootprint) {
if let AggregateMessageOrigin::Sibling(id) = origin {
use AggregateMessageOrigin::*;
use MessageOrigin::*;
if let Xcm(Sibling(id)) = origin {
Inner::on_queue_changed(id, fp)
}
}
}

/// Convert a sibling `ParaId` to an `AggregateMessageOrigin`.
pub struct ParaIdToSibling;
impl sp_runtime::traits::Convert<ParaId, AggregateMessageOrigin> for ParaIdToSibling {
pub struct ParaIdToXcmSibling;
impl sp_runtime::traits::Convert<ParaId, AggregateMessageOrigin> for ParaIdToXcmSibling {
fn convert(para_id: ParaId) -> AggregateMessageOrigin {
AggregateMessageOrigin::Sibling(para_id)
use AggregateMessageOrigin::*;
use MessageOrigin::*;
Xcm(Sibling(para_id))
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ pallet-bridge-messages = { path = "../../../../../bridges/modules/messages", def
pallet-bridge-parachains = { path = "../../../../../bridges/modules/parachains", default-features = false }
pallet-bridge-relayers = { path = "../../../../../bridges/modules/relayers", default-features = false }
bridge-runtime-common = { path = "../../../../../bridges/bin/runtime-common", default-features = false }
bridge-hub-common = { path = "../common", default-features = false }


[dev-dependencies]
static_assertions = "1.1"
Expand All @@ -115,6 +117,7 @@ std = [
"bp-runtime/std",
"bp-wococo/std",
"bridge-runtime-common/std",
"bridge-hub-common/std",
"codec/std",
"cumulus-pallet-aura-ext/std",
"cumulus-pallet-dmp-queue/std",
Expand Down Expand Up @@ -179,6 +182,7 @@ std = [

runtime-benchmarks = [
"bridge-runtime-common/runtime-benchmarks",
"bridge-hub-common/runtime-benchmarks",
"cumulus-pallet-dmp-queue/runtime-benchmarks",
"cumulus-pallet-parachain-system/runtime-benchmarks",
"cumulus-pallet-session-benchmarking/runtime-benchmarks",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ use sp_std::prelude::*;
use sp_version::NativeVersion;
use sp_version::RuntimeVersion;

use cumulus_primitives_core::{AggregateMessageOrigin, ParaId};
use cumulus_primitives_core::{AggregateMessageOrigin, MessageOrigin, ParaId};
use frame_support::{
construct_runtime,
dispatch::DispatchClass,
genesis_builder_helper::{build_config, create_default_config},
parameter_types,
traits::{ConstBool, ConstU32, ConstU64, ConstU8, Everything, TransformOrigin},
traits::{ConstBool, ConstU32, ConstU64, ConstU8, Everything, TransformOrigin, ProcessMessage},
weights::{ConstantMultiplier, Weight},
PalletId,
};
Expand Down Expand Up @@ -91,6 +91,7 @@ use parachains_common::{
AccountId, Balance, BlockNumber, Hash, Header, Nonce, Signature, AVERAGE_ON_INITIALIZE_RATIO,
HOURS, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION,
};
use bridge_hub_common::BridgeHubMessageProcessor;

/// Enum for handling differences in the runtime configuration for BridgeHubRococo vs
/// BridgeHubWococo.
Expand Down Expand Up @@ -357,6 +358,10 @@ parameter_types! {
pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block;
}

// FIXME: Replace with actual implementation once we've added our pallets to the runtime
pub type SnowbridgeMessageProcessor = ();
pub type SnowbridgeQueuePausedQuery = ();

impl pallet_message_queue::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = weights::pallet_message_queue::WeightInfo<Runtime>;
Expand All @@ -365,15 +370,18 @@ impl pallet_message_queue::Config for Runtime {
cumulus_primitives_core::AggregateMessageOrigin,
>;
#[cfg(not(feature = "runtime-benchmarks"))]
type MessageProcessor = xcm_builder::ProcessXcmMessage<
AggregateMessageOrigin,
xcm_executor::XcmExecutor<xcm_config::XcmConfig>,
RuntimeCall,
type MessageProcessor = BridgeHubMessageProcessor<
xcm_builder::ProcessXcmMessage<
MessageOrigin,
xcm_executor::XcmExecutor<xcm_config::XcmConfig>,
RuntimeCall,
>,
SnowbridgeMessageProcessor
>;
type Size = u32;
// The XCMP queue pallet is only ever able to handle the `Sibling(ParaId)` origin:
type QueueChangeHandler = NarrowOriginToSibling<XcmpQueue>;
type QueuePausedQuery = NarrowOriginToSibling<XcmpQueue>;
type QueueChangeHandler = NarrowOriginToXcmSibling<XcmpQueue>;
type QueuePausedQuery = (NarrowOriginToXcmSibling<XcmpQueue>, SnowbridgeQueuePausedQuery);
type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>;
type MaxStale = sp_core::ConstU32<8>;
type ServiceWeight = MessageQueueServiceWeight;
Expand All @@ -400,7 +408,7 @@ impl cumulus_pallet_xcmp_queue::Config for Runtime {
type ChannelInfo = ParachainSystem;
type VersionWrapper = PolkadotXcm;
// Enqueue XCMP messages from siblings for later processing.
type XcmpQueue = TransformOrigin<MessageQueue, AggregateMessageOrigin, ParaId, ParaIdToSibling>;
type XcmpQueue = TransformOrigin<MessageQueue, AggregateMessageOrigin, ParaId, ParaIdToXcmSibling>;
type MaxInboundSuspended = sp_core::ConstU32<1_000>;
type ControllerOrigin = EnsureRoot<AccountId>;
type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin;
Expand All @@ -409,7 +417,7 @@ impl cumulus_pallet_xcmp_queue::Config for Runtime {
}

parameter_types! {
pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent;
pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Xcm(MessageOrigin::Parent);
}

impl cumulus_pallet_dmp_queue::Config for Runtime {
Expand Down Expand Up @@ -519,7 +527,6 @@ construct_runtime!(
PolkadotXcm: pallet_xcm::{Pallet, Call, Event<T>, Origin, Config<T>} = 31,
CumulusXcm: cumulus_pallet_xcm::{Pallet, Event<T>, Origin} = 32,
DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event<T>} = 33,
MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event<T>} = 34,

// Handy utilities.
Utility: pallet_utility::{Pallet, Call, Event} = 40,
Expand All @@ -540,6 +547,8 @@ construct_runtime!(
BridgeWococoToRococoMessages: pallet_bridge_messages::<Instance2>::{Pallet, Call, Storage, Event<T>, Config<T>} = 45,

BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event<T>} = 47,

MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event<T>} = 255,
}
);

Expand Down
25 changes: 25 additions & 0 deletions cumulus/parachains/runtimes/bridge-hubs/common/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[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]
sp-std = { path = "../../../../../substrate/primitives/std", default-features = false }
frame-support = { path = "../../../../../substrate/frame/support", default-features = false }
cumulus-primitives-core = { path = "../../../../primitives/core", default-features = false }

[features]
default = [ "std" ]
std = [
"sp-std/std",
"frame-support/std",
"cumulus-primitives-core/std"
]

runtime-benchmarks = [
"frame-support/runtime-benchmarks",
"cumulus-primitives-core/runtime-benchmarks"
]
36 changes: 36 additions & 0 deletions cumulus/parachains/runtimes/bridge-hubs/common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use sp_std::marker::PhantomData;
use frame_support::traits::{ProcessMessage, ProcessMessageError};
use frame_support::weights::WeightMeter;
use cumulus_primitives_core::{AggregateMessageOrigin, MessageOrigin};

pub struct BridgeHubMessageProcessor<XcmProcessor, SnowbridgeProcessor>(PhantomData<(XcmProcessor, SnowbridgeProcessor)>)
where
XcmProcessor: ProcessMessage<Origin = MessageOrigin>,
SnowbridgeProcessor: ProcessMessage<Origin = MessageOrigin>;

impl<
XcmProcessor,
SnowbridgeProcessor
> ProcessMessage for BridgeHubMessageProcessor<
XcmProcessor,
SnowbridgeProcessor
>
where
XcmProcessor: ProcessMessage<Origin = MessageOrigin>,
SnowbridgeProcessor: ProcessMessage<Origin = MessageOrigin>
{
type Origin = AggregateMessageOrigin;

fn process_message(
message: &[u8],
origin: Self::Origin,
meter: &mut WeightMeter,
id: &mut [u8; 32],
) -> Result<bool, ProcessMessageError> {
use AggregateMessageOrigin::*;
match origin {
Xcm(inner) => XcmProcessor::process_message(message, inner, meter, id),
Other(inner) => SnowbridgeProcessor::process_message(message, inner, meter, id)
}
}
}
37 changes: 25 additions & 12 deletions cumulus/primitives/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,18 @@ impl From<MessageSendError> for &'static str {
}
}

/// The origin of an inbound message.
/// The aggregate origin of an inbound message.
#[derive(Encode, Decode, MaxEncodedLen, Clone, Eq, PartialEq, TypeInfo, Debug)]
pub enum AggregateMessageOrigin {
/// The message came from the DMP or HRMP subsystem
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think we can just change this enum, since its use by the MQ pallet as queue ID.
That would mean that we need a lazy migration across all parachain which is a huge pain.
It would be better to just add a variant to it like Abridged or Other and keeping the others compatible.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless this change goes in directly after #1246 in the same release, but its difficult.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also this doesn't make sense, XCM is not an origin or transport protocol. I can't tell if you are indicating the format of the message or its origin with this type? If the latter, why not just add a new variant to the AggregateMessageOrigin enum, like ExternalConsensus(Junction), where the Junction is expected to be of the variant GlobalConsensus(NetworkId)?

Copy link
Copy Markdown
Contributor Author

@vgeddes vgeddes Nov 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think we can just change this enum, since its use by the MQ pallet as queue ID.

Good point, didn't think of that. I'll will just add another variant to the enum then.

Here's a new design, inline with the above suggested changes.

Since the NetworkId and Junction types are not stable across XCM versions (and because they are only meant to be used at higher protocol layers), I have not used them here.

/// The origin of an inbound message.
#[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),
	/// External consensus
	ExternalConsensus {
		origin: ExternalConsensusOrigin,
		dest: ExternalConsensusDestination
	}
}

/// External consensus destinations
#[derive(Encode, Decode, MaxEncodedLen, Clone, Eq, PartialEq, TypeInfo, Debug)]
pub enum ExternalConsensusDestination {
	// This network is reachable via Snowbridge on BridgeHub
	Ethereum { chain_id: u64 }
}

/// The origin of a message destined for an external consensus system
#[derive(Encode, Decode, MaxEncodedLen, Clone, Eq, PartialEq, TypeInfo, Debug)]
pub enum ExternalConsensusOrigin {
	Here,
	Sibling(ParaId)
}

Xcm(MessageOrigin),
/// The message came from some other pallet
Other(MessageOrigin),
}

/// The origin of an inbound message.
#[derive(Encode, Decode, MaxEncodedLen, Clone, Eq, PartialEq, TypeInfo, Debug)]
pub enum MessageOrigin {
/// The message came from the para-chain itself.
Here,
/// The message came from the relay-chain.
Expand All @@ -93,24 +102,27 @@ pub enum AggregateMessageOrigin {
Sibling(ParaId),
}

impl From<AggregateMessageOrigin> for xcm::v3::MultiLocation {
fn from(origin: AggregateMessageOrigin) -> Self {
impl From<MessageOrigin> for xcm::v3::MultiLocation {
fn from(origin: MessageOrigin) -> Self {
use MessageOrigin::*;
match origin {
AggregateMessageOrigin::Here => MultiLocation::here(),
AggregateMessageOrigin::Parent => MultiLocation::parent(),
AggregateMessageOrigin::Sibling(id) =>
MultiLocation::new(1, Junction::Parachain(id.into())),
Here => MultiLocation::here(),
Parent => MultiLocation::parent(),
Sibling(id) => {
MultiLocation::new(1, Junction::Parachain(id.into()))
},
}
}
}

#[cfg(feature = "runtime-benchmarks")]
impl From<u32> for AggregateMessageOrigin {
fn from(x: u32) -> Self {
use MessageOrigin::*;
match x {
0 => Self::Here,
1 => Self::Parent,
p => Self::Sibling(ParaId::from(p)),
0 => Self::Xcm(Here),
1 => Self::Xcm(Parent),
p => Self::Xcm(Sibling(ParaId::from(p))),
}
}
}
Expand Down Expand Up @@ -265,11 +277,12 @@ impl CumulusDigestItem {
/// well-behaving runtimes should not produce headers with more than one.
pub fn extract_relay_parent(digest: &Digest) -> Option<relay_chain::Hash> {
digest.convert_first(|d| match d {
DigestItem::Consensus(id, val) if id == &CUMULUS_CONSENSUS_ID =>
DigestItem::Consensus(id, val) if id == &CUMULUS_CONSENSUS_ID => {
match CumulusDigestItem::decode(&mut &val[..]) {
Ok(CumulusDigestItem::RelayParent(hash)) => Some(hash),
_ => None,
},
}
},
_ => None,
})
}
Expand Down
10 changes: 8 additions & 2 deletions substrate/frame/support/src/traits/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,14 @@ pub trait QueuePausedQuery<Origin> {
fn is_paused(origin: &Origin) -> bool;
}

impl<Origin> QueuePausedQuery<Origin> for () {
fn is_paused(_: &Origin) -> bool {
#[impl_trait_for_tuples::impl_for_tuples(30)]
impl<Origin> QueuePausedQuery<Origin> for Tuple {
fn is_paused(origin: &Origin) -> bool {
for_tuples!( #(
if Tuple::is_paused(origin) {
return true;
}
)* );
false
}
}