Skip to content
multiasset.rs 34.7 KiB
Newer Older
Francisco Aguirre's avatar
Francisco Aguirre committed
impl TryFrom<NewMultiAssetFilter> for MultiAssetFilter {
	type Error = ();
	fn try_from(new: NewMultiAssetFilter) -> Result<MultiAssetFilter, Self::Error> {
		use NewMultiAssetFilter::*;
		Ok(match new {
			Definite(x) => Self::Definite(x.try_into()?),
			Wild(x) => Self::Wild(x.try_into()?),
		})
	}
}

Gavin Wood's avatar
Gavin Wood committed
impl TryFrom<(OldMultiAssetFilter, u32)> for MultiAssetFilter {
	type Error = ();
	fn try_from(old: (OldMultiAssetFilter, u32)) -> Result<MultiAssetFilter, ()> {
		let count = old.1;
		Ok(match old.0 {
			OldMultiAssetFilter::Definite(x) if count >= x.len() as u32 =>
				Self::Definite(x.try_into()?),
			OldMultiAssetFilter::Wild(x) => Self::Wild((x, count).try_into()?),
			_ => return Err(()),
		})
	}
}

#[cfg(test)]
mod tests {
	use super::super::prelude::*;

	#[test]
	fn conversion_works() {
		let _: MultiAssets = (Here, 1u128).into();
	}

	#[test]
	fn from_sorted_and_deduplicated_works() {
		use super::*;
		use alloc::vec;

		let empty = vec![];
		let r = MultiAssets::from_sorted_and_deduplicated(empty);
		assert_eq!(r, Ok(MultiAssets(vec![])));

		let dup_fun = vec![(Here, 100).into(), (Here, 10).into()];
		let r = MultiAssets::from_sorted_and_deduplicated(dup_fun);
		assert!(r.is_err());

		let dup_nft = vec![(Here, *b"notgood!").into(), (Here, *b"notgood!").into()];
		let r = MultiAssets::from_sorted_and_deduplicated(dup_nft);
		assert!(r.is_err());

		let good_fun = vec![(Here, 10).into(), (Parent, 10).into()];
		let r = MultiAssets::from_sorted_and_deduplicated(good_fun.clone());
		assert_eq!(r, Ok(MultiAssets(good_fun)));

		let bad_fun = vec![(Parent, 10).into(), (Here, 10).into()];
		let r = MultiAssets::from_sorted_and_deduplicated(bad_fun);
		assert!(r.is_err());

		let good_abstract_fun = vec![(Here, 100).into(), ([0u8; 32], 10).into()];
		let r = MultiAssets::from_sorted_and_deduplicated(good_abstract_fun.clone());
		assert_eq!(r, Ok(MultiAssets(good_abstract_fun)));

		let bad_abstract_fun = vec![([0u8; 32], 10).into(), (Here, 10).into()];
		let r = MultiAssets::from_sorted_and_deduplicated(bad_abstract_fun);
		assert!(r.is_err());

		let good_nft = vec![(Here, ()).into(), (Here, *b"good").into()];
		let r = MultiAssets::from_sorted_and_deduplicated(good_nft.clone());
		assert_eq!(r, Ok(MultiAssets(good_nft)));

		let bad_nft = vec![(Here, *b"bad!").into(), (Here, ()).into()];
		let r = MultiAssets::from_sorted_and_deduplicated(bad_nft);
		assert!(r.is_err());

		let good_abstract_nft = vec![(Here, ()).into(), ([0u8; 32], ()).into()];
		let r = MultiAssets::from_sorted_and_deduplicated(good_abstract_nft.clone());
		assert_eq!(r, Ok(MultiAssets(good_abstract_nft)));

		let bad_abstract_nft = vec![([0u8; 32], ()).into(), (Here, ()).into()];
		let r = MultiAssets::from_sorted_and_deduplicated(bad_abstract_nft);
		assert!(r.is_err());

		let mixed_good = vec![(Here, 10).into(), (Here, *b"good").into()];
		let r = MultiAssets::from_sorted_and_deduplicated(mixed_good.clone());
		assert_eq!(r, Ok(MultiAssets(mixed_good)));

		let mixed_bad = vec![(Here, *b"bad!").into(), (Here, 10).into()];
		let r = MultiAssets::from_sorted_and_deduplicated(mixed_bad);
		assert!(r.is_err());
	}
	#[test]
	fn reanchor_preserves_sorting() {
		use super::*;
		use alloc::vec;

		let reanchor_context = X1(Parachain(2000));
		let dest = MultiLocation::new(1, Here);

		let asset_1: MultiAsset =
			(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1))), 10).into();
		let mut asset_1_reanchored = asset_1.clone();
		assert!(asset_1_reanchored.reanchor(&dest, reanchor_context).is_ok());
		assert_eq!(
			asset_1_reanchored,
			(MultiLocation::new(0, X3(Parachain(2000), PalletInstance(50), GeneralIndex(1))), 10)
				.into()
		);

		let asset_2: MultiAsset = (MultiLocation::new(1, Here), 10).into();
		let mut asset_2_reanchored = asset_2.clone();
		assert!(asset_2_reanchored.reanchor(&dest, reanchor_context).is_ok());
		assert_eq!(asset_2_reanchored, (MultiLocation::new(0, Here), 10).into());

		let asset_3: MultiAsset = (MultiLocation::new(1, X1(Parachain(1000))), 10).into();
		let mut asset_3_reanchored = asset_3.clone();
		assert!(asset_3_reanchored.reanchor(&dest, reanchor_context).is_ok());
		assert_eq!(asset_3_reanchored, (MultiLocation::new(0, X1(Parachain(1000))), 10).into());

		let mut assets: MultiAssets =
			vec![asset_1.clone(), asset_2.clone(), asset_3.clone()].into();
		assert_eq!(assets.clone(), vec![asset_1.clone(), asset_2.clone(), asset_3.clone()].into());

		assert!(assets.reanchor(&dest, reanchor_context).is_ok());
		assert_eq!(assets, vec![asset_2_reanchored, asset_3_reanchored, asset_1_reanchored].into());
	}

	#[test]
	fn decoding_respects_limit() {
		use super::*;

		// Having lots of one asset will work since they are deduplicated
		let lots_of_one_asset: MultiAssets =
			vec![(GeneralIndex(1), 1u128).into(); MAX_ITEMS_IN_MULTIASSETS + 1].into();
		let encoded = lots_of_one_asset.encode();
		assert!(MultiAssets::decode(&mut &encoded[..]).is_ok());

		// Fewer assets than the limit works
		let mut few_assets: MultiAssets = Vec::new().into();
		for i in 0..MAX_ITEMS_IN_MULTIASSETS {
			few_assets.push((GeneralIndex(i as u128), 1u128).into());
		}
		let encoded = few_assets.encode();
		assert!(MultiAssets::decode(&mut &encoded[..]).is_ok());

		// Having lots of different assets will not work
		let mut too_many_different_assets: MultiAssets = Vec::new().into();
		for i in 0..MAX_ITEMS_IN_MULTIASSETS + 1 {
			too_many_different_assets.push((GeneralIndex(i as u128), 1u128).into());
		}
		let encoded = too_many_different_assets.encode();
		assert!(MultiAssets::decode(&mut &encoded[..]).is_err());
	}
Gavin Wood's avatar
Gavin Wood committed
}