XCM revamp (#2836)

* Remove unused relaying XCM

* Aggregate HRMP (XCMP/HMP) messages. Payloads for spambot.

* Revert lock

* Fix

* Broken example

* Introduce fee payment mechanics into XCM.

* Weight limitations on XCM execution

* Mock environment for tests and the first test

* Tests for XCM and a few refactors.

* Remove code that's not ready

* Fix for an XCM and an additional test

* Query response system

* XCMP message dispatch system reimagining

- Moved most of the logic into xcm-handler pallet
- Altered the outgoing XCMP API from push to pull
- Changed underlying outgoing queue data structures to avoid multi-page read/writes
- Introduced queuing for incoming messages
- Introduced signal messages as a flow-control sub-stream
- Introduced flow-control with basic threshold back-pressure
- Introduced overall weight limitation on messages executed
- Additonal alterations to XCM APIs for the new system

* Some build fixes

* Remove the Encode bounds sprayed around

* More faff

* Fix bounds amek use latest scale codec.

* remove println

* fixes

* Fix XcmExecutor Tests

* Fix XCM bounds using derivative crate

* Refactor names of XcmGeneric &c into Xcm

* Repot the xcm-executor into xcm-builder

* Docs

* Docs

* Fixes

* Update xcm/src/lib.rs

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

* Fixes

* Docs

* Update runtime/parachains/src/ump.rs

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

* Docs

* Fixes

* Fixes

* Fixes

* Docs

* Fixes

* Fixes

* Introduce transfer_asset specialisation.

* Fixes

* Fixes

Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
This commit is contained in:
Gavin Wood
2021-04-07 22:38:29 +02:00
committed by GitHub
parent 8eae0fa443
commit adc238ad86
37 changed files with 2436 additions and 574 deletions
+80 -8
View File
@@ -24,6 +24,7 @@ use super::{MultiLocation, Xcm};
#[derive(Copy, Clone, Encode, Decode, Eq, PartialEq, Ord, PartialOrd, Debug)]
pub enum Error {
Undefined,
Overflow,
Unimplemented,
UnhandledXcmVersion,
UnhandledXcmMessage,
@@ -32,12 +33,44 @@ pub enum Error {
UntrustedReserveLocation,
UntrustedTeleportLocation,
DestinationBufferOverflow,
CannotReachDestination,
CannotReachDestination(#[codec(skip)] &'static str),
MultiLocationFull,
FailedToDecode,
BadOrigin,
ExceedsMaxMessageSize,
FailedToTransactAsset(#[codec(skip)] &'static str),
WeightLimitReached,
Wildcard,
/// The case where an XCM message has specified a optional weight limit and the weight required for
/// processing is too great.
///
/// Used by:
/// - `Transact`
TooMuchWeightRequired,
/// The fees specified by the XCM message were not found in the holding account.
///
/// Used by:
/// - `BuyExecution`
NotHoldingFees,
/// The weight of an XCM message is not computable ahead of execution. This generally means at least part
/// of the message is invalid, which could be due to it containing overly nested structures or an invalid
/// nested data segment (e.g. for the call in `Transact`).
WeightNotComputable,
/// The XCM did noto pass the barrier condition for execution. The barrier condition differs on different
/// chains and in different circumstances, but generally it means that the conditions surrounding the message
/// were not such that the chain considers the message worth spending time executing. Since most chains
/// lift the barrier to execution on apropriate payment, presentation of an NFT voucher, or based on the
/// message origin, it means that none of those were the case.
Barrier,
/// Indicates that it is not possible for a location to have an asset be withdrawn or transferred from its
/// ownership. This probably means it doesn't own (enough of) it, but may also indicate that it is under a
/// lock, hold, freeze or is otherwise unavailable.
NotWithdrawable,
/// Indicates that the consensus system cannot deposit an asset under the ownership of a particular location.
LocationCannotHold,
/// We attempted to send an XCM to the local consensus system. Execution was not possible probably due to
/// no execution weight being assigned.
DestinationIsLocal,
}
impl From<()> for Error {
@@ -48,22 +81,61 @@ impl From<()> for Error {
pub type Result = result::Result<(), Error>;
pub trait ExecuteXcm {
fn execute_xcm(origin: MultiLocation, msg: Xcm) -> Result;
/// Local weight type; execution time in picoseconds.
pub type Weight = u64;
/// Outcome of an XCM excution.
#[derive(Copy, Clone, Encode, Decode, Eq, PartialEq, Debug)]
pub enum Outcome {
/// Execution completed successfully; given weight was used.
Complete(Weight),
/// Execution started, but did not complete successfully due to the given error; given weight was used.
Incomplete(Weight, Error),
/// Execution did not start due to the given error.
Error(Error),
}
impl ExecuteXcm for () {
fn execute_xcm(_origin: MultiLocation, _msg: Xcm) -> Result {
Err(Error::Unimplemented)
impl Outcome {
pub fn ensure_complete(self) -> Result {
match self {
Outcome::Complete(_) => Ok(()),
Outcome::Incomplete(_, e) => Err(e),
Outcome::Error(e) => Err(e),
}
}
pub fn ensure_execution(self) -> result::Result<Weight, Error> {
match self {
Outcome::Complete(w) => Ok(w),
Outcome::Incomplete(w, _) => Ok(w),
Outcome::Error(e) => Err(e),
}
}
/// How much weight was used by the XCM execution attempt.
pub fn weight_used(&self) -> Weight {
match self {
Outcome::Complete(w) => *w,
Outcome::Incomplete(w, _) => *w,
Outcome::Error(_) => 0,
}
}
}
pub trait ExecuteXcm<Call> {
fn execute_xcm(origin: MultiLocation, message: Xcm<Call>, weight_limit: Weight) -> Outcome;
}
impl<C> ExecuteXcm<C> for () {
fn execute_xcm(_origin: MultiLocation, _message: Xcm<C>, _weight_limit: Weight) -> Outcome {
Outcome::Error(Error::Unimplemented)
}
}
pub trait SendXcm {
fn send_xcm(dest: MultiLocation, msg: Xcm) -> Result;
fn send_xcm(dest: MultiLocation, msg: Xcm<()>) -> Result;
}
impl SendXcm for () {
fn send_xcm(_dest: MultiLocation, _msg: Xcm) -> Result {
fn send_xcm(_dest: MultiLocation, _msg: Xcm<()>) -> Result {
Err(Error::Unimplemented)
}
}