mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 13:31:10 +00:00
[xcm] Assets: sort after prepend_with (#4235)
Adds sorting to the XCM Assets' `prepend_with`, which could modify the order of `AssetId` locations. Relates to: https://github.com/paritytech/polkadot-sdk/pull/4186 (the same fix for `reanchored`) Part of: https://github.com/paritytech/polkadot-sdk/pull/2129
This commit is contained in:
@@ -825,7 +825,9 @@ impl MultiAssets {
|
||||
|
||||
/// Prepend a `MultiLocation` to any concrete asset items, giving it a new root location.
|
||||
pub fn prepend_with(&mut self, prefix: &MultiLocation) -> Result<(), ()> {
|
||||
self.0.iter_mut().try_for_each(|i| i.prepend_with(prefix))
|
||||
self.0.iter_mut().try_for_each(|i| i.prepend_with(prefix))?;
|
||||
self.0.sort();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Mutate the location of the asset identifier if concrete, giving it the same location
|
||||
@@ -1213,8 +1215,73 @@ mod tests {
|
||||
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());
|
||||
|
||||
// decoding respects limits and sorting
|
||||
assert!(assets
|
||||
.using_encoded(|mut enc| MultiAssets::decode(&mut enc).map(|_| ()))
|
||||
.is_ok());
|
||||
|
||||
assert!(assets.reanchor(&dest, reanchor_context).is_ok());
|
||||
assert_eq!(assets, vec![asset_2_reanchored, asset_3_reanchored, asset_1_reanchored].into());
|
||||
assert_eq!(assets.0, vec![asset_2_reanchored, asset_3_reanchored, asset_1_reanchored]);
|
||||
|
||||
// decoding respects limits and sorting
|
||||
assert!(assets
|
||||
.using_encoded(|mut enc| MultiAssets::decode(&mut enc).map(|_| ()))
|
||||
.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prepend_preserves_sorting() {
|
||||
use super::*;
|
||||
use alloc::vec;
|
||||
|
||||
let prefix = MultiLocation::new(0, X1(Parachain(1000)));
|
||||
|
||||
let asset_1: MultiAsset =
|
||||
(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1))), 10).into();
|
||||
let mut asset_1_prepended = asset_1.clone();
|
||||
assert!(asset_1_prepended.prepend_with(&prefix).is_ok());
|
||||
// changes interior X2->X3
|
||||
assert_eq!(
|
||||
asset_1_prepended,
|
||||
(MultiLocation::new(0, X3(Parachain(1000), PalletInstance(50), GeneralIndex(1))), 10)
|
||||
.into()
|
||||
);
|
||||
|
||||
let asset_2: MultiAsset =
|
||||
(MultiLocation::new(1, X2(PalletInstance(50), GeneralIndex(1))), 10).into();
|
||||
let mut asset_2_prepended = asset_2.clone();
|
||||
assert!(asset_2_prepended.prepend_with(&prefix).is_ok());
|
||||
// changes parent
|
||||
assert_eq!(
|
||||
asset_2_prepended,
|
||||
(MultiLocation::new(0, X2(PalletInstance(50), GeneralIndex(1))), 10).into()
|
||||
);
|
||||
|
||||
let asset_3: MultiAsset =
|
||||
(MultiLocation::new(2, X2(PalletInstance(50), GeneralIndex(1))), 10).into();
|
||||
let mut asset_3_prepended = asset_3.clone();
|
||||
assert!(asset_3_prepended.prepend_with(&prefix).is_ok());
|
||||
// changes parent
|
||||
assert_eq!(
|
||||
asset_3_prepended,
|
||||
(MultiLocation::new(1, X2(PalletInstance(50), GeneralIndex(1))), 10).into()
|
||||
);
|
||||
|
||||
// `From` impl does sorting.
|
||||
let mut assets: MultiAssets = vec![asset_1, asset_2, asset_3].into();
|
||||
// decoding respects limits and sorting
|
||||
assert!(assets
|
||||
.using_encoded(|mut enc| MultiAssets::decode(&mut enc).map(|_| ()))
|
||||
.is_ok());
|
||||
|
||||
// let's do `prepend_with`
|
||||
assert!(assets.prepend_with(&prefix).is_ok());
|
||||
assert_eq!(assets.0, vec![asset_2_prepended, asset_1_prepended, asset_3_prepended]);
|
||||
|
||||
// decoding respects limits and sorting
|
||||
assert!(assets
|
||||
.using_encoded(|mut enc| MultiAssets::decode(&mut enc).map(|_| ()))
|
||||
.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -723,7 +723,9 @@ impl Assets {
|
||||
|
||||
/// Prepend a `Location` to any concrete asset items, giving it a new root location.
|
||||
pub fn prepend_with(&mut self, prefix: &Location) -> Result<(), ()> {
|
||||
self.0.iter_mut().try_for_each(|i| i.prepend_with(prefix))
|
||||
self.0.iter_mut().try_for_each(|i| i.prepend_with(prefix))?;
|
||||
self.0.sort();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Return a reference to an item at a specific index or `None` if it doesn't exist.
|
||||
@@ -1035,8 +1037,61 @@ mod tests {
|
||||
let mut assets: Assets = 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());
|
||||
|
||||
// decoding respects limits and sorting
|
||||
assert!(assets.using_encoded(|mut enc| Assets::decode(&mut enc).map(|_| ())).is_ok());
|
||||
|
||||
assert!(assets.reanchor(&dest, &reanchor_context).is_ok());
|
||||
assert_eq!(assets, vec![asset_2_reanchored, asset_3_reanchored, asset_1_reanchored].into());
|
||||
assert_eq!(assets.0, vec![asset_2_reanchored, asset_3_reanchored, asset_1_reanchored]);
|
||||
|
||||
// decoding respects limits and sorting
|
||||
assert!(assets.using_encoded(|mut enc| Assets::decode(&mut enc).map(|_| ())).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prepend_preserves_sorting() {
|
||||
use super::*;
|
||||
use alloc::vec;
|
||||
|
||||
let prefix = Location::new(0, [Parachain(1000)]);
|
||||
|
||||
let asset_1: Asset = (Location::new(0, [PalletInstance(50), GeneralIndex(1)]), 10).into();
|
||||
let mut asset_1_prepended = asset_1.clone();
|
||||
assert!(asset_1_prepended.prepend_with(&prefix).is_ok());
|
||||
// changes interior X2->X3
|
||||
assert_eq!(
|
||||
asset_1_prepended,
|
||||
(Location::new(0, [Parachain(1000), PalletInstance(50), GeneralIndex(1)]), 10).into()
|
||||
);
|
||||
|
||||
let asset_2: Asset = (Location::new(1, [PalletInstance(50), GeneralIndex(1)]), 10).into();
|
||||
let mut asset_2_prepended = asset_2.clone();
|
||||
assert!(asset_2_prepended.prepend_with(&prefix).is_ok());
|
||||
// changes parent
|
||||
assert_eq!(
|
||||
asset_2_prepended,
|
||||
(Location::new(0, [PalletInstance(50), GeneralIndex(1)]), 10).into()
|
||||
);
|
||||
|
||||
let asset_3: Asset = (Location::new(2, [PalletInstance(50), GeneralIndex(1)]), 10).into();
|
||||
let mut asset_3_prepended = asset_3.clone();
|
||||
assert!(asset_3_prepended.prepend_with(&prefix).is_ok());
|
||||
// changes parent
|
||||
assert_eq!(
|
||||
asset_3_prepended,
|
||||
(Location::new(1, [PalletInstance(50), GeneralIndex(1)]), 10).into()
|
||||
);
|
||||
|
||||
// `From` impl does sorting.
|
||||
let mut assets: Assets = vec![asset_1, asset_2, asset_3].into();
|
||||
// decoding respects limits and sorting
|
||||
assert!(assets.using_encoded(|mut enc| Assets::decode(&mut enc).map(|_| ())).is_ok());
|
||||
|
||||
// let's do `prepend_with`
|
||||
assert!(assets.prepend_with(&prefix).is_ok());
|
||||
assert_eq!(assets.0, vec![asset_2_prepended, asset_1_prepended, asset_3_prepended]);
|
||||
|
||||
// decoding respects limits and sorting
|
||||
assert!(assets.using_encoded(|mut enc| Assets::decode(&mut enc).map(|_| ())).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user