mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 10:31:03 +00:00
XCM docs and tests (#2948)
* WIP * add tests and docs for DoubleEncoded * reformat parent_count * add test for match_and_split * fix append_with docs and add tests * move Parachain enum variant to tuple * Fix stuff * add to append test * simplify match * formatting * format and extend doc comments (including examples) * fix typo * add some doc comments * add test for location inverter * Add more tests/docs * Fix build * matches fungibles * currency adapter. * add more tests for location inverter * extract max length magic number into constant * adapters. * Apply suggestions from code review * Final touches. * Repot and fixes * Remove last todo * Apply suggestions from code review Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> * Update xcm/xcm-builder/src/barriers.rs Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> * Update xcm/xcm-builder/src/barriers.rs Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> * Update xcm/xcm-builder/src/currency_adapter.rs Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> * Update xcm/xcm-builder/src/filter_asset_location.rs Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> * Update xcm/xcm-builder/src/matches_fungible.rs Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> * Update xcm/xcm-executor/src/traits/conversion.rs Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> * Update xcm/xcm-executor/src/traits/conversion.rs Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> * Update xcm/xcm-executor/src/traits/transact_asset.rs Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> * Update xcm/xcm-executor/src/traits/should_execute.rs Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> Co-authored-by: kianenigma <kian@parity.io> Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
This commit is contained in:
@@ -14,40 +14,16 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Adapters to work with `frame_support::traits::tokens::fungibles` through XCM.
|
||||
|
||||
use sp_std::{prelude::*, result, marker::PhantomData, borrow::Borrow};
|
||||
use xcm::v0::{Error as XcmError, Result, MultiAsset, MultiLocation, Junction};
|
||||
use frame_support::traits::{Get, tokens::fungibles, Contains};
|
||||
use xcm_executor::traits::{TransactAsset, Convert};
|
||||
use xcm_executor::traits::{TransactAsset, Convert, MatchesFungibles, Error as MatchError};
|
||||
|
||||
/// Asset transaction errors.
|
||||
pub enum Error {
|
||||
/// Asset not found.
|
||||
AssetNotFound,
|
||||
/// `MultiLocation` to `AccountId` conversion failed.
|
||||
AccountIdConversionFailed,
|
||||
/// `u128` amount to currency `Balance` conversion failed.
|
||||
AmountToBalanceConversionFailed,
|
||||
/// `MultiLocation` to `AssetId` conversion failed.
|
||||
AssetIdConversionFailed,
|
||||
}
|
||||
|
||||
impl From<Error> for XcmError {
|
||||
fn from(e: Error) -> Self {
|
||||
match e {
|
||||
Error::AssetNotFound => XcmError::FailedToTransactAsset("AssetNotFound"),
|
||||
Error::AccountIdConversionFailed =>
|
||||
XcmError::FailedToTransactAsset("AccountIdConversionFailed"),
|
||||
Error::AmountToBalanceConversionFailed =>
|
||||
XcmError::FailedToTransactAsset("AmountToBalanceConversionFailed"),
|
||||
Error::AssetIdConversionFailed =>
|
||||
XcmError::FailedToTransactAsset("AssetIdConversionFailed"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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)>);
|
||||
impl<
|
||||
Prefix: Get<MultiLocation>,
|
||||
@@ -73,23 +49,6 @@ impl<
|
||||
}
|
||||
}
|
||||
|
||||
pub trait MatchesFungibles<AssetId, Balance> {
|
||||
fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), Error>;
|
||||
}
|
||||
|
||||
#[impl_trait_for_tuples::impl_for_tuples(30)]
|
||||
impl<
|
||||
AssetId: Clone,
|
||||
Balance: Clone,
|
||||
> MatchesFungibles<AssetId, Balance> for Tuple {
|
||||
fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), Error> {
|
||||
for_tuples!( #(
|
||||
match Tuple::matches_fungibles(a) { o @ Ok(_) => return o, _ => () }
|
||||
)* );
|
||||
Err(Error::AssetNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ConvertedConcreteAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>(
|
||||
PhantomData<(AssetId, Balance, ConvertAssetId, ConvertBalance)>
|
||||
);
|
||||
@@ -101,13 +60,13 @@ impl<
|
||||
> MatchesFungibles<AssetId, Balance> for
|
||||
ConvertedConcreteAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>
|
||||
{
|
||||
fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), Error> {
|
||||
fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> {
|
||||
let (id, amount) = match a {
|
||||
MultiAsset::ConcreteFungible { id, amount } => (id, amount),
|
||||
_ => return Err(Error::AssetNotFound),
|
||||
_ => return Err(MatchError::AssetNotFound),
|
||||
};
|
||||
let what = ConvertAssetId::convert_ref(id).map_err(|_| Error::AssetIdConversionFailed)?;
|
||||
let amount = ConvertBalance::convert_ref(amount).map_err(|_| Error::AmountToBalanceConversionFailed)?;
|
||||
let what = ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
|
||||
let amount = ConvertBalance::convert_ref(amount).map_err(|_| MatchError::AmountToBalanceConversionFailed)?;
|
||||
Ok((what, amount))
|
||||
}
|
||||
}
|
||||
@@ -123,13 +82,13 @@ impl<
|
||||
> MatchesFungibles<AssetId, Balance> for
|
||||
ConvertedAbstractAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>
|
||||
{
|
||||
fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), Error> {
|
||||
fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> {
|
||||
let (id, amount) = match a {
|
||||
MultiAsset::AbstractFungible { id, amount } => (id, amount),
|
||||
_ => return Err(Error::AssetNotFound),
|
||||
_ => return Err(MatchError::AssetNotFound),
|
||||
};
|
||||
let what = ConvertAssetId::convert_ref(id).map_err(|_| Error::AssetIdConversionFailed)?;
|
||||
let amount = ConvertBalance::convert_ref(amount).map_err(|_| Error::AmountToBalanceConversionFailed)?;
|
||||
let what = ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
|
||||
let amount = ConvertBalance::convert_ref(amount).map_err(|_| MatchError::AmountToBalanceConversionFailed)?;
|
||||
Ok((what, amount))
|
||||
}
|
||||
}
|
||||
@@ -151,9 +110,9 @@ impl<
|
||||
// Check we handle this asset.
|
||||
let (asset_id, amount) = Matcher::matches_fungibles(what)?;
|
||||
let source = AccountIdConverter::convert_ref(from)
|
||||
.map_err(|()| Error::AccountIdConversionFailed)?;
|
||||
.map_err(|()| MatchError::AccountIdConversionFailed)?;
|
||||
let dest = AccountIdConverter::convert_ref(to)
|
||||
.map_err(|()| Error::AccountIdConversionFailed)?;
|
||||
.map_err(|()| MatchError::AccountIdConversionFailed)?;
|
||||
Assets::transfer(asset_id, &source, &dest, amount, true)
|
||||
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))?;
|
||||
Ok(what.clone().into())
|
||||
@@ -208,7 +167,7 @@ impl<
|
||||
// Check we handle this asset.
|
||||
let (asset_id, amount) = Matcher::matches_fungibles(what)?;
|
||||
let who = AccountIdConverter::convert_ref(who)
|
||||
.map_err(|()| Error::AccountIdConversionFailed)?;
|
||||
.map_err(|()| MatchError::AccountIdConversionFailed)?;
|
||||
Assets::mint_into(asset_id, &who, amount)
|
||||
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))
|
||||
}
|
||||
@@ -220,7 +179,7 @@ impl<
|
||||
// Check we handle this asset.
|
||||
let (asset_id, amount) = Matcher::matches_fungibles(what)?;
|
||||
let who = AccountIdConverter::convert_ref(who)
|
||||
.map_err(|()| Error::AccountIdConversionFailed)?;
|
||||
.map_err(|()| MatchError::AccountIdConversionFailed)?;
|
||||
Assets::burn_from(asset_id, &who, amount)
|
||||
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))?;
|
||||
Ok(what.clone().into())
|
||||
|
||||
Reference in New Issue
Block a user