Reanchor should return canonical location (#4470)

* Reanchor should return canonical

* Formatting

* Formatting

* Update xcm/src/v1/multilocation.rs

* Formatting

* Fixes

* Don't discard unreanchorable assets

* Formatting

* Docs

* Fixes

* Fixes

* tidy
This commit is contained in:
Gavin Wood
2021-12-14 09:21:34 +01:00
committed by GitHub
parent ca72ad636c
commit 32bb94afff
8 changed files with 241 additions and 34 deletions
+38 -2
View File
@@ -194,7 +194,7 @@ impl Assets {
self.fungible = fungible
.into_iter()
.map(|(mut id, amount)| {
let _ = id.reanchor(prepend);
let _ = id.prepend_with(prepend);
(id, amount)
})
.collect();
@@ -203,12 +203,48 @@ impl Assets {
self.non_fungible = non_fungible
.into_iter()
.map(|(mut class, inst)| {
let _ = class.reanchor(prepend);
let _ = class.prepend_with(prepend);
(class, inst)
})
.collect();
}
/// Mutate the assets to be interpreted as the same assets from the perspective of a `target`
/// chain. The local chain's `ancestry` is provided.
///
/// Any assets which were unable to be reanchored are introduced into `failed_bin`.
pub fn reanchor(
&mut self,
target: &MultiLocation,
ancestry: &MultiLocation,
mut maybe_failed_bin: Option<&mut Self>,
) {
let mut fungible = Default::default();
mem::swap(&mut self.fungible, &mut fungible);
self.fungible = fungible
.into_iter()
.filter_map(|(mut id, amount)| match id.reanchor(target, ancestry) {
Ok(()) => Some((id, amount)),
Err(()) => {
maybe_failed_bin.as_mut().map(|f| f.fungible.insert(id, amount));
None
},
})
.collect();
let mut non_fungible = Default::default();
mem::swap(&mut self.non_fungible, &mut non_fungible);
self.non_fungible = non_fungible
.into_iter()
.filter_map(|(mut class, inst)| match class.reanchor(target, ancestry) {
Ok(()) => Some((class, inst)),
Err(()) => {
maybe_failed_bin.as_mut().map(|f| f.non_fungible.insert((class, inst)));
None
},
})
.collect();
}
/// Returns an error unless all `assets` are contained in `self`. In the case of an error, the first asset in
/// `assets` which is not wholly in `self` is returned.
pub fn ensure_contains(&self, assets: &MultiAssets) -> Result<(), TakeError> {