mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 16:51:02 +00:00
[XCM] Multiple FungiblesAdapters support + WeightTrader::buy_weight more accurate error (#6739)
* Change ParaId->Sibling for `SiblingParachainConvertsVia` * [XCM] Multiple `FungiblesAdapter`s support + `WeightTrader::buy_weight` more accurate error * Added test for `ConvertedConcreteId` with `AsPrefixedGeneralIndex` * Solution 3. - new MatchedConvertedConcreteId with matching capabilities * Review fixes * Renamed `AssetNotFound` -> `AssetNotHandled` --------- Co-authored-by: parity-processbot <>
This commit is contained in:
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
//! Adapters to work with `frame_support::traits::tokens::fungibles` through XCM.
|
//! Adapters to work with `frame_support::traits::tokens::fungibles` through XCM.
|
||||||
|
|
||||||
use frame_support::traits::Get;
|
use frame_support::traits::{Contains, Get};
|
||||||
use sp_std::{borrow::Borrow, marker::PhantomData, prelude::*, result};
|
use sp_std::{borrow::Borrow, marker::PhantomData, prelude::*, result};
|
||||||
use xcm::latest::prelude::*;
|
use xcm::latest::prelude::*;
|
||||||
use xcm_executor::traits::{Convert, Error as MatchError, MatchesFungibles, MatchesNonFungibles};
|
use xcm_executor::traits::{Convert, Error as MatchError, MatchesFungibles, MatchesNonFungibles};
|
||||||
@@ -69,7 +69,7 @@ impl<
|
|||||||
fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> {
|
fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> {
|
||||||
let (amount, id) = match (&a.fun, &a.id) {
|
let (amount, id) = match (&a.fun, &a.id) {
|
||||||
(Fungible(ref amount), Concrete(ref id)) => (amount, id),
|
(Fungible(ref amount), Concrete(ref id)) => (amount, id),
|
||||||
_ => return Err(MatchError::AssetNotFound),
|
_ => return Err(MatchError::AssetNotHandled),
|
||||||
};
|
};
|
||||||
let what =
|
let what =
|
||||||
ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
|
ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
|
||||||
@@ -89,7 +89,7 @@ impl<
|
|||||||
fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(ClassId, InstanceId), MatchError> {
|
fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(ClassId, InstanceId), MatchError> {
|
||||||
let (instance, class) = match (&a.fun, &a.id) {
|
let (instance, class) = match (&a.fun, &a.id) {
|
||||||
(NonFungible(ref instance), Concrete(ref class)) => (instance, class),
|
(NonFungible(ref instance), Concrete(ref class)) => (instance, class),
|
||||||
_ => return Err(MatchError::AssetNotFound),
|
_ => return Err(MatchError::AssetNotHandled),
|
||||||
};
|
};
|
||||||
let what =
|
let what =
|
||||||
ConvertClassId::convert_ref(class).map_err(|_| MatchError::AssetIdConversionFailed)?;
|
ConvertClassId::convert_ref(class).map_err(|_| MatchError::AssetIdConversionFailed)?;
|
||||||
@@ -113,7 +113,7 @@ impl<
|
|||||||
fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> {
|
fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> {
|
||||||
let (amount, id) = match (&a.fun, &a.id) {
|
let (amount, id) = match (&a.fun, &a.id) {
|
||||||
(Fungible(ref amount), Abstract(ref id)) => (amount, id),
|
(Fungible(ref amount), Abstract(ref id)) => (amount, id),
|
||||||
_ => return Err(MatchError::AssetNotFound),
|
_ => return Err(MatchError::AssetNotHandled),
|
||||||
};
|
};
|
||||||
let what =
|
let what =
|
||||||
ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
|
ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
|
||||||
@@ -133,7 +133,7 @@ impl<
|
|||||||
fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(ClassId, InstanceId), MatchError> {
|
fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(ClassId, InstanceId), MatchError> {
|
||||||
let (instance, class) = match (&a.fun, &a.id) {
|
let (instance, class) = match (&a.fun, &a.id) {
|
||||||
(NonFungible(ref instance), Abstract(ref class)) => (instance, class),
|
(NonFungible(ref instance), Abstract(ref class)) => (instance, class),
|
||||||
_ => return Err(MatchError::AssetNotFound),
|
_ => return Err(MatchError::AssetNotHandled),
|
||||||
};
|
};
|
||||||
let what =
|
let what =
|
||||||
ConvertClassId::convert_ref(class).map_err(|_| MatchError::AssetIdConversionFailed)?;
|
ConvertClassId::convert_ref(class).map_err(|_| MatchError::AssetIdConversionFailed)?;
|
||||||
@@ -147,3 +147,204 @@ impl<
|
|||||||
pub type ConvertedConcreteAssetId<A, B, C, O> = ConvertedConcreteId<A, B, C, O>;
|
pub type ConvertedConcreteAssetId<A, B, C, O> = ConvertedConcreteId<A, B, C, O>;
|
||||||
#[deprecated = "Use `ConvertedAbstractId` instead"]
|
#[deprecated = "Use `ConvertedAbstractId` instead"]
|
||||||
pub type ConvertedAbstractAssetId<A, B, C, O> = ConvertedAbstractId<A, B, C, O>;
|
pub type ConvertedAbstractAssetId<A, B, C, O> = ConvertedAbstractId<A, B, C, O>;
|
||||||
|
|
||||||
|
pub struct MatchedConvertedConcreteId<AssetId, Balance, MatchAssetId, ConvertAssetId, ConvertOther>(
|
||||||
|
PhantomData<(AssetId, Balance, MatchAssetId, ConvertAssetId, ConvertOther)>,
|
||||||
|
);
|
||||||
|
impl<
|
||||||
|
AssetId: Clone,
|
||||||
|
Balance: Clone,
|
||||||
|
MatchAssetId: Contains<MultiLocation>,
|
||||||
|
ConvertAssetId: Convert<MultiLocation, AssetId>,
|
||||||
|
ConvertBalance: Convert<u128, Balance>,
|
||||||
|
> MatchesFungibles<AssetId, Balance>
|
||||||
|
for MatchedConvertedConcreteId<AssetId, Balance, MatchAssetId, ConvertAssetId, ConvertBalance>
|
||||||
|
{
|
||||||
|
fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> {
|
||||||
|
let (amount, id) = match (&a.fun, &a.id) {
|
||||||
|
(Fungible(ref amount), Concrete(ref id)) if MatchAssetId::contains(id) => (amount, id),
|
||||||
|
_ => return Err(MatchError::AssetNotHandled),
|
||||||
|
};
|
||||||
|
let what =
|
||||||
|
ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
|
||||||
|
let amount = ConvertBalance::convert_ref(amount)
|
||||||
|
.map_err(|_| MatchError::AmountToBalanceConversionFailed)?;
|
||||||
|
Ok((what, amount))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<
|
||||||
|
ClassId: Clone,
|
||||||
|
InstanceId: Clone,
|
||||||
|
MatchClassId: Contains<MultiLocation>,
|
||||||
|
ConvertClassId: Convert<MultiLocation, ClassId>,
|
||||||
|
ConvertInstanceId: Convert<AssetInstance, InstanceId>,
|
||||||
|
> MatchesNonFungibles<ClassId, InstanceId>
|
||||||
|
for MatchedConvertedConcreteId<ClassId, InstanceId, MatchClassId, ConvertClassId, ConvertInstanceId>
|
||||||
|
{
|
||||||
|
fn matches_nonfungibles(a: &MultiAsset) -> result::Result<(ClassId, InstanceId), MatchError> {
|
||||||
|
let (instance, class) = match (&a.fun, &a.id) {
|
||||||
|
(NonFungible(ref instance), Concrete(ref class)) if MatchClassId::contains(class) =>
|
||||||
|
(instance, class),
|
||||||
|
_ => return Err(MatchError::AssetNotHandled),
|
||||||
|
};
|
||||||
|
let what =
|
||||||
|
ConvertClassId::convert_ref(class).map_err(|_| MatchError::AssetIdConversionFailed)?;
|
||||||
|
let instance = ConvertInstanceId::convert_ref(instance)
|
||||||
|
.map_err(|_| MatchError::InstanceConversionFailed)?;
|
||||||
|
Ok((what, instance))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
use xcm_executor::traits::JustTry;
|
||||||
|
|
||||||
|
struct OnlyParentZero;
|
||||||
|
impl Contains<MultiLocation> for OnlyParentZero {
|
||||||
|
fn contains(a: &MultiLocation) -> bool {
|
||||||
|
match a {
|
||||||
|
MultiLocation { parents: 0, .. } => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn matched_converted_concrete_id_for_fungibles_works() {
|
||||||
|
type AssetIdForTrustBackedAssets = u32;
|
||||||
|
type Balance = u128;
|
||||||
|
frame_support::parameter_types! {
|
||||||
|
pub TrustBackedAssetsPalletLocation: MultiLocation = PalletInstance(50).into();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConvertedConcreteId cfg
|
||||||
|
type Converter = MatchedConvertedConcreteId<
|
||||||
|
AssetIdForTrustBackedAssets,
|
||||||
|
Balance,
|
||||||
|
OnlyParentZero,
|
||||||
|
AsPrefixedGeneralIndex<
|
||||||
|
TrustBackedAssetsPalletLocation,
|
||||||
|
AssetIdForTrustBackedAssets,
|
||||||
|
JustTry,
|
||||||
|
>,
|
||||||
|
JustTry,
|
||||||
|
>;
|
||||||
|
assert_eq!(
|
||||||
|
TrustBackedAssetsPalletLocation::get(),
|
||||||
|
MultiLocation { parents: 0, interior: X1(PalletInstance(50)) }
|
||||||
|
);
|
||||||
|
|
||||||
|
// err - does not match
|
||||||
|
assert_eq!(
|
||||||
|
Converter::matches_fungibles(&MultiAsset {
|
||||||
|
id: Concrete(MultiLocation::new(1, X2(PalletInstance(50), GeneralIndex(1)))),
|
||||||
|
fun: Fungible(12345),
|
||||||
|
}),
|
||||||
|
Err(MatchError::AssetNotHandled)
|
||||||
|
);
|
||||||
|
|
||||||
|
// err - matches, but convert fails
|
||||||
|
assert_eq!(
|
||||||
|
Converter::matches_fungibles(&MultiAsset {
|
||||||
|
id: Concrete(MultiLocation::new(
|
||||||
|
0,
|
||||||
|
X2(PalletInstance(50), GeneralKey { length: 1, data: [1; 32] })
|
||||||
|
)),
|
||||||
|
fun: Fungible(12345),
|
||||||
|
}),
|
||||||
|
Err(MatchError::AssetIdConversionFailed)
|
||||||
|
);
|
||||||
|
|
||||||
|
// err - matches, but NonFungible
|
||||||
|
assert_eq!(
|
||||||
|
Converter::matches_fungibles(&MultiAsset {
|
||||||
|
id: Concrete(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1)))),
|
||||||
|
fun: NonFungible(Index(54321)),
|
||||||
|
}),
|
||||||
|
Err(MatchError::AssetNotHandled)
|
||||||
|
);
|
||||||
|
|
||||||
|
// ok
|
||||||
|
assert_eq!(
|
||||||
|
Converter::matches_fungibles(&MultiAsset {
|
||||||
|
id: Concrete(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1)))),
|
||||||
|
fun: Fungible(12345),
|
||||||
|
}),
|
||||||
|
Ok((1, 12345))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn matched_converted_concrete_id_for_nonfungibles_works() {
|
||||||
|
type ClassId = u32;
|
||||||
|
type ClassInstanceId = u64;
|
||||||
|
frame_support::parameter_types! {
|
||||||
|
pub TrustBackedAssetsPalletLocation: MultiLocation = PalletInstance(50).into();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConvertedConcreteId cfg
|
||||||
|
struct ClassInstanceIdConverter;
|
||||||
|
impl Convert<AssetInstance, ClassInstanceId> for ClassInstanceIdConverter {
|
||||||
|
fn convert_ref(value: impl Borrow<AssetInstance>) -> Result<ClassInstanceId, ()> {
|
||||||
|
value.borrow().clone().try_into().map_err(|_| ())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reverse_ref(value: impl Borrow<ClassInstanceId>) -> Result<AssetInstance, ()> {
|
||||||
|
Ok(AssetInstance::from(value.borrow().clone()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Converter = MatchedConvertedConcreteId<
|
||||||
|
ClassId,
|
||||||
|
ClassInstanceId,
|
||||||
|
OnlyParentZero,
|
||||||
|
AsPrefixedGeneralIndex<TrustBackedAssetsPalletLocation, ClassId, JustTry>,
|
||||||
|
ClassInstanceIdConverter,
|
||||||
|
>;
|
||||||
|
assert_eq!(
|
||||||
|
TrustBackedAssetsPalletLocation::get(),
|
||||||
|
MultiLocation { parents: 0, interior: X1(PalletInstance(50)) }
|
||||||
|
);
|
||||||
|
|
||||||
|
// err - does not match
|
||||||
|
assert_eq!(
|
||||||
|
Converter::matches_nonfungibles(&MultiAsset {
|
||||||
|
id: Concrete(MultiLocation::new(1, X2(PalletInstance(50), GeneralIndex(1)))),
|
||||||
|
fun: NonFungible(Index(54321)),
|
||||||
|
}),
|
||||||
|
Err(MatchError::AssetNotHandled)
|
||||||
|
);
|
||||||
|
|
||||||
|
// err - matches, but convert fails
|
||||||
|
assert_eq!(
|
||||||
|
Converter::matches_nonfungibles(&MultiAsset {
|
||||||
|
id: Concrete(MultiLocation::new(
|
||||||
|
0,
|
||||||
|
X2(PalletInstance(50), GeneralKey { length: 1, data: [1; 32] })
|
||||||
|
)),
|
||||||
|
fun: NonFungible(Index(54321)),
|
||||||
|
}),
|
||||||
|
Err(MatchError::AssetIdConversionFailed)
|
||||||
|
);
|
||||||
|
|
||||||
|
// err - matches, but Fungible vs NonFungible
|
||||||
|
assert_eq!(
|
||||||
|
Converter::matches_nonfungibles(&MultiAsset {
|
||||||
|
id: Concrete(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1)))),
|
||||||
|
fun: Fungible(12345),
|
||||||
|
}),
|
||||||
|
Err(MatchError::AssetNotHandled)
|
||||||
|
);
|
||||||
|
|
||||||
|
// ok
|
||||||
|
assert_eq!(
|
||||||
|
Converter::matches_nonfungibles(&MultiAsset {
|
||||||
|
id: Concrete(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1)))),
|
||||||
|
fun: NonFungible(Index(54321)),
|
||||||
|
}),
|
||||||
|
Ok((1, 54321))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ use xcm_executor::{
|
|||||||
|
|
||||||
/// Asset transaction errors.
|
/// Asset transaction errors.
|
||||||
enum Error {
|
enum Error {
|
||||||
/// Asset not found.
|
/// The given asset is not handled. (According to [`XcmError::AssetNotFound`])
|
||||||
AssetNotFound,
|
AssetNotHandled,
|
||||||
/// `MultiLocation` to `AccountId` conversion failed.
|
/// `MultiLocation` to `AccountId` conversion failed.
|
||||||
AccountIdConversionFailed,
|
AccountIdConversionFailed,
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ impl From<Error> for XcmError {
|
|||||||
fn from(e: Error) -> Self {
|
fn from(e: Error) -> Self {
|
||||||
use XcmError::FailedToTransactAsset;
|
use XcmError::FailedToTransactAsset;
|
||||||
match e {
|
match e {
|
||||||
Error::AssetNotFound => XcmError::AssetNotFound,
|
Error::AssetNotHandled => XcmError::AssetNotFound,
|
||||||
Error::AccountIdConversionFailed => FailedToTransactAsset("AccountIdConversionFailed"),
|
Error::AccountIdConversionFailed => FailedToTransactAsset("AccountIdConversionFailed"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,7 +143,7 @@ impl<
|
|||||||
log::trace!(target: "xcm::currency_adapter", "can_check_in origin: {:?}, what: {:?}", _origin, what);
|
log::trace!(target: "xcm::currency_adapter", "can_check_in origin: {:?}, what: {:?}", _origin, what);
|
||||||
// Check we handle this asset.
|
// Check we handle this asset.
|
||||||
let amount: Currency::Balance =
|
let amount: Currency::Balance =
|
||||||
Matcher::matches_fungible(what).ok_or(Error::AssetNotFound)?;
|
Matcher::matches_fungible(what).ok_or(Error::AssetNotHandled)?;
|
||||||
match CheckedAccount::get() {
|
match CheckedAccount::get() {
|
||||||
Some((checked_account, MintLocation::Local)) =>
|
Some((checked_account, MintLocation::Local)) =>
|
||||||
Self::can_reduce_checked(checked_account, amount),
|
Self::can_reduce_checked(checked_account, amount),
|
||||||
@@ -168,7 +168,7 @@ impl<
|
|||||||
|
|
||||||
fn can_check_out(_dest: &MultiLocation, what: &MultiAsset, _context: &XcmContext) -> Result {
|
fn can_check_out(_dest: &MultiLocation, what: &MultiAsset, _context: &XcmContext) -> Result {
|
||||||
log::trace!(target: "xcm::currency_adapter", "check_out dest: {:?}, what: {:?}", _dest, what);
|
log::trace!(target: "xcm::currency_adapter", "check_out dest: {:?}, what: {:?}", _dest, what);
|
||||||
let amount = Matcher::matches_fungible(what).ok_or(Error::AssetNotFound)?;
|
let amount = Matcher::matches_fungible(what).ok_or(Error::AssetNotHandled)?;
|
||||||
match CheckedAccount::get() {
|
match CheckedAccount::get() {
|
||||||
Some((checked_account, MintLocation::Local)) =>
|
Some((checked_account, MintLocation::Local)) =>
|
||||||
Self::can_accrue_checked(checked_account, amount),
|
Self::can_accrue_checked(checked_account, amount),
|
||||||
@@ -194,7 +194,7 @@ impl<
|
|||||||
fn deposit_asset(what: &MultiAsset, who: &MultiLocation, _context: &XcmContext) -> Result {
|
fn deposit_asset(what: &MultiAsset, who: &MultiLocation, _context: &XcmContext) -> Result {
|
||||||
log::trace!(target: "xcm::currency_adapter", "deposit_asset what: {:?}, who: {:?}", what, who);
|
log::trace!(target: "xcm::currency_adapter", "deposit_asset what: {:?}, who: {:?}", what, who);
|
||||||
// Check we handle this asset.
|
// Check we handle this asset.
|
||||||
let amount = Matcher::matches_fungible(&what).ok_or(Error::AssetNotFound)?;
|
let amount = Matcher::matches_fungible(&what).ok_or(Error::AssetNotHandled)?;
|
||||||
let who =
|
let who =
|
||||||
AccountIdConverter::convert_ref(who).map_err(|()| Error::AccountIdConversionFailed)?;
|
AccountIdConverter::convert_ref(who).map_err(|()| Error::AccountIdConversionFailed)?;
|
||||||
let _imbalance = Currency::deposit_creating(&who, amount);
|
let _imbalance = Currency::deposit_creating(&who, amount);
|
||||||
@@ -208,7 +208,7 @@ impl<
|
|||||||
) -> result::Result<Assets, XcmError> {
|
) -> result::Result<Assets, XcmError> {
|
||||||
log::trace!(target: "xcm::currency_adapter", "withdraw_asset what: {:?}, who: {:?}", what, who);
|
log::trace!(target: "xcm::currency_adapter", "withdraw_asset what: {:?}, who: {:?}", what, who);
|
||||||
// Check we handle this asset.
|
// Check we handle this asset.
|
||||||
let amount = Matcher::matches_fungible(what).ok_or(Error::AssetNotFound)?;
|
let amount = Matcher::matches_fungible(what).ok_or(Error::AssetNotHandled)?;
|
||||||
let who =
|
let who =
|
||||||
AccountIdConverter::convert_ref(who).map_err(|()| Error::AccountIdConversionFailed)?;
|
AccountIdConverter::convert_ref(who).map_err(|()| Error::AccountIdConversionFailed)?;
|
||||||
Currency::withdraw(&who, amount, WithdrawReasons::TRANSFER, AllowDeath)
|
Currency::withdraw(&who, amount, WithdrawReasons::TRANSFER, AllowDeath)
|
||||||
@@ -223,7 +223,7 @@ impl<
|
|||||||
_context: &XcmContext,
|
_context: &XcmContext,
|
||||||
) -> result::Result<Assets, XcmError> {
|
) -> result::Result<Assets, XcmError> {
|
||||||
log::trace!(target: "xcm::currency_adapter", "internal_transfer_asset asset: {:?}, from: {:?}, to: {:?}", asset, from, to);
|
log::trace!(target: "xcm::currency_adapter", "internal_transfer_asset asset: {:?}, from: {:?}, to: {:?}", asset, from, to);
|
||||||
let amount = Matcher::matches_fungible(asset).ok_or(Error::AssetNotFound)?;
|
let amount = Matcher::matches_fungible(asset).ok_or(Error::AssetNotHandled)?;
|
||||||
let from =
|
let from =
|
||||||
AccountIdConverter::convert_ref(from).map_err(|()| Error::AccountIdConversionFailed)?;
|
AccountIdConverter::convert_ref(from).map_err(|()| Error::AccountIdConversionFailed)?;
|
||||||
let to =
|
let to =
|
||||||
|
|||||||
@@ -48,9 +48,10 @@ impl<Instance> MatchesNonFungible<Instance> for Tuple {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Errors associated with [`MatchesFungibles`] operation.
|
/// Errors associated with [`MatchesFungibles`] operation.
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Asset not found.
|
/// The given asset is not handled. (According to [`XcmError::AssetNotFound`])
|
||||||
AssetNotFound,
|
AssetNotHandled,
|
||||||
/// `MultiLocation` to `AccountId` conversion failed.
|
/// `MultiLocation` to `AccountId` conversion failed.
|
||||||
AccountIdConversionFailed,
|
AccountIdConversionFailed,
|
||||||
/// `u128` amount to currency `Balance` conversion failed.
|
/// `u128` amount to currency `Balance` conversion failed.
|
||||||
@@ -65,7 +66,7 @@ impl From<Error> for XcmError {
|
|||||||
fn from(e: Error) -> Self {
|
fn from(e: Error) -> Self {
|
||||||
use XcmError::FailedToTransactAsset;
|
use XcmError::FailedToTransactAsset;
|
||||||
match e {
|
match e {
|
||||||
Error::AssetNotFound => XcmError::AssetNotFound,
|
Error::AssetNotHandled => XcmError::AssetNotFound,
|
||||||
Error::AccountIdConversionFailed => FailedToTransactAsset("AccountIdConversionFailed"),
|
Error::AccountIdConversionFailed => FailedToTransactAsset("AccountIdConversionFailed"),
|
||||||
Error::AmountToBalanceConversionFailed =>
|
Error::AmountToBalanceConversionFailed =>
|
||||||
FailedToTransactAsset("AmountToBalanceConversionFailed"),
|
FailedToTransactAsset("AmountToBalanceConversionFailed"),
|
||||||
@@ -86,7 +87,7 @@ impl<AssetId, Balance> MatchesFungibles<AssetId, Balance> for Tuple {
|
|||||||
match Tuple::matches_fungibles(a) { o @ Ok(_) => return o, _ => () }
|
match Tuple::matches_fungibles(a) { o @ Ok(_) => return o, _ => () }
|
||||||
)* );
|
)* );
|
||||||
log::trace!(target: "xcm::matches_fungibles", "did not match fungibles asset: {:?}", &a);
|
log::trace!(target: "xcm::matches_fungibles", "did not match fungibles asset: {:?}", &a);
|
||||||
Err(Error::AssetNotFound)
|
Err(Error::AssetNotHandled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,6 +102,6 @@ impl<AssetId, Instance> MatchesNonFungibles<AssetId, Instance> for Tuple {
|
|||||||
match Tuple::matches_nonfungibles(a) { o @ Ok(_) => return o, _ => () }
|
match Tuple::matches_nonfungibles(a) { o @ Ok(_) => return o, _ => () }
|
||||||
)* );
|
)* );
|
||||||
log::trace!(target: "xcm::matches_non_fungibles", "did not match fungibles asset: {:?}", &a);
|
log::trace!(target: "xcm::matches_non_fungibles", "did not match fungibles asset: {:?}", &a);
|
||||||
Err(Error::AssetNotFound)
|
Err(Error::AssetNotHandled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,16 +67,29 @@ impl WeightTrader for Tuple {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {
|
fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {
|
||||||
|
let mut too_expensive_error_found = false;
|
||||||
let mut last_error = None;
|
let mut last_error = None;
|
||||||
for_tuples!( #(
|
for_tuples!( #(
|
||||||
match Tuple.buy_weight(weight, payment.clone()) {
|
match Tuple.buy_weight(weight, payment.clone()) {
|
||||||
Ok(assets) => return Ok(assets),
|
Ok(assets) => return Ok(assets),
|
||||||
Err(e) => { last_error = Some(e) }
|
Err(e) => {
|
||||||
|
if let XcmError::TooExpensive = e {
|
||||||
|
too_expensive_error_found = true;
|
||||||
|
}
|
||||||
|
last_error = Some(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)* );
|
)* );
|
||||||
let last_error = last_error.unwrap_or(XcmError::TooExpensive);
|
|
||||||
log::trace!(target: "xcm::buy_weight", "last_error: {:?}", last_error);
|
log::trace!(target: "xcm::buy_weight", "last_error: {:?}, too_expensive_error_found: {}", last_error, too_expensive_error_found);
|
||||||
Err(last_error)
|
|
||||||
|
// 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 {
|
||||||
|
last_error.unwrap_or(XcmError::TooExpensive)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {
|
fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ use xcm_executor::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub type SovereignAccountOf = (
|
pub type SovereignAccountOf = (
|
||||||
SiblingParachainConvertsVia<ParaId, AccountId>,
|
SiblingParachainConvertsVia<Sibling, AccountId>,
|
||||||
AccountId32Aliases<RelayNetwork, AccountId>,
|
AccountId32Aliases<RelayNetwork, AccountId>,
|
||||||
ParentIsPreset<AccountId>,
|
ParentIsPreset<AccountId>,
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user