From cb5a244f3d4e7966fe1fb6ccd32030dd715d0b40 Mon Sep 17 00:00:00 2001 From: Shaun Wang Date: Wed, 10 Mar 2021 10:57:44 +1300 Subject: [PATCH] Support xcm local execution in xcm-handler. (#357) * Support xcm local execution in xcm handler. * Add docs. --- Cargo.lock | 1 + pallets/xcm-handler/Cargo.toml | 4 +++- pallets/xcm-handler/src/lib.rs | 23 ++++++++++++++++++++++- rococo-parachains/runtime/src/lib.rs | 1 + 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d249158bfc..f2c36dfacd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1304,6 +1304,7 @@ dependencies = [ "parity-scale-codec", "sp-std", "xcm", + "xcm-executor", ] [[package]] diff --git a/pallets/xcm-handler/Cargo.toml b/pallets/xcm-handler/Cargo.toml index b982c1dba6..c5d57a2b32 100644 --- a/pallets/xcm-handler/Cargo.toml +++ b/pallets/xcm-handler/Cargo.toml @@ -16,6 +16,7 @@ frame-system = { git = "https://github.com/paritytech/substrate", default-featur # Polkadot Dependencies xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" } +xcm-executor = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" } # Cumulus Dependencies cumulus-primitives-core = { path = "../../primitives/core", default-features = false } @@ -29,5 +30,6 @@ std = [ "frame-support/std", "frame-system/std", "cumulus-primitives-core/std", - "xcm/std" + "xcm/std", + "xcm-executor/std", ] diff --git a/pallets/xcm-handler/src/lib.rs b/pallets/xcm-handler/src/lib.rs index 1f80eee780..03d50fa19a 100644 --- a/pallets/xcm-handler/src/lib.rs +++ b/pallets/xcm-handler/src/lib.rs @@ -27,12 +27,13 @@ use cumulus_primitives_core::{ DownwardMessageHandler, HrmpMessageHandler, HrmpMessageSender, InboundDownwardMessage, InboundHrmpMessage, OutboundHrmpMessage, ParaId, UpwardMessageSender, }; -use frame_support::{decl_error, decl_event, decl_module, sp_runtime::traits::Hash, traits::EnsureOrigin}; +use frame_support::{decl_error, decl_event, decl_module, dispatch::DispatchResult, sp_runtime::traits::Hash, traits::EnsureOrigin}; use sp_std::convert::{TryFrom, TryInto}; use xcm::{ v0::{Error as XcmError, ExecuteXcm, Junction, MultiLocation, SendXcm, Xcm}, VersionedXcm, }; +use xcm_executor::traits::LocationConversion; pub trait Config: frame_system::Config { type Event: From> + Into<::Event>; @@ -45,6 +46,9 @@ pub trait Config: frame_system::Config { /// Required origin for sending XCM messages. Typically Root or parachain /// council majority. type SendXcmOrigin: EnsureOrigin; + /// Utility for converting from the signed origin (of type `Self::AccountId`) into a sensible + /// `MultiLocation` ready for passing to the XCM interpreter. + type AccountIdConverter: LocationConversion; } decl_event! { @@ -68,6 +72,8 @@ decl_error! { pub enum Error for Module { /// Failed to send XCM message. FailedToSend, + /// Bad XCM origin. + BadXcmOrigin, } } @@ -101,6 +107,21 @@ decl_module! { } } +impl Module { + /// Execute an XCM message locally. Returns `DispatchError` if failed. + pub fn execute_xcm(origin: T::AccountId, xcm: Xcm) -> DispatchResult { + let xcm_origin = T::AccountIdConverter::try_into_location(origin) + .map_err(|_| Error::::BadXcmOrigin)?; + let hash = T::Hashing::hash(&xcm.encode()); + let event = match T::XcmExecutor::execute_xcm(xcm_origin, xcm) { + Ok(_) => Event::::Success(hash), + Err(e) => Event::::Fail(hash, e), + }; + Self::deposit_event(event); + Ok(()) + } +} + impl DownwardMessageHandler for Module { fn handle_downward_message(msg: InboundDownwardMessage) { let hash = msg.using_encoded(T::Hashing::hash); diff --git a/rococo-parachains/runtime/src/lib.rs b/rococo-parachains/runtime/src/lib.rs index 3c1741a621..b056057149 100644 --- a/rococo-parachains/runtime/src/lib.rs +++ b/rococo-parachains/runtime/src/lib.rs @@ -290,6 +290,7 @@ impl cumulus_pallet_xcm_handler::Config for Runtime { type UpwardMessageSender = ParachainSystem; type HrmpMessageSender = ParachainSystem; type SendXcmOrigin = EnsureRoot; + type AccountIdConverter = LocationConverter; } construct_runtime! {