diff --git a/CHANGELOG.md b/CHANGELOG.md
index a96475d830..48939176a2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+## [Unreleased]
+
+### Added
+
+- Location conversion tests for relays and parachains ([polkadot-fellows/runtimes#487](https://github.com/polkadot-fellows/runtimes/pull/487))
+
Changelog for the runtimes governed by the Polkadot Fellowship.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
diff --git a/relay/kusama/tests/location_conversion.rs b/relay/kusama/tests/location_conversion.rs
new file mode 100644
index 0000000000..d5c3557c32
--- /dev/null
+++ b/relay/kusama/tests/location_conversion.rs
@@ -0,0 +1,99 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Polkadot.
+
+// Polkadot is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Polkadot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Polkadot. If not, see .
+
+use polkadot_primitives::AccountId;
+use sp_core::crypto::Ss58Codec;
+use staging_kusama_runtime::xcm_config::SovereignAccountOf;
+use xcm::prelude::*;
+use xcm_runtime_apis::conversions::LocationToAccountHelper;
+
+const ALICE: [u8; 32] = [1u8; 32];
+
+#[test]
+fn location_conversion_works() {
+ // the purpose of hardcoded values is to catch an unintended location conversion logic change.
+ struct TestCase {
+ description: &'static str,
+ location: Location,
+ expected_account_id_str: &'static str,
+ }
+
+ let test_cases = vec![
+ // DescribeTerminus
+ TestCase {
+ description: "DescribeTerminus Child",
+ location: Location::new(0, [Parachain(1111)]),
+ expected_account_id_str: "5Ec4AhP4h37t7TFsAZ4HhFq6k92usAAJDUC3ADSZ4H4Acru3",
+ },
+ // DescribePalletTerminal
+ TestCase {
+ description: "DescribePalletTerminal Child",
+ location: Location::new(0, [Parachain(1111), PalletInstance(50)]),
+ expected_account_id_str: "5FjEBrKn3STAFsZpQF4jzwxUYHNGnNgzdZqSQfTzeJ82XKp6",
+ },
+ // DescribeAccountId32Terminal
+ TestCase {
+ description: "DescribeAccountId32Terminal Child",
+ location: Location::new(
+ 0,
+ [
+ Parachain(1111),
+ Junction::AccountId32 { network: None, id: AccountId::from(ALICE).into() },
+ ],
+ ),
+ expected_account_id_str: "5D6CDyPd9Mya81xFN3nChiKqLvUzd8zS9fwKhfCW6FtJKjS2",
+ },
+ // DescribeAccountKey20Terminal
+ TestCase {
+ description: "DescribeAccountKey20Terminal Sibling",
+ location: Location::new(
+ 0,
+ [Parachain(1111), AccountKey20 { network: None, key: [123u8; 20] }],
+ ),
+ expected_account_id_str: "5DEZsy7tsnNXB7ehLGkF8b4EUqfLQWqEzGiy2RrneC8uRNMK",
+ },
+ // DescribeTreasuryVoiceTerminal
+ TestCase {
+ description: "DescribeTreasuryVoiceTerminal Child",
+ location: Location::new(
+ 0,
+ [Parachain(1111), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5GenE4vJgHvwYVcD6b4nBvH5HNY4pzpVHWoqwFpNMFT7a2oX",
+ },
+ // DescribeBodyTerminal
+ TestCase {
+ description: "DescribeBodyTerminal Child",
+ location: Location::new(
+ 0,
+ [Parachain(1111), Plurality { id: BodyId::Unit, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5DPgGBFTTYm1dGbtB1VWHJ3T3ScvdrskGGx6vSJZNP1WNStV",
+ },
+ ];
+
+ for tc in test_cases {
+ let expected =
+ AccountId::from_string(tc.expected_account_id_str).expect("Invalid AccountId string");
+
+ let got = LocationToAccountHelper::::convert_location(
+ tc.location.into(),
+ )
+ .unwrap();
+
+ assert_eq!(got, expected, "{}", tc.description);
+ }
+}
diff --git a/relay/polkadot/tests/location_conversion.rs b/relay/polkadot/tests/location_conversion.rs
new file mode 100644
index 0000000000..bfa899bf5f
--- /dev/null
+++ b/relay/polkadot/tests/location_conversion.rs
@@ -0,0 +1,99 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Polkadot.
+
+// Polkadot is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Polkadot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Polkadot. If not, see .
+
+use polkadot_primitives::AccountId;
+use polkadot_runtime::xcm_config::SovereignAccountOf;
+use sp_core::crypto::Ss58Codec;
+use xcm::prelude::*;
+use xcm_runtime_apis::conversions::LocationToAccountHelper;
+
+const ALICE: [u8; 32] = [1u8; 32];
+
+#[test]
+fn location_conversion_works() {
+ // the purpose of hardcoded values is to catch an unintended location conversion logic change.
+ struct TestCase {
+ description: &'static str,
+ location: Location,
+ expected_account_id_str: &'static str,
+ }
+
+ let test_cases = vec![
+ // DescribeTerminus
+ TestCase {
+ description: "DescribeTerminus Child",
+ location: Location::new(0, [Parachain(1111)]),
+ expected_account_id_str: "5Ec4AhP4h37t7TFsAZ4HhFq6k92usAAJDUC3ADSZ4H4Acru3",
+ },
+ // DescribePalletTerminal
+ TestCase {
+ description: "DescribePalletTerminal Child",
+ location: Location::new(0, [Parachain(1111), PalletInstance(50)]),
+ expected_account_id_str: "5FjEBrKn3STAFsZpQF4jzwxUYHNGnNgzdZqSQfTzeJ82XKp6",
+ },
+ // DescribeAccountId32Terminal
+ TestCase {
+ description: "DescribeAccountId32Terminal Child",
+ location: Location::new(
+ 0,
+ [
+ Parachain(1111),
+ Junction::AccountId32 { network: None, id: AccountId::from(ALICE).into() },
+ ],
+ ),
+ expected_account_id_str: "5D6CDyPd9Mya81xFN3nChiKqLvUzd8zS9fwKhfCW6FtJKjS2",
+ },
+ // DescribeAccountKey20Terminal
+ TestCase {
+ description: "DescribeAccountKey20Terminal Child",
+ location: Location::new(
+ 0,
+ [Parachain(1111), AccountKey20 { network: None, key: [123u8; 20] }],
+ ),
+ expected_account_id_str: "5DEZsy7tsnNXB7ehLGkF8b4EUqfLQWqEzGiy2RrneC8uRNMK",
+ },
+ // DescribeTreasuryVoiceTerminal
+ TestCase {
+ description: "DescribeTreasuryVoiceTerminal Child",
+ location: Location::new(
+ 0,
+ [Parachain(1111), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5GenE4vJgHvwYVcD6b4nBvH5HNY4pzpVHWoqwFpNMFT7a2oX",
+ },
+ // DescribeBodyTerminal
+ TestCase {
+ description: "DescribeBodyTerminal Child",
+ location: Location::new(
+ 0,
+ [Parachain(1111), Plurality { id: BodyId::Unit, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5DPgGBFTTYm1dGbtB1VWHJ3T3ScvdrskGGx6vSJZNP1WNStV",
+ },
+ ];
+
+ for tc in test_cases {
+ let expected =
+ AccountId::from_string(tc.expected_account_id_str).expect("Invalid AccountId string");
+
+ let got = LocationToAccountHelper::::convert_location(
+ tc.location.into(),
+ )
+ .unwrap();
+
+ assert_eq!(got, expected, "{}", tc.description);
+ }
+}
diff --git a/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs b/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs
index 4ae5e17a73..13907fa8e1 100644
--- a/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs
+++ b/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs
@@ -37,6 +37,7 @@ use frame_support::{assert_ok, traits::fungibles::InspectEnumerable};
use parachains_common::{AccountId, AssetIdForTrustBackedAssets, AuraId, Balance};
use parachains_runtimes_test_utils::SlotDurations;
use sp_consensus_aura::SlotDuration;
+use sp_core::crypto::Ss58Codec;
use sp_runtime::traits::MaybeEquivalence;
use sp_std::ops::Mul;
use system_parachains_constants::kusama::{
@@ -45,6 +46,7 @@ use system_parachains_constants::kusama::{
use xcm::latest::prelude::{Assets as XcmAssets, *};
use xcm_builder::WithLatestLocationConverter;
use xcm_executor::traits::{ConvertLocation, JustTry};
+use xcm_runtime_apis::conversions::LocationToAccountHelper;
const ALICE: [u8; 32] = [1u8; 32];
const SOME_ASSET_ADMIN: [u8; 32] = [5u8; 32];
@@ -1303,3 +1305,104 @@ pub mod remove_when_updated_to_stable2409 {
})
}
}
+
+#[test]
+fn location_conversion_works() {
+ let alice_32 =
+ AccountId32 { network: None, id: polkadot_core_primitives::AccountId::from(ALICE).into() };
+ let bob_20 = AccountKey20 { network: None, key: [123u8; 20] };
+
+ // the purpose of hardcoded values is to catch an unintended location conversion logic change.
+ struct TestCase {
+ description: &'static str,
+ location: Location,
+ expected_account_id_str: &'static str,
+ }
+
+ let test_cases = vec![
+ // DescribeTerminus
+ TestCase {
+ description: "DescribeTerminus Parent",
+ location: Location::new(1, Here),
+ expected_account_id_str: "5Dt6dpkWPwLaH4BBCKJwjiWrFVAGyYk3tLUabvyn4v7KtESG",
+ },
+ TestCase {
+ description: "DescribeTerminus Sibling",
+ location: Location::new(1, [Parachain(1111)]),
+ expected_account_id_str: "5Eg2fnssmmJnF3z1iZ1NouAuzciDaaDQH7qURAy3w15jULDk",
+ },
+ // DescribePalletTerminal
+ TestCase {
+ description: "DescribePalletTerminal Parent",
+ location: Location::new(1, [PalletInstance(50)]),
+ expected_account_id_str: "5CnwemvaAXkWFVwibiCvf2EjqwiqBi29S5cLLydZLEaEw6jZ",
+ },
+ TestCase {
+ description: "DescribePalletTerminal Sibling",
+ location: Location::new(1, [Parachain(1111), PalletInstance(50)]),
+ expected_account_id_str: "5GFBgPjpEQPdaxEnFirUoa51u5erVx84twYxJVuBRAT2UP2g",
+ },
+ // DescribeAccountId32Terminal
+ TestCase {
+ description: "DescribeAccountId32Terminal Parent",
+ location: Location::new(1, [alice_32]),
+ expected_account_id_str: "5DN5SGsuUG7PAqFL47J9meViwdnk9AdeSWKFkcHC45hEzVz4",
+ },
+ TestCase {
+ description: "DescribeAccountId32Terminal Sibling",
+ location: Location::new(1, [Parachain(1111), alice_32]),
+ expected_account_id_str: "5DGRXLYwWGce7wvm14vX1Ms4Vf118FSWQbJkyQigY2pfm6bg",
+ },
+ // DescribeAccountKey20Terminal
+ TestCase {
+ description: "DescribeAccountKey20Terminal Parent",
+ location: Location::new(1, [bob_20]),
+ expected_account_id_str: "5CJeW9bdeos6EmaEofTUiNrvyVobMBfWbdQvhTe6UciGjH2n",
+ },
+ TestCase {
+ description: "DescribeAccountKey20Terminal Sibling",
+ location: Location::new(1, [Parachain(1111), bob_20]),
+ expected_account_id_str: "5CE6V5AKH8H4rg2aq5KMbvaVUDMumHKVPPQEEDMHPy3GmJQp",
+ },
+ // DescribeTreasuryVoiceTerminal
+ TestCase {
+ description: "DescribeTreasuryVoiceTerminal Parent",
+ location: Location::new(1, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]),
+ expected_account_id_str: "5CUjnE2vgcUCuhxPwFoQ5r7p1DkhujgvMNDHaF2bLqRp4D5F",
+ },
+ TestCase {
+ description: "DescribeTreasuryVoiceTerminal Sibling",
+ location: Location::new(
+ 1,
+ [Parachain(1111), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5G6TDwaVgbWmhqRUKjBhRRnH4ry9L9cjRymUEmiRsLbSE4gB",
+ },
+ // DescribeBodyTerminal
+ TestCase {
+ description: "DescribeBodyTerminal Parent",
+ location: Location::new(1, [Plurality { id: BodyId::Unit, part: BodyPart::Voice }]),
+ expected_account_id_str: "5EBRMTBkDisEXsaN283SRbzx9Xf2PXwUxxFCJohSGo4jYe6B",
+ },
+ TestCase {
+ description: "DescribeBodyTerminal Sibling",
+ location: Location::new(
+ 1,
+ [Parachain(1111), Plurality { id: BodyId::Unit, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5DBoExvojy8tYnHgLL97phNH975CyT45PWTZEeGoBZfAyRMH",
+ },
+ ];
+
+ for tc in test_cases {
+ let expected = polkadot_core_primitives::AccountId::from_string(tc.expected_account_id_str)
+ .expect("Invalid AccountId string");
+
+ let got = LocationToAccountHelper::::convert_location(
+ tc.location.into(),
+ )
+ .unwrap();
+
+ assert_eq!(got, expected, "{}", tc.description);
+ }
+}
diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs b/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs
index 63cb71cfad..4cb83a2b0d 100644
--- a/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs
+++ b/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs
@@ -39,6 +39,7 @@ use parachains_common::{
};
use parachains_runtimes_test_utils::SlotDurations;
use sp_consensus_aura::SlotDuration;
+use sp_core::crypto::Ss58Codec;
use sp_runtime::traits::MaybeEquivalence;
use sp_std::ops::Mul;
use system_parachains_constants::{
@@ -47,6 +48,7 @@ use system_parachains_constants::{
use xcm::latest::prelude::{Assets as XcmAssets, *};
use xcm_builder::WithLatestLocationConverter;
use xcm_executor::traits::{ConvertLocation, JustTry};
+use xcm_runtime_apis::conversions::LocationToAccountHelper;
const ALICE: [u8; 32] = [1u8; 32];
const SOME_ASSET_ADMIN: [u8; 32] = [5u8; 32];
@@ -1327,3 +1329,104 @@ pub mod remove_when_updated_to_stable2409 {
})
}
}
+
+#[test]
+fn location_conversion_works() {
+ let alice_32 =
+ AccountId32 { network: None, id: polkadot_core_primitives::AccountId::from(ALICE).into() };
+ let bob_20 = AccountKey20 { network: None, key: [123u8; 20] };
+
+ // the purpose of hardcoded values is to catch an unintended location conversion logic change.
+ struct TestCase {
+ description: &'static str,
+ location: Location,
+ expected_account_id_str: &'static str,
+ }
+
+ let test_cases = vec![
+ // DescribeTerminus
+ TestCase {
+ description: "DescribeTerminus Parent",
+ location: Location::new(1, Here),
+ expected_account_id_str: "5Dt6dpkWPwLaH4BBCKJwjiWrFVAGyYk3tLUabvyn4v7KtESG",
+ },
+ TestCase {
+ description: "DescribeTerminus Sibling",
+ location: Location::new(1, [Parachain(1111)]),
+ expected_account_id_str: "5Eg2fnssmmJnF3z1iZ1NouAuzciDaaDQH7qURAy3w15jULDk",
+ },
+ // DescribePalletTerminal
+ TestCase {
+ description: "DescribePalletTerminal Parent",
+ location: Location::new(1, [PalletInstance(50)]),
+ expected_account_id_str: "5CnwemvaAXkWFVwibiCvf2EjqwiqBi29S5cLLydZLEaEw6jZ",
+ },
+ TestCase {
+ description: "DescribePalletTerminal Sibling",
+ location: Location::new(1, [Parachain(1111), PalletInstance(50)]),
+ expected_account_id_str: "5GFBgPjpEQPdaxEnFirUoa51u5erVx84twYxJVuBRAT2UP2g",
+ },
+ // DescribeAccountId32Terminal
+ TestCase {
+ description: "DescribeAccountId32Terminal Parent",
+ location: Location::new(1, [alice_32]),
+ expected_account_id_str: "5DN5SGsuUG7PAqFL47J9meViwdnk9AdeSWKFkcHC45hEzVz4",
+ },
+ TestCase {
+ description: "DescribeAccountId32Terminal Sibling",
+ location: Location::new(1, [Parachain(1111), alice_32]),
+ expected_account_id_str: "5DGRXLYwWGce7wvm14vX1Ms4Vf118FSWQbJkyQigY2pfm6bg",
+ },
+ // DescribeAccountKey20Terminal
+ TestCase {
+ description: "DescribeAccountKey20Terminal Parent",
+ location: Location::new(1, [bob_20]),
+ expected_account_id_str: "5CJeW9bdeos6EmaEofTUiNrvyVobMBfWbdQvhTe6UciGjH2n",
+ },
+ TestCase {
+ description: "DescribeAccountKey20Terminal Sibling",
+ location: Location::new(1, [Parachain(1111), bob_20]),
+ expected_account_id_str: "5CE6V5AKH8H4rg2aq5KMbvaVUDMumHKVPPQEEDMHPy3GmJQp",
+ },
+ // DescribeTreasuryVoiceTerminal
+ TestCase {
+ description: "DescribeTreasuryVoiceTerminal Parent",
+ location: Location::new(1, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]),
+ expected_account_id_str: "5CUjnE2vgcUCuhxPwFoQ5r7p1DkhujgvMNDHaF2bLqRp4D5F",
+ },
+ TestCase {
+ description: "DescribeTreasuryVoiceTerminal Sibling",
+ location: Location::new(
+ 1,
+ [Parachain(1111), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5G6TDwaVgbWmhqRUKjBhRRnH4ry9L9cjRymUEmiRsLbSE4gB",
+ },
+ // DescribeBodyTerminal
+ TestCase {
+ description: "DescribeBodyTerminal Parent",
+ location: Location::new(1, [Plurality { id: BodyId::Unit, part: BodyPart::Voice }]),
+ expected_account_id_str: "5EBRMTBkDisEXsaN283SRbzx9Xf2PXwUxxFCJohSGo4jYe6B",
+ },
+ TestCase {
+ description: "DescribeBodyTerminal Sibling",
+ location: Location::new(
+ 1,
+ [Parachain(1111), Plurality { id: BodyId::Unit, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5DBoExvojy8tYnHgLL97phNH975CyT45PWTZEeGoBZfAyRMH",
+ },
+ ];
+
+ for tc in test_cases {
+ let expected = polkadot_core_primitives::AccountId::from_string(tc.expected_account_id_str)
+ .expect("Invalid AccountId string");
+
+ let got = LocationToAccountHelper::::convert_location(
+ tc.location.into(),
+ )
+ .unwrap();
+
+ assert_eq!(got, expected, "{}", tc.description);
+ }
+}
diff --git a/system-parachains/bridge-hubs/bridge-hub-kusama/tests/tests.rs b/system-parachains/bridge-hubs/bridge-hub-kusama/tests/tests.rs
index 805f8cb051..e2525e6d87 100644
--- a/system-parachains/bridge-hubs/bridge-hub-kusama/tests/tests.rs
+++ b/system-parachains/bridge-hubs/bridge-hub-kusama/tests/tests.rs
@@ -36,6 +36,7 @@ use codec::{Decode, Encode};
use frame_support::{dispatch::GetDispatchInfo, parameter_types, traits::ConstU8};
use parachains_common::{AccountId, AuraId, Balance};
use sp_consensus_aura::SlotDuration;
+use sp_core::crypto::Ss58Codec;
use sp_keyring::AccountKeyring::Alice;
use sp_runtime::{
generic::{Era, SignedPayload},
@@ -46,6 +47,7 @@ use system_parachains_constants::kusama::{
};
use xcm::latest::prelude::*;
use xcm_executor::traits::ConvertLocation;
+use xcm_runtime_apis::conversions::LocationToAccountHelper;
// Para id of sibling chain used in tests.
pub const SIBLING_PARACHAIN_ID: u32 = 1000;
@@ -367,3 +369,106 @@ fn treasury_pallet_account_not_none() {
LocationToAccountId::convert_location(&RelayTreasuryLocation::get()).unwrap()
)
}
+
+#[test]
+fn location_conversion_works() {
+ let alice_32 = xcm::prelude::AccountId32 {
+ network: None,
+ id: polkadot_core_primitives::AccountId::from(Alice).into(),
+ };
+ let bob_20 = AccountKey20 { network: None, key: [123u8; 20] };
+
+ // the purpose of hardcoded values is to catch an unintended location conversion logic change.
+ struct TestCase {
+ description: &'static str,
+ location: Location,
+ expected_account_id_str: &'static str,
+ }
+
+ let test_cases = vec![
+ // DescribeTerminus
+ TestCase {
+ description: "DescribeTerminus Parent",
+ location: Location::new(1, Here),
+ expected_account_id_str: "5Dt6dpkWPwLaH4BBCKJwjiWrFVAGyYk3tLUabvyn4v7KtESG",
+ },
+ TestCase {
+ description: "DescribeTerminus Sibling",
+ location: Location::new(1, [Parachain(1111)]),
+ expected_account_id_str: "5Eg2fnssmmJnF3z1iZ1NouAuzciDaaDQH7qURAy3w15jULDk",
+ },
+ // DescribePalletTerminal
+ TestCase {
+ description: "DescribePalletTerminal Parent",
+ location: Location::new(1, [PalletInstance(50)]),
+ expected_account_id_str: "5CnwemvaAXkWFVwibiCvf2EjqwiqBi29S5cLLydZLEaEw6jZ",
+ },
+ TestCase {
+ description: "DescribePalletTerminal Sibling",
+ location: Location::new(1, [Parachain(1111), PalletInstance(50)]),
+ expected_account_id_str: "5GFBgPjpEQPdaxEnFirUoa51u5erVx84twYxJVuBRAT2UP2g",
+ },
+ // DescribeAccountId32Terminal
+ TestCase {
+ description: "DescribeAccountId32Terminal Parent",
+ location: Location::new(1, [alice_32]),
+ expected_account_id_str: "5EueAXd4h8u75nSbFdDJbC29cmi4Uo1YJssqEL9idvindxFL",
+ },
+ TestCase {
+ description: "DescribeAccountId32Terminal Sibling",
+ location: Location::new(1, [Parachain(1111), alice_32]),
+ expected_account_id_str: "5Dmbuiq48fU4iW58FKYqoGbbfxFHjbAeGLMtjFg6NNCw3ssr",
+ },
+ // DescribeAccountKey20Terminal
+ TestCase {
+ description: "DescribeAccountKey20Terminal Parent",
+ location: Location::new(1, [bob_20]),
+ expected_account_id_str: "5CJeW9bdeos6EmaEofTUiNrvyVobMBfWbdQvhTe6UciGjH2n",
+ },
+ TestCase {
+ description: "DescribeAccountKey20Terminal Sibling",
+ location: Location::new(1, [Parachain(1111), bob_20]),
+ expected_account_id_str: "5CE6V5AKH8H4rg2aq5KMbvaVUDMumHKVPPQEEDMHPy3GmJQp",
+ },
+ // DescribeTreasuryVoiceTerminal
+ TestCase {
+ description: "DescribeTreasuryVoiceTerminal Parent",
+ location: Location::new(1, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]),
+ expected_account_id_str: "5CUjnE2vgcUCuhxPwFoQ5r7p1DkhujgvMNDHaF2bLqRp4D5F",
+ },
+ TestCase {
+ description: "DescribeTreasuryVoiceTerminal Sibling",
+ location: Location::new(
+ 1,
+ [Parachain(1111), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5G6TDwaVgbWmhqRUKjBhRRnH4ry9L9cjRymUEmiRsLbSE4gB",
+ },
+ // DescribeBodyTerminal
+ TestCase {
+ description: "DescribeBodyTerminal Parent",
+ location: Location::new(1, [Plurality { id: BodyId::Unit, part: BodyPart::Voice }]),
+ expected_account_id_str: "5EBRMTBkDisEXsaN283SRbzx9Xf2PXwUxxFCJohSGo4jYe6B",
+ },
+ TestCase {
+ description: "DescribeBodyTerminal Sibling",
+ location: Location::new(
+ 1,
+ [Parachain(1111), Plurality { id: BodyId::Unit, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5DBoExvojy8tYnHgLL97phNH975CyT45PWTZEeGoBZfAyRMH",
+ },
+ ];
+
+ for tc in test_cases {
+ let expected = polkadot_core_primitives::AccountId::from_string(tc.expected_account_id_str)
+ .expect("Invalid AccountId string");
+
+ let got = LocationToAccountHelper::::convert_location(
+ tc.location.into(),
+ )
+ .unwrap();
+
+ assert_eq!(got, expected, "{}", tc.description);
+ }
+}
diff --git a/system-parachains/bridge-hubs/bridge-hub-polkadot/tests/tests.rs b/system-parachains/bridge-hubs/bridge-hub-polkadot/tests/tests.rs
index c3301047cd..956604c200 100644
--- a/system-parachains/bridge-hubs/bridge-hub-polkadot/tests/tests.rs
+++ b/system-parachains/bridge-hubs/bridge-hub-polkadot/tests/tests.rs
@@ -37,6 +37,7 @@ use codec::{Decode, Encode};
use frame_support::{dispatch::GetDispatchInfo, parameter_types, traits::ConstU8};
use parachains_common::{AccountId, AuraId, Balance};
use sp_consensus_aura::SlotDuration;
+use sp_core::crypto::Ss58Codec;
use sp_keyring::AccountKeyring::Alice;
use sp_runtime::{
generic::{Era, SignedPayload},
@@ -47,6 +48,7 @@ use system_parachains_constants::polkadot::{
};
use xcm::latest::prelude::*;
use xcm_executor::traits::ConvertLocation;
+use xcm_runtime_apis::conversions::LocationToAccountHelper;
// Para id of sibling chain used in tests.
pub const SIBLING_PARACHAIN_ID: u32 = 1000;
@@ -368,3 +370,106 @@ fn treasury_pallet_account_not_none() {
LocationToAccountId::convert_location(&RelayTreasuryLocation::get()).unwrap()
)
}
+
+#[test]
+fn location_conversion_works() {
+ let alice_32 = xcm::prelude::AccountId32 {
+ network: None,
+ id: polkadot_core_primitives::AccountId::from(Alice).into(),
+ };
+ let bob_20 = AccountKey20 { network: None, key: [123u8; 20] };
+
+ // the purpose of hardcoded values is to catch an unintended location conversion logic change.
+ struct TestCase {
+ description: &'static str,
+ location: Location,
+ expected_account_id_str: &'static str,
+ }
+
+ let test_cases = vec![
+ // DescribeTerminus
+ TestCase {
+ description: "DescribeTerminus Parent",
+ location: Location::new(1, Here),
+ expected_account_id_str: "5Dt6dpkWPwLaH4BBCKJwjiWrFVAGyYk3tLUabvyn4v7KtESG",
+ },
+ TestCase {
+ description: "DescribeTerminus Sibling",
+ location: Location::new(1, [Parachain(1111)]),
+ expected_account_id_str: "5Eg2fnssmmJnF3z1iZ1NouAuzciDaaDQH7qURAy3w15jULDk",
+ },
+ // DescribePalletTerminal
+ TestCase {
+ description: "DescribePalletTerminal Parent",
+ location: Location::new(1, [PalletInstance(50)]),
+ expected_account_id_str: "5CnwemvaAXkWFVwibiCvf2EjqwiqBi29S5cLLydZLEaEw6jZ",
+ },
+ TestCase {
+ description: "DescribePalletTerminal Sibling",
+ location: Location::new(1, [Parachain(1111), PalletInstance(50)]),
+ expected_account_id_str: "5GFBgPjpEQPdaxEnFirUoa51u5erVx84twYxJVuBRAT2UP2g",
+ },
+ // DescribeAccountId32Terminal
+ TestCase {
+ description: "DescribeAccountId32Terminal Parent",
+ location: Location::new(1, [alice_32]),
+ expected_account_id_str: "5EueAXd4h8u75nSbFdDJbC29cmi4Uo1YJssqEL9idvindxFL",
+ },
+ TestCase {
+ description: "DescribeAccountId32Terminal Sibling",
+ location: Location::new(1, [Parachain(1111), alice_32]),
+ expected_account_id_str: "5Dmbuiq48fU4iW58FKYqoGbbfxFHjbAeGLMtjFg6NNCw3ssr",
+ },
+ // DescribeAccountKey20Terminal
+ TestCase {
+ description: "DescribeAccountKey20Terminal Parent",
+ location: Location::new(1, [bob_20]),
+ expected_account_id_str: "5CJeW9bdeos6EmaEofTUiNrvyVobMBfWbdQvhTe6UciGjH2n",
+ },
+ TestCase {
+ description: "DescribeAccountKey20Terminal Sibling",
+ location: Location::new(1, [Parachain(1111), bob_20]),
+ expected_account_id_str: "5CE6V5AKH8H4rg2aq5KMbvaVUDMumHKVPPQEEDMHPy3GmJQp",
+ },
+ // DescribeTreasuryVoiceTerminal
+ TestCase {
+ description: "DescribeTreasuryVoiceTerminal Parent",
+ location: Location::new(1, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]),
+ expected_account_id_str: "5CUjnE2vgcUCuhxPwFoQ5r7p1DkhujgvMNDHaF2bLqRp4D5F",
+ },
+ TestCase {
+ description: "DescribeTreasuryVoiceTerminal Sibling",
+ location: Location::new(
+ 1,
+ [Parachain(1111), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5G6TDwaVgbWmhqRUKjBhRRnH4ry9L9cjRymUEmiRsLbSE4gB",
+ },
+ // DescribeBodyTerminal
+ TestCase {
+ description: "DescribeBodyTerminal Parent",
+ location: Location::new(1, [Plurality { id: BodyId::Unit, part: BodyPart::Voice }]),
+ expected_account_id_str: "5EBRMTBkDisEXsaN283SRbzx9Xf2PXwUxxFCJohSGo4jYe6B",
+ },
+ TestCase {
+ description: "DescribeBodyTerminal Sibling",
+ location: Location::new(
+ 1,
+ [Parachain(1111), Plurality { id: BodyId::Unit, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5DBoExvojy8tYnHgLL97phNH975CyT45PWTZEeGoBZfAyRMH",
+ },
+ ];
+
+ for tc in test_cases {
+ let expected = polkadot_core_primitives::AccountId::from_string(tc.expected_account_id_str)
+ .expect("Invalid AccountId string");
+
+ let got = LocationToAccountHelper::::convert_location(
+ tc.location.into(),
+ )
+ .unwrap();
+
+ assert_eq!(got, expected, "{}", tc.description);
+ }
+}
diff --git a/system-parachains/collectives/collectives-polkadot/tests/location_conversion.rs b/system-parachains/collectives/collectives-polkadot/tests/location_conversion.rs
new file mode 100644
index 0000000000..21c3315916
--- /dev/null
+++ b/system-parachains/collectives/collectives-polkadot/tests/location_conversion.rs
@@ -0,0 +1,123 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Polkadot.
+
+// Polkadot is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Polkadot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Polkadot. If not, see .
+
+use collectives_polkadot_runtime::xcm_config::LocationToAccountId;
+use polkadot_core_primitives::AccountId;
+use sp_core::crypto::Ss58Codec;
+use xcm::prelude::*;
+use xcm_runtime_apis::conversions::LocationToAccountHelper;
+
+const ALICE: [u8; 32] = [1u8; 32];
+
+#[test]
+fn location_conversion_works() {
+ let alice_32 = AccountId32 { network: None, id: AccountId::from(ALICE).into() };
+ let bob_20 = AccountKey20 { network: None, key: [123u8; 20] };
+
+ // the purpose of hardcoded values is to catch an unintended location conversion logic change.
+ struct TestCase {
+ description: &'static str,
+ location: Location,
+ expected_account_id_str: &'static str,
+ }
+
+ let test_cases = vec![
+ // DescribeTerminus
+ TestCase {
+ description: "DescribeTerminus Parent",
+ location: Location::new(1, Here),
+ expected_account_id_str: "5Dt6dpkWPwLaH4BBCKJwjiWrFVAGyYk3tLUabvyn4v7KtESG",
+ },
+ TestCase {
+ description: "DescribeTerminus Sibling",
+ location: Location::new(1, [Parachain(1111)]),
+ expected_account_id_str: "5Eg2fnssmmJnF3z1iZ1NouAuzciDaaDQH7qURAy3w15jULDk",
+ },
+ // DescribePalletTerminal
+ TestCase {
+ description: "DescribePalletTerminal Parent",
+ location: Location::new(1, [PalletInstance(50)]),
+ expected_account_id_str: "5CnwemvaAXkWFVwibiCvf2EjqwiqBi29S5cLLydZLEaEw6jZ",
+ },
+ TestCase {
+ description: "DescribePalletTerminal Sibling",
+ location: Location::new(1, [Parachain(1111), PalletInstance(50)]),
+ expected_account_id_str: "5GFBgPjpEQPdaxEnFirUoa51u5erVx84twYxJVuBRAT2UP2g",
+ },
+ // DescribeAccountId32Terminal
+ TestCase {
+ description: "DescribeAccountId32Terminal Parent",
+ location: Location::new(1, [alice_32]),
+ expected_account_id_str: "5DN5SGsuUG7PAqFL47J9meViwdnk9AdeSWKFkcHC45hEzVz4",
+ },
+ TestCase {
+ description: "DescribeAccountId32Terminal Sibling",
+ location: Location::new(1, [Parachain(1111), alice_32]),
+ expected_account_id_str: "5DGRXLYwWGce7wvm14vX1Ms4Vf118FSWQbJkyQigY2pfm6bg",
+ },
+ // DescribeAccountKey20Terminal
+ TestCase {
+ description: "DescribeAccountKey20Terminal Parent",
+ location: Location::new(1, [bob_20]),
+ expected_account_id_str: "5CJeW9bdeos6EmaEofTUiNrvyVobMBfWbdQvhTe6UciGjH2n",
+ },
+ TestCase {
+ description: "DescribeAccountKey20Terminal Sibling",
+ location: Location::new(1, [Parachain(1111), bob_20]),
+ expected_account_id_str: "5CE6V5AKH8H4rg2aq5KMbvaVUDMumHKVPPQEEDMHPy3GmJQp",
+ },
+ // DescribeTreasuryVoiceTerminal
+ TestCase {
+ description: "DescribeTreasuryVoiceTerminal Parent",
+ location: Location::new(1, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]),
+ expected_account_id_str: "5CUjnE2vgcUCuhxPwFoQ5r7p1DkhujgvMNDHaF2bLqRp4D5F",
+ },
+ TestCase {
+ description: "DescribeTreasuryVoiceTerminal Sibling",
+ location: Location::new(
+ 1,
+ [Parachain(1111), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5G6TDwaVgbWmhqRUKjBhRRnH4ry9L9cjRymUEmiRsLbSE4gB",
+ },
+ // DescribeBodyTerminal
+ TestCase {
+ description: "DescribeBodyTerminal Parent",
+ location: Location::new(1, [Plurality { id: BodyId::Unit, part: BodyPart::Voice }]),
+ expected_account_id_str: "5EBRMTBkDisEXsaN283SRbzx9Xf2PXwUxxFCJohSGo4jYe6B",
+ },
+ TestCase {
+ description: "DescribeBodyTerminal Sibling",
+ location: Location::new(
+ 1,
+ [Parachain(1111), Plurality { id: BodyId::Unit, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5DBoExvojy8tYnHgLL97phNH975CyT45PWTZEeGoBZfAyRMH",
+ },
+ ];
+
+ for tc in test_cases {
+ let expected =
+ AccountId::from_string(tc.expected_account_id_str).expect("Invalid AccountId string");
+
+ let got = LocationToAccountHelper::::convert_location(
+ tc.location.into(),
+ )
+ .unwrap();
+
+ assert_eq!(got, expected, "{}", tc.description);
+ }
+}
diff --git a/system-parachains/coretime/coretime-kusama/src/tests.rs b/system-parachains/coretime/coretime-kusama/src/tests.rs
index 0253477c2e..0ccccbdac4 100644
--- a/system-parachains/coretime/coretime-kusama/src/tests.rs
+++ b/system-parachains/coretime/coretime-kusama/src/tests.rs
@@ -16,6 +16,7 @@
use crate::{
coretime::{BrokerPalletId, CoretimeBurnAccount},
+ xcm_config::LocationToAccountId,
*,
};
use coretime::CoretimeAllocator;
@@ -29,7 +30,11 @@ use frame_support::{
use kusama_runtime_constants::system_parachain::coretime::TIMESLICE_PERIOD;
use pallet_broker::{ConfigRecordOf, RCBlockNumberOf, SaleInfo};
use parachains_runtimes_test_utils::ExtBuilder;
+use sp_core::crypto::Ss58Codec;
use sp_runtime::traits::AccountIdConversion;
+use xcm_runtime_apis::conversions::LocationToAccountHelper;
+
+const ALICE: [u8; 32] = [1u8; 32];
fn advance_to(b: BlockNumber) {
while System::block_number() < b {
@@ -41,8 +46,6 @@ fn advance_to(b: BlockNumber) {
#[test]
fn bulk_revenue_is_burnt() {
- const ALICE: [u8; 32] = [1u8; 32];
-
ExtBuilder::::default()
.with_collators(vec![AccountId::from(ALICE)])
.with_session_keys(vec![(
@@ -110,3 +113,104 @@ fn timeslice_period_is_sane() {
#[cfg(not(feature = "fast-runtime"))]
assert_eq!(TIMESLICE_PERIOD, 80);
}
+
+#[test]
+fn location_conversion_works() {
+ let alice_32 =
+ AccountId32 { network: None, id: polkadot_core_primitives::AccountId::from(ALICE).into() };
+ let bob_20 = AccountKey20 { network: None, key: [123u8; 20] };
+
+ // the purpose of hardcoded values is to catch an unintended location conversion logic change.
+ struct TestCase {
+ description: &'static str,
+ location: Location,
+ expected_account_id_str: &'static str,
+ }
+
+ let test_cases = vec![
+ // DescribeTerminus
+ TestCase {
+ description: "DescribeTerminus Parent",
+ location: Location::new(1, Here),
+ expected_account_id_str: "5Dt6dpkWPwLaH4BBCKJwjiWrFVAGyYk3tLUabvyn4v7KtESG",
+ },
+ TestCase {
+ description: "DescribeTerminus Sibling",
+ location: Location::new(1, [Parachain(1111)]),
+ expected_account_id_str: "5Eg2fnssmmJnF3z1iZ1NouAuzciDaaDQH7qURAy3w15jULDk",
+ },
+ // DescribePalletTerminal
+ TestCase {
+ description: "DescribePalletTerminal Parent",
+ location: Location::new(1, [PalletInstance(50)]),
+ expected_account_id_str: "5CnwemvaAXkWFVwibiCvf2EjqwiqBi29S5cLLydZLEaEw6jZ",
+ },
+ TestCase {
+ description: "DescribePalletTerminal Sibling",
+ location: Location::new(1, [Parachain(1111), PalletInstance(50)]),
+ expected_account_id_str: "5GFBgPjpEQPdaxEnFirUoa51u5erVx84twYxJVuBRAT2UP2g",
+ },
+ // DescribeAccountId32Terminal
+ TestCase {
+ description: "DescribeAccountId32Terminal Parent",
+ location: Location::new(1, [alice_32]),
+ expected_account_id_str: "5DN5SGsuUG7PAqFL47J9meViwdnk9AdeSWKFkcHC45hEzVz4",
+ },
+ TestCase {
+ description: "DescribeAccountId32Terminal Sibling",
+ location: Location::new(1, [Parachain(1111), alice_32]),
+ expected_account_id_str: "5DGRXLYwWGce7wvm14vX1Ms4Vf118FSWQbJkyQigY2pfm6bg",
+ },
+ // DescribeAccountKey20Terminal
+ TestCase {
+ description: "DescribeAccountKey20Terminal Parent",
+ location: Location::new(1, [bob_20]),
+ expected_account_id_str: "5CJeW9bdeos6EmaEofTUiNrvyVobMBfWbdQvhTe6UciGjH2n",
+ },
+ TestCase {
+ description: "DescribeAccountKey20Terminal Sibling",
+ location: Location::new(1, [Parachain(1111), bob_20]),
+ expected_account_id_str: "5CE6V5AKH8H4rg2aq5KMbvaVUDMumHKVPPQEEDMHPy3GmJQp",
+ },
+ // DescribeTreasuryVoiceTerminal
+ TestCase {
+ description: "DescribeTreasuryVoiceTerminal Parent",
+ location: Location::new(1, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]),
+ expected_account_id_str: "5CUjnE2vgcUCuhxPwFoQ5r7p1DkhujgvMNDHaF2bLqRp4D5F",
+ },
+ TestCase {
+ description: "DescribeTreasuryVoiceTerminal Sibling",
+ location: Location::new(
+ 1,
+ [Parachain(1111), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5G6TDwaVgbWmhqRUKjBhRRnH4ry9L9cjRymUEmiRsLbSE4gB",
+ },
+ // DescribeBodyTerminal
+ TestCase {
+ description: "DescribeBodyTerminal Parent",
+ location: Location::new(1, [Plurality { id: BodyId::Unit, part: BodyPart::Voice }]),
+ expected_account_id_str: "5EBRMTBkDisEXsaN283SRbzx9Xf2PXwUxxFCJohSGo4jYe6B",
+ },
+ TestCase {
+ description: "DescribeBodyTerminal Sibling",
+ location: Location::new(
+ 1,
+ [Parachain(1111), Plurality { id: BodyId::Unit, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5DBoExvojy8tYnHgLL97phNH975CyT45PWTZEeGoBZfAyRMH",
+ },
+ ];
+
+ for tc in test_cases {
+ let expected = polkadot_core_primitives::AccountId::from_string(tc.expected_account_id_str)
+ .expect("Invalid AccountId string");
+
+ let got = LocationToAccountHelper::::convert_location(
+ tc.location.into(),
+ )
+ .unwrap();
+
+ assert_eq!(got, expected, "{}", tc.description);
+ }
+}
diff --git a/system-parachains/coretime/coretime-polkadot/src/tests.rs b/system-parachains/coretime/coretime-polkadot/src/tests.rs
index 3ec85da4b2..cb5a4217c6 100644
--- a/system-parachains/coretime/coretime-polkadot/src/tests.rs
+++ b/system-parachains/coretime/coretime-polkadot/src/tests.rs
@@ -16,6 +16,7 @@
use crate::{
coretime::{BrokerPalletId, CoretimeBurnAccount},
+ xcm_config::LocationToAccountId,
*,
};
use coretime::CoretimeAllocator;
@@ -29,7 +30,11 @@ use frame_support::{
use pallet_broker::{ConfigRecordOf, RCBlockNumberOf, SaleInfo};
use parachains_runtimes_test_utils::ExtBuilder;
use polkadot_runtime_constants::system_parachain::coretime::TIMESLICE_PERIOD;
+use sp_core::crypto::Ss58Codec;
use sp_runtime::traits::AccountIdConversion;
+use xcm_runtime_apis::conversions::LocationToAccountHelper;
+
+const ALICE: [u8; 32] = [1u8; 32];
fn advance_to(b: BlockNumber) {
while System::block_number() < b {
@@ -41,8 +46,6 @@ fn advance_to(b: BlockNumber) {
#[test]
fn bulk_revenue_is_burnt() {
- const ALICE: [u8; 32] = [1u8; 32];
-
ExtBuilder::::default()
.with_collators(vec![AccountId::from(ALICE)])
.with_session_keys(vec![(
@@ -110,3 +113,104 @@ fn timeslice_period_is_sane() {
#[cfg(not(feature = "fast-runtime"))]
assert_eq!(TIMESLICE_PERIOD, 80);
}
+
+#[test]
+fn location_conversion_works() {
+ let alice_32 =
+ AccountId32 { network: None, id: polkadot_core_primitives::AccountId::from(ALICE).into() };
+ let bob_20 = AccountKey20 { network: None, key: [123u8; 20] };
+
+ // the purpose of hardcoded values is to catch an unintended location conversion logic change.
+ struct TestCase {
+ description: &'static str,
+ location: Location,
+ expected_account_id_str: &'static str,
+ }
+
+ let test_cases = vec![
+ // DescribeTerminus
+ TestCase {
+ description: "DescribeTerminus Parent",
+ location: Location::new(1, Here),
+ expected_account_id_str: "5Dt6dpkWPwLaH4BBCKJwjiWrFVAGyYk3tLUabvyn4v7KtESG",
+ },
+ TestCase {
+ description: "DescribeTerminus Sibling",
+ location: Location::new(1, [Parachain(1111)]),
+ expected_account_id_str: "5Eg2fnssmmJnF3z1iZ1NouAuzciDaaDQH7qURAy3w15jULDk",
+ },
+ // DescribePalletTerminal
+ TestCase {
+ description: "DescribePalletTerminal Parent",
+ location: Location::new(1, [PalletInstance(50)]),
+ expected_account_id_str: "5CnwemvaAXkWFVwibiCvf2EjqwiqBi29S5cLLydZLEaEw6jZ",
+ },
+ TestCase {
+ description: "DescribePalletTerminal Sibling",
+ location: Location::new(1, [Parachain(1111), PalletInstance(50)]),
+ expected_account_id_str: "5GFBgPjpEQPdaxEnFirUoa51u5erVx84twYxJVuBRAT2UP2g",
+ },
+ // DescribeAccountId32Terminal
+ TestCase {
+ description: "DescribeAccountId32Terminal Parent",
+ location: Location::new(1, [alice_32]),
+ expected_account_id_str: "5DN5SGsuUG7PAqFL47J9meViwdnk9AdeSWKFkcHC45hEzVz4",
+ },
+ TestCase {
+ description: "DescribeAccountId32Terminal Sibling",
+ location: Location::new(1, [Parachain(1111), alice_32]),
+ expected_account_id_str: "5DGRXLYwWGce7wvm14vX1Ms4Vf118FSWQbJkyQigY2pfm6bg",
+ },
+ // DescribeAccountKey20Terminal
+ TestCase {
+ description: "DescribeAccountKey20Terminal Parent",
+ location: Location::new(1, [bob_20]),
+ expected_account_id_str: "5CJeW9bdeos6EmaEofTUiNrvyVobMBfWbdQvhTe6UciGjH2n",
+ },
+ TestCase {
+ description: "DescribeAccountKey20Terminal Sibling",
+ location: Location::new(1, [Parachain(1111), bob_20]),
+ expected_account_id_str: "5CE6V5AKH8H4rg2aq5KMbvaVUDMumHKVPPQEEDMHPy3GmJQp",
+ },
+ // DescribeTreasuryVoiceTerminal
+ TestCase {
+ description: "DescribeTreasuryVoiceTerminal Parent",
+ location: Location::new(1, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]),
+ expected_account_id_str: "5CUjnE2vgcUCuhxPwFoQ5r7p1DkhujgvMNDHaF2bLqRp4D5F",
+ },
+ TestCase {
+ description: "DescribeTreasuryVoiceTerminal Sibling",
+ location: Location::new(
+ 1,
+ [Parachain(1111), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5G6TDwaVgbWmhqRUKjBhRRnH4ry9L9cjRymUEmiRsLbSE4gB",
+ },
+ // DescribeBodyTerminal
+ TestCase {
+ description: "DescribeBodyTerminal Parent",
+ location: Location::new(1, [Plurality { id: BodyId::Unit, part: BodyPart::Voice }]),
+ expected_account_id_str: "5EBRMTBkDisEXsaN283SRbzx9Xf2PXwUxxFCJohSGo4jYe6B",
+ },
+ TestCase {
+ description: "DescribeBodyTerminal Sibling",
+ location: Location::new(
+ 1,
+ [Parachain(1111), Plurality { id: BodyId::Unit, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5DBoExvojy8tYnHgLL97phNH975CyT45PWTZEeGoBZfAyRMH",
+ },
+ ];
+
+ for tc in test_cases {
+ let expected = polkadot_core_primitives::AccountId::from_string(tc.expected_account_id_str)
+ .expect("Invalid AccountId string");
+
+ let got = LocationToAccountHelper::::convert_location(
+ tc.location.into(),
+ )
+ .unwrap();
+
+ assert_eq!(got, expected, "{}", tc.description);
+ }
+}
diff --git a/system-parachains/people/people-kusama/src/lib.rs b/system-parachains/people/people-kusama/src/lib.rs
index 619cd0422d..3390839256 100644
--- a/system-parachains/people/people-kusama/src/lib.rs
+++ b/system-parachains/people/people-kusama/src/lib.rs
@@ -21,6 +21,8 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
// Genesis preset configurations.
pub mod genesis_config_presets;
pub mod people;
+#[cfg(test)]
+mod tests;
mod weights;
pub mod xcm_config;
diff --git a/system-parachains/people/people-kusama/src/tests.rs b/system-parachains/people/people-kusama/src/tests.rs
new file mode 100644
index 0000000000..7b459977e6
--- /dev/null
+++ b/system-parachains/people/people-kusama/src/tests.rs
@@ -0,0 +1,123 @@
+// Copyright (C) Parity Technologies and the various Polkadot contributors, see Contributions.md
+// for a list of specific contributors.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use crate::xcm_config::LocationToAccountId;
+use polkadot_primitives::AccountId;
+use sp_core::crypto::Ss58Codec;
+use xcm::prelude::*;
+use xcm_runtime_apis::conversions::LocationToAccountHelper;
+
+const ALICE: [u8; 32] = [1u8; 32];
+
+#[test]
+fn location_conversion_works() {
+ let alice_32 = AccountId32 { network: None, id: AccountId::from(ALICE).into() };
+ let bob_20 = AccountKey20 { network: None, key: [123u8; 20] };
+
+ // the purpose of hardcoded values is to catch an unintended location conversion logic change.
+ struct TestCase {
+ description: &'static str,
+ location: Location,
+ expected_account_id_str: &'static str,
+ }
+
+ let test_cases = vec![
+ // DescribeTerminus
+ TestCase {
+ description: "DescribeTerminus Parent",
+ location: Location::new(1, Here),
+ expected_account_id_str: "5Dt6dpkWPwLaH4BBCKJwjiWrFVAGyYk3tLUabvyn4v7KtESG",
+ },
+ TestCase {
+ description: "DescribeTerminus Sibling",
+ location: Location::new(1, [Parachain(1111)]),
+ expected_account_id_str: "5Eg2fnssmmJnF3z1iZ1NouAuzciDaaDQH7qURAy3w15jULDk",
+ },
+ // DescribePalletTerminal
+ TestCase {
+ description: "DescribePalletTerminal Parent",
+ location: Location::new(1, [PalletInstance(50)]),
+ expected_account_id_str: "5CnwemvaAXkWFVwibiCvf2EjqwiqBi29S5cLLydZLEaEw6jZ",
+ },
+ TestCase {
+ description: "DescribePalletTerminal Sibling",
+ location: Location::new(1, [Parachain(1111), PalletInstance(50)]),
+ expected_account_id_str: "5GFBgPjpEQPdaxEnFirUoa51u5erVx84twYxJVuBRAT2UP2g",
+ },
+ // DescribeAccountId32Terminal
+ TestCase {
+ description: "DescribeAccountId32Terminal Parent",
+ location: Location::new(1, [alice_32]),
+ expected_account_id_str: "5DN5SGsuUG7PAqFL47J9meViwdnk9AdeSWKFkcHC45hEzVz4",
+ },
+ TestCase {
+ description: "DescribeAccountId32Terminal Sibling",
+ location: Location::new(1, [Parachain(1111), alice_32]),
+ expected_account_id_str: "5DGRXLYwWGce7wvm14vX1Ms4Vf118FSWQbJkyQigY2pfm6bg",
+ },
+ // DescribeAccountKey20Terminal
+ TestCase {
+ description: "DescribeAccountKey20Terminal Parent",
+ location: Location::new(1, [bob_20]),
+ expected_account_id_str: "5CJeW9bdeos6EmaEofTUiNrvyVobMBfWbdQvhTe6UciGjH2n",
+ },
+ TestCase {
+ description: "DescribeAccountKey20Terminal Sibling",
+ location: Location::new(1, [Parachain(1111), bob_20]),
+ expected_account_id_str: "5CE6V5AKH8H4rg2aq5KMbvaVUDMumHKVPPQEEDMHPy3GmJQp",
+ },
+ // DescribeTreasuryVoiceTerminal
+ TestCase {
+ description: "DescribeTreasuryVoiceTerminal Parent",
+ location: Location::new(1, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]),
+ expected_account_id_str: "5CUjnE2vgcUCuhxPwFoQ5r7p1DkhujgvMNDHaF2bLqRp4D5F",
+ },
+ TestCase {
+ description: "DescribeTreasuryVoiceTerminal Sibling",
+ location: Location::new(
+ 1,
+ [Parachain(1111), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5G6TDwaVgbWmhqRUKjBhRRnH4ry9L9cjRymUEmiRsLbSE4gB",
+ },
+ // DescribeBodyTerminal
+ TestCase {
+ description: "DescribeBodyTerminal Parent",
+ location: Location::new(1, [Plurality { id: BodyId::Unit, part: BodyPart::Voice }]),
+ expected_account_id_str: "5EBRMTBkDisEXsaN283SRbzx9Xf2PXwUxxFCJohSGo4jYe6B",
+ },
+ TestCase {
+ description: "DescribeBodyTerminal Sibling",
+ location: Location::new(
+ 1,
+ [Parachain(1111), Plurality { id: BodyId::Unit, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5DBoExvojy8tYnHgLL97phNH975CyT45PWTZEeGoBZfAyRMH",
+ },
+ ];
+
+ for tc in test_cases {
+ let expected =
+ AccountId::from_string(tc.expected_account_id_str).expect("Invalid AccountId string");
+
+ let got = LocationToAccountHelper::::convert_location(
+ tc.location.into(),
+ )
+ .unwrap();
+
+ assert_eq!(got, expected, "{}", tc.description);
+ }
+}
diff --git a/system-parachains/people/people-polkadot/src/lib.rs b/system-parachains/people/people-polkadot/src/lib.rs
index 4dd70c027b..a439971e5f 100644
--- a/system-parachains/people/people-polkadot/src/lib.rs
+++ b/system-parachains/people/people-polkadot/src/lib.rs
@@ -21,6 +21,8 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
// Genesis preset configurations.
pub mod genesis_config_presets;
pub mod people;
+#[cfg(test)]
+mod tests;
mod weights;
pub mod xcm_config;
diff --git a/system-parachains/people/people-polkadot/src/tests.rs b/system-parachains/people/people-polkadot/src/tests.rs
new file mode 100644
index 0000000000..7e0d7d61a7
--- /dev/null
+++ b/system-parachains/people/people-polkadot/src/tests.rs
@@ -0,0 +1,123 @@
+// Copyright (C) Parity Technologies and the various Polkadot contributors, see Contributions.md
+// for a list of specific contributors.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use crate::xcm_config::LocationToAccountId;
+use cumulus_primitives_core::relay_chain::AccountId;
+use sp_core::crypto::Ss58Codec;
+use xcm::prelude::*;
+use xcm_runtime_apis::conversions::LocationToAccountHelper;
+
+const ALICE: [u8; 32] = [1u8; 32];
+
+#[test]
+fn location_conversion_works() {
+ let alice_32 = AccountId32 { network: None, id: AccountId::from(ALICE).into() };
+ let bob_20 = AccountKey20 { network: None, key: [123u8; 20] };
+
+ // the purpose of hardcoded values is to catch an unintended location conversion logic change.
+ struct TestCase {
+ description: &'static str,
+ location: Location,
+ expected_account_id_str: &'static str,
+ }
+
+ let test_cases = vec![
+ // DescribeTerminus
+ TestCase {
+ description: "DescribeTerminus Parent",
+ location: Location::new(1, Here),
+ expected_account_id_str: "5Dt6dpkWPwLaH4BBCKJwjiWrFVAGyYk3tLUabvyn4v7KtESG",
+ },
+ TestCase {
+ description: "DescribeTerminus Sibling",
+ location: Location::new(1, [Parachain(1111)]),
+ expected_account_id_str: "5Eg2fnssmmJnF3z1iZ1NouAuzciDaaDQH7qURAy3w15jULDk",
+ },
+ // DescribePalletTerminal
+ TestCase {
+ description: "DescribePalletTerminal Parent",
+ location: Location::new(1, [PalletInstance(50)]),
+ expected_account_id_str: "5CnwemvaAXkWFVwibiCvf2EjqwiqBi29S5cLLydZLEaEw6jZ",
+ },
+ TestCase {
+ description: "DescribePalletTerminal Sibling",
+ location: Location::new(1, [Parachain(1111), PalletInstance(50)]),
+ expected_account_id_str: "5GFBgPjpEQPdaxEnFirUoa51u5erVx84twYxJVuBRAT2UP2g",
+ },
+ // DescribeAccountId32Terminal
+ TestCase {
+ description: "DescribeAccountId32Terminal Parent",
+ location: Location::new(1, [alice_32]),
+ expected_account_id_str: "5DN5SGsuUG7PAqFL47J9meViwdnk9AdeSWKFkcHC45hEzVz4",
+ },
+ TestCase {
+ description: "DescribeAccountId32Terminal Sibling",
+ location: Location::new(1, [Parachain(1111), alice_32]),
+ expected_account_id_str: "5DGRXLYwWGce7wvm14vX1Ms4Vf118FSWQbJkyQigY2pfm6bg",
+ },
+ // DescribeAccountKey20Terminal
+ TestCase {
+ description: "DescribeAccountKey20Terminal Parent",
+ location: Location::new(1, [bob_20]),
+ expected_account_id_str: "5CJeW9bdeos6EmaEofTUiNrvyVobMBfWbdQvhTe6UciGjH2n",
+ },
+ TestCase {
+ description: "DescribeAccountKey20Terminal Sibling",
+ location: Location::new(1, [Parachain(1111), bob_20]),
+ expected_account_id_str: "5CE6V5AKH8H4rg2aq5KMbvaVUDMumHKVPPQEEDMHPy3GmJQp",
+ },
+ // DescribeTreasuryVoiceTerminal
+ TestCase {
+ description: "DescribeTreasuryVoiceTerminal Parent",
+ location: Location::new(1, [Plurality { id: BodyId::Treasury, part: BodyPart::Voice }]),
+ expected_account_id_str: "5CUjnE2vgcUCuhxPwFoQ5r7p1DkhujgvMNDHaF2bLqRp4D5F",
+ },
+ TestCase {
+ description: "DescribeTreasuryVoiceTerminal Sibling",
+ location: Location::new(
+ 1,
+ [Parachain(1111), Plurality { id: BodyId::Treasury, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5G6TDwaVgbWmhqRUKjBhRRnH4ry9L9cjRymUEmiRsLbSE4gB",
+ },
+ // DescribeBodyTerminal
+ TestCase {
+ description: "DescribeBodyTerminal Parent",
+ location: Location::new(1, [Plurality { id: BodyId::Unit, part: BodyPart::Voice }]),
+ expected_account_id_str: "5EBRMTBkDisEXsaN283SRbzx9Xf2PXwUxxFCJohSGo4jYe6B",
+ },
+ TestCase {
+ description: "DescribeBodyTerminal Sibling",
+ location: Location::new(
+ 1,
+ [Parachain(1111), Plurality { id: BodyId::Unit, part: BodyPart::Voice }],
+ ),
+ expected_account_id_str: "5DBoExvojy8tYnHgLL97phNH975CyT45PWTZEeGoBZfAyRMH",
+ },
+ ];
+
+ for tc in test_cases {
+ let expected =
+ AccountId::from_string(tc.expected_account_id_str).expect("Invalid AccountId string");
+
+ let got = LocationToAccountHelper::::convert_location(
+ tc.location.into(),
+ )
+ .unwrap();
+
+ assert_eq!(got, expected, "{}", tc.description);
+ }
+}