DMP Queue pallet (#416)

* Introduce the converter into the hub

* Parachain recognises Rococo governance body as admin

* Whitespace

* Use UsingComponents for fee payment in XCM

* Fixes

* Fixes for XCM permissions

* Remove encode_call test

* Fixes

* Rococo Collator supports Shell runtime

* Fixes

* Fixes

* Initial draft of DMP Queue pallet

* DMP Queue builds.

* Companion for Polkadot gav-allow-xcm-exec

* Bump

* Fix std

* Fixes

* fix and improve docs

* fix compile errors in tests

* add test for try_service_message

* update cargo.lock

* Fixes

* Make test name read well

* Fixes

* Add a couple of simple tests

* Tests

* Tests

* Update pallets/dmp-queue/src/lib.rs

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>

* Update pallets/dmp-queue/src/lib.rs

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>

* Update pallets/dmp-queue/src/lib.rs

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>

* Update pallets/dmp-queue/src/lib.rs

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>

* Update pallets/dmp-queue/src/lib.rs

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>

* Update pallets/dmp-queue/src/lib.rs

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>

* Update pallets/dmp-queue/src/lib.rs

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>

* Chain ID and ParaID don't collide

* Fixes

* Update pallets/dmp-queue/src/lib.rs

Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>

* Update pallets/dmp-queue/src/lib.rs

Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>

* Fixes

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>
Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
This commit is contained in:
Gavin Wood
2021-05-02 16:11:58 +02:00
committed by GitHub
parent 315c5d1c15
commit 3f687171c2
14 changed files with 1279 additions and 369 deletions
+59 -26
View File
@@ -20,12 +20,13 @@
#![cfg_attr(not(feature = "std"), no_std)]
use sp_std::convert::TryFrom;
use cumulus_primitives_core::{ParaId, DownwardMessageHandler, InboundDownwardMessage};
use sp_std::{prelude::*, convert::TryFrom};
use cumulus_primitives_core::{ParaId, DmpMessageHandler};
use cumulus_primitives_core::relay_chain::BlockNumber as RelayBlockNumber;
use codec::{Encode, Decode};
use sp_runtime::traits::BadOrigin;
use xcm::{VersionedXcm, v0::{Xcm, Junction, Outcome, ExecuteXcm}};
use frame_support::{traits::Get, dispatch::Weight};
use frame_support::dispatch::Weight;
pub use pallet::*;
#[frame_support::pallet]
@@ -45,9 +46,6 @@ pub mod pallet {
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
type XcmExecutor: ExecuteXcm<Self::Call>;
#[pallet::constant]
type MaxWeight: Get<Weight>;
}
#[pallet::error]
@@ -74,33 +72,68 @@ pub mod pallet {
/// \[ id, outcome \]
ExecutedDownward([u8; 8], Outcome),
}
}
/// For an incoming downward message, this just adapts an XCM executor and executes DMP messages
/// immediately up until some `MaxWeight` at which point it errors. Their origin is asserted to be
/// the Parent location.
impl<T: Config> DownwardMessageHandler for Pallet<T> {
fn handle_downward_message(msg: InboundDownwardMessage) -> Weight {
let id = sp_io::hashing::twox_64(&msg.msg[..]);
let msg = VersionedXcm::<T::Call>::decode(&mut &msg.msg[..])
/// For an incoming downward message, this just adapts an XCM executor and executes DMP messages
/// immediately. Their origin is asserted to be the Parent location.
///
/// The weight `limit` is only respected as the maximum for an individual message.
///
/// Because this largely ignores the given weight limit, it probably isn't good for most production
/// uses. Use DmpQueue pallet for a more robust design.
pub struct UnlimitedDmpExecution<T>(sp_std::marker::PhantomData<T>);
impl<T: Config> DmpMessageHandler for UnlimitedDmpExecution<T> {
fn handle_dmp_messages(
iter: impl Iterator<Item=(RelayBlockNumber, Vec<u8>)>,
limit: Weight,
) -> Weight {
let mut used = 0;
for (_sent_at, data) in iter {
let id = sp_io::hashing::twox_64(&data[..]);
let msg = VersionedXcm::<T::Call>::decode(&mut &data[..])
.map(Xcm::<T::Call>::try_from);
match msg {
Err(_) => Pallet::<T>::deposit_event(Event::InvalidFormat(id)),
Ok(Err(())) => Pallet::<T>::deposit_event(Event::UnsupportedVersion(id)),
Ok(Ok(x)) => {
let weight_limit = T::MaxWeight::get();
let outcome = T::XcmExecutor::execute_xcm(Junction::Parent.into(), x, weight_limit);
let weight_used = outcome.weight_used();
Self::deposit_event(Event::ExecutedDownward(id, outcome));
weight_used
let outcome = T::XcmExecutor::execute_xcm(Junction::Parent.into(), x, limit);
used += outcome.weight_used();
Pallet::<T>::deposit_event(Event::ExecutedDownward(id, outcome));
}
Ok(Err(())) => {
Self::deposit_event(Event::UnsupportedVersion(id));
0
},
Err(_) => {
Self::deposit_event(Event::InvalidFormat(id));
0
},
}
}
used
}
}
/// For an incoming downward message, this just adapts an XCM executor and executes DMP messages
/// immediately. Their origin is asserted to be the Parent location.
///
/// This respects the given weight limit and silently drops messages if they would break it. It
/// probably isn't good for most production uses. Use DmpQueue pallet for a more robust design.
pub struct LimitAndDropDmpExecution<T>(sp_std::marker::PhantomData<T>);
impl<T: Config> DmpMessageHandler for LimitAndDropDmpExecution<T> {
fn handle_dmp_messages(
iter: impl Iterator<Item=(RelayBlockNumber, Vec<u8>)>,
limit: Weight,
) -> Weight {
let mut used = 0;
for (_sent_at, data) in iter {
let id = sp_io::hashing::twox_64(&data[..]);
let msg = VersionedXcm::<T::Call>::decode(&mut &data[..])
.map(Xcm::<T::Call>::try_from);
match msg {
Err(_) => Pallet::<T>::deposit_event(Event::InvalidFormat(id)),
Ok(Err(())) => Pallet::<T>::deposit_event(Event::UnsupportedVersion(id)),
Ok(Ok(x)) => {
let weight_limit = limit.saturating_sub(used);
let outcome = T::XcmExecutor::execute_xcm(Junction::Parent.into(), x, weight_limit);
used += outcome.weight_used();
Pallet::<T>::deposit_event(Event::ExecutedDownward(id, outcome));
}
}
}
used
}
}