Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Kusama origins as xcm multi_location #6273

Merged
merged 18 commits into from
Dec 21, 2022
Merged
Show file tree
Hide file tree
Changes from 7 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
13 changes: 13 additions & 0 deletions runtime/kusama/constants/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,19 @@ pub mod fee {
}
}

/// XCM protocol related constants.
pub mod xcm {
/// Pluralistic bodies existing within the consensus.
pub mod body {
// Preallocated for the Root body.
#[allow(dead_code)]
const ROOT_INDEX: u32 = 0;
// The bodies corresponding to the runtime origins representing a plurality voice given via a referendum.
pub const STAKING_ADMIN_INDEX: u32 = 1;
pub const FELLOWS_INDEX: u32 = 2;
}
}

#[cfg(test)]
mod tests {
use super::{
Expand Down
41 changes: 33 additions & 8 deletions runtime/kusama/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,19 @@

use super::{
parachains_origin, AccountId, Balances, CouncilCollective, ParaId, Runtime, RuntimeCall,
RuntimeEvent, RuntimeOrigin, WeightToFee, XcmPallet,
RuntimeEvent, RuntimeOrigin, StakingAdmin, WeightToFee, XcmPallet,
};
use frame_support::{match_types, parameter_types, traits::Everything};
use kusama_runtime_constants::xcm::body::{FELLOWS_INDEX, STAKING_ADMIN_INDEX};
use runtime_common::{xcm_sender, ToAuthor};
use xcm::latest::prelude::*;
use xcm_builder::{
AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom,
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! {
Expand Down Expand Up @@ -154,6 +155,10 @@ impl xcm_executor::Config for XcmConfig {

parameter_types! {
pub const CouncilBodyId: BodyId = BodyId::Executive;
// StakingAdmin pluralistic body.
pub const StakingAdminBodyId: BodyId = BodyId::Index(STAKING_ADMIN_INDEX);
// Fellows pluralistic body.
pub const FellowsBodyId: BodyId = BodyId::Index(FELLOWS_INDEX);
}

/// Type to convert the council origin to a Plurality `MultiLocation` value.
Expand All @@ -172,13 +177,33 @@ pub type LocalOriginToLocation = (
// And a usual Signed origin to be used in XCM as a corresponding AccountId32
SignedToAccountId32<RuntimeOrigin, AccountId, KusamaNetwork>,
);

/// Type to convert the `StakingAdmin` origin to a Plurality `MultiLocation` value.
pub type StakingAdminToPlurality =
OriginToPluralityVoice<RuntimeOrigin, StakingAdmin, StakingAdminBodyId>;

/// Type to convert the Fellows origin to a Plurality `MultiLocation` value.
pub type FellowsToPlurality = OriginToPluralityVoice<RuntimeOrigin, StakingAdmin, FellowsBodyId>;
muharem marked this conversation as resolved.
Show resolved Hide resolved

/// 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<RuntimeOrigin, CouncilToPlurality>;
// 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<RuntimeOrigin, LocalPalletOriginToLocation>;
type XcmRouter = XcmRouter;
// Anyone can execute XCM messages locally.
type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
Expand Down
13 changes: 13 additions & 0 deletions xcm/pallet-xcm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1517,6 +1517,19 @@ impl<Prefix: Get<MultiLocation>, Body: Get<BodyId>> Contains<MultiLocation>
}
}

/// Filter for `MultiLocation` to find those which represent a voice of an identified plurality.
///
/// May reasonably be used with `EnsureXcm`.
pub struct IsVoiceOfBody<Prefix, Body>(PhantomData<(Prefix, Body)>);
impl<Prefix: Get<MultiLocation>, Body: Get<BodyId>> Contains<MultiLocation>
for IsVoiceOfBody<Prefix, Body>
{
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<F>(PhantomData<F>);
Expand Down
2 changes: 1 addition & 1 deletion xcm/xcm-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down
17 changes: 17 additions & 0 deletions xcm/xcm-builder/src/origin_conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<RuntimeOrigin, EnsureBodyOrigin, Body>(
PhantomData<(RuntimeOrigin, EnsureBodyOrigin, Body)>,
);
impl<RuntimeOrigin: Clone, EnsureBodyOrigin: EnsureOrigin<RuntimeOrigin>, Body: Get<BodyId>>
Convert<RuntimeOrigin, MultiLocation>
for OriginToPluralityVoice<RuntimeOrigin, EnsureBodyOrigin, Body>
{
fn convert(o: RuntimeOrigin) -> Result<MultiLocation, RuntimeOrigin> {
match EnsureBodyOrigin::try_origin(o) {
Ok(_) => Ok(Junction::Plurality { id: Body::get(), part: BodyPart::Voice }.into()),
KiChjang marked this conversation as resolved.
Show resolved Hide resolved
Err(o) => Err(o),
}
}
}