difftreelog
fix asset_to_collection
in: master
1 file changed
pallets/foreign-assets/src/lib.rsdiffbeforeafterboth223 .expect("key length < max property key length; qed")223 .expect("key length < max property key length; qed")224 }224 }225225226 /// Converts a multilocation to the Unique Network's local collection226 /// Converts a multilocation to a local collection on Unique Network.227 /// (i.e. the collection originally created on the Unique Network's parachain).228 ///227 ///229 /// The multilocation corresponds to a Unique Network's collection if:228 /// The multilocation corresponds to a local collection if:230 /// * It is `Here` location that corresponds to the native token of this parachain.229 /// * It is `Here` location that corresponds to the native token of this parachain.231 /// * It is `../Parachain(<Unique Network Para ID>)` that also corresponds to the native token of this parachain.230 /// * It is `../Parachain(<Unique Network Para ID>)` that also corresponds to the native token of this parachain.232 /// * It is `../Parachain(<Unique Network Para ID>)/GeneralIndex(<Collection ID>)` that corresponds231 /// * It is `../Parachain(<Unique Network Para ID>)/GeneralIndex(<Collection ID>)` that corresponds233 /// to the collection with the ID equal to `<Collection ID>`. The `<Collection ID>` must be in the valid range,232 /// to the collection with the ID equal to `<Collection ID>`. The `<Collection ID>` must be in the valid range,234 /// otherwise the `AssetIdConversionFailed` error will be returned.233 /// otherwise `None` is returned.235 ///234 ///236 /// If the multilocation doesn't match the patterns listed above,235 /// If the multilocation doesn't match the patterns listed above,237 /// or the `<Collection ID>` points to a foreign collection,236 /// or the `<Collection ID>` points to a foreign collection,238 /// the function returns `Ok(None)`, identifying that the given multilocation doesn't correspond to a local collection.237 /// `None` is returned, identifying that the given multilocation doesn't correspond to a native collection.239 fn native_asset_location_to_collection(238 fn local_asset_location_to_collection(asset_location: &MultiLocation) -> Option<CollectionId> {240 asset_location: &MultiLocation,241 ) -> Result<Option<CollectionId>, XcmError> {242 let self_location = T::SelfLocation::get();239 let self_location = T::SelfLocation::get();243240244 if *asset_location == Here.into() || *asset_location == self_location {241 if *asset_location == Here.into() || *asset_location == self_location {245 Ok(Some(NATIVE_FUNGIBLE_COLLECTION_ID))242 Some(NATIVE_FUNGIBLE_COLLECTION_ID)246 } else if asset_location.parents == self_location.parents {243 } else if asset_location.parents == self_location.parents {247 match asset_location244 match asset_location248 .interior245 .interior249 .match_and_split(&self_location.interior)246 .match_and_split(&self_location.interior)250 {247 {251 Some(GeneralIndex(collection_id)) => {248 Some(GeneralIndex(collection_id)) => {252 let collection_id = CollectionId(249 let collection_id = CollectionId((*collection_id).try_into().ok()?);253 (*collection_id)254 .try_into()255 .map_err(|_| XcmExecutorError::AssetIdConversionFailed)?,256 );257250258 if Self::collection_to_foreign_reserve_location(collection_id).is_some() {251 Self::collection_to_foreign_reserve_location(collection_id)259 Ok(None)252 .is_none()260 } else {261 Ok(Some(collection_id))253 .then_some(collection_id)262 }263 }254 }264 _ => Ok(None),255 _ => None,265 }256 }266 } else {257 } else {267 Ok(None)258 None268 }259 }269 }260 }270261271 /// Converts a multiasset to a Unique Network's collection (either local or a foreign one).262 /// Converts an asset ID to a Unique Network's collection (either foreign or a local one).272 ///263 ///273 /// The function will try to convert the multiasset's reserve location264 /// The function will check if the asset's reserve location has the corresponding274 /// to the Unique Network's local collection.265 /// foreign collection on Unique Network, and will return the collection ID if found.275 ///266 ///267 /// If no corresponding foreign collection is found, the function will check276 /// If the multilocation doesn't correspond to a local collection,268 /// if the asset's reserve location corresponds to a local collection.277 /// the function will check if the reserve location has the corresponding269 /// If the local collection is found, its ID is returned.278 /// derivative Unique Network's collection, and will return the said collection ID if found.279 ///270 ///280 /// If all of the above have failed, the `AssetIdConversionFailed` error will be returned.271 /// If all of the above have failed, the `AssetIdConversionFailed` error will be returned.281 fn multiasset_to_collection(asset: &MultiAsset) -> Result<CollectionId, XcmError> {272 fn asset_to_collection(asset_id: &AssetId) -> Result<CollectionId, XcmError> {282 let AssetId::Concrete(asset_reserve_location) = asset.id else {273 let AssetId::Concrete(asset_reserve_location) = asset_id else {283 return Err(XcmExecutorError::AssetNotHandled.into());274 return Err(XcmExecutorError::AssetNotHandled.into());284 };275 };285276286 Self::native_asset_location_to_collection(&asset_reserve_location)?277 Self::foreign_reserve_location_to_collection(asset_reserve_location)287 .or_else(|| Self::foreign_reserve_location_to_collection(asset_reserve_location))278 .or_else(|| Self::local_asset_location_to_collection(asset_reserve_location))288 .ok_or_else(|| XcmExecutorError::AssetIdConversionFailed.into())279 .ok_or_else(|| XcmExecutorError::AssetIdConversionFailed.into())289 }280 }290281293 /// The asset instance corresponds to the Unique Network's token ID if it is in the following format:284 /// The asset instance corresponds to the Unique Network's token ID if it is in the following format:294 /// `AssetInstance::Index(<token ID>)`.285 /// `AssetInstance::Index(<token ID>)`.295 ///286 ///296 /// If the asset instance is not in the valid format or the `<token ID>` points to a non-existent token,287 /// If the asset instance is not in the valid format or the `<token ID>` can't fit into the valid token ID,297 /// the `AssetNotFound` error will be returned.288 /// the `AssetNotFound` error will be returned.298 fn native_asset_instance_to_token_id(289 fn native_asset_instance_to_token_id(299 asset_instance: &AssetInstance,290 asset_instance: &AssetInstance,439 let to = T::LocationToAccountId::convert_location(to)430 let to = T::LocationToAccountId::convert_location(to)440 .ok_or(XcmExecutorError::AccountIdConversionFailed)?;431 .ok_or(XcmExecutorError::AccountIdConversionFailed)?;441432442 let collection_id = Self::multiasset_to_collection(what)?;433 let collection_id = Self::asset_to_collection(&what.id)?;443 let dispatch =434 let dispatch =444 T::CollectionDispatch::dispatch(collection_id).map_err(|_| XcmError::AssetNotFound)?;435 T::CollectionDispatch::dispatch(collection_id).map_err(|_| XcmError::AssetNotFound)?;445436471 let from = T::LocationToAccountId::convert_location(from)462 let from = T::LocationToAccountId::convert_location(from)472 .ok_or(XcmExecutorError::AccountIdConversionFailed)?;463 .ok_or(XcmExecutorError::AccountIdConversionFailed)?;473464474 let collection_id = Self::multiasset_to_collection(what)?;465 let collection_id = Self::asset_to_collection(&what.id)?;475 let dispatch =466 let dispatch =476 T::CollectionDispatch::dispatch(collection_id).map_err(|_| XcmError::AssetNotFound)?;467 T::CollectionDispatch::dispatch(collection_id).map_err(|_| XcmError::AssetNotFound)?;477468503 let to = T::LocationToAccountId::convert_location(to)494 let to = T::LocationToAccountId::convert_location(to)504 .ok_or(XcmExecutorError::AccountIdConversionFailed)?;495 .ok_or(XcmExecutorError::AccountIdConversionFailed)?;505496506 let collection_id = Self::multiasset_to_collection(what)?;497 let collection_id = Self::asset_to_collection(&what.id)?;507498508 let dispatch =499 let dispatch =509 T::CollectionDispatch::dispatch(collection_id).map_err(|_| XcmError::AssetNotFound)?;500 T::CollectionDispatch::dispatch(collection_id).map_err(|_| XcmError::AssetNotFound)?;