diff --git a/relay/kusama/tests/location_conversion.rs b/relay/kusama/tests/location_conversion.rs new file mode 100644 index 0000000000..6aa6793783 --- /dev/null +++ b/relay/kusama/tests/location_conversion.rs @@ -0,0 +1,132 @@ +// 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 xcm::prelude::*; +use xcm_runtime_apis::conversions::LocationToAccountHelper; +use staging_kusama_runtime::xcm_config::SovereignAccountOf; + +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 Parent", + location: Location::new(1, Here), + expected_account_id_str: "5GyWtDJP7qaipWRGr4KJ6VUDxRXf4jDnPW6KPTeCekHfqZkD", + }, + TestCase { + description: "DescribeTerminus Sibling", + location: Location::new(1, [Parachain(1111)]), + expected_account_id_str: "5EC5GfEFm9XEBYjXzxb1VseMHsG2VhPeGTGWF9H8tYZnGsSk", + }, + // 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, + [AccountId32 { network: None, id: AccountId::from(ALICE).into() }], + ), + expected_account_id_str: "5DN5SGsuUG7PAqFL47J9meViwdnk9AdeSWKFkcHC45hEzVz4", + }, + TestCase { + description: "DescribeAccountId32Terminal Sibling", + location: Location::new( + 1, + [ + Parachain(1111), + Junction::AccountId32 { network: None, id: AccountId::from(ALICE).into() }, + ], + ), + expected_account_id_str: "5DGRXLYwWGce7wvm14vX1Ms4Vf118FSWQbJkyQigY2pfm6bg", + }, + // DescribeAccountKey20Terminal + TestCase { + description: "DescribeAccountKey20Terminal Parent", + location: Location::new(1, [AccountKey20 { network: None, key: [0u8; 20] }]), + expected_account_id_str: "5F5Ec11567pa919wJkX6VHtv2ZXS5W698YCW35EdEbrg14cg", + }, + TestCase { + description: "DescribeAccountKey20Terminal Sibling", + location: Location::new( + 1, + [Parachain(1111), AccountKey20 { network: None, key: [0u8; 20] }], + ), + expected_account_id_str: "5CB2FbUds2qvcJNhDiTbRZwiS3trAy6ydFGMSVutmYijpPAg", + }, + // 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/relay/polkadot/src/lib.rs b/relay/polkadot/src/lib.rs index 2ee7fdd5c7..c6190f7458 100644 --- a/relay/polkadot/src/lib.rs +++ b/relay/polkadot/src/lib.rs @@ -1175,7 +1175,8 @@ impl InstanceFilter for ProxyType { matches!( c, RuntimeCall::Staking(..) | - RuntimeCall::Session(..) | RuntimeCall::Utility(..) | + RuntimeCall::Session(..) | + RuntimeCall::Utility(..) | RuntimeCall::FastUnstake(..) | RuntimeCall::VoterList(..) | RuntimeCall::NominationPools(..) diff --git a/relay/polkadot/tests/location_conversion.rs b/relay/polkadot/tests/location_conversion.rs new file mode 100644 index 0000000000..d256ea1f52 --- /dev/null +++ b/relay/polkadot/tests/location_conversion.rs @@ -0,0 +1,132 @@ +// 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 Parent", + location: Location::new(1, Here), + expected_account_id_str: "5GyWtDJP7qaipWRGr4KJ6VUDxRXf4jDnPW6KPTeCekHfqZkD", + }, + TestCase { + description: "DescribeTerminus Sibling", + location: Location::new(1, [Parachain(1111)]), + expected_account_id_str: "5EC5GfEFm9XEBYjXzxb1VseMHsG2VhPeGTGWF9H8tYZnGsSk", + }, + // 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, + [AccountId32 { network: None, id: AccountId::from(ALICE).into() }], + ), + expected_account_id_str: "5DN5SGsuUG7PAqFL47J9meViwdnk9AdeSWKFkcHC45hEzVz4", + }, + TestCase { + description: "DescribeAccountId32Terminal Sibling", + location: Location::new( + 1, + [ + Parachain(1111), + Junction::AccountId32 { network: None, id: AccountId::from(ALICE).into() }, + ], + ), + expected_account_id_str: "5DGRXLYwWGce7wvm14vX1Ms4Vf118FSWQbJkyQigY2pfm6bg", + }, + // DescribeAccountKey20Terminal + TestCase { + description: "DescribeAccountKey20Terminal Parent", + location: Location::new(1, [AccountKey20 { network: None, key: [0u8; 20] }]), + expected_account_id_str: "5F5Ec11567pa919wJkX6VHtv2ZXS5W698YCW35EdEbrg14cg", + }, + TestCase { + description: "DescribeAccountKey20Terminal Sibling", + location: Location::new( + 1, + [Parachain(1111), AccountKey20 { network: None, key: [0u8; 20] }], + ), + expected_account_id_str: "5CB2FbUds2qvcJNhDiTbRZwiS3trAy6ydFGMSVutmYijpPAg", + }, + // 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/asset-hubs/asset-hub-kusama/tests/tests.rs b/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs index 9e3e2ded06..21becfd4aa 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]; @@ -706,3 +708,112 @@ fn treasury_pallet_account_not_none() { LocationToAccountId::convert_location(&RelayTreasuryLocation::get()).unwrap() ) } + +#[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 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, + [AccountId32 { network: None, id: polkadot_core_primitives::AccountId::from(ALICE).into() }], + ), + expected_account_id_str: "5DN5SGsuUG7PAqFL47J9meViwdnk9AdeSWKFkcHC45hEzVz4", + }, + TestCase { + description: "DescribeAccountId32Terminal Sibling", + location: Location::new( + 1, + [ + Parachain(1111), + Junction::AccountId32 { network: None, id: polkadot_core_primitives::AccountId::from(ALICE).into() }, + ], + ), + expected_account_id_str: "5DGRXLYwWGce7wvm14vX1Ms4Vf118FSWQbJkyQigY2pfm6bg", + }, + // DescribeAccountKey20Terminal + TestCase { + description: "DescribeAccountKey20Terminal Parent", + location: Location::new(1, [AccountKey20 { network: None, key: [0u8; 20] }]), + expected_account_id_str: "5F5Ec11567pa919wJkX6VHtv2ZXS5W698YCW35EdEbrg14cg", + }, + TestCase { + description: "DescribeAccountKey20Terminal Sibling", + location: Location::new( + 1, + [Parachain(1111), AccountKey20 { network: None, key: [0u8; 20] }], + ), + expected_account_id_str: "5CB2FbUds2qvcJNhDiTbRZwiS3trAy6ydFGMSVutmYijpPAg", + }, + // 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 7da4172102..a55287ff61 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]; @@ -730,3 +732,112 @@ fn change_xcm_bridge_hub_ethereum_base_fee_by_governance_works() { }, ) } + +#[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 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, + [AccountId32 { network: None, id: polkadot_core_primitives::AccountId::from(ALICE).into() }], + ), + expected_account_id_str: "5DN5SGsuUG7PAqFL47J9meViwdnk9AdeSWKFkcHC45hEzVz4", + }, + TestCase { + description: "DescribeAccountId32Terminal Sibling", + location: Location::new( + 1, + [ + Parachain(1111), + Junction::AccountId32 { network: None, id: polkadot_core_primitives::AccountId::from(ALICE).into() }, + ], + ), + expected_account_id_str: "5DGRXLYwWGce7wvm14vX1Ms4Vf118FSWQbJkyQigY2pfm6bg", + }, + // DescribeAccountKey20Terminal + TestCase { + description: "DescribeAccountKey20Terminal Parent", + location: Location::new(1, [AccountKey20 { network: None, key: [0u8; 20] }]), + expected_account_id_str: "5F5Ec11567pa919wJkX6VHtv2ZXS5W698YCW35EdEbrg14cg", + }, + TestCase { + description: "DescribeAccountKey20Terminal Sibling", + location: Location::new( + 1, + [Parachain(1111), AccountKey20 { network: None, key: [0u8; 20] }], + ), + expected_account_id_str: "5CB2FbUds2qvcJNhDiTbRZwiS3trAy6ydFGMSVutmYijpPAg", + }, + // 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..9ba9b0be29 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,112 @@ fn treasury_pallet_account_not_none() { LocationToAccountId::convert_location(&RelayTreasuryLocation::get()).unwrap() ) } + +#[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 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, + [xcm::prelude::AccountId32 { network: None, id: polkadot_core_primitives::AccountId::from(Alice).into() }], + ), + expected_account_id_str: "5EueAXd4h8u75nSbFdDJbC29cmi4Uo1YJssqEL9idvindxFL", + }, + TestCase { + description: "DescribeAccountId32Terminal Sibling", + location: Location::new( + 1, + [ + Parachain(1111), + Junction::AccountId32 { network: None, id: polkadot_core_primitives::AccountId::from(Alice).into() }, + ], + ), + expected_account_id_str: "5Dmbuiq48fU4iW58FKYqoGbbfxFHjbAeGLMtjFg6NNCw3ssr", + }, + // DescribeAccountKey20Terminal + TestCase { + description: "DescribeAccountKey20Terminal Parent", + location: Location::new(1, [AccountKey20 { network: None, key: [0u8; 20] }]), + expected_account_id_str: "5F5Ec11567pa919wJkX6VHtv2ZXS5W698YCW35EdEbrg14cg", + }, + TestCase { + description: "DescribeAccountKey20Terminal Sibling", + location: Location::new( + 1, + [Parachain(1111), AccountKey20 { network: None, key: [0u8; 20] }], + ), + expected_account_id_str: "5CB2FbUds2qvcJNhDiTbRZwiS3trAy6ydFGMSVutmYijpPAg", + }, + // 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..8be231d526 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,112 @@ fn treasury_pallet_account_not_none() { LocationToAccountId::convert_location(&RelayTreasuryLocation::get()).unwrap() ) } + +#[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 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, + [xcm::prelude::AccountId32 { network: None, id: polkadot_core_primitives::AccountId::from(Alice).into() }], + ), + expected_account_id_str: "5EueAXd4h8u75nSbFdDJbC29cmi4Uo1YJssqEL9idvindxFL", + }, + TestCase { + description: "DescribeAccountId32Terminal Sibling", + location: Location::new( + 1, + [ + Parachain(1111), + Junction::AccountId32 { network: None, id: polkadot_core_primitives::AccountId::from(Alice).into() }, + ], + ), + expected_account_id_str: "5Dmbuiq48fU4iW58FKYqoGbbfxFHjbAeGLMtjFg6NNCw3ssr", + }, + // DescribeAccountKey20Terminal + TestCase { + description: "DescribeAccountKey20Terminal Parent", + location: Location::new(1, [AccountKey20 { network: None, key: [0u8; 20] }]), + expected_account_id_str: "5F5Ec11567pa919wJkX6VHtv2ZXS5W698YCW35EdEbrg14cg", + }, + TestCase { + description: "DescribeAccountKey20Terminal Sibling", + location: Location::new( + 1, + [Parachain(1111), AccountKey20 { network: None, key: [0u8; 20] }], + ), + expected_account_id_str: "5CB2FbUds2qvcJNhDiTbRZwiS3trAy6ydFGMSVutmYijpPAg", + }, + // 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..42ab6d314a --- /dev/null +++ b/system-parachains/collectives/collectives-polkadot/tests/location_conversion.rs @@ -0,0 +1,132 @@ +// 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_core_primitives::AccountId; +use sp_core::crypto::Ss58Codec; +use xcm::prelude::*; +use xcm_runtime_apis::conversions::LocationToAccountHelper; +use collectives_polkadot_runtime::xcm_config::LocationToAccountId; + +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 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, + [AccountId32 { network: None, id: AccountId::from(ALICE).into() }], + ), + expected_account_id_str: "5DN5SGsuUG7PAqFL47J9meViwdnk9AdeSWKFkcHC45hEzVz4", + }, + TestCase { + description: "DescribeAccountId32Terminal Sibling", + location: Location::new( + 1, + [ + Parachain(1111), + Junction::AccountId32 { network: None, id: AccountId::from(ALICE).into() }, + ], + ), + expected_account_id_str: "5DGRXLYwWGce7wvm14vX1Ms4Vf118FSWQbJkyQigY2pfm6bg", + }, + // DescribeAccountKey20Terminal + TestCase { + description: "DescribeAccountKey20Terminal Parent", + location: Location::new(1, [AccountKey20 { network: None, key: [0u8; 20] }]), + expected_account_id_str: "5F5Ec11567pa919wJkX6VHtv2ZXS5W698YCW35EdEbrg14cg", + }, + TestCase { + description: "DescribeAccountKey20Terminal Sibling", + location: Location::new( + 1, + [Parachain(1111), AccountKey20 { network: None, key: [0u8; 20] }], + ), + expected_account_id_str: "5CB2FbUds2qvcJNhDiTbRZwiS3trAy6ydFGMSVutmYijpPAg", + }, + // 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..23c892243b 100644 --- a/system-parachains/coretime/coretime-kusama/src/tests.rs +++ b/system-parachains/coretime/coretime-kusama/src/tests.rs @@ -29,7 +29,12 @@ 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; +use crate::xcm_config::LocationToAccountId; + +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,112 @@ fn timeslice_period_is_sane() { #[cfg(not(feature = "fast-runtime"))] assert_eq!(TIMESLICE_PERIOD, 80); } + +#[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 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, + [xcm::prelude::AccountId32 { network: None, id: polkadot_core_primitives::AccountId::from(ALICE).into() }], + ), + expected_account_id_str: "5DN5SGsuUG7PAqFL47J9meViwdnk9AdeSWKFkcHC45hEzVz4", + }, + TestCase { + description: "DescribeAccountId32Terminal Sibling", + location: Location::new( + 1, + [ + Parachain(1111), + Junction::AccountId32 { network: None, id: polkadot_core_primitives::AccountId::from(ALICE).into() }, + ], + ), + expected_account_id_str: "5DGRXLYwWGce7wvm14vX1Ms4Vf118FSWQbJkyQigY2pfm6bg", + }, + // DescribeAccountKey20Terminal + TestCase { + description: "DescribeAccountKey20Terminal Parent", + location: Location::new(1, [AccountKey20 { network: None, key: [0u8; 20] }]), + expected_account_id_str: "5F5Ec11567pa919wJkX6VHtv2ZXS5W698YCW35EdEbrg14cg", + }, + TestCase { + description: "DescribeAccountKey20Terminal Sibling", + location: Location::new( + 1, + [Parachain(1111), AccountKey20 { network: None, key: [0u8; 20] }], + ), + expected_account_id_str: "5CB2FbUds2qvcJNhDiTbRZwiS3trAy6ydFGMSVutmYijpPAg", + }, + // 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..e9730c60d7 100644 --- a/system-parachains/coretime/coretime-polkadot/src/tests.rs +++ b/system-parachains/coretime/coretime-polkadot/src/tests.rs @@ -28,8 +28,13 @@ use frame_support::{ }; use pallet_broker::{ConfigRecordOf, RCBlockNumberOf, SaleInfo}; use parachains_runtimes_test_utils::ExtBuilder; +use sp_core::crypto::Ss58Codec; use polkadot_runtime_constants::system_parachain::coretime::TIMESLICE_PERIOD; use sp_runtime::traits::AccountIdConversion; +use xcm_runtime_apis::conversions::LocationToAccountHelper; +use crate::xcm_config::LocationToAccountId; + +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,112 @@ fn timeslice_period_is_sane() { #[cfg(not(feature = "fast-runtime"))] assert_eq!(TIMESLICE_PERIOD, 80); } + +#[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 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, + [xcm::prelude::AccountId32 { network: None, id: polkadot_core_primitives::AccountId::from(ALICE).into() }], + ), + expected_account_id_str: "5DN5SGsuUG7PAqFL47J9meViwdnk9AdeSWKFkcHC45hEzVz4", + }, + TestCase { + description: "DescribeAccountId32Terminal Sibling", + location: Location::new( + 1, + [ + Parachain(1111), + Junction::AccountId32 { network: None, id: polkadot_core_primitives::AccountId::from(ALICE).into() }, + ], + ), + expected_account_id_str: "5DGRXLYwWGce7wvm14vX1Ms4Vf118FSWQbJkyQigY2pfm6bg", + }, + // DescribeAccountKey20Terminal + TestCase { + description: "DescribeAccountKey20Terminal Parent", + location: Location::new(1, [AccountKey20 { network: None, key: [0u8; 20] }]), + expected_account_id_str: "5F5Ec11567pa919wJkX6VHtv2ZXS5W698YCW35EdEbrg14cg", + }, + TestCase { + description: "DescribeAccountKey20Terminal Sibling", + location: Location::new( + 1, + [Parachain(1111), AccountKey20 { network: None, key: [0u8; 20] }], + ), + expected_account_id_str: "5CB2FbUds2qvcJNhDiTbRZwiS3trAy6ydFGMSVutmYijpPAg", + }, + // 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 3cc6c85e53..d0fc682f69 100644 --- a/system-parachains/people/people-kusama/src/lib.rs +++ b/system-parachains/people/people-kusama/src/lib.rs @@ -23,6 +23,7 @@ pub mod genesis_config_presets; pub mod people; mod weights; pub mod xcm_config; +mod tests; use codec::{Decode, Encode, MaxEncodedLen}; use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; 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..c433653482 --- /dev/null +++ b/system-parachains/people/people-kusama/src/tests.rs @@ -0,0 +1,132 @@ +// 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 polkadot_primitives::AccountId; +use sp_core::crypto::Ss58Codec; +use xcm::prelude::*; +use xcm_runtime_apis::conversions::LocationToAccountHelper; +use crate::xcm_config::LocationToAccountId; + +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 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, + [xcm::prelude::AccountId32 { network: None, id: AccountId::from(ALICE).into() }], + ), + expected_account_id_str: "5DN5SGsuUG7PAqFL47J9meViwdnk9AdeSWKFkcHC45hEzVz4", + }, + TestCase { + description: "DescribeAccountId32Terminal Sibling", + location: Location::new( + 1, + [ + Parachain(1111), + Junction::AccountId32 { network: None, id: AccountId::from(ALICE).into() }, + ], + ), + expected_account_id_str: "5DGRXLYwWGce7wvm14vX1Ms4Vf118FSWQbJkyQigY2pfm6bg", + }, + // DescribeAccountKey20Terminal + TestCase { + description: "DescribeAccountKey20Terminal Parent", + location: Location::new(1, [AccountKey20 { network: None, key: [0u8; 20] }]), + expected_account_id_str: "5F5Ec11567pa919wJkX6VHtv2ZXS5W698YCW35EdEbrg14cg", + }, + TestCase { + description: "DescribeAccountKey20Terminal Sibling", + location: Location::new( + 1, + [Parachain(1111), AccountKey20 { network: None, key: [0u8; 20] }], + ), + expected_account_id_str: "5CB2FbUds2qvcJNhDiTbRZwiS3trAy6ydFGMSVutmYijpPAg", + }, + // 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..0c0ccd2722 100644 --- a/system-parachains/people/people-polkadot/src/lib.rs +++ b/system-parachains/people/people-polkadot/src/lib.rs @@ -23,6 +23,7 @@ pub mod genesis_config_presets; pub mod people; mod weights; pub mod xcm_config; +mod tests; use codec::{Decode, Encode, MaxEncodedLen}; use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; 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..5d0dbd7a20 --- /dev/null +++ b/system-parachains/people/people-polkadot/src/tests.rs @@ -0,0 +1,132 @@ +// 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 cumulus_primitives_core::relay_chain::AccountId; +use sp_core::crypto::Ss58Codec; +use xcm::prelude::*; +use xcm_runtime_apis::conversions::LocationToAccountHelper; +use crate::xcm_config::LocationToAccountId; + +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 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, + [xcm::prelude::AccountId32 { network: None, id: AccountId::from(ALICE).into() }], + ), + expected_account_id_str: "5DN5SGsuUG7PAqFL47J9meViwdnk9AdeSWKFkcHC45hEzVz4", + }, + TestCase { + description: "DescribeAccountId32Terminal Sibling", + location: Location::new( + 1, + [ + Parachain(1111), + Junction::AccountId32 { network: None, id: AccountId::from(ALICE).into() }, + ], + ), + expected_account_id_str: "5DGRXLYwWGce7wvm14vX1Ms4Vf118FSWQbJkyQigY2pfm6bg", + }, + // DescribeAccountKey20Terminal + TestCase { + description: "DescribeAccountKey20Terminal Parent", + location: Location::new(1, [AccountKey20 { network: None, key: [0u8; 20] }]), + expected_account_id_str: "5F5Ec11567pa919wJkX6VHtv2ZXS5W698YCW35EdEbrg14cg", + }, + TestCase { + description: "DescribeAccountKey20Terminal Sibling", + location: Location::new( + 1, + [Parachain(1111), AccountKey20 { network: None, key: [0u8; 20] }], + ), + expected_account_id_str: "5CB2FbUds2qvcJNhDiTbRZwiS3trAy6ydFGMSVutmYijpPAg", + }, + // 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); + } +}