|
15 | 15 | // along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
16 | 16 |
|
17 | 17 | use frame_support::traits::Get;
|
18 |
| -use parity_scale_codec::{Decode, Encode}; |
| 18 | +use parity_scale_codec::{Compact, Decode, Encode}; |
19 | 19 | use sp_io::hashing::blake2_256;
|
20 | 20 | use sp_runtime::traits::{AccountIdConversion, TrailingZeroInput};
|
21 |
| -use sp_std::{borrow::Borrow, marker::PhantomData}; |
| 21 | +use sp_std::{borrow::Borrow, vec::Vec, marker::PhantomData}; |
22 | 22 | use xcm::latest::prelude::*;
|
23 | 23 | use xcm_executor::traits::Convert;
|
24 | 24 |
|
| 25 | +/// temporary struct that mimin the behavior of the upstream type: |
| 26 | +/// HashedDescription<AccountId, DescribeFamily<DescribeAllTerminal>> |
| 27 | +pub struct HashedDescriptionDescribeFamilyAllTerminal<AccountId>(PhantomData<AccountId>); |
| 28 | +impl<AccountId: From<[u8; 32]> + Clone> HashedDescriptionDescribeFamilyAllTerminal<AccountId> { |
| 29 | + fn describe_location_suffix(l: &MultiLocation) -> Result<Vec<u8>, ()> { |
| 30 | + match (l.parents, &l.interior) { |
| 31 | + (0, Here) => Ok(Vec::new()), |
| 32 | + (0, X1(PalletInstance(i))) => Ok((b"Pallet", Compact::<u32>::from(*i as u32)).encode()), |
| 33 | + (0, X1(AccountId32 { id, .. })) => Ok((b"AccountId32", id).encode()), |
| 34 | + (0, X1(AccountKey20 { key, .. })) => Ok((b"AccountKey20", key).encode()), |
| 35 | + _ => return Err(()), |
| 36 | + } |
| 37 | + } |
| 38 | +} |
| 39 | + |
| 40 | +impl<AccountId: From<[u8; 32]> + Clone> Convert<MultiLocation, AccountId> |
| 41 | + for HashedDescriptionDescribeFamilyAllTerminal<AccountId> { |
| 42 | + fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> { |
| 43 | + let l = location.borrow(); |
| 44 | + let to_hash = match (l.parents, l.interior.first()) { |
| 45 | + (0, Some(Parachain(index))) => { |
| 46 | + let tail = l.interior.split_first().0; |
| 47 | + let interior = Self::describe_location_suffix(&tail.into())?; |
| 48 | + (b"ChildChain", Compact::<u32>::from(*index), interior).encode() |
| 49 | + }, |
| 50 | + (1, Some(Parachain(index))) => { |
| 51 | + let tail = l.interior.split_first().0; |
| 52 | + let interior = Self::describe_location_suffix(&tail.into())?; |
| 53 | + (b"SiblingChain", Compact::<u32>::from(*index), interior).encode() |
| 54 | + }, |
| 55 | + (1, _) => { |
| 56 | + let tail = l.interior.into(); |
| 57 | + let interior = Self::describe_location_suffix(&tail)?; |
| 58 | + (b"ParentChain", interior).encode() |
| 59 | + }, |
| 60 | + _ => return Err(()), |
| 61 | + }; |
| 62 | + Ok(blake2_256(&to_hash).into()) |
| 63 | + } |
| 64 | + fn reverse_ref(_: impl Borrow<AccountId>) -> Result<MultiLocation, ()> { |
| 65 | + Err(()) |
| 66 | + } |
| 67 | +} |
| 68 | + |
25 | 69 | /// Prefix for generating alias account for accounts coming
|
26 | 70 | /// from chains that use 32 byte long representations.
|
27 | 71 | pub const FOREIGN_CHAIN_PREFIX_PARA_32: [u8; 37] = *b"ForeignChainAliasAccountPrefix_Para32";
|
@@ -541,4 +585,70 @@ mod tests {
|
541 | 585 | };
|
542 | 586 | assert!(ForeignChainAliasAccount::<[u8; 32]>::convert(mul).is_err());
|
543 | 587 | }
|
| 588 | + |
| 589 | + #[test] |
| 590 | + fn test_hashed_family_all_terminal_converter() { |
| 591 | + type Converter<AccountId> = HashedDescriptionDescribeFamilyAllTerminal<AccountId>; |
| 592 | + |
| 593 | + assert_eq!( |
| 594 | + [ |
| 595 | + 129, 211, 14, 6, 146, 54, 225, 200, 135, 103, 248, 244, 125, 112, 53, 133, |
| 596 | + 91, 42, 215, 236, 154, 199, 191, 208, 110, 148, 223, 55, 92, 216, 250, 34 |
| 597 | + ], |
| 598 | + Converter::<[u8; 32]>::convert(MultiLocation { |
| 599 | + parents: 0, |
| 600 | + interior: X2(Parachain(1), AccountId32 { network: None, id: [0u8; 32] }), |
| 601 | + }).unwrap() |
| 602 | + ); |
| 603 | + assert_eq!( |
| 604 | + [ |
| 605 | + 17, 142, 105, 253, 199, 34, 43, 136, 155, 48, 12, 137, 155, 219, 155, 110, |
| 606 | + 93, 181, 93, 252, 124, 60, 250, 195, 229, 86, 31, 220, 121, 111, 254, 252 |
| 607 | + ], |
| 608 | + Converter::<[u8; 32]>::convert(MultiLocation { |
| 609 | + parents: 1, |
| 610 | + interior: X2(Parachain(1), AccountId32 { network: None, id: [0u8; 32] }), |
| 611 | + }).unwrap() |
| 612 | + ); |
| 613 | + assert_eq!( |
| 614 | + [ |
| 615 | + 237, 65, 190, 49, 53, 182, 196, 183, 151, 24, 214, 23, 72, 244, 235, 87, |
| 616 | + 187, 67, 52, 122, 195, 192, 10, 58, 253, 49, 0, 112, 175, 224, 125, 66 |
| 617 | + ], |
| 618 | + Converter::<[u8; 32]>::convert(MultiLocation { |
| 619 | + parents: 0, |
| 620 | + interior: X2(Parachain(1), AccountKey20 { network: None, key: [0u8; 20] }), |
| 621 | + }).unwrap() |
| 622 | + ); |
| 623 | + assert_eq!( |
| 624 | + [ |
| 625 | + 226, 225, 225, 162, 254, 156, 113, 95, 68, 155, 160, 118, 126, 18, 166, 132, |
| 626 | + 144, 19, 8, 204, 228, 112, 164, 189, 179, 124, 249, 1, 168, 110, 151, 50 |
| 627 | + ], |
| 628 | + Converter::<[u8; 32]>::convert(MultiLocation { |
| 629 | + parents: 1, |
| 630 | + interior: X2(Parachain(1), AccountKey20 { network: None, key: [0u8; 20] }), |
| 631 | + }).unwrap() |
| 632 | + ); |
| 633 | + assert_eq!( |
| 634 | + [ |
| 635 | + 254, 186, 179, 229, 13, 24, 84, 36, 84, 35, 64, 95, 114, 136, 62, 69, 247, |
| 636 | + 74, 215, 104, 121, 114, 53, 6, 124, 46, 42, 245, 121, 197, 12, 208 |
| 637 | + ], |
| 638 | + Converter::<[u8; 32]>::convert(MultiLocation { |
| 639 | + parents: 1, |
| 640 | + interior: X2(Parachain(2), PalletInstance(3)), |
| 641 | + }).unwrap() |
| 642 | + ); |
| 643 | + assert_eq!( |
| 644 | + [ |
| 645 | + 217, 56, 0, 36, 228, 154, 250, 26, 200, 156, 1, 39, 254, 162, 16, 187, 107, |
| 646 | + 67, 27, 16, 218, 254, 250, 184, 6, 27, 216, 138, 194, 93, 23, 165 |
| 647 | + ], |
| 648 | + Converter::<[u8; 32]>::convert(MultiLocation { |
| 649 | + parents: 1, |
| 650 | + interior: Here, |
| 651 | + }).unwrap() |
| 652 | + ); |
| 653 | + } |
544 | 654 | }
|
0 commit comments