From 79c47093d74b6f03a5c335f45010e61b34ec0fef Mon Sep 17 00:00:00 2001 From: Daniel Shiposha Date: Tue, 31 Oct 2023 11:30:41 +0100 Subject: [PATCH] fix: asset_to_collection --- pallets/foreign-assets/src/lib.rs | 63 +++++++++++++------------------ 1 file changed, 27 insertions(+), 36 deletions(-) diff --git a/pallets/foreign-assets/src/lib.rs b/pallets/foreign-assets/src/lib.rs index 4d4818d104..9ef4dd5fdb 100644 --- a/pallets/foreign-assets/src/lib.rs +++ b/pallets/foreign-assets/src/lib.rs @@ -223,68 +223,59 @@ impl Pallet { .expect("key length < max property key length; qed") } - /// Converts a multilocation to the Unique Network's local collection - /// (i.e. the collection originally created on the Unique Network's parachain). + /// Converts a multilocation to a local collection on Unique Network. /// - /// The multilocation corresponds to a Unique Network's collection if: + /// The multilocation corresponds to a local collection if: /// * It is `Here` location that corresponds to the native token of this parachain. /// * It is `../Parachain()` that also corresponds to the native token of this parachain. /// * It is `../Parachain()/GeneralIndex()` that corresponds /// to the collection with the ID equal to ``. The `` must be in the valid range, - /// otherwise the `AssetIdConversionFailed` error will be returned. + /// otherwise `None` is returned. /// /// If the multilocation doesn't match the patterns listed above, /// or the `` points to a foreign collection, - /// the function returns `Ok(None)`, identifying that the given multilocation doesn't correspond to a local collection. - fn native_asset_location_to_collection( - asset_location: &MultiLocation, - ) -> Result, XcmError> { + /// `None` is returned, identifying that the given multilocation doesn't correspond to a native collection. + fn local_asset_location_to_collection(asset_location: &MultiLocation) -> Option { let self_location = T::SelfLocation::get(); if *asset_location == Here.into() || *asset_location == self_location { - Ok(Some(NATIVE_FUNGIBLE_COLLECTION_ID)) + Some(NATIVE_FUNGIBLE_COLLECTION_ID) } else if asset_location.parents == self_location.parents { match asset_location .interior .match_and_split(&self_location.interior) { Some(GeneralIndex(collection_id)) => { - let collection_id = CollectionId( - (*collection_id) - .try_into() - .map_err(|_| XcmExecutorError::AssetIdConversionFailed)?, - ); - - if Self::collection_to_foreign_reserve_location(collection_id).is_some() { - Ok(None) - } else { - Ok(Some(collection_id)) - } + let collection_id = CollectionId((*collection_id).try_into().ok()?); + + Self::collection_to_foreign_reserve_location(collection_id) + .is_none() + .then_some(collection_id) } - _ => Ok(None), + _ => None, } } else { - Ok(None) + None } } - /// Converts a multiasset to a Unique Network's collection (either local or a foreign one). + /// Converts an asset ID to a Unique Network's collection (either foreign or a local one). /// - /// The function will try to convert the multiasset's reserve location - /// to the Unique Network's local collection. + /// The function will check if the asset's reserve location has the corresponding + /// foreign collection on Unique Network, and will return the collection ID if found. /// - /// If the multilocation doesn't correspond to a local collection, - /// the function will check if the reserve location has the corresponding - /// derivative Unique Network's collection, and will return the said collection ID if found. + /// If no corresponding foreign collection is found, the function will check + /// if the asset's reserve location corresponds to a local collection. + /// If the local collection is found, its ID is returned. /// /// If all of the above have failed, the `AssetIdConversionFailed` error will be returned. - fn multiasset_to_collection(asset: &MultiAsset) -> Result { - let AssetId::Concrete(asset_reserve_location) = asset.id else { + fn asset_to_collection(asset_id: &AssetId) -> Result { + let AssetId::Concrete(asset_reserve_location) = asset_id else { return Err(XcmExecutorError::AssetNotHandled.into()); }; - Self::native_asset_location_to_collection(&asset_reserve_location)? - .or_else(|| Self::foreign_reserve_location_to_collection(asset_reserve_location)) + Self::foreign_reserve_location_to_collection(asset_reserve_location) + .or_else(|| Self::local_asset_location_to_collection(asset_reserve_location)) .ok_or_else(|| XcmExecutorError::AssetIdConversionFailed.into()) } @@ -293,7 +284,7 @@ impl Pallet { /// The asset instance corresponds to the Unique Network's token ID if it is in the following format: /// `AssetInstance::Index()`. /// - /// If the asset instance is not in the valid format or the `` points to a non-existent token, + /// If the asset instance is not in the valid format or the `` can't fit into the valid token ID, /// the `AssetNotFound` error will be returned. fn native_asset_instance_to_token_id( asset_instance: &AssetInstance, @@ -439,7 +430,7 @@ impl TransactAsset for Pallet { let to = T::LocationToAccountId::convert_location(to) .ok_or(XcmExecutorError::AccountIdConversionFailed)?; - let collection_id = Self::multiasset_to_collection(what)?; + let collection_id = Self::asset_to_collection(&what.id)?; let dispatch = T::CollectionDispatch::dispatch(collection_id).map_err(|_| XcmError::AssetNotFound)?; @@ -471,7 +462,7 @@ impl TransactAsset for Pallet { let from = T::LocationToAccountId::convert_location(from) .ok_or(XcmExecutorError::AccountIdConversionFailed)?; - let collection_id = Self::multiasset_to_collection(what)?; + let collection_id = Self::asset_to_collection(&what.id)?; let dispatch = T::CollectionDispatch::dispatch(collection_id).map_err(|_| XcmError::AssetNotFound)?; @@ -503,7 +494,7 @@ impl TransactAsset for Pallet { let to = T::LocationToAccountId::convert_location(to) .ok_or(XcmExecutorError::AccountIdConversionFailed)?; - let collection_id = Self::multiasset_to_collection(what)?; + let collection_id = Self::asset_to_collection(&what.id)?; let dispatch = T::CollectionDispatch::dispatch(collection_id).map_err(|_| XcmError::AssetNotFound)?;