Use same fmt and clippy configs as in Substrate (#7611)

* Use same rustfmt.toml as Substrate

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* format format file

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Format with new config

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Add Substrate Clippy config

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Print Clippy version in CI

Otherwise its difficult to reproduce locally.

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Make fmt happy

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Update node/core/pvf/src/error.rs

Co-authored-by: Tsvetomir Dimitrov <tsvetomir@parity.io>

* Update node/core/pvf/src/error.rs

Co-authored-by: Tsvetomir Dimitrov <tsvetomir@parity.io>

---------

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
Co-authored-by: Tsvetomir Dimitrov <tsvetomir@parity.io>
This commit is contained in:
Oliver Tale-Yazdi
2023-08-14 16:29:29 +02:00
committed by GitHub
parent ac435c96cf
commit 342d720573
203 changed files with 1880 additions and 1504 deletions
@@ -52,7 +52,8 @@ pub mod pallet {
/// If set to `Err`, benchmarks which rely on an `exchange_asset` will be skipped.
fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError>;
/// A `(MultiLocation, Junction)` that is one of the `UniversalAliases` configured by the XCM executor.
/// A `(MultiLocation, Junction)` that is one of the `UniversalAliases` configured by the
/// XCM executor.
///
/// If set to `Err`, benchmarks which rely on a universal alias will be skipped.
fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError>;
@@ -75,13 +76,15 @@ pub mod pallet {
/// Return an unlocker, owner and assets that can be locked and unlocked.
fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError>;
/// A `(MultiLocation, NetworkId, InteriorMultiLocation)` we can successfully export message to.
/// A `(MultiLocation, NetworkId, InteriorMultiLocation)` we can successfully export message
/// to.
///
/// If set to `Err`, benchmarks which rely on `export_message` will be skipped.
fn export_message_origin_and_destination(
) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError>;
/// A `(MultiLocation, MultiLocation)` that is one of the `Aliasers` configured by the XCM executor.
/// A `(MultiLocation, MultiLocation)` that is one of the `Aliasers` configured by the XCM
/// executor.
///
/// If set to `Err`, benchmarks which rely on a universal alias will be skipped.
fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError>;
+57 -51
View File
@@ -195,9 +195,9 @@ pub mod pallet {
/// The type used to actually dispatch an XCM to its destination.
type XcmRouter: SendXcm;
/// Required origin for executing XCM messages, including the teleport functionality. If successful,
/// then it resolves to `MultiLocation` which exists as an interior location within this chain's XCM
/// context.
/// Required origin for executing XCM messages, including the teleport functionality. If
/// successful, then it resolves to `MultiLocation` which exists as an interior location
/// within this chain's XCM context.
type ExecuteXcmOrigin: EnsureOrigin<
<Self as SysConfig>::RuntimeOrigin,
Success = MultiLocation,
@@ -212,7 +212,8 @@ pub mod pallet {
/// Our XCM filter which messages to be teleported using the dedicated extrinsic must pass.
type XcmTeleportFilter: Contains<(MultiLocation, Vec<MultiAsset>)>;
/// Our XCM filter which messages to be reserve-transferred using the dedicated extrinsic must pass.
/// Our XCM filter which messages to be reserve-transferred using the dedicated extrinsic
/// must pass.
type XcmReserveTransferFilter: Contains<(MultiLocation, Vec<MultiAsset>)>;
/// Means of measuring the weight consumed by an XCM message locally.
@@ -290,8 +291,8 @@ pub mod pallet {
/// Query response has been received and query is removed. The registered notification has
/// been dispatched and executed successfully.
Notified { query_id: QueryId, pallet_index: u8, call_index: u8 },
/// Query response has been received and query is removed. The registered notification could
/// not be dispatched because the dispatch weight is greater than the maximum weight
/// Query response has been received and query is removed. The registered notification
/// could not be dispatched because the dispatch weight is greater than the maximum weight
/// originally budgeted by this runtime for the query result.
NotifyOverweight {
query_id: QueryId,
@@ -371,7 +372,8 @@ pub mod pallet {
cost: MultiAssets,
message_id: XcmHash,
},
/// We have requested that a remote chain stops sending us XCM version change notifications.
/// We have requested that a remote chain stops sending us XCM version change
/// notifications.
VersionNotifyUnrequested {
destination: MultiLocation,
cost: MultiAssets,
@@ -402,8 +404,8 @@ pub mod pallet {
/// The desired destination was unreachable, generally because there is a no way of routing
/// to it.
Unreachable,
/// There was some other issue (i.e. not to do with routing) in sending the message. Perhaps
/// a lack of space for buffering the message.
/// There was some other issue (i.e. not to do with routing) in sending the message.
/// Perhaps a lack of space for buffering the message.
SendFailure,
/// The message execution fails the filter.
Filtered,
@@ -791,12 +793,13 @@ pub mod pallet {
/// with all fees taken as needed from the asset.
///
/// - `origin`: Must be capable of withdrawing the `assets` and executing XCM.
/// - `dest`: Destination context for the assets. Will typically be `X2(Parent, Parachain(..))` to send
/// from parachain to parachain, or `X1(Parachain(..))` to send from relay to parachain.
/// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will generally be
/// an `AccountId32` value.
/// - `assets`: The assets to be withdrawn. The first item should be the currency used to to pay the fee on the
/// `dest` side. May not be empty.
/// - `dest`: Destination context for the assets. Will typically be `X2(Parent,
/// Parachain(..))` to send from parachain to parachain, or `X1(Parachain(..))` to send
/// from relay to parachain.
/// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will
/// generally be an `AccountId32` value.
/// - `assets`: The assets to be withdrawn. The first item should be the currency used to to
/// pay the fee on the `dest` side. May not be empty.
/// - `fee_asset_item`: The index into `assets` of the item which should be used to pay
/// fees.
#[pallet::call_index(1)]
@@ -839,12 +842,13 @@ pub mod pallet {
/// with all fees taken as needed from the asset.
///
/// - `origin`: Must be capable of withdrawing the `assets` and executing XCM.
/// - `dest`: Destination context for the assets. Will typically be `X2(Parent, Parachain(..))` to send
/// from parachain to parachain, or `X1(Parachain(..))` to send from relay to parachain.
/// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will generally be
/// an `AccountId32` value.
/// - `assets`: The assets to be withdrawn. This should include the assets used to pay the fee on the
/// `dest` side.
/// - `dest`: Destination context for the assets. Will typically be `X2(Parent,
/// Parachain(..))` to send from parachain to parachain, or `X1(Parachain(..))` to send
/// from relay to parachain.
/// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will
/// generally be an `AccountId32` value.
/// - `assets`: The assets to be withdrawn. This should include the assets used to pay the
/// fee on the `dest` side.
/// - `fee_asset_item`: The index into `assets` of the item which should be used to pay
/// fees.
#[pallet::call_index(2)]
@@ -885,12 +889,12 @@ pub mod pallet {
/// An event is deposited indicating whether `msg` could be executed completely or only
/// partially.
///
/// No more than `max_weight` will be used in its attempted execution. If this is less than the
/// maximum amount of weight that the message could take to be executed, then no execution
/// attempt will be made.
/// No more than `max_weight` will be used in its attempted execution. If this is less than
/// the maximum amount of weight that the message could take to be executed, then no
/// execution attempt will be made.
///
/// NOTE: A successful return to this does *not* imply that the `msg` was executed successfully
/// to completion; only that *some* of it was executed.
/// NOTE: A successful return to this does *not* imply that the `msg` was executed
/// successfully to completion; only that *some* of it was executed.
#[pallet::call_index(3)]
#[pallet::weight(max_weight.saturating_add(T::WeightInfo::execute()))]
pub fn execute(
@@ -1012,12 +1016,13 @@ pub mod pallet {
/// at risk.
///
/// - `origin`: Must be capable of withdrawing the `assets` and executing XCM.
/// - `dest`: Destination context for the assets. Will typically be `X2(Parent, Parachain(..))` to send
/// from parachain to parachain, or `X1(Parachain(..))` to send from relay to parachain.
/// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will generally be
/// an `AccountId32` value.
/// - `assets`: The assets to be withdrawn. This should include the assets used to pay the fee on the
/// `dest` side.
/// - `dest`: Destination context for the assets. Will typically be `X2(Parent,
/// Parachain(..))` to send from parachain to parachain, or `X1(Parachain(..))` to send
/// from relay to parachain.
/// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will
/// generally be an `AccountId32` value.
/// - `assets`: The assets to be withdrawn. This should include the assets used to pay the
/// fee on the `dest` side.
/// - `fee_asset_item`: The index into `assets` of the item which should be used to pay
/// fees.
/// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase.
@@ -1063,12 +1068,13 @@ pub mod pallet {
/// at risk.
///
/// - `origin`: Must be capable of withdrawing the `assets` and executing XCM.
/// - `dest`: Destination context for the assets. Will typically be `X2(Parent, Parachain(..))` to send
/// from parachain to parachain, or `X1(Parachain(..))` to send from relay to parachain.
/// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will generally be
/// an `AccountId32` value.
/// - `assets`: The assets to be withdrawn. The first item should be the currency used to to pay the fee on the
/// `dest` side. May not be empty.
/// - `dest`: Destination context for the assets. Will typically be `X2(Parent,
/// Parachain(..))` to send from parachain to parachain, or `X1(Parachain(..))` to send
/// from relay to parachain.
/// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will
/// generally be an `AccountId32` value.
/// - `assets`: The assets to be withdrawn. The first item should be the currency used to to
/// pay the fee on the `dest` side. May not be empty.
/// - `fee_asset_item`: The index into `assets` of the item which should be used to pay
/// fees.
/// - `weight_limit`: The remote-side weight limit, if any, for the XCM fee purchase.
@@ -1561,13 +1567,13 @@ impl<T: Config> Pallet<T> {
///
/// - `message`: The message whose outcome should be reported.
/// - `responder`: The origin from which a response should be expected.
/// - `notify`: A dispatchable function which will be called once the outcome of `message`
/// is known. It may be a dispatchable in any pallet of the local chain, but other than
/// the usual origin, it must accept exactly two arguments: `query_id: QueryId` and
/// `outcome: Response`, and in that order. It should expect that the origin is
/// `Origin::Response` and will contain the responder's location.
/// - `timeout`: The block number after which it is permissible for `notify` not to be
/// called even if a response is received.
/// - `notify`: A dispatchable function which will be called once the outcome of `message` is
/// known. It may be a dispatchable in any pallet of the local chain, but other than the usual
/// origin, it must accept exactly two arguments: `query_id: QueryId` and `outcome: Response`,
/// and in that order. It should expect that the origin is `Origin::Response` and will contain
/// the responder's location.
/// - `timeout`: The block number after which it is permissible for `notify` not to be called
/// even if a response is received.
///
/// `report_outcome_notify` may return an error if the `responder` is not invertible.
///
@@ -2090,8 +2096,8 @@ impl<T: Config> OnResponse for Pallet<T> {
call_index,
};
Self::deposit_event(e);
// Not much to do with the result as it is. It's up to the parachain to ensure that the
// message makes sense.
// Not much to do with the result as it is. It's up to the
// parachain to ensure that the message makes sense.
error_and_info.post_info.actual_weight
},
}
@@ -2159,8 +2165,8 @@ where
}
}
/// Filter for `MultiLocation` to find those which represent a strict majority approval of an identified
/// plurality.
/// Filter for `MultiLocation` to find those which represent a strict majority approval of an
/// identified plurality.
///
/// May reasonably be used with `EnsureXcm`.
pub struct IsMajorityOfBody<Prefix, Body>(PhantomData<(Prefix, Body)>);
@@ -2186,8 +2192,8 @@ impl<Prefix: Get<MultiLocation>, Body: Get<BodyId>> Contains<MultiLocation>
}
}
/// `EnsureOrigin` implementation succeeding with a `MultiLocation` value to recognize and filter the
/// `Origin::Xcm` item.
/// `EnsureOrigin` implementation succeeding with a `MultiLocation` value to recognize and filter
/// the `Origin::Xcm` item.
pub struct EnsureXcm<F>(PhantomData<F>);
impl<O: OriginTrait + From<Origin>, F: Contains<MultiLocation>> EnsureOrigin<O> for EnsureXcm<F>
where
+5 -3
View File
@@ -73,7 +73,8 @@ impl<T> DoubleEncoded<T> {
impl<T: Decode> DoubleEncoded<T> {
/// Decode the inner encoded value and store it.
/// Returns a reference to the value in case of success and `Err(())` in case the decoding fails.
/// Returns a reference to the value in case of success and `Err(())` in case the decoding
/// fails.
pub fn ensure_decoded(&mut self) -> Result<&T, ()> {
if self.decoded.is_none() {
self.decoded =
@@ -92,8 +93,9 @@ impl<T: Decode> DoubleEncoded<T> {
.ok_or(())
}
/// Provides an API similar to `TryInto` that allows fallible conversion to the inner value type.
/// `TryInto` implementation would collide with std blanket implementation based on `TryFrom`.
/// Provides an API similar to `TryInto` that allows fallible conversion to the inner value
/// type. `TryInto` implementation would collide with std blanket implementation based on
/// `TryFrom`.
pub fn try_into(mut self) -> Result<T, ()> {
self.ensure_decoded()?;
self.decoded.ok_or(())
+8 -4
View File
@@ -360,7 +360,8 @@ impl<Call> TryFrom<VersionedXcm<Call>> for v3::Xcm<Call> {
}
}
/// Convert an `Xcm` datum into a `VersionedXcm`, based on a destination `MultiLocation` which will interpret it.
/// Convert an `Xcm` datum into a `VersionedXcm`, based on a destination `MultiLocation` which will
/// interpret it.
pub trait WrapVersion {
fn wrap_version<RuntimeCall>(
dest: &latest::MultiLocation,
@@ -368,7 +369,8 @@ pub trait WrapVersion {
) -> Result<VersionedXcm<RuntimeCall>, ()>;
}
/// `()` implementation does nothing with the XCM, just sending with whatever version it was authored as.
/// `()` implementation does nothing with the XCM, just sending with whatever version it was
/// authored as.
impl WrapVersion for () {
fn wrap_version<RuntimeCall>(
_: &latest::MultiLocation,
@@ -378,7 +380,8 @@ impl WrapVersion for () {
}
}
/// `WrapVersion` implementation which attempts to always convert the XCM to version 2 before wrapping it.
/// `WrapVersion` implementation which attempts to always convert the XCM to version 2 before
/// wrapping it.
pub struct AlwaysV2;
impl WrapVersion for AlwaysV2 {
fn wrap_version<RuntimeCall>(
@@ -389,7 +392,8 @@ impl WrapVersion for AlwaysV2 {
}
}
/// `WrapVersion` implementation which attempts to always convert the XCM to version 3 before wrapping it.
/// `WrapVersion` implementation which attempts to always convert the XCM to version 3 before
/// wrapping it.
pub struct AlwaysV3;
impl WrapVersion for AlwaysV3 {
fn wrap_version<Call>(
+8 -8
View File
@@ -32,13 +32,13 @@ pub enum Junction {
///
/// Generally used when the context is a Polkadot Relay-chain.
Parachain(#[codec(compact)] u32),
/// A 32-byte identifier for an account of a specific network that is respected as a sovereign endpoint within
/// the context.
/// A 32-byte identifier for an account of a specific network that is respected as a sovereign
/// endpoint within the context.
///
/// Generally used when the context is a Substrate-based chain.
AccountId32 { network: NetworkId, id: [u8; 32] },
/// An 8-byte index for an account of a specific network that is respected as a sovereign endpoint within
/// the context.
/// An 8-byte index for an account of a specific network that is respected as a sovereign
/// endpoint within the context.
///
/// May be used when the context is a Frame-based chain and includes e.g. an indices pallet.
AccountIndex64 {
@@ -46,8 +46,8 @@ pub enum Junction {
#[codec(compact)]
index: u64,
},
/// A 20-byte identifier for an account of a specific network that is respected as a sovereign endpoint within
/// the context.
/// A 20-byte identifier for an account of a specific network that is respected as a sovereign
/// endpoint within the context.
///
/// May be used when the context is an Ethereum or Bitcoin chain or smart-contract.
AccountKey20 { network: NetworkId, key: [u8; 20] },
@@ -73,8 +73,8 @@ pub enum Junction {
OnlyChild,
/// A pluralistic body existing within consensus.
///
/// Typical to be used to represent a governance origin of a chain, but could in principle be used to represent
/// things such as multisigs also.
/// Typical to be used to represent a governance origin of a chain, but could in principle be
/// used to represent things such as multisigs also.
Plurality { id: BodyId, part: BodyPart },
}
+39 -39
View File
@@ -39,11 +39,10 @@
//! - `Order` is now obsolete and replaced entirely by `Instruction`.
//! - `Xcm` is now a simple wrapper around a `Vec<Instruction>`.
//! - During conversion from `Order` to `Instruction`, we do not handle `BuyExecution`s that have
//! nested XCMs, i.e. if the `instructions` field in the `BuyExecution` enum struct variant is
//! not empty, then the conversion will fail. To address this, rewrite the XCM using
//! `Instruction`s in chronological order.
//! - During conversion from `Xcm` to `Instruction`, we do not handle `RelayedFrom` messages at
//! all.
//! nested XCMs, i.e. if the `instructions` field in the `BuyExecution` enum struct variant is not
//! empty, then the conversion will fail. To address this, rewrite the XCM using `Instruction`s in
//! chronological order.
//! - During conversion from `Xcm` to `Instruction`, we do not handle `RelayedFrom` messages at all.
//!
//! ### XCM Pallet
//! - The `Weigher` configuration item must have sensible weights defined for `BuyExecution` and
@@ -153,20 +152,20 @@ pub enum BodyId {
Executive,
/// The unambiguous technical body (for Polkadot, this would be the Technical Committee).
Technical,
/// The unambiguous legislative body (for Polkadot, this could be considered the opinion of a majority of
/// lock-voters).
/// The unambiguous legislative body (for Polkadot, this could be considered the opinion of a
/// majority of lock-voters).
Legislative,
/// The unambiguous judicial body (this doesn't exist on Polkadot, but if it were to get a "grand oracle", it
/// may be considered as that).
/// The unambiguous judicial body (this doesn't exist on Polkadot, but if it were to get a
/// "grand oracle", it may be considered as that).
Judicial,
/// The unambiguous defense body (for Polkadot, an opinion on the topic given via a public referendum
/// on the `staking_admin` track).
/// The unambiguous defense body (for Polkadot, an opinion on the topic given via a public
/// referendum on the `staking_admin` track).
Defense,
/// The unambiguous administration body (for Polkadot, an opinion on the topic given via a public referendum
/// on the `general_admin` track).
/// The unambiguous administration body (for Polkadot, an opinion on the topic given via a
/// public referendum on the `general_admin` track).
Administration,
/// The unambiguous treasury body (for Polkadot, an opinion on the topic given via a public referendum
/// on the `treasurer` track).
/// The unambiguous treasury body (for Polkadot, an opinion on the topic given via a public
/// referendum on the `treasurer` track).
Treasury,
}
@@ -422,8 +421,8 @@ pub type Weight = u64;
///
/// All messages are delivered from a known *origin*, expressed as a `MultiLocation`.
///
/// This is the inner XCM format and is version-sensitive. Messages are typically passed using the outer
/// XCM format, known as `VersionedXcm`.
/// This is the inner XCM format and is version-sensitive. Messages are typically passed using the
/// outer XCM format, known as `VersionedXcm`.
#[derive(Derivative, Encode, Decode, TypeInfo, xcm_procedural::XcmWeightInfoTrait)]
#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))]
#[codec(encode_bound())]
@@ -508,8 +507,8 @@ pub enum Instruction<RuntimeCall> {
/// - `dest`: The location whose sovereign account will own the assets and thus the effective
/// beneficiary for the assets and the notification target for the reserve asset deposit
/// message.
/// - `xcm`: The instructions that should follow the `ReserveAssetDeposited`
/// instruction, which is sent onwards to `dest`.
/// - `xcm`: The instructions that should follow the `ReserveAssetDeposited` instruction, which
/// is sent onwards to `dest`.
///
/// Safety: No concerns.
///
@@ -538,10 +537,11 @@ pub enum Instruction<RuntimeCall> {
call: DoubleEncoded<RuntimeCall>,
},
/// A message to notify about a new incoming HRMP channel. This message is meant to be sent by the
/// relay-chain to a para.
/// A message to notify about a new incoming HRMP channel. This message is meant to be sent by
/// the relay-chain to a para.
///
/// - `sender`: The sender in the to-be opened channel. Also, the initiator of the channel opening.
/// - `sender`: The sender in the to-be opened channel. Also, the initiator of the channel
/// opening.
/// - `max_message_size`: The maximum size of a message proposed by the sender.
/// - `max_capacity`: The maximum number of messages that can be queued in the channel.
///
@@ -558,8 +558,8 @@ pub enum Instruction<RuntimeCall> {
},
/// A message to notify about that a previously sent open channel request has been accepted by
/// the recipient. That means that the channel will be opened during the next relay-chain session
/// change. This message is meant to be sent by the relay-chain to a para.
/// the recipient. That means that the channel will be opened during the next relay-chain
/// session change. This message is meant to be sent by the relay-chain to a para.
///
/// Safety: The message should originate directly from the relay-chain.
///
@@ -573,10 +573,10 @@ pub enum Instruction<RuntimeCall> {
recipient: u32,
},
/// A message to notify that the other party in an open channel decided to close it. In particular,
/// `initiator` is going to close the channel opened from `sender` to the `recipient`. The close
/// will be enacted at the next relay-chain session change. This message is meant to be sent by
/// the relay-chain to a para.
/// A message to notify that the other party in an open channel decided to close it. In
/// particular, `initiator` is going to close the channel opened from `sender` to the
/// `recipient`. The close will be enacted at the next relay-chain session change. This message
/// is meant to be sent by the relay-chain to a para.
///
/// Safety: The message should originate directly from the relay-chain.
///
@@ -639,8 +639,8 @@ pub enum Instruction<RuntimeCall> {
///
/// - `assets`: The asset(s) to remove from holding.
/// - `max_assets`: The maximum number of unique assets/asset instances to remove from holding.
/// Only the first `max_assets` assets/instances of those matched by `assets` will be removed,
/// prioritized under standard asset ordering. Any others will remain in holding.
/// Only the first `max_assets` assets/instances of those matched by `assets` will be
/// removed, prioritized under standard asset ordering. Any others will remain in holding.
/// - `beneficiary`: The new owner for the assets.
///
/// Kind: *Instruction*
@@ -661,13 +661,13 @@ pub enum Instruction<RuntimeCall> {
///
/// - `assets`: The asset(s) to remove from holding.
/// - `max_assets`: The maximum number of unique assets/asset instances to remove from holding.
/// Only the first `max_assets` assets/instances of those matched by `assets` will be removed,
/// prioritized under standard asset ordering. Any others will remain in holding.
/// Only the first `max_assets` assets/instances of those matched by `assets` will be
/// removed, prioritized under standard asset ordering. Any others will remain in holding.
/// - `dest`: The location whose sovereign account will own the assets and thus the effective
/// beneficiary for the assets and the notification target for the reserve asset deposit
/// message.
/// - `xcm`: The orders that should follow the `ReserveAssetDeposited` instruction
/// which is sent onwards to `dest`.
/// - `xcm`: The orders that should follow the `ReserveAssetDeposited` instruction which is
/// sent onwards to `dest`.
///
/// Kind: *Instruction*
///
@@ -699,9 +699,9 @@ pub enum Instruction<RuntimeCall> {
///
/// - `assets`: The asset(s) to remove from holding.
/// - `reserve`: A valid location that acts as a reserve for all asset(s) in `assets`. The
/// sovereign account of this consensus system *on the reserve location* will have appropriate
/// assets withdrawn and `effects` will be executed on them. There will typically be only one
/// valid location on any given asset/chain combination.
/// sovereign account of this consensus system *on the reserve location* will have
/// appropriate assets withdrawn and `effects` will be executed on them. There will typically
/// be only one valid location on any given asset/chain combination.
/// - `xcm`: The instructions to execute on the assets once withdrawn *on the reserve
/// location*.
///
@@ -718,8 +718,8 @@ pub enum Instruction<RuntimeCall> {
/// - `xcm`: The instructions to execute on the assets once arrived *on the destination
/// location*.
///
/// NOTE: The `dest` location *MUST* respect this origin as a valid teleportation origin for all
/// `assets`. If it does not, then the assets may be lost.
/// NOTE: The `dest` location *MUST* respect this origin as a valid teleportation origin for
/// all `assets`. If it does not, then the assets may be lost.
///
/// Kind: *Instruction*
///
+43 -33
View File
@@ -17,11 +17,14 @@
//! Cross-Consensus Message format asset data structures.
//!
//! This encompasses four types for representing assets:
//! - `MultiAsset`: A description of a single asset, either an instance of a non-fungible or some amount of a fungible.
//! - `MultiAssets`: A collection of `MultiAsset`s. These are stored in a `Vec` and sorted with fungibles first.
//! - `Wild`: A single asset wildcard, this can either be "all" assets, or all assets of a specific kind.
//! - `MultiAssetFilter`: A combination of `Wild` and `MultiAssets` designed for efficiently filtering an XCM holding
//! account.
//! - `MultiAsset`: A description of a single asset, either an instance of a non-fungible or some
//! amount of a fungible.
//! - `MultiAssets`: A collection of `MultiAsset`s. These are stored in a `Vec` and sorted with
//! fungibles first.
//! - `Wild`: A single asset wildcard, this can either be "all" assets, or all assets of a specific
//! kind.
//! - `MultiAssetFilter`: A combination of `Wild` and `MultiAssets` designed for efficiently
//! filtering an XCM holding account.
use super::MultiLocation;
use crate::v3::{
@@ -42,8 +45,8 @@ pub enum AssetInstance {
/// Undefined - used if the non-fungible asset class has only one instance.
Undefined,
/// A compact index. Technically this could be greater than `u128`, but this implementation supports only
/// values up to `2**128 - 1`.
/// A compact index. Technically this could be greater than `u128`, but this implementation
/// supports only values up to `2**128 - 1`.
Index(#[codec(compact)] u128),
/// A 4-byte fixed-length datum.
@@ -165,19 +168,21 @@ impl AssetId {
Ok(())
}
/// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding `MultiAsset` value.
/// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding
/// `MultiAsset` value.
pub fn into_multiasset(self, fun: Fungibility) -> MultiAsset {
MultiAsset { fun, id: self }
}
/// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding `WildMultiAsset`
/// wildcard (`AllOf`) value.
/// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding
/// `WildMultiAsset` wildcard (`AllOf`) value.
pub fn into_wild(self, fun: WildFungibility) -> WildMultiAsset {
WildMultiAsset::AllOf { fun, id: self }
}
}
/// Classification of whether an asset is fungible or not, along with a mandatory amount or instance.
/// Classification of whether an asset is fungible or not, along with a mandatory amount or
/// instance.
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo)]
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
pub enum Fungibility {
@@ -300,7 +305,8 @@ impl TryFrom<NewMultiAsset> for MultiAsset {
}
}
/// A `Vec` of `MultiAsset`s. There may be no duplicate fungible items in here and when decoding, they must be sorted.
/// A `Vec` of `MultiAsset`s. There may be no duplicate fungible items in here and when decoding,
/// they must be sorted.
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, TypeInfo)]
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
pub struct MultiAssets(Vec<MultiAsset>);
@@ -370,11 +376,12 @@ impl MultiAssets {
Self(Vec::new())
}
/// Create a new instance of `MultiAssets` from a `Vec<MultiAsset>` whose contents are sorted and
/// which contain no duplicates.
/// Create a new instance of `MultiAssets` from a `Vec<MultiAsset>` whose contents are sorted
/// and which contain no duplicates.
///
/// Returns `Ok` if the operation succeeds and `Err` if `r` is out of order or had duplicates. If you can't
/// guarantee that `r` is sorted and deduplicated, then use `From::<Vec<MultiAsset>>::from` which is infallible.
/// Returns `Ok` if the operation succeeds and `Err` if `r` is out of order or had duplicates.
/// If you can't guarantee that `r` is sorted and deduplicated, then use
/// `From::<Vec<MultiAsset>>::from` which is infallible.
pub fn from_sorted_and_deduplicated(r: Vec<MultiAsset>) -> Result<Self, ()> {
if r.is_empty() {
return Ok(Self(Vec::new()))
@@ -389,20 +396,22 @@ impl MultiAssets {
Ok(Self(r))
}
/// Create a new instance of `MultiAssets` from a `Vec<MultiAsset>` whose contents are sorted and
/// which contain no duplicates.
/// Create a new instance of `MultiAssets` from a `Vec<MultiAsset>` whose contents are sorted
/// and which contain no duplicates.
///
/// In release mode, this skips any checks to ensure that `r` is correct, making it a negligible-cost operation.
/// Generally though you should avoid using it unless you have a strict proof that `r` is valid.
/// In release mode, this skips any checks to ensure that `r` is correct, making it a
/// negligible-cost operation. Generally though you should avoid using it unless you have a
/// strict proof that `r` is valid.
#[cfg(test)]
pub fn from_sorted_and_deduplicated_skip_checks(r: Vec<MultiAsset>) -> Self {
Self::from_sorted_and_deduplicated(r).expect("Invalid input r is not sorted/deduped")
}
/// Create a new instance of `MultiAssets` from a `Vec<MultiAsset>` whose contents are sorted and
/// which contain no duplicates.
/// Create a new instance of `MultiAssets` from a `Vec<MultiAsset>` whose contents are sorted
/// and which contain no duplicates.
///
/// In release mode, this skips any checks to ensure that `r` is correct, making it a negligible-cost operation.
/// Generally though you should avoid using it unless you have a strict proof that `r` is valid.
/// In release mode, this skips any checks to ensure that `r` is correct, making it a
/// negligible-cost operation. Generally though you should avoid using it unless you have a
/// strict proof that `r` is valid.
///
/// In test mode, this checks anyway and panics on fail.
#[cfg(not(test))]
@@ -410,7 +419,8 @@ impl MultiAssets {
Self(r)
}
/// Add some asset onto the list, saturating. This is quite a laborious operation since it maintains the ordering.
/// Add some asset onto the list, saturating. This is quite a laborious operation since it
/// maintains the ordering.
pub fn push(&mut self, a: MultiAsset) {
if let Fungibility::Fungible(ref amount) = a.fun {
for asset in self.0.iter_mut().filter(|x| x.id == a.id) {
@@ -489,19 +499,19 @@ impl TryFrom<NewWildFungibility> for WildFungibility {
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode, TypeInfo)]
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
pub enum WildMultiAsset {
/// All assets in the holding register, up to `usize` individual assets (different instances of non-fungibles could
/// be separate assets).
/// All assets in the holding register, up to `usize` individual assets (different instances of
/// non-fungibles could be separate assets).
All,
/// All assets in the holding register of a given fungibility and ID. If operating on non-fungibles, then a limit
/// is provided for the maximum amount of matching instances.
/// All assets in the holding register of a given fungibility and ID. If operating on
/// non-fungibles, then a limit is provided for the maximum amount of matching instances.
AllOf { id: AssetId, fun: WildFungibility },
}
impl WildMultiAsset {
/// Returns true if `self` is a super-set of the given `inner`.
///
/// Typically, any wildcard is never contained in anything else, and a wildcard can contain any other non-wildcard.
/// For more details, see the implementation and tests.
/// Typically, any wildcard is never contained in anything else, and a wildcard can contain any
/// other non-wildcard. For more details, see the implementation and tests.
pub fn contains(&self, inner: &MultiAsset) -> bool {
use WildMultiAsset::*;
match self {
@@ -565,8 +575,8 @@ impl From<MultiAssets> for MultiAssetFilter {
impl MultiAssetFilter {
/// Returns true if `self` is a super-set of the given `inner`.
///
/// Typically, any wildcard is never contained in anything else, and a wildcard can contain any other non-wildcard.
/// For more details, see the implementation and tests.
/// Typically, any wildcard is never contained in anything else, and a wildcard can contain any
/// other non-wildcard. For more details, see the implementation and tests.
pub fn contains(&self, inner: &MultiAsset) -> bool {
match self {
MultiAssetFilter::Definite(ref assets) => assets.contains(inner),
+16 -13
View File
@@ -174,8 +174,8 @@ impl MultiLocation {
self.interior.push_front(new)
}
/// Consumes `self` and returns a `MultiLocation` suffixed with `new`, or an `Err` with theoriginal value of
/// `self` in case of overflow.
/// Consumes `self` and returns a `MultiLocation` suffixed with `new`, or an `Err` with
/// theoriginal value of `self` in case of overflow.
pub fn pushed_with_interior(self, new: Junction) -> result::Result<Self, (Self, Junction)> {
match self.interior.pushed_with(new) {
Ok(i) => Ok(MultiLocation { interior: i, parents: self.parents }),
@@ -183,8 +183,8 @@ impl MultiLocation {
}
}
/// Consumes `self` and returns a `MultiLocation` prefixed with `new`, or an `Err` with the original value of
/// `self` in case of overflow.
/// Consumes `self` and returns a `MultiLocation` prefixed with `new`, or an `Err` with the
/// original value of `self` in case of overflow.
pub fn pushed_front_with_interior(
self,
new: Junction,
@@ -430,7 +430,8 @@ impl From<Parent> for MultiLocation {
}
}
/// A tuple struct which can be converted into a `MultiLocation` of `parents` value 1 with the inner interior.
/// A tuple struct which can be converted into a `MultiLocation` of `parents` value 1 with the inner
/// interior.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct ParentThen(pub Junctions);
impl From<ParentThen> for MultiLocation {
@@ -448,7 +449,8 @@ impl From<Ancestor> for MultiLocation {
}
}
/// A unit struct which can be converted into a `MultiLocation` of the inner `parents` value and the inner interior.
/// A unit struct which can be converted into a `MultiLocation` of the inner `parents` value and the
/// inner interior.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct AncestorThen<Interior>(pub u8, pub Interior);
impl<Interior: Into<Junctions>> From<AncestorThen<Interior>> for MultiLocation {
@@ -598,8 +600,8 @@ impl Junctions {
}
}
/// Splits off the first junction, returning the remaining suffix (first item in tuple) and the first element
/// (second item in tuple) or `None` if it was empty.
/// Splits off the first junction, returning the remaining suffix (first item in tuple) and the
/// first element (second item in tuple) or `None` if it was empty.
pub fn split_first(self) -> (Junctions, Option<Junction>) {
match self {
Junctions::Here => (Junctions::Here, None),
@@ -614,8 +616,8 @@ impl Junctions {
}
}
/// Splits off the last junction, returning the remaining prefix (first item in tuple) and the last element
/// (second item in tuple) or `None` if it was empty.
/// Splits off the last junction, returning the remaining prefix (first item in tuple) and the
/// last element (second item in tuple) or `None` if it was empty.
pub fn split_last(self) -> (Junctions, Option<Junction>) {
match self {
Junctions::Here => (Junctions::Here, None),
@@ -727,7 +729,8 @@ impl Junctions {
}
}
/// Returns the junction at index `i`, or `None` if the location doesn't contain that many elements.
/// Returns the junction at index `i`, or `None` if the location doesn't contain that many
/// elements.
pub fn at(&self, i: usize) -> Option<&Junction> {
Some(match (i, self) {
(0, Junctions::X1(ref a)) => a,
@@ -770,8 +773,8 @@ impl Junctions {
})
}
/// Returns a mutable reference to the junction at index `i`, or `None` if the location doesn't contain that many
/// elements.
/// Returns a mutable reference to the junction at index `i`, or `None` if the location doesn't
/// contain that many elements.
pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> {
Some(match (i, self) {
(0, Junctions::X1(ref mut a)) => a,
+17 -14
View File
@@ -81,7 +81,8 @@ pub enum Error {
/// Used by `Transact` when the functor cannot be decoded.
#[codec(index = 17)]
FailedToDecode,
/// Used by `Transact` to indicate that the given weight limit could be breached by the functor.
/// Used by `Transact` to indicate that the given weight limit could be breached by the
/// functor.
#[codec(index = 18)]
MaxWeightInvalid,
/// Used by `BuyExecution` when the Holding Register does not contain payable fees.
@@ -94,7 +95,8 @@ pub enum Error {
#[codec(index = 21)]
Trap(u64),
// Errors that happen prior to instructions being executed. These fall outside of the XCM spec.
// Errors that happen prior to instructions being executed. These fall outside of the XCM
// spec.
/// XCM version not able to be handled.
UnhandledXcmVersion,
/// Execution of the XCM would potentially result in a greater weight used than weight limit.
@@ -161,7 +163,8 @@ pub type Result = result::Result<(), Error>;
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.
/// 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),
@@ -194,9 +197,9 @@ impl Outcome {
/// Type of XCM message executor.
pub trait ExecuteXcm<RuntimeCall> {
/// Execute some XCM `message` from `origin` using no more than `weight_limit` weight. The weight limit is
/// a basic hard-limit and the implementation may place further restrictions or requirements on weight and
/// other aspects.
/// Execute some XCM `message` from `origin` using no more than `weight_limit` weight. The
/// weight limit is a basic hard-limit and the implementation may place further restrictions or
/// requirements on weight and other aspects.
fn execute_xcm(
origin: impl Into<MultiLocation>,
message: Xcm<RuntimeCall>,
@@ -215,8 +218,8 @@ pub trait ExecuteXcm<RuntimeCall> {
/// Execute some XCM `message` from `origin` using no more than `weight_limit` weight.
///
/// Some amount of `weight_credit` may be provided which, depending on the implementation, may allow
/// execution without associated payment.
/// Some amount of `weight_credit` may be provided which, depending on the implementation, may
/// allow execution without associated payment.
fn execute_xcm_in_credit(
origin: impl Into<MultiLocation>,
message: Xcm<RuntimeCall>,
@@ -263,9 +266,9 @@ pub type SendResult = result::Result<(), SendError>;
/// Utility for sending an XCM message.
///
/// These can be amalgamated in tuples to form sophisticated routing systems. In tuple format, each router might return
/// `NotApplicable` to pass the execution to the next sender item. Note that each `NotApplicable`
/// might alter the destination and the XCM message for to the next router.
/// These can be amalgamated in tuples to form sophisticated routing systems. In tuple format, each
/// router might return `NotApplicable` to pass the execution to the next sender item. Note that
/// each `NotApplicable` might alter the destination and the XCM message for to the next router.
///
///
/// # Example
@@ -330,9 +333,9 @@ pub type SendResult = result::Result<(), SendError>;
pub trait SendXcm {
/// Send an XCM `message` to a given `destination`.
///
/// If it is not a destination which can be reached with this type but possibly could by others, then it *MUST*
/// return `NotApplicable`. Any other error will cause the tuple implementation to exit early without
/// trying other type fields.
/// If it is not a destination which can be reached with this type but possibly could by others,
/// then it *MUST* return `NotApplicable`. Any other error will cause the tuple implementation
/// to exit early without trying other type fields.
fn send_xcm(destination: impl Into<MultiLocation>, message: Xcm<()>) -> SendResult;
}
+20 -19
View File
@@ -127,20 +127,20 @@ pub enum BodyId {
Executive,
/// The unambiguous technical body (for Polkadot, this would be the Technical Committee).
Technical,
/// The unambiguous legislative body (for Polkadot, this could be considered the opinion of a majority of
/// lock-voters).
/// The unambiguous legislative body (for Polkadot, this could be considered the opinion of a
/// majority of lock-voters).
Legislative,
/// The unambiguous judicial body (this doesn't exist on Polkadot, but if it were to get a "grand oracle", it
/// may be considered as that).
/// The unambiguous judicial body (this doesn't exist on Polkadot, but if it were to get a
/// "grand oracle", it may be considered as that).
Judicial,
/// The unambiguous defense body (for Polkadot, an opinion on the topic given via a public referendum
/// on the `staking_admin` track).
/// The unambiguous defense body (for Polkadot, an opinion on the topic given via a public
/// referendum on the `staking_admin` track).
Defense,
/// The unambiguous administration body (for Polkadot, an opinion on the topic given via a public referendum
/// on the `general_admin` track).
/// The unambiguous administration body (for Polkadot, an opinion on the topic given via a
/// public referendum on the `general_admin` track).
Administration,
/// The unambiguous treasury body (for Polkadot, an opinion on the topic given via a public referendum
/// on the `treasurer` track).
/// The unambiguous treasury body (for Polkadot, an opinion on the topic given via a public
/// referendum on the `treasurer` track).
Treasury,
}
@@ -266,13 +266,13 @@ pub enum Junction {
///
/// Generally used when the context is a Polkadot Relay-chain.
Parachain(#[codec(compact)] u32),
/// A 32-byte identifier for an account of a specific network that is respected as a sovereign endpoint within
/// the context.
/// A 32-byte identifier for an account of a specific network that is respected as a sovereign
/// endpoint within the context.
///
/// Generally used when the context is a Substrate-based chain.
AccountId32 { network: Option<NetworkId>, id: [u8; 32] },
/// An 8-byte index for an account of a specific network that is respected as a sovereign endpoint within
/// the context.
/// An 8-byte index for an account of a specific network that is respected as a sovereign
/// endpoint within the context.
///
/// May be used when the context is a Frame-based chain and includes e.g. an indices pallet.
AccountIndex64 {
@@ -280,8 +280,8 @@ pub enum Junction {
#[codec(compact)]
index: u64,
},
/// A 20-byte identifier for an account of a specific network that is respected as a sovereign endpoint within
/// the context.
/// A 20-byte identifier for an account of a specific network that is respected as a sovereign
/// endpoint within the context.
///
/// May be used when the context is an Ethereum or Bitcoin chain or smart-contract.
AccountKey20 { network: Option<NetworkId>, key: [u8; 20] },
@@ -310,8 +310,8 @@ pub enum Junction {
OnlyChild,
/// A pluralistic body existing within consensus.
///
/// Typical to be used to represent a governance origin of a chain, but could in principle be used to represent
/// things such as multisigs also.
/// Typical to be used to represent a governance origin of a chain, but could in principle be
/// used to represent things such as multisigs also.
Plurality { id: BodyId, part: BodyPart },
/// A global network capable of externalizing its own consensus. This is not generally
/// meaningful outside of the universal level.
@@ -413,7 +413,8 @@ impl Junction {
/// Convert `self` into a `MultiLocation` containing `n` parents.
///
/// Similar to `Self::into_location`, with the added ability to specify the number of parent junctions.
/// Similar to `Self::into_location`, with the added ability to specify the number of parent
/// junctions.
pub const fn into_exterior(self, n: u8) -> MultiLocation {
MultiLocation { parents: n, interior: Junctions::X1(self) }
}
+10 -8
View File
@@ -137,7 +137,8 @@ impl Junctions {
/// Convert `self` into a `MultiLocation` containing `n` parents.
///
/// Similar to `Self::into_location`, with the added ability to specify the number of parent junctions.
/// Similar to `Self::into_location`, with the added ability to specify the number of parent
/// junctions.
pub const fn into_exterior(self, n: u8) -> MultiLocation {
MultiLocation { parents: n, interior: self }
}
@@ -309,8 +310,8 @@ impl Junctions {
}
}
/// Splits off the first junction, returning the remaining suffix (first item in tuple) and the first element
/// (second item in tuple) or `None` if it was empty.
/// Splits off the first junction, returning the remaining suffix (first item in tuple) and the
/// first element (second item in tuple) or `None` if it was empty.
pub fn split_first(self) -> (Junctions, Option<Junction>) {
match self {
Junctions::Here => (Junctions::Here, None),
@@ -325,8 +326,8 @@ impl Junctions {
}
}
/// Splits off the last junction, returning the remaining prefix (first item in tuple) and the last element
/// (second item in tuple) or `None` if it was empty.
/// Splits off the last junction, returning the remaining prefix (first item in tuple) and the
/// last element (second item in tuple) or `None` if it was empty.
pub fn split_last(self) -> (Junctions, Option<Junction>) {
match self {
Junctions::Here => (Junctions::Here, None),
@@ -469,7 +470,8 @@ impl Junctions {
}
}
/// Returns the junction at index `i`, or `None` if the location doesn't contain that many elements.
/// Returns the junction at index `i`, or `None` if the location doesn't contain that many
/// elements.
pub fn at(&self, i: usize) -> Option<&Junction> {
Some(match (i, self) {
(0, Junctions::X1(ref a)) => a,
@@ -512,8 +514,8 @@ impl Junctions {
})
}
/// Returns a mutable reference to the junction at index `i`, or `None` if the location doesn't contain that many
/// elements.
/// Returns a mutable reference to the junction at index `i`, or `None` if the location doesn't
/// contain that many elements.
pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> {
Some(match (i, self) {
(0, Junctions::X1(ref mut a)) => a,
+37 -32
View File
@@ -367,8 +367,8 @@ impl XcmContext {
///
/// All messages are delivered from a known *origin*, expressed as a `MultiLocation`.
///
/// This is the inner XCM format and is version-sensitive. Messages are typically passed using the outer
/// XCM format, known as `VersionedXcm`.
/// This is the inner XCM format and is version-sensitive. Messages are typically passed using the
/// outer XCM format, known as `VersionedXcm`.
#[derive(Derivative, Encode, Decode, TypeInfo, xcm_procedural::XcmWeightInfoTrait)]
#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))]
#[codec(encode_bound())]
@@ -417,9 +417,8 @@ pub enum Instruction<Call> {
/// - `response`: The message content.
/// - `max_weight`: The maximum weight that handling this response should take.
/// - `querier`: The location responsible for the initiation of the response, if there is one.
/// In general this will tend to be the same location as the receiver of this message.
/// NOTE: As usual, this is interpreted from the perspective of the receiving consensus
/// system.
/// In general this will tend to be the same location as the receiver of this message. NOTE:
/// As usual, this is interpreted from the perspective of the receiving consensus system.
///
/// Safety: Since this is information only, there are no immediate concerns. However, it should
/// be remembered that even if the Origin behaves reasonably, it can always be asked to make
@@ -460,8 +459,8 @@ pub enum Instruction<Call> {
/// - `dest`: The location whose sovereign account will own the assets and thus the effective
/// beneficiary for the assets and the notification target for the reserve asset deposit
/// message.
/// - `xcm`: The instructions that should follow the `ReserveAssetDeposited`
/// instruction, which is sent onwards to `dest`.
/// - `xcm`: The instructions that should follow the `ReserveAssetDeposited` instruction, which
/// is sent onwards to `dest`.
///
/// Safety: No concerns.
///
@@ -487,10 +486,11 @@ pub enum Instruction<Call> {
/// Errors:
Transact { origin_kind: OriginKind, require_weight_at_most: Weight, call: DoubleEncoded<Call> },
/// A message to notify about a new incoming HRMP channel. This message is meant to be sent by the
/// relay-chain to a para.
/// A message to notify about a new incoming HRMP channel. This message is meant to be sent by
/// the relay-chain to a para.
///
/// - `sender`: The sender in the to-be opened channel. Also, the initiator of the channel opening.
/// - `sender`: The sender in the to-be opened channel. Also, the initiator of the channel
/// opening.
/// - `max_message_size`: The maximum size of a message proposed by the sender.
/// - `max_capacity`: The maximum number of messages that can be queued in the channel.
///
@@ -507,8 +507,8 @@ pub enum Instruction<Call> {
},
/// A message to notify about that a previously sent open channel request has been accepted by
/// the recipient. That means that the channel will be opened during the next relay-chain session
/// change. This message is meant to be sent by the relay-chain to a para.
/// the recipient. That means that the channel will be opened during the next relay-chain
/// session change. This message is meant to be sent by the relay-chain to a para.
///
/// Safety: The message should originate directly from the relay-chain.
///
@@ -522,10 +522,10 @@ pub enum Instruction<Call> {
recipient: u32,
},
/// A message to notify that the other party in an open channel decided to close it. In particular,
/// `initiator` is going to close the channel opened from `sender` to the `recipient`. The close
/// will be enacted at the next relay-chain session change. This message is meant to be sent by
/// the relay-chain to a para.
/// A message to notify that the other party in an open channel decided to close it. In
/// particular, `initiator` is going to close the channel opened from `sender` to the
/// `recipient`. The close will be enacted at the next relay-chain session change. This message
/// is meant to be sent by the relay-chain to a para.
///
/// Safety: The message should originate directly from the relay-chain.
///
@@ -593,8 +593,8 @@ pub enum Instruction<Call> {
/// - `dest`: The location whose sovereign account will own the assets and thus the effective
/// beneficiary for the assets and the notification target for the reserve asset deposit
/// message.
/// - `xcm`: The orders that should follow the `ReserveAssetDeposited` instruction
/// which is sent onwards to `dest`.
/// - `xcm`: The orders that should follow the `ReserveAssetDeposited` instruction which is
/// sent onwards to `dest`.
///
/// Kind: *Instruction*
///
@@ -623,9 +623,9 @@ pub enum Instruction<Call> {
///
/// - `assets`: The asset(s) to remove from holding.
/// - `reserve`: A valid location that acts as a reserve for all asset(s) in `assets`. The
/// sovereign account of this consensus system *on the reserve location* will have appropriate
/// assets withdrawn and `effects` will be executed on them. There will typically be only one
/// valid location on any given asset/chain combination.
/// sovereign account of this consensus system *on the reserve location* will have
/// appropriate assets withdrawn and `effects` will be executed on them. There will typically
/// be only one valid location on any given asset/chain combination.
/// - `xcm`: The instructions to execute on the assets once withdrawn *on the reserve
/// location*.
///
@@ -642,8 +642,8 @@ pub enum Instruction<Call> {
/// - `xcm`: The instructions to execute on the assets once arrived *on the destination
/// location*.
///
/// NOTE: The `dest` location *MUST* respect this origin as a valid teleportation origin for all
/// `assets`. If it does not, then the assets may be lost.
/// NOTE: The `dest` location *MUST* respect this origin as a valid teleportation origin for
/// all `assets`. If it does not, then the assets may be lost.
///
/// Kind: *Instruction*
///
@@ -809,7 +809,8 @@ pub enum Instruction<Call> {
/// Kind: *Instruction*
///
/// Errors:
/// - `ExpectationFalse`: If the value of the Transact Status Register is not equal to the parameter.
/// - `ExpectationFalse`: If the value of the Transact Status Register is not equal to the
/// parameter.
ExpectTransactStatus(MaybeErrorCode),
/// Query the existence of a particular pallet type.
@@ -830,11 +831,15 @@ pub enum Instruction<Call> {
/// Ensure that a particular pallet with a particular version exists.
///
/// - `index: Compact`: The index which identifies the pallet. An error if no pallet exists at this index.
/// - `index: Compact`: The index which identifies the pallet. An error if no pallet exists at
/// this index.
/// - `name: Vec<u8>`: Name which must be equal to the name of the pallet.
/// - `module_name: Vec<u8>`: Module name which must be equal to the name of the module in which the pallet exists.
/// - `crate_major: Compact`: Version number which must be equal to the major version of the crate which implements the pallet.
/// - `min_crate_minor: Compact`: Version number which must be at most the minor version of the crate which implements the pallet.
/// - `module_name: Vec<u8>`: Module name which must be equal to the name of the module in
/// which the pallet exists.
/// - `crate_major: Compact`: Version number which must be equal to the major version of the
/// crate which implements the pallet.
/// - `min_crate_minor: Compact`: Version number which must be at most the minor version of the
/// crate which implements the pallet.
///
/// Safety: No concerns.
///
@@ -961,8 +966,8 @@ pub enum Instruction<Call> {
/// of course, if there is no record that the asset actually is locked.
///
/// - `asset`: The asset(s) to be unlocked.
/// - `locker`: The location from which a previous `NoteUnlockable` was sent and to which
/// an `UnlockAsset` should be sent.
/// - `locker`: The location from which a previous `NoteUnlockable` was sent and to which an
/// `UnlockAsset` should be sent.
///
/// Kind: *Instruction*.
///
@@ -971,8 +976,8 @@ pub enum Instruction<Call> {
/// Sets the Fees Mode Register.
///
/// - `jit_withdraw`: The fees mode item; if set to `true` then fees for any instructions
/// are withdrawn as needed using the same mechanism as `WithdrawAssets`.
/// - `jit_withdraw`: The fees mode item; if set to `true` then fees for any instructions are
/// withdrawn as needed using the same mechanism as `WithdrawAssets`.
///
/// Kind: *Instruction*.
///
+33 -24
View File
@@ -17,11 +17,14 @@
//! Cross-Consensus Message format asset data structures.
//!
//! This encompasses four types for representing assets:
//! - `MultiAsset`: A description of a single asset, either an instance of a non-fungible or some amount of a fungible.
//! - `MultiAssets`: A collection of `MultiAsset`s. These are stored in a `Vec` and sorted with fungibles first.
//! - `Wild`: A single asset wildcard, this can either be "all" assets, or all assets of a specific kind.
//! - `MultiAssetFilter`: A combination of `Wild` and `MultiAssets` designed for efficiently filtering an XCM holding
//! account.
//! - `MultiAsset`: A description of a single asset, either an instance of a non-fungible or some
//! amount of a fungible.
//! - `MultiAssets`: A collection of `MultiAsset`s. These are stored in a `Vec` and sorted with
//! fungibles first.
//! - `Wild`: A single asset wildcard, this can either be "all" assets, or all assets of a specific
//! kind.
//! - `MultiAssetFilter`: A combination of `Wild` and `MultiAssets` designed for efficiently
//! filtering an XCM holding account.
use super::{InteriorMultiLocation, MultiLocation};
use crate::v2::{
@@ -47,8 +50,8 @@ pub enum AssetInstance {
/// Undefined - used if the non-fungible asset class has only one instance.
Undefined,
/// A compact index. Technically this could be greater than `u128`, but this implementation supports only
/// values up to `2**128 - 1`.
/// A compact index. Technically this could be greater than `u128`, but this implementation
/// supports only values up to `2**128 - 1`.
Index(#[codec(compact)] u128),
/// A 4-byte fixed-length datum.
@@ -234,7 +237,8 @@ impl TryFrom<AssetInstance> for u128 {
}
}
/// Classification of whether an asset is fungible or not, along with a mandatory amount or instance.
/// Classification of whether an asset is fungible or not, along with a mandatory amount or
/// instance.
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, TypeInfo, MaxEncodedLen)]
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
pub enum Fungibility {
@@ -387,13 +391,14 @@ impl AssetId {
Ok(())
}
/// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding `MultiAsset` value.
/// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding
/// `MultiAsset` value.
pub fn into_multiasset(self, fun: Fungibility) -> MultiAsset {
MultiAsset { fun, id: self }
}
/// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding `WildMultiAsset`
/// wildcard (`AllOf`) value.
/// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding
/// `WildMultiAsset` wildcard (`AllOf`) value.
pub fn into_wild(self, fun: WildFungibility) -> WildMultiAsset {
WildMultiAsset::AllOf { fun, id: self }
}
@@ -576,11 +581,12 @@ impl MultiAssets {
Self(Vec::new())
}
/// Create a new instance of `MultiAssets` from a `Vec<MultiAsset>` whose contents are sorted and
/// which contain no duplicates.
/// Create a new instance of `MultiAssets` from a `Vec<MultiAsset>` whose contents are sorted
/// and which contain no duplicates.
///
/// Returns `Ok` if the operation succeeds and `Err` if `r` is out of order or had duplicates. If you can't
/// guarantee that `r` is sorted and deduplicated, then use `From::<Vec<MultiAsset>>::from` which is infallible.
/// Returns `Ok` if the operation succeeds and `Err` if `r` is out of order or had duplicates.
/// If you can't guarantee that `r` is sorted and deduplicated, then use
/// `From::<Vec<MultiAsset>>::from` which is infallible.
pub fn from_sorted_and_deduplicated(r: Vec<MultiAsset>) -> Result<Self, ()> {
if r.is_empty() {
return Ok(Self(Vec::new()))
@@ -595,20 +601,22 @@ impl MultiAssets {
Ok(Self(r))
}
/// Create a new instance of `MultiAssets` from a `Vec<MultiAsset>` whose contents are sorted and
/// which contain no duplicates.
/// Create a new instance of `MultiAssets` from a `Vec<MultiAsset>` whose contents are sorted
/// and which contain no duplicates.
///
/// In release mode, this skips any checks to ensure that `r` is correct, making it a negligible-cost operation.
/// Generally though you should avoid using it unless you have a strict proof that `r` is valid.
/// In release mode, this skips any checks to ensure that `r` is correct, making it a
/// negligible-cost operation. Generally though you should avoid using it unless you have a
/// strict proof that `r` is valid.
#[cfg(test)]
pub fn from_sorted_and_deduplicated_skip_checks(r: Vec<MultiAsset>) -> Self {
Self::from_sorted_and_deduplicated(r).expect("Invalid input r is not sorted/deduped")
}
/// Create a new instance of `MultiAssets` from a `Vec<MultiAsset>` whose contents are sorted and
/// which contain no duplicates.
/// Create a new instance of `MultiAssets` from a `Vec<MultiAsset>` whose contents are sorted
/// and which contain no duplicates.
///
/// In release mode, this skips any checks to ensure that `r` is correct, making it a negligible-cost operation.
/// Generally though you should avoid using it unless you have a strict proof that `r` is valid.
/// In release mode, this skips any checks to ensure that `r` is correct, making it a
/// negligible-cost operation. Generally though you should avoid using it unless you have a
/// strict proof that `r` is valid.
///
/// In test mode, this checks anyway and panics on fail.
#[cfg(not(test))]
@@ -616,7 +624,8 @@ impl MultiAssets {
Self(r)
}
/// Add some asset onto the list, saturating. This is quite a laborious operation since it maintains the ordering.
/// Add some asset onto the list, saturating. This is quite a laborious operation since it
/// maintains the ordering.
pub fn push(&mut self, a: MultiAsset) {
for asset in self.0.iter_mut().filter(|x| x.id == a.id) {
match (&a.fun, &mut asset.fun) {
+8 -6
View File
@@ -198,8 +198,8 @@ impl MultiLocation {
self.interior.push_front(new)
}
/// Consumes `self` and returns a `MultiLocation` suffixed with `new`, or an `Err` with theoriginal value of
/// `self` in case of overflow.
/// Consumes `self` and returns a `MultiLocation` suffixed with `new`, or an `Err` with
/// theoriginal value of `self` in case of overflow.
pub fn pushed_with_interior(
self,
new: impl Into<Junction>,
@@ -210,8 +210,8 @@ impl MultiLocation {
}
}
/// Consumes `self` and returns a `MultiLocation` prefixed with `new`, or an `Err` with the original value of
/// `self` in case of overflow.
/// Consumes `self` and returns a `MultiLocation` prefixed with `new`, or an `Err` with the
/// original value of `self` in case of overflow.
pub fn pushed_front_with_interior(
self,
new: impl Into<Junction>,
@@ -472,7 +472,8 @@ impl From<Parent> for MultiLocation {
}
}
/// A tuple struct which can be converted into a `MultiLocation` of `parents` value 1 with the inner interior.
/// A tuple struct which can be converted into a `MultiLocation` of `parents` value 1 with the inner
/// interior.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct ParentThen(pub Junctions);
impl From<ParentThen> for MultiLocation {
@@ -490,7 +491,8 @@ impl From<Ancestor> for MultiLocation {
}
}
/// A unit struct which can be converted into a `MultiLocation` of the inner `parents` value and the inner interior.
/// A unit struct which can be converted into a `MultiLocation` of the inner `parents` value and the
/// inner interior.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct AncestorThen<Interior>(pub u8, pub Interior);
impl<Interior: Into<Junctions>> From<AncestorThen<Interior>> for MultiLocation {
+6 -3
View File
@@ -86,7 +86,8 @@ pub enum Error {
/// Used by `Transact` when the functor cannot be decoded.
#[codec(index = 17)]
FailedToDecode,
/// Used by `Transact` to indicate that the given weight limit could be breached by the functor.
/// Used by `Transact` to indicate that the given weight limit could be breached by the
/// functor.
#[codec(index = 18)]
MaxWeightInvalid,
/// Used by `BuyExecution` when the Holding Register does not contain payable fees.
@@ -138,7 +139,8 @@ pub enum Error {
#[codec(index = 34)]
NotDepositable,
// Errors that happen prior to instructions being executed. These fall outside of the XCM spec.
// Errors that happen prior to instructions being executed. These fall outside of the XCM
// spec.
/// XCM version not able to be handled.
UnhandledXcmVersion,
/// Execution of the XCM would potentially result in a greater weight used than weight limit.
@@ -263,7 +265,8 @@ impl From<Error> for Outcome {
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.
/// 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),
@@ -22,9 +22,9 @@ use sp_std::{marker::PhantomData, prelude::*, result};
use xcm::latest::prelude::*;
use xcm_executor::traits::{Error as MatchError, MatchesFungibles, MatchesNonFungibles};
/// Converter struct implementing `AssetIdConversion` converting a numeric asset ID (must be `TryFrom/TryInto<u128>`) into
/// a `GeneralIndex` junction, prefixed by some `MultiLocation` value. The `MultiLocation` value will typically be a
/// `PalletInstance` junction.
/// Converter struct implementing `AssetIdConversion` converting a numeric asset ID (must be
/// `TryFrom/TryInto<u128>`) into a `GeneralIndex` junction, prefixed by some `MultiLocation` value.
/// The `MultiLocation` value will typically be a `PalletInstance` junction.
pub struct AsPrefixedGeneralIndex<Prefix, AssetId, ConvertAssetId>(
PhantomData<(Prefix, AssetId, ConvertAssetId)>,
);
@@ -44,8 +44,8 @@ impl From<Error> for XcmError {
}
}
/// Simple adapter to use a currency as asset transactor. This type can be used as `type AssetTransactor` in
/// `xcm::Config`.
/// Simple adapter to use a currency as asset transactor. This type can be used as `type
/// AssetTransactor` in `xcm::Config`.
///
/// # Example
/// ```
@@ -63,8 +63,8 @@ impl<
/// The location which is allowed to mint a particular asset.
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum MintLocation {
/// This chain is allowed to mint the asset. When we track teleports of the asset we ensure that
/// no more of the asset returns back to the chain than has been sent out.
/// This chain is allowed to mint the asset. When we track teleports of the asset we ensure
/// that no more of the asset returns back to the chain than has been sent out.
Local,
/// This chain is not allowed to mint the asset. When we track teleports of the asset we ensure
/// that no more of the asset is sent out from the chain than has been previously received.
@@ -345,10 +345,11 @@ impl<Network: Get<Option<NetworkId>>, AccountId: From<[u8; 20]> + Into<[u8; 20]>
}
}
/// Converts a location which is a top-level relay chain (which provides its own consensus) into a 32-byte `AccountId`.
/// Converts a location which is a top-level relay chain (which provides its own consensus) into a
/// 32-byte `AccountId`.
///
/// This will always result in the *same account ID* being returned for the same Relay-chain, regardless of the relative security of
/// this Relay-chain compared to the local chain.
/// This will always result in the *same account ID* being returned for the same Relay-chain,
/// regardless of the relative security of this Relay-chain compared to the local chain.
///
/// Note: No distinction is made between the cases when the given `UniversalLocation` lies within
/// the same consensus system (i.e. is itself or a parent) and when it is a foreign consensus
@@ -20,7 +20,8 @@ use frame_support::traits::{Contains, ContainsPair};
use sp_std::marker::PhantomData;
use xcm::latest::prelude::*;
/// Alias a Foreign `AccountId32` with a local `AccountId32` if the foreign `AccountId32` matches the `Prefix` pattern.
/// Alias a Foreign `AccountId32` with a local `AccountId32` if the foreign `AccountId32` matches
/// the `Prefix` pattern.
///
/// Requires that the prefixed origin `AccountId32` matches the target `AccountId32`.
pub struct AliasForeignAccountId32<Prefix>(PhantomData<Prefix>);
@@ -24,7 +24,8 @@ use sp_std::marker::PhantomData;
use xcm::latest::{BodyId, BodyPart, Junction, Junctions::*, MultiLocation, NetworkId, OriginKind};
use xcm_executor::traits::{ConvertLocation, ConvertOrigin};
/// Sovereign accounts use the system's `Signed` origin with an account ID derived from the `LocationConverter`.
/// Sovereign accounts use the system's `Signed` origin with an account ID derived from the
/// `LocationConverter`.
pub struct SovereignSignedViaLocation<LocationConverter, RuntimeOrigin>(
PhantomData<(LocationConverter, RuntimeOrigin)>,
);
@@ -269,10 +270,11 @@ where
}
}
/// `Convert` implementation to convert from some a `Signed` (system) `Origin` into an `AccountId32`.
/// `Convert` implementation to convert from some a `Signed` (system) `Origin` into an
/// `AccountId32`.
///
/// Typically used when configuring `pallet-xcm` for allowing normal accounts to dispatch an XCM from an `AccountId32`
/// origin.
/// Typically used when configuring `pallet-xcm` for allowing normal accounts to dispatch an XCM
/// from an `AccountId32` origin.
pub struct SignedToAccountId32<RuntimeOrigin, AccountId, Network>(
PhantomData<(RuntimeOrigin, AccountId, Network)>,
);
@@ -296,11 +298,11 @@ where
}
}
/// `Convert` implementation to convert from some an origin which implements `Backing` into a corresponding `Plurality`
/// `MultiLocation`.
/// `Convert` implementation to convert from some an origin which implements `Backing` into a
/// corresponding `Plurality` `MultiLocation`.
///
/// Typically used when configuring `pallet-xcm` for allowing a collective's Origin to dispatch an XCM from a
/// `Plurality` origin.
/// Typically used when configuring `pallet-xcm` for allowing a collective's Origin to dispatch an
/// XCM from a `Plurality` origin.
pub struct BackingToPlurality<RuntimeOrigin, COrigin, Body>(
PhantomData<(RuntimeOrigin, COrigin, Body)>,
);
+2 -1
View File
@@ -396,7 +396,8 @@ fn max_assets_limit_should_work() {
);
assert_eq!(r, Outcome::Incomplete(Weight::from_parts(95, 95), XcmError::HoldingWouldOverflow));
// Attempt to withdraw 4 different assets and then the same 4 and then a different 4 will succeed.
// Attempt to withdraw 4 different assets and then the same 4 and then a different 4 will
// succeed.
let message = Xcm(vec![
WithdrawAsset(([1u8; 32], 100u128).into()),
WithdrawAsset(([2u8; 32], 100u128).into()),
@@ -80,7 +80,8 @@ fn sending_to_bridged_chain_works() {
)];
assert_eq!(take_received_remote_messages(), expected);
// The export cost 50 ref time and 50 proof size weight units (and thus 100 units of balance).
// The export cost 50 ref time and 50 proof size weight units (and thus 100 units of
// balance).
assert_eq!(asset_list(Parachain(100)), vec![(Here, 1000u128 - price).into()]);
let entry = LogEntry {
@@ -154,7 +155,8 @@ fn sending_to_parachain_of_bridged_chain_works() {
)];
assert_eq!(take_received_remote_messages(), expected);
// The export cost 50 ref time and 50 proof size weight units (and thus 100 units of balance).
// The export cost 50 ref time and 50 proof size weight units (and thus 100 units of
// balance).
assert_eq!(asset_list(Parachain(100)), vec![(Here, 1000u128 - price).into()]);
let entry = LogEntry {
+2 -2
View File
@@ -60,8 +60,8 @@ pub enum TestOrigin {
/// A dummy call.
///
/// Each item contains the amount of weight that it *wants* to consume as the first item, and the actual amount (if
/// different from the former) in the second option.
/// Each item contains the amount of weight that it *wants* to consume as the first item, and the
/// actual amount (if different from the former) in the second option.
#[derive(Debug, Encode, Decode, Eq, PartialEq, Clone, Copy, scale_info::TypeInfo)]
pub enum TestCall {
OnlyRoot(Weight, Option<Weight>),
@@ -95,7 +95,8 @@ fn pallet_query_with_results_should_work() {
#[test]
fn prepaid_result_of_query_should_get_free_execution() {
let query_id = 33;
// We put this in manually here, but normally this would be done at the point of crafting the message.
// We put this in manually here, but normally this would be done at the point of crafting the
// message.
expect_response(query_id, Parent.into());
let the_response = Response::Assets((Parent, 100u128).into());
@@ -300,7 +300,8 @@ pub trait HaulBlob {
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum HaulBlobError {
/// Represents point-to-point link failure with a human-readable explanation of the specific issue is provided.
/// Represents point-to-point link failure with a human-readable explanation of the specific
/// issue is provided.
Transport(&'static str),
}
@@ -361,8 +362,9 @@ impl<
message.try_into().map_err(|_| DispatchBlobError::UnsupportedXcmVersion)?;
// Prepend our bridge instance discriminator.
// Can be used for fine-grained control of origin on destination in case of multiple bridge instances,
// e.g. restrict `type UniversalAliases` and `UniversalOrigin` instruction to trust just particular bridge instance for `NetworkId`.
// Can be used for fine-grained control of origin on destination in case of multiple bridge
// instances, e.g. restrict `type UniversalAliases` and `UniversalOrigin` instruction to
// trust just particular bridge instance for `NetworkId`.
if let Some(bridge_instance) = OurPlaceBridgeInstance::get() {
message.0.insert(0, DescendOrigin(bridge_instance));
}
+3 -2
View File
@@ -114,8 +114,9 @@ where
}
}
/// Function trait for handling some revenue. Similar to a negative imbalance (credit) handler, but for a
/// `MultiAsset`. Sensible implementations will deposit the asset in some known treasury or block-author account.
/// Function trait for handling some revenue. Similar to a negative imbalance (credit) handler, but
/// for a `MultiAsset`. Sensible implementations will deposit the asset in some known treasury or
/// block-author account.
pub trait TakeRevenue {
/// Do something with the given `revenue`, which is a single non-wildcard `MultiAsset`.
fn take_revenue(revenue: MultiAsset);
+2 -2
View File
@@ -101,8 +101,8 @@ fn transfer_asset_works() {
/// A parachain wants to be notified that a transfer worked correctly.
/// It includes a `QueryHolding` order after the deposit to get notified on success.
/// This somewhat abuses `QueryHolding` as an indication of execution success. It works because
/// order execution halts on error (so no `QueryResponse` will be sent if the previous order failed).
/// The inner response sent due to the query is not used.
/// order execution halts on error (so no `QueryResponse` will be sent if the previous order
/// failed). The inner response sent due to the query is not used.
///
/// Asserts that the balances are updated correctly and the expected XCM is sent.
#[test]
+27 -20
View File
@@ -132,15 +132,17 @@ impl Assets {
/// Mutate `self` to contain all given `assets`, saturating if necessary.
///
/// NOTE: [`Assets`] are always sorted, allowing us to optimize this function from `O(n^2)` to `O(n)`.
/// NOTE: [`Assets`] are always sorted, allowing us to optimize this function from `O(n^2)` to
/// `O(n)`.
pub fn subsume_assets(&mut self, mut assets: Assets) {
let mut f_iter = assets.fungible.iter_mut();
let mut g_iter = self.fungible.iter_mut();
if let (Some(mut f), Some(mut g)) = (f_iter.next(), g_iter.next()) {
loop {
if f.0 == g.0 {
// keys are equal. in this case, we add `self`'s balance for the asset onto `assets`, balance, knowing
// that the `append` operation which follows will clobber `self`'s value and only use `assets`'s.
// keys are equal. in this case, we add `self`'s balance for the asset onto
// `assets`, balance, knowing that the `append` operation which follows will
// clobber `self`'s value and only use `assets`'s.
(*f.1).saturating_accrue(*g.1);
}
if f.0 <= g.0 {
@@ -186,8 +188,9 @@ impl Assets {
/// Alter any concretely identified assets by prepending the given `MultiLocation`.
///
/// WARNING: For now we consider this infallible and swallow any errors. It is thus the caller's responsibility to
/// ensure that any internal asset IDs are able to be prepended without overflow.
/// WARNING: For now we consider this infallible and swallow any errors. It is thus the caller's
/// responsibility to ensure that any internal asset IDs are able to be prepended without
/// overflow.
pub fn prepend_location(&mut self, prepend: &MultiLocation) {
let mut fungible = Default::default();
mem::swap(&mut self.fungible, &mut fungible);
@@ -269,8 +272,8 @@ impl Assets {
self.non_fungible.is_superset(&assets.non_fungible)
}
/// Returns an error unless all `assets` are contained in `self`. In the case of an error, the first asset in
/// `assets` which is not wholly in `self` is returned.
/// Returns an error unless all `assets` are contained in `self`. In the case of an error, the
/// first asset in `assets` which is not wholly in `self` is returned.
pub fn ensure_contains(&self, assets: &MultiAssets) -> Result<(), TakeError> {
for asset in assets.inner().iter() {
match asset {
@@ -292,16 +295,17 @@ impl Assets {
/// Mutates `self` to its original value less `mask` and returns assets that were removed.
///
/// If `saturate` is `true`, then `self` is considered to be masked by `mask`, thereby avoiding any attempt at
/// reducing it by assets it does not contain. In this case, the function is infallible. If `saturate` is `false`
/// and `mask` references a definite asset which `self` does not contain then an error is returned.
/// If `saturate` is `true`, then `self` is considered to be masked by `mask`, thereby avoiding
/// any attempt at reducing it by assets it does not contain. In this case, the function is
/// infallible. If `saturate` is `false` and `mask` references a definite asset which `self`
/// does not contain then an error is returned.
///
/// The number of unique assets which are removed will respect the `count` parameter in the
/// counted wildcard variants.
///
/// Returns `Ok` with the definite assets token from `self` and mutates `self` to its value minus
/// `mask`. Returns `Err` in the non-saturating case where `self` did not contain (enough of) a definite asset to
/// be removed.
/// Returns `Ok` with the definite assets token from `self` and mutates `self` to its value
/// minus `mask`. Returns `Err` in the non-saturating case where `self` did not contain (enough
/// of) a definite asset to be removed.
fn general_take(
&mut self,
mask: MultiAssetFilter,
@@ -386,24 +390,27 @@ impl Assets {
Ok(taken)
}
/// Mutates `self` to its original value less `mask` and returns `true` iff it contains at least `mask`.
/// Mutates `self` to its original value less `mask` and returns `true` iff it contains at least
/// `mask`.
///
/// Returns `Ok` with the non-wildcard equivalence of `mask` taken and mutates `self` to its value minus
/// `mask` if `self` contains `asset`, and return `Err` otherwise.
/// Returns `Ok` with the non-wildcard equivalence of `mask` taken and mutates `self` to its
/// value minus `mask` if `self` contains `asset`, and return `Err` otherwise.
pub fn saturating_take(&mut self, asset: MultiAssetFilter) -> Assets {
self.general_take(asset, true)
.expect("general_take never results in error when saturating")
}
/// Mutates `self` to its original value less `mask` and returns `true` iff it contains at least `mask`.
/// Mutates `self` to its original value less `mask` and returns `true` iff it contains at least
/// `mask`.
///
/// Returns `Ok` with the non-wildcard equivalence of `asset` taken and mutates `self` to its value minus
/// `asset` if `self` contains `asset`, and return `Err` otherwise.
/// Returns `Ok` with the non-wildcard equivalence of `asset` taken and mutates `self` to its
/// value minus `asset` if `self` contains `asset`, and return `Err` otherwise.
pub fn try_take(&mut self, mask: MultiAssetFilter) -> Result<Assets, TakeError> {
self.general_take(mask, false)
}
/// Consumes `self` and returns its original value excluding `asset` iff it contains at least `asset`.
/// Consumes `self` and returns its original value excluding `asset` iff it contains at least
/// `asset`.
pub fn checked_sub(mut self, asset: MultiAsset) -> Result<Assets, Assets> {
match asset.fun {
Fungible(amount) => {
+13 -9
View File
@@ -356,7 +356,8 @@ impl<Config: config::Config> XcmExecutor<Config> {
}
/// Execute any final operations after having executed the XCM message.
/// This includes refunding surplus weight, trapping extra holding funds, and returning any errors during execution.
/// This includes refunding surplus weight, trapping extra holding funds, and returning any
/// errors during execution.
pub fn post_process(mut self, xcm_weight: Weight) -> Outcome {
// We silently drop any error from our attempt to refund the surplus as it's a charitable
// thing so best-effort is all we will do.
@@ -533,9 +534,10 @@ impl<Config: config::Config> XcmExecutor<Config> {
Config::IsTeleporter::contains(asset, &origin),
XcmError::UntrustedTeleportLocation
);
// We should check that the asset can actually be teleported in (for this to be in error, there
// would need to be an accounting violation by one of the trusted chains, so it's unlikely, but we
// don't want to punish a possibly innocent chain/user).
// We should check that the asset can actually be teleported in (for this to be
// in error, there would need to be an accounting violation by one of the
// trusted chains, so it's unlikely, but we don't want to punish a possibly
// innocent chain/user).
Config::AssetTransactor::can_check_in(&origin, asset, &self.context)?;
}
for asset in assets.into_inner().into_iter() {
@@ -603,8 +605,8 @@ impl<Config: config::Config> XcmExecutor<Config> {
Ok(())
},
ReportError(response_info) => {
// Report the given result by sending a QueryResponse XCM to a previously given outcome
// destination if one was registered.
// Report the given result by sending a QueryResponse XCM to a previously given
// outcome destination if one was registered.
self.respond(
self.cloned_origin(),
Response::ExecutionResult(self.error),
@@ -823,10 +825,12 @@ impl<Config: config::Config> XcmExecutor<Config> {
Ok(())
},
ExportMessage { network, destination, xcm } => {
// The actual message sent to the bridge for forwarding is prepended with `UniversalOrigin`
// and `DescendOrigin` in order to ensure that the message is executed with this Origin.
// The actual message sent to the bridge for forwarding is prepended with
// `UniversalOrigin` and `DescendOrigin` in order to ensure that the message is
// executed with this Origin.
//
// Prepend the desired message with instructions which effectively rewrite the origin.
// Prepend the desired message with instructions which effectively rewrite the
// origin.
//
// This only works because the remote chain empowers the bridge
// to speak for the local network.
@@ -24,8 +24,8 @@ pub trait AssetExchange {
/// - `origin`: The location attempting the exchange; this should generally not matter.
/// - `give`: The assets which have been removed from the caller.
/// - `want`: The minimum amount of assets which should be given to the caller in case any
/// exchange happens. If more assets are provided, then they should generally be of the
/// same asset class if at all possible.
/// exchange happens. If more assets are provided, then they should generally be of the same
/// asset class if at all possible.
/// - `maximal`: If `true`, then as much as possible should be exchanged.
///
/// `Ok` is returned along with the new set of assets which have been exchanged for `give`. At
@@ -69,8 +69,8 @@ pub trait AssetLock {
/// unlock.
type UnlockTicket: Enact;
/// `Enact` implementer for `prepare_reduce_unlockable`. This type may be dropped safely to avoid doing the
/// unlock.
/// `Enact` implementer for `prepare_reduce_unlockable`. This type may be dropped safely to
/// avoid doing the unlock.
type ReduceTicket: Enact;
/// Prepare to lock an asset. On success, a `Self::LockTicket` it returned, which can be used
@@ -40,9 +40,9 @@ impl<AccountId> ConvertLocation<AccountId> for Tuple {
/// A converter `trait` for origin types.
///
/// Can be amalgamated into tuples. If any of the tuple elements returns `Ok(_)`, it short circuits. Else, the `Err(_)`
/// of the last tuple item is returned. Each intermediate `Err(_)` might return a different `origin` of type `Origin`
/// which is passed to the next convert item.
/// Can be amalgamated into tuples. If any of the tuple elements returns `Ok(_)`, it short circuits.
/// Else, the `Err(_)` of the last tuple item is returned. Each intermediate `Err(_)` might return a
/// different `origin` of type `Origin` which is passed to the next convert item.
///
/// ```rust
/// # use xcm::latest::{MultiLocation, Junctions, Junction, OriginKind};
@@ -19,7 +19,8 @@ use xcm::latest::{MultiAsset, MultiLocation};
/// Filters assets/location pairs.
///
/// Can be amalgamated into tuples. If any item returns `true`, it short-circuits, else `false` is returned.
/// Can be amalgamated into tuples. If any item returns `true`, it short-circuits, else `false` is
/// returned.
#[deprecated = "Use `frame_support::traits::ContainsPair<MultiAsset, MultiLocation>` instead"]
pub trait FilterAssetLocation {
/// A filter to distinguish between asset/location pairs.
@@ -107,11 +107,14 @@ impl VersionChangeNotifier for () {
/// The possible state of an XCM query response.
#[derive(Debug, PartialEq, Eq)]
pub enum QueryResponseStatus<BlockNumber> {
/// The response has arrived, and includes the inner Response and the block number it arrived at.
/// The response has arrived, and includes the inner Response and the block number it arrived
/// at.
Ready { response: Response, at: BlockNumber },
/// The response has not yet arrived, the XCM might still be executing or the response might be in transit.
/// The response has not yet arrived, the XCM might still be executing or the response might be
/// in transit.
Pending { timeout: BlockNumber },
/// No response with the given `QueryId` was found, or the response was already queried and removed from local storage.
/// No response with the given `QueryId` was found, or the response was already queried and
/// removed from local storage.
NotFound,
/// Got an unexpected XCM version.
UnexpectedVersion,
@@ -144,7 +147,8 @@ pub trait QueryHandler {
///
/// - `message`: The message whose outcome should be reported.
/// - `responder`: The origin from which a response should be expected.
/// - `timeout`: The block number after which it is permissible to return `NotFound` from `take_response`.
/// - `timeout`: The block number after which it is permissible to return `NotFound` from
/// `take_response`.
///
/// `report_outcome` may return an error if the `responder` is not invertible.
///
@@ -32,8 +32,8 @@ pub struct Properties {
/// Trait to determine whether the execution engine should actually execute a given XCM.
///
/// Can be amalgamated into a tuple to have multiple trials. If any of the tuple elements returns `Ok()`, the
/// execution stops. Else, `Err(_)` is returned if all elements reject the message.
/// Can be amalgamated into a tuple to have multiple trials. If any of the tuple elements returns
/// `Ok()`, the execution stops. Else, `Err(_)` is returned if all elements reject the message.
pub trait ShouldExecute {
/// Returns `true` if the given `message` may be executed.
///
@@ -20,11 +20,13 @@ use xcm::latest::{Error as XcmError, MultiAsset, MultiLocation, Result as XcmRes
/// Facility for asset transacting.
///
/// This should work with as many asset/location combinations as possible. Locations to support may include non-account
/// locations such as a `MultiLocation::X1(Junction::Parachain)`. Different chains may handle them in different ways.
/// This should work with as many asset/location combinations as possible. Locations to support may
/// include non-account locations such as a `MultiLocation::X1(Junction::Parachain)`. Different
/// chains may handle them in different ways.
///
/// Can be amalgamated as a tuple of items that implement this trait. In such executions, if any of the transactors
/// returns `Ok(())`, then it will short circuit. Else, execution is passed to the next transactor.
/// Can be amalgamated as a tuple of items that implement this trait. In such executions, if any of
/// the transactors returns `Ok(())`, then it will short circuit. Else, execution is passed to the
/// next transactor.
pub trait TransactAsset {
/// Ensure that `check_in` will do as expected.
///
@@ -37,19 +39,23 @@ pub trait TransactAsset {
Err(XcmError::Unimplemented)
}
/// An asset has been teleported in from the given origin. This should do whatever housekeeping is needed.
/// An asset has been teleported in from the given origin. This should do whatever housekeeping
/// is needed.
///
/// NOTE: This will make only a best-effort at bookkeeping. The caller should ensure that `can_check_in` has
/// returned with `Ok` in order to guarantee that this operation proceeds properly.
/// NOTE: This will make only a best-effort at bookkeeping. The caller should ensure that
/// `can_check_in` has returned with `Ok` in order to guarantee that this operation proceeds
/// properly.
///
/// Implementation note: In general this will do one of two things: On chains where the asset is native,
/// it will reduce the assets from a special "teleported" account so that a) total-issuance is preserved;
/// and b) to ensure that no more assets can be teleported in than were teleported out overall (this should
/// not be needed if the teleporting chains are to be trusted, but better to be safe than sorry). On chains
/// where the asset is not native then it will generally just be a no-op.
/// Implementation note: In general this will do one of two things: On chains where the asset is
/// native, it will reduce the assets from a special "teleported" account so that a)
/// total-issuance is preserved; and b) to ensure that no more assets can be teleported in than
/// were teleported out overall (this should not be needed if the teleporting chains are to be
/// trusted, but better to be safe than sorry). On chains where the asset is not native then it
/// will generally just be a no-op.
///
/// When composed as a tuple, all type-items are called. It is up to the implementer that there exists no
/// value for `_what` which can cause side-effects for more than one of the type-items.
/// When composed as a tuple, all type-items are called. It is up to the implementer that there
/// exists no value for `_what` which can cause side-effects for more than one of the
/// type-items.
fn check_in(_origin: &MultiLocation, _what: &MultiAsset, _context: &XcmContext) {}
/// Ensure that `check_out` will do as expected.
@@ -63,16 +69,19 @@ pub trait TransactAsset {
Err(XcmError::Unimplemented)
}
/// An asset has been teleported out to the given destination. This should do whatever housekeeping is needed.
/// An asset has been teleported out to the given destination. This should do whatever
/// housekeeping is needed.
///
/// Implementation note: In general this will do one of two things: On chains where the asset is native,
/// it will increase the assets in a special "teleported" account so that a) total-issuance is preserved; and
/// b) to ensure that no more assets can be teleported in than were teleported out overall (this should not
/// be needed if the teleporting chains are to be trusted, but better to be safe than sorry). On chains where
/// the asset is not native then it will generally just be a no-op.
/// Implementation note: In general this will do one of two things: On chains where the asset is
/// native, it will increase the assets in a special "teleported" account so that a)
/// total-issuance is preserved; and b) to ensure that no more assets can be teleported in than
/// were teleported out overall (this should not be needed if the teleporting chains are to be
/// trusted, but better to be safe than sorry). On chains where the asset is not native then it
/// will generally just be a no-op.
///
/// When composed as a tuple, all type-items are called. It is up to the implementer that there exists no
/// value for `_what` which can cause side-effects for more than one of the type-items.
/// When composed as a tuple, all type-items are called. It is up to the implementer that there
/// exists no value for `_what` which can cause side-effects for more than one of the
/// type-items.
fn check_out(_dest: &MultiLocation, _what: &MultiAsset, _context: &XcmContext) {}
/// Deposit the `what` asset into the account of `who`.
@@ -56,8 +56,8 @@ pub trait WeightTrader: Sized {
context: &XcmContext,
) -> Result<Assets, XcmError>;
/// Attempt a refund of `weight` into some asset. The caller does not guarantee that the weight was
/// purchased using `buy_weight`.
/// Attempt a refund of `weight` into some asset. The caller does not guarantee that the weight
/// was purchased using `buy_weight`.
///
/// Default implementation refunds nothing.
fn refund_weight(&mut self, _weight: Weight, _context: &XcmContext) -> Option<MultiAsset> {
@@ -93,8 +93,8 @@ impl WeightTrader for Tuple {
log::trace!(target: "xcm::buy_weight", "last_error: {:?}, too_expensive_error_found: {}", last_error, too_expensive_error_found);
// if we have multiple traders, and first one returns `TooExpensive` and others fail e.g. `AssetNotFound`
// then it is more accurate to return `TooExpensive` then `AssetNotFound`
// if we have multiple traders, and first one returns `TooExpensive` and others fail e.g.
// `AssetNotFound` then it is more accurate to return `TooExpensive` then `AssetNotFound`
Err(if too_expensive_error_found {
XcmError::TooExpensive
} else {
+13 -13
View File
@@ -161,12 +161,12 @@ macro_rules! decl_test_relay_chain {
///
/// ```ignore
/// decl_test_parachain! {
/// pub struct ParaA {
/// Runtime = parachain::Runtime,
/// XcmpMessageHandler = parachain::MsgQueue,
/// DmpMessageHandler = parachain::MsgQueue,
/// new_ext = para_ext(),
/// }
/// pub struct ParaA {
/// Runtime = parachain::Runtime,
/// XcmpMessageHandler = parachain::MsgQueue,
/// DmpMessageHandler = parachain::MsgQueue,
/// new_ext = para_ext(),
/// }
/// }
/// ```
#[macro_export]
@@ -272,13 +272,13 @@ thread_local! {
///
/// ```ignore
/// decl_test_network! {
/// pub struct ExampleNet {
/// relay_chain = Relay,
/// parachains = vec![
/// (1, ParaA),
/// (2, ParaB),
/// ],
/// }
/// pub struct ExampleNet {
/// relay_chain = Relay,
/// parachains = vec![
/// (1, ParaA),
/// (2, ParaB),
/// ],
/// }
/// }
/// ```
#[macro_export]