diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs index a67e2d467351..125ce049b195 100644 --- a/runtime/kusama/src/lib.rs +++ b/runtime/kusama/src/lib.rs @@ -106,7 +106,7 @@ pub mod xcm_config; // Governance configurations. pub mod governance; use governance::{ - old::CouncilCollective, pallet_custom_origins, AuctionAdmin, GeneralAdmin, LeaseAdmin, + old::CouncilCollective, pallet_custom_origins, AuctionAdmin, Fellows, GeneralAdmin, LeaseAdmin, StakingAdmin, Treasurer, TreasurySpender, }; use xcm_config::CheckAccount; diff --git a/runtime/kusama/src/xcm_config.rs b/runtime/kusama/src/xcm_config.rs index 17310dd5ead1..55a474e239f6 100644 --- a/runtime/kusama/src/xcm_config.rs +++ b/runtime/kusama/src/xcm_config.rs @@ -17,8 +17,8 @@ //! XCM configurations for the Kusama runtime. use super::{ - parachains_origin, AccountId, Balances, CouncilCollective, ParaId, Runtime, RuntimeCall, - RuntimeEvent, RuntimeOrigin, WeightToFee, XcmPallet, + parachains_origin, AccountId, Balances, CouncilCollective, Fellows, ParaId, Runtime, + RuntimeCall, RuntimeEvent, RuntimeOrigin, StakingAdmin, WeightToFee, XcmPallet, }; use frame_support::{match_types, parameter_types, traits::Everything}; use runtime_common::{xcm_sender, ToAuthor}; @@ -28,8 +28,8 @@ use xcm_builder::{ AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, BackingToPlurality, ChildParachainAsNative, ChildParachainConvertsVia, ChildSystemParachainAsSuperuser, CurrencyAdapter as XcmCurrencyAdapter, FixedWeightBounds, IsChildSystemParachain, IsConcrete, - LocationInverter, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, - TakeWeightCredit, UsingComponents, WeightInfoBounds, + LocationInverter, OriginToPluralityVoice, SignedAccountId32AsNative, SignedToAccountId32, + SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, WeightInfoBounds, }; parameter_types! { @@ -154,6 +154,10 @@ impl xcm_executor::Config for XcmConfig { parameter_types! { pub const CouncilBodyId: BodyId = BodyId::Executive; + // StakingAdmin pluralistic body. + pub const StakingAdminBodyId: BodyId = BodyId::Defense; + // Fellows pluralistic body. + pub const FellowsBodyId: BodyId = BodyId::Technical; } /// Type to convert the council origin to a Plurality `MultiLocation` value. @@ -172,13 +176,33 @@ pub type LocalOriginToLocation = ( // And a usual Signed origin to be used in XCM as a corresponding AccountId32 SignedToAccountId32, ); + +/// Type to convert the `StakingAdmin` origin to a Plurality `MultiLocation` value. +pub type StakingAdminToPlurality = + OriginToPluralityVoice; + +/// Type to convert the Fellows origin to a Plurality `MultiLocation` value. +pub type FellowsToPlurality = OriginToPluralityVoice; + +/// Type to convert a pallet `Origin` type value into a `MultiLocation` value which represents an interior location +/// of this chain for a destination chain. +pub type LocalPalletOriginToLocation = ( + // We allow an origin from the Collective pallet to be used in XCM as a corresponding Plurality of the + // `Unit` body. + CouncilToPlurality, + // StakingAdmin origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + StakingAdminToPlurality, + // Fellows origin to be used in XCM as a corresponding Plurality `MultiLocation` value. + FellowsToPlurality, +); + impl pallet_xcm::Config for Runtime { type RuntimeEvent = RuntimeEvent; - // We only allow the council to send messages. This is basically safe to enable for everyone - // (safe the possibility of someone spamming the parachain if they're willing to pay the KSM to - // send from the Relay-chain), but it's useless until we bring in XCM v3 which will make - // `DescendOrigin` a bit more useful. - type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; + // We only allow the root, the council, fellows and the staking admin to send messages. + // This is basically safe to enable for everyone (safe the possibility of someone spamming the parachain + // if they're willing to pay the KSM to send from the Relay-chain), but it's useless until we bring in XCM v3 + // which will make `DescendOrigin` a bit more useful. + type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; type XcmRouter = XcmRouter; // Anyone can execute XCM messages locally. type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin; diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs index 78dc5087d960..a66da4dcd718 100644 --- a/xcm/pallet-xcm/src/lib.rs +++ b/xcm/pallet-xcm/src/lib.rs @@ -1517,6 +1517,19 @@ impl, Body: Get> Contains } } +/// Filter for `MultiLocation` to find those which represent a voice of an identified plurality. +/// +/// May reasonably be used with `EnsureXcm`. +pub struct IsVoiceOfBody(PhantomData<(Prefix, Body)>); +impl, Body: Get> Contains + for IsVoiceOfBody +{ + fn contains(l: &MultiLocation) -> bool { + let maybe_suffix = l.match_and_split(&Prefix::get()); + matches!(maybe_suffix, Some(Plurality { id, part }) if id == &Body::get() && part == &BodyPart::Voice) + } +} + /// `EnsureOrigin` implementation succeeding with a `MultiLocation` value to recognize and filter the /// `Origin::Xcm` item. pub struct EnsureXcm(PhantomData); diff --git a/xcm/src/v0/junction.rs b/xcm/src/v0/junction.rs index 67f17f464a37..450e882ac3e8 100644 --- a/xcm/src/v0/junction.rs +++ b/xcm/src/v0/junction.rs @@ -52,6 +52,15 @@ pub enum BodyId { /// The unambiguous judicial body (this doesn't exist on Polkadot, but if it were to get a "grand oracle", it /// may be considered as that). Judicial, + /// The unambiguous defense body (for Polkadot, an opinion on the topic given via a public referendum + /// on the `staking_admin` track). + Defense, + /// The unambiguous administration body (for Polkadot, an opinion on the topic given via a public referendum + /// on the `general_admin` track). + Administration, + /// The unambiguous treasury body (for Polkadot, an opinion on the topic given via a public referendum + /// on the `treasurer` track). + Treasury, } /// A part of a pluralistic body. diff --git a/xcm/xcm-builder/src/lib.rs b/xcm/xcm-builder/src/lib.rs index e3473d55d5eb..aa55c56d2cd7 100644 --- a/xcm/xcm-builder/src/lib.rs +++ b/xcm/xcm-builder/src/lib.rs @@ -37,7 +37,7 @@ pub use location_conversion::{ mod origin_conversion; pub use origin_conversion::{ BackingToPlurality, ChildParachainAsNative, ChildSystemParachainAsSuperuser, EnsureXcmOrigin, - ParentAsSuperuser, RelayChainAsNative, SiblingParachainAsNative, + OriginToPluralityVoice, ParentAsSuperuser, RelayChainAsNative, SiblingParachainAsNative, SiblingSystemParachainAsSuperuser, SignedAccountId32AsNative, SignedAccountKey20AsNative, SignedToAccountId32, SovereignSignedViaLocation, }; diff --git a/xcm/xcm-builder/src/origin_conversion.rs b/xcm/xcm-builder/src/origin_conversion.rs index 9fe50eaf9c3f..4d024a9d12c2 100644 --- a/xcm/xcm-builder/src/origin_conversion.rs +++ b/xcm/xcm-builder/src/origin_conversion.rs @@ -321,3 +321,20 @@ where }) } } + +/// `Convert` implementation to convert from an origin which passes the check of an `EnsureOrigin` +/// into a voice of a given pluralistic `Body`. +pub struct OriginToPluralityVoice( + PhantomData<(RuntimeOrigin, EnsureBodyOrigin, Body)>, +); +impl, Body: Get> + Convert + for OriginToPluralityVoice +{ + fn convert(o: RuntimeOrigin) -> Result { + match EnsureBodyOrigin::try_origin(o) { + Ok(_) => Ok(Junction::Plurality { id: Body::get(), part: BodyPart::Voice }.into()), + Err(o) => Err(o), + } + } +}