Unverified Commit 6be14014 authored by Shawn Tabrizi's avatar Shawn Tabrizi Committed by GitHub
Browse files

Add Basic XCM (#1934)



* basic setup

* fix compile

* add back xcmsink

* Update primitives.rs

* add downward xcm for sudo

* Update paras_sudo_wrapper.rs

* Update Cargo.lock

* some cleanups

* Add error log
Co-authored-by: Sergey Pepyakin's avatarSergei Shulepov <sergei@parity.io>
parent b892796b
Pipeline #117043 failed with stages
in 25 minutes and 7 seconds
...@@ -5509,6 +5509,7 @@ dependencies = [ ...@@ -5509,6 +5509,7 @@ dependencies = [
"sp-trie", "sp-trie",
"static_assertions", "static_assertions",
"trie-db", "trie-db",
"xcm",
] ]
[[package]] [[package]]
...@@ -5558,6 +5559,7 @@ dependencies = [ ...@@ -5558,6 +5559,7 @@ dependencies = [
"sp-trie", "sp-trie",
"sp-version", "sp-version",
"xcm", "xcm",
"xcm-executor",
] ]
[[package]] [[package]]
...@@ -6535,6 +6537,9 @@ dependencies = [ ...@@ -6535,6 +6537,9 @@ dependencies = [
"sp-transaction-pool", "sp-transaction-pool",
"sp-version", "sp-version",
"substrate-wasm-builder", "substrate-wasm-builder",
"xcm",
"xcm-builder",
"xcm-executor",
] ]
[[package]] [[package]]
......
...@@ -39,6 +39,8 @@ primitives = { package = "polkadot-primitives", path = "../../primitives", defau ...@@ -39,6 +39,8 @@ primitives = { package = "polkadot-primitives", path = "../../primitives", defau
libsecp256k1 = { version = "0.3.5", default-features = false, optional = true } libsecp256k1 = { version = "0.3.5", default-features = false, optional = true }
runtime-parachains = { package = "polkadot-runtime-parachains", path = "../parachains", default-features = false } runtime-parachains = { package = "polkadot-runtime-parachains", path = "../parachains", default-features = false }
xcm = { path = "../../xcm", default-features = false }
[dev-dependencies] [dev-dependencies]
hex-literal = "0.3.1" hex-literal = "0.3.1"
keyring = { package = "sp-keyring", git = "https://github.com/paritytech/substrate", branch = "master" } keyring = { package = "sp-keyring", git = "https://github.com/paritytech/substrate", branch = "master" }
...@@ -81,6 +83,7 @@ std = [ ...@@ -81,6 +83,7 @@ std = [
"pallet-vesting/std", "pallet-vesting/std",
"pallet-transaction-payment/std", "pallet-transaction-payment/std",
"runtime-parachains/std", "runtime-parachains/std",
"xcm/std",
] ]
runtime-benchmarks = [ runtime-benchmarks = [
"libsecp256k1/hmac", "libsecp256k1/hmac",
......
...@@ -28,6 +28,7 @@ use runtime_parachains::{ ...@@ -28,6 +28,7 @@ use runtime_parachains::{
configuration, dmp, ump, hrmp, paras::{self, ParaGenesisArgs}, configuration, dmp, ump, hrmp, paras::{self, ParaGenesisArgs},
}; };
use primitives::v1::Id as ParaId; use primitives::v1::Id as ParaId;
use parity_scale_codec::Encode;
/// The module's configuration trait. /// The module's configuration trait.
pub trait Config: pub trait Config:
...@@ -73,16 +74,16 @@ decl_module! { ...@@ -73,16 +74,16 @@ decl_module! {
Ok(()) Ok(())
} }
/// Send a downward message to the given para. /// Send a downward XCM to the given para.
/// ///
/// The given parachain should exist and the payload should not exceed the preconfigured size /// The given parachain should exist and the payload should not exceed the preconfigured size
/// `config.max_downward_message_size`. /// `config.max_downward_message_size`.
#[weight = (1_000, DispatchClass::Operational)] #[weight = (1_000, DispatchClass::Operational)]
pub fn sudo_queue_downward_message(origin, id: ParaId, payload: Vec<u8>) -> DispatchResult { pub fn sudo_queue_downward_xcm(origin, id: ParaId, xcm: xcm::VersionedXcm) -> DispatchResult {
ensure_root(origin)?; ensure_root(origin)?;
ensure!(<paras::Module<T>>::is_valid_para(id), Error::<T>::ParaDoesntExist); ensure!(<paras::Module<T>>::is_valid_para(id), Error::<T>::ParaDoesntExist);
let config = <configuration::Module<T>>::config(); let config = <configuration::Module<T>>::config();
<dmp::Module<T>>::queue_downward_message(&config, id, payload) <dmp::Module<T>>::queue_downward_message(&config, id, xcm.encode())
.map_err(|e| match e { .map_err(|e| match e {
dmp::QueueDownwardMessageError::ExceedsMaxMessageSize => dmp::QueueDownwardMessageError::ExceedsMaxMessageSize =>
Error::<T>::ExceedsMaxMessageSize.into(), Error::<T>::ExceedsMaxMessageSize.into(),
......
...@@ -35,6 +35,7 @@ pallet-offences = { git = "https://github.com/paritytech/substrate", branch = "m ...@@ -35,6 +35,7 @@ pallet-offences = { git = "https://github.com/paritytech/substrate", branch = "m
frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true } frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true }
xcm = { package = "xcm", path = "../../xcm", default-features = false } xcm = { package = "xcm", path = "../../xcm", default-features = false }
xcm-executor = { package = "xcm-executor", path = "../../xcm/xcm-executor", default-features = false }
primitives = { package = "polkadot-primitives", path = "../../primitives", default-features = false } primitives = { package = "polkadot-primitives", path = "../../primitives", default-features = false }
libsecp256k1 = { version = "0.3.5", default-features = false, optional = true } libsecp256k1 = { version = "0.3.5", default-features = false, optional = true }
...@@ -84,6 +85,7 @@ std = [ ...@@ -84,6 +85,7 @@ std = [
"pallet-timestamp/std", "pallet-timestamp/std",
"pallet-vesting/std", "pallet-vesting/std",
"xcm/std", "xcm/std",
"xcm-executor/std",
] ]
runtime-benchmarks = [ runtime-benchmarks = [
"libsecp256k1/hmac", "libsecp256k1/hmac",
......
...@@ -52,6 +52,42 @@ impl UmpSink for () { ...@@ -52,6 +52,42 @@ impl UmpSink for () {
} }
} }
/// A specific implementation of a UmpSink where messages are in the XCM format
/// and will be forwarded to the XCM Executor.
pub struct XcmSink<Config>(sp_std::marker::PhantomData<Config>);
impl<Config: xcm_executor::Config> UmpSink for XcmSink<Config> {
fn process_upward_message(origin: ParaId, msg: Vec<u8>) -> Weight {
use parity_scale_codec::Decode;
use xcm::VersionedXcm;
use xcm::v0::{Junction, MultiLocation, ExecuteXcm};
use xcm_executor::XcmExecutor;
let weight: Weight = 0;
if let Ok(versioned_xcm_message) = VersionedXcm::decode(&mut &msg[..]) {
match versioned_xcm_message {
VersionedXcm::V0(xcm_message) => {
let xcm_junction: Junction = Junction::Parachain { id: origin.into() };
let xcm_location: MultiLocation = xcm_junction.into();
// TODO: Do something with result.
let _result = XcmExecutor::<Config>::execute_xcm(xcm_location, xcm_message);
}
}
} else {
frame_support::debug::error!(
target: "xcm",
"Failed to decode versioned XCM from upward message.",
);
}
// TODO: to be sound, this implementation must ensure that returned (and thus consumed)
// weight is limited to some small portion of the total block weight (as a ballpark, 1/4, 1/8
// or lower).
weight
}
}
/// An error returned by [`check_upward_messages`] that indicates a violation of one of acceptance /// An error returned by [`check_upward_messages`] that indicates a violation of one of acceptance
/// criteria rules. /// criteria rules.
pub enum AcceptanceCheckErr { pub enum AcceptanceCheckErr {
......
...@@ -53,6 +53,10 @@ primitives = { package = "polkadot-primitives", path = "../../primitives", defau ...@@ -53,6 +53,10 @@ primitives = { package = "polkadot-primitives", path = "../../primitives", defau
polkadot-parachain = { path = "../../parachain", default-features = false } polkadot-parachain = { path = "../../parachain", default-features = false }
runtime-parachains = { package = "polkadot-runtime-parachains", path = "../parachains", default-features = false } runtime-parachains = { package = "polkadot-runtime-parachains", path = "../parachains", default-features = false }
xcm = { package = "xcm", path = "../../xcm", default-features = false }
xcm-executor = { package = "xcm-executor", path = "../../xcm/xcm-executor", default-features = false }
xcm-builder = { package = "xcm-builder", path = "../../xcm/xcm-builder", default-features = false }
[build-dependencies] [build-dependencies]
substrate-wasm-builder = "3.0.0" substrate-wasm-builder = "3.0.0"
...@@ -99,6 +103,9 @@ std = [ ...@@ -99,6 +103,9 @@ std = [
"sp-version/std", "sp-version/std",
"serde_derive", "serde_derive",
"serde/std", "serde/std",
"xcm/std",
"xcm-executor/std",
"xcm-builder/std",
] ]
# When enabled, the runtime api will not be build. # When enabled, the runtime api will not be build.
# #
......
...@@ -82,6 +82,15 @@ use runtime_parachains::scheduler as parachains_scheduler; ...@@ -82,6 +82,15 @@ use runtime_parachains::scheduler as parachains_scheduler;
pub use pallet_balances::Call as BalancesCall; pub use pallet_balances::Call as BalancesCall;
pub use pallet_staking::StakerStatus; pub use pallet_staking::StakerStatus;
use polkadot_parachain::primitives::Id as ParaId;
use xcm::v0::{MultiLocation, NetworkId};
use xcm_executor::traits::IsConcrete;
use xcm_builder::{
AccountId32Aliases, ChildParachainConvertsVia, SovereignSignedViaLocation,
CurrencyAdapter as XcmCurrencyAdapter, ChildParachainAsNative,
SignedAccountId32AsNative, ChildSystemParachainAsSuperuser, LocationInverter,
};
/// Constant values used within the runtime. /// Constant values used within the runtime.
pub mod constants; pub mod constants;
use constants::{time::*, currency::*, fee::*}; use constants::{time::*, currency::*, fee::*};
...@@ -535,10 +544,51 @@ impl parachains_paras::Config for Runtime { ...@@ -535,10 +544,51 @@ impl parachains_paras::Config for Runtime {
type Origin = Origin; type Origin = Origin;
} }
parameter_types! {
pub const RocLocation: MultiLocation = MultiLocation::Null;
pub const RococoNetwork: NetworkId = NetworkId::Polkadot;
pub const Ancestry: MultiLocation = MultiLocation::Null;
}
pub type LocationConverter = (
ChildParachainConvertsVia<ParaId, AccountId>,
AccountId32Aliases<RococoNetwork, AccountId>,
);
pub type LocalAssetTransactor =
XcmCurrencyAdapter<
// Use this currency:
Balances,
// Use this currency when it is a fungible asset matching the given location or name:
IsConcrete<RocLocation>,
// We can convert the MultiLocations with our converter above:
LocationConverter,
// Our chain's account ID type (we can't get away without mentioning it explicitly):
AccountId,
>;
type LocalOriginConverter = (
SovereignSignedViaLocation<LocationConverter, Origin>,
ChildParachainAsNative<parachains_origin::Origin, Origin>,
SignedAccountId32AsNative<RococoNetwork, Origin>,
ChildSystemParachainAsSuperuser<ParaId, Origin>,
);
pub struct XcmConfig;
impl xcm_executor::Config for XcmConfig {
type Call = Call;
type XcmSender = ();
type AssetTransactor = LocalAssetTransactor;
type OriginConverter = LocalOriginConverter;
type IsReserve = ();
type IsTeleporter = ();
type LocationInverter = LocationInverter<Ancestry>;
}
impl parachains_session_info::Config for Runtime {} impl parachains_session_info::Config for Runtime {}
impl parachains_ump::Config for Runtime { impl parachains_ump::Config for Runtime {
type UmpSink = (); // TODO: #1873 To be handled by the XCM receiver. type UmpSink = crate::parachains_ump::XcmSink<XcmConfig>;
} }
impl parachains_dmp::Config for Runtime {} impl parachains_dmp::Config for Runtime {}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment