xcm-builder: PayOverXcm supports fallible convertors for asset kind and beneficiary conversion (#1572)

`PayOverXcm` type accepts two converters to transform the `AssetKind`
and `Beneficiary` parameter types into recognized `xcm` types. In this
PR, we've modified the bounds for these converters, transitioning from
`Convert` to `TryConvert`.

One such use case for this adjustment is when dealing with versioned xcm
types for `AssetKind` and `Beneficiary`. These types might be not
convertible to the latest xcm version, hence the need for fallible
conversion.

This changes required for
https://github.com/paritytech/polkadot-sdk/pull/1333
This commit is contained in:
Muharem Ismailov
2023-09-18 11:04:47 +02:00
committed by GitHub
parent e38998801e
commit a8e82a365e
3 changed files with 17 additions and 15 deletions
@@ -18,7 +18,7 @@ use crate::universal_exports::ensure_is_remote;
use frame_support::traits::Get; use frame_support::traits::Get;
use parity_scale_codec::{Compact, Decode, Encode}; use parity_scale_codec::{Compact, Decode, Encode};
use sp_io::hashing::blake2_256; use sp_io::hashing::blake2_256;
use sp_runtime::traits::{AccountIdConversion, Convert, TrailingZeroInput}; use sp_runtime::traits::{AccountIdConversion, TrailingZeroInput, TryConvert};
use sp_std::{marker::PhantomData, prelude::*}; use sp_std::{marker::PhantomData, prelude::*};
use xcm::latest::prelude::*; use xcm::latest::prelude::*;
use xcm_executor::traits::ConvertLocation; use xcm_executor::traits::ConvertLocation;
@@ -322,10 +322,10 @@ impl<Network: Get<Option<NetworkId>>, AccountId: From<[u8; 32]> + Into<[u8; 32]>
/// network (provided by `Network`) and the `AccountId`'s `[u8; 32]` datum for the `id`. /// network (provided by `Network`) and the `AccountId`'s `[u8; 32]` datum for the `id`.
pub struct AliasesIntoAccountId32<Network, AccountId>(PhantomData<(Network, AccountId)>); pub struct AliasesIntoAccountId32<Network, AccountId>(PhantomData<(Network, AccountId)>);
impl<'a, Network: Get<Option<NetworkId>>, AccountId: Clone + Into<[u8; 32]> + Clone> impl<'a, Network: Get<Option<NetworkId>>, AccountId: Clone + Into<[u8; 32]> + Clone>
Convert<&'a AccountId, MultiLocation> for AliasesIntoAccountId32<Network, AccountId> TryConvert<&'a AccountId, MultiLocation> for AliasesIntoAccountId32<Network, AccountId>
{ {
fn convert(who: &AccountId) -> MultiLocation { fn try_convert(who: &AccountId) -> Result<MultiLocation, &AccountId> {
AccountId32 { network: Network::get(), id: who.clone().into() }.into() Ok(AccountId32 { network: Network::get(), id: who.clone().into() }.into())
} }
} }
+10 -8
View File
@@ -20,7 +20,7 @@ use frame_support::traits::{
tokens::{Pay, PaymentStatus}, tokens::{Pay, PaymentStatus},
Get, Get,
}; };
use sp_runtime::traits::Convert; use sp_runtime::traits::TryConvert;
use sp_std::{marker::PhantomData, vec}; use sp_std::{marker::PhantomData, vec};
use xcm::{opaque::lts::Weight, prelude::*}; use xcm::{opaque::lts::Weight, prelude::*};
use xcm_executor::traits::{QueryHandler, QueryResponseStatus}; use xcm_executor::traits::{QueryHandler, QueryResponseStatus};
@@ -71,8 +71,8 @@ impl<
Timeout: Get<Querier::BlockNumber>, Timeout: Get<Querier::BlockNumber>,
Beneficiary: Clone, Beneficiary: Clone,
AssetKind, AssetKind,
AssetKindToLocatableAsset: Convert<AssetKind, LocatableAssetId>, AssetKindToLocatableAsset: TryConvert<AssetKind, LocatableAssetId>,
BeneficiaryRefToLocation: for<'a> Convert<&'a Beneficiary, MultiLocation>, BeneficiaryRefToLocation: for<'a> TryConvert<&'a Beneficiary, MultiLocation>,
> Pay > Pay
for PayOverXcm< for PayOverXcm<
Interior, Interior,
@@ -96,12 +96,14 @@ impl<
asset_kind: Self::AssetKind, asset_kind: Self::AssetKind,
amount: Self::Balance, amount: Self::Balance,
) -> Result<Self::Id, Self::Error> { ) -> Result<Self::Id, Self::Error> {
let locatable = AssetKindToLocatableAsset::convert(asset_kind); let locatable = AssetKindToLocatableAsset::try_convert(asset_kind)
.map_err(|_| xcm::latest::Error::InvalidLocation)?;
let LocatableAssetId { asset_id, location: asset_location } = locatable; let LocatableAssetId { asset_id, location: asset_location } = locatable;
let destination = Querier::UniversalLocation::get() let destination = Querier::UniversalLocation::get()
.invert_target(&asset_location) .invert_target(&asset_location)
.map_err(|()| Self::Error::LocationNotInvertible)?; .map_err(|()| Self::Error::LocationNotInvertible)?;
let beneficiary = BeneficiaryRefToLocation::convert(&who); let beneficiary = BeneficiaryRefToLocation::try_convert(&who)
.map_err(|_| xcm::latest::Error::InvalidLocation)?;
let query_id = Querier::new_query(asset_location, Timeout::get(), Interior::get()); let query_id = Querier::new_query(asset_location, Timeout::get(), Interior::get());
@@ -196,10 +198,10 @@ pub struct LocatableAssetId {
/// Adapter `struct` which implements a conversion from any `AssetKind` into a [`LocatableAssetId`] /// Adapter `struct` which implements a conversion from any `AssetKind` into a [`LocatableAssetId`]
/// value using a fixed `Location` for the `location` field. /// value using a fixed `Location` for the `location` field.
pub struct FixedLocation<Location>(sp_std::marker::PhantomData<Location>); pub struct FixedLocation<Location>(sp_std::marker::PhantomData<Location>);
impl<Location: Get<MultiLocation>, AssetKind: Into<AssetId>> Convert<AssetKind, LocatableAssetId> impl<Location: Get<MultiLocation>, AssetKind: Into<AssetId>> TryConvert<AssetKind, LocatableAssetId>
for FixedLocation<Location> for FixedLocation<Location>
{ {
fn convert(value: AssetKind) -> LocatableAssetId { fn try_convert(value: AssetKind) -> Result<LocatableAssetId, AssetKind> {
LocatableAssetId { asset_id: value.into(), location: Location::get() } Ok(LocatableAssetId { asset_id: value.into(), location: Location::get() })
} }
} }
@@ -29,9 +29,9 @@ pub struct AssetKind {
} }
pub struct LocatableAssetKindConverter; pub struct LocatableAssetKindConverter;
impl sp_runtime::traits::Convert<AssetKind, LocatableAssetId> for LocatableAssetKindConverter { impl sp_runtime::traits::TryConvert<AssetKind, LocatableAssetId> for LocatableAssetKindConverter {
fn convert(value: AssetKind) -> LocatableAssetId { fn try_convert(value: AssetKind) -> Result<LocatableAssetId, AssetKind> {
LocatableAssetId { asset_id: value.asset_id, location: value.destination } Ok(LocatableAssetId { asset_id: value.asset_id, location: value.destination })
} }
} }