diff --git a/Cargo.lock b/Cargo.lock index 4630fea95..a992270b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9987,6 +9987,7 @@ dependencies = [ "polkadot-runtime-parachains", "runtime-common", "scale-info", + "serde", "sp-core", "sp-debug-derive", "sp-io", diff --git a/runtime/integration-tests/Cargo.toml b/runtime/integration-tests/Cargo.toml index 9eb10acbf..96eae61ec 100644 --- a/runtime/integration-tests/Cargo.toml +++ b/runtime/integration-tests/Cargo.toml @@ -8,6 +8,7 @@ version = "0.1.0" [dev-dependencies] codec = { package = "parity-scale-codec", version = "3.0.0" } scale-info = { version = "2.1.2", features = ["derive"] } +serde = { version = "1.0.144", features = ["derive"] } # Spacewalk libraries spacewalk-primitives = { git = "https://github.com/pendulum-chain/spacewalk", default-features = false, rev = "58983d2695c309665c9c017a022436aaee088f3d"} diff --git a/runtime/integration-tests/src/amplitude_tests.rs b/runtime/integration-tests/src/amplitude_tests.rs index 8e165bd5d..9ecad6ce6 100644 --- a/runtime/integration-tests/src/amplitude_tests.rs +++ b/runtime/integration-tests/src/amplitude_tests.rs @@ -131,7 +131,7 @@ fn assethub_transfer_asset_to_amplitude_and_back() { } #[test] -fn transfer_native_token_to_sibling_parachain_and_back() { +fn transfer_native_token_from_amplitude_to_sibling_parachain_and_back() { transfer_native_token_from_parachain1_to_parachain2_and_back!( KusamaMockNet, amplitude_runtime, diff --git a/runtime/integration-tests/src/mock.rs b/runtime/integration-tests/src/mock.rs index 6ac7f863a..29f8e8090 100644 --- a/runtime/integration-tests/src/mock.rs +++ b/runtime/integration-tests/src/mock.rs @@ -2,14 +2,14 @@ use crate::{ sibling, AMPLITUDE_ID, KUSAMA_ASSETHUB_ID, PENDULUM_ID, POLKADOT_ASSETHUB_ID, SIBLING_ID, }; use frame_support::traits::GenesisBuild; -use pendulum_runtime::CurrencyId; +use pendulum_runtime::CurrencyId as PendulumCurrencyId; +use sibling::CurrencyId as SiblingCurrencyId; use polkadot_core_primitives::{AccountId, Balance, BlockNumber}; use polkadot_parachain::primitives::Id as ParaId; use polkadot_primitives::v2::{MAX_CODE_SIZE, MAX_POV_SIZE}; use polkadot_runtime_parachains::configuration::HostConfiguration; use sp_io::TestExternalities; use sp_runtime::traits::AccountIdConversion; -use sp_tracing; use xcm_emulator::Weight; use statemine_runtime as kusama_asset_hub_runtime; @@ -63,9 +63,7 @@ macro_rules! build_relaychain { } macro_rules! build_parachain_with_orml { - ($self:ident, $runtime:ty, $system:tt, $balance:tt, $orml_balance:tt) => {{ - sp_tracing::try_init_simple(); - + ($self:ident, $runtime:ty, $system:tt, $balance:tt, $orml_balance:tt, $currency_id_type:ty) => {{ let mut t = frame_system::GenesisConfig::default().build_storage::<$runtime>().unwrap(); pallet_balances::GenesisConfig::<$runtime> { balances: vec![(AccountId::from(ALICE), $balance), (AccountId::from(BOB), $balance)], @@ -73,6 +71,7 @@ macro_rules! build_parachain_with_orml { .assimilate_storage(&mut t) .unwrap(); + type CurrencyId = $currency_id_type; orml_tokens::GenesisConfig::<$runtime> { balances: vec![ (AccountId::from(BOB), CurrencyId::XCM(0), units($orml_balance)), @@ -210,7 +209,7 @@ impl ExtBuilderParachain { } // ------------------- for Pendulum and Amplitude ------------------- -impl ExtBuilderParachain { +impl ExtBuilderParachain { pub fn pendulum_default() -> Self { Self { balances: vec![], chain: ParachainType::Pendulum } } @@ -218,14 +217,10 @@ impl ExtBuilderParachain { pub fn amplitude_default() -> Self { Self { balances: vec![], chain: ParachainType::Amplitude } } - - pub fn sibling_default() -> Self { - Self { balances: vec![], chain: ParachainType::Sibling } - } } -impl Builder for ExtBuilderParachain { - fn balances(mut self, balances: Vec<(AccountId, CurrencyId, Balance)>) -> Self { +impl Builder for ExtBuilderParachain { + fn balances(mut self, balances: Vec<(AccountId, PendulumCurrencyId, Balance)>) -> Self { self.balances = balances; self } @@ -239,7 +234,8 @@ impl Builder for ExtBuilderParachain { Runtime, System, INITIAL_BALANCE, - ORML_INITIAL_BALANCE + ORML_INITIAL_BALANCE, + PendulumCurrencyId ) }, ParachainType::Amplitude => { @@ -249,9 +245,30 @@ impl Builder for ExtBuilderParachain { Runtime, System, INITIAL_BALANCE, - ORML_INITIAL_BALANCE + ORML_INITIAL_BALANCE, + PendulumCurrencyId ) }, + _ => panic!("cannot use this chain to build"), + } + } +} + +// ------------------- for Sibling ------------------- +impl ExtBuilderParachain { + pub fn sibling_default() -> Self { + Self { balances: vec![], chain: ParachainType::Sibling } + } +} + +impl Builder for ExtBuilderParachain { + fn balances(mut self, balances: Vec<(AccountId, SiblingCurrencyId, Balance)>) -> Self { + self.balances = balances; + self + } + + fn build(self) -> TestExternalities { + match self.chain { ParachainType::Sibling => { use sibling::{Runtime, System}; build_parachain_with_orml!( @@ -259,7 +276,8 @@ impl Builder for ExtBuilderParachain { Runtime, System, INITIAL_BALANCE, - ORML_INITIAL_BALANCE + ORML_INITIAL_BALANCE, + SiblingCurrencyId ) }, _ => panic!("cannot use this chain to build"), diff --git a/runtime/integration-tests/src/pendulum_tests.rs b/runtime/integration-tests/src/pendulum_tests.rs index c312bad4b..690c3da12 100644 --- a/runtime/integration-tests/src/pendulum_tests.rs +++ b/runtime/integration-tests/src/pendulum_tests.rs @@ -131,7 +131,7 @@ fn assethub_transfer_asset_to_pendulum_and_back() { } #[test] -fn transfer_native_token_to_sibling_parachain_and_back() { +fn transfer_native_token_from_pendulum_to_sibling_parachain_and_back() { transfer_native_token_from_parachain1_to_parachain2_and_back!( PolkadotMockNet, pendulum_runtime, diff --git a/runtime/integration-tests/src/sibling.rs b/runtime/integration-tests/src/sibling.rs index abe0f5430..23891f07c 100644 --- a/runtime/integration-tests/src/sibling.rs +++ b/runtime/integration-tests/src/sibling.rs @@ -2,6 +2,9 @@ #![cfg(test)] use core::marker::PhantomData; +use runtime_common::parachains::kusama::asset_hub; +use serde::{Serialize, Deserialize}; +use codec::{MaxEncodedLen, Decode, Encode}; use frame_support::{ log, match_types, parameter_types, traits::{ConstU32, ContainsPair, Everything, Nothing}, @@ -14,7 +17,9 @@ use orml_traits::{ use pallet_xcm::XcmPassthrough; use polkadot_parachain::primitives::Sibling; use polkadot_runtime_common::MAXIMUM_BLOCK_WEIGHT; +use scale_info::TypeInfo; use sp_core::H256; +use sp_debug_derive::RuntimeDebug; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, Convert, IdentityLookup, Zero}, @@ -30,7 +35,6 @@ use xcm_executor::{ Assets, XcmExecutor, }; -use spacewalk_primitives::CurrencyId; use xcm::latest::Weight as XCMWeight; use xcm_builder::{ AccountId32Aliases, AllowUnpaidExecutionFrom, ConvertedConcreteId, EnsureXcmOrigin, @@ -39,6 +43,11 @@ use xcm_builder::{ SignedToAccountId32, SovereignSignedViaLocation, }; +use crate::{AMPLITUDE_ID, PENDULUM_ID, KUSAMA_ASSETHUB_ID, POLKADOT_ASSETHUB_ID}; + +const XCM_ASSET_RELAY_DOT: u8 = 0; +const XCM_ASSET_ASSETHUB_USDT: u8 = 1; + pub type AccountId = AccountId32; parameter_types! { @@ -63,6 +72,42 @@ pub type LocationToAccountId = ( AccountId32Aliases, ); +#[derive( + Encode, + Decode, + Eq, + PartialEq, + Copy, + Clone, + RuntimeDebug, + PartialOrd, + Ord, + MaxEncodedLen, + TypeInfo, +)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub enum CurrencyId { + Pendulum, + Amplitude, + Native, + XCM(u8), +} + +// Convert from u32 parachain id to CurrencyId +// Needed for the test macro so it works regardless of the XCM sender parachain +impl From for CurrencyId { + fn from(id: u32) -> Self { + match id { + PENDULUM_ID => CurrencyId::Pendulum, + AMPLITUDE_ID => CurrencyId::Amplitude, + KUSAMA_ASSETHUB_ID | POLKADOT_ASSETHUB_ID => CurrencyId::XCM(XCM_ASSET_ASSETHUB_USDT), + id if id == u32::from(ParachainInfo::parachain_id()) => CurrencyId::Native, + // Relay + _ => CurrencyId::XCM(XCM_ASSET_RELAY_DOT), + } + } +} + /// CurrencyIdConvert /// This type implements conversions from our `CurrencyId` type into `MultiLocation` and vice-versa. /// A currency locally is identified with a `CurrencyId` variant but in the network it is identified @@ -77,6 +122,15 @@ impl Convert> for CurrencyIdConvert { 1, X2(Parachain(ParachainInfo::parachain_id().into()), PalletInstance(10)), )), + CurrencyId::Pendulum => Some(MultiLocation::new( + 1, + X2(Parachain(PENDULUM_ID), PalletInstance(10)), + )), + CurrencyId::Amplitude => Some(MultiLocation::new( + 1, + X2(Parachain(AMPLITUDE_ID), PalletInstance(10)), + )), + // TODO see how to use KUSAMA/POLKADOT asset hub based on the XCM sender chain (PENDULUM/AMPLITUDE) if needed _ => None, } } @@ -85,11 +139,13 @@ impl Convert> for CurrencyIdConvert { impl Convert> for CurrencyIdConvert { fn convert(location: MultiLocation) -> Option { match location { - // Just for testing purposes, parachain id is not verified so this can be used by all runtimes - MultiLocation { parents: 1, interior: X2(Parachain(_id), PalletInstance(10)) } => - Some(CurrencyId::Native), + MultiLocation { parents: 1, interior: X2(Parachain(PENDULUM_ID), PalletInstance(10)) } => + Some(CurrencyId::Pendulum), + MultiLocation { parents: 1, interior: X2(Parachain(AMPLITUDE_ID), PalletInstance(10)) } => + Some(CurrencyId::Amplitude), MultiLocation { parents: 0, interior: X1(PalletInstance(10)) } => Some(CurrencyId::Native), + // TODO see how to use KUSAMA/POLKADOT asset hub based on the XCM sender chain (PENDULUM/AMPLITUDE) if needed _ => None, } } diff --git a/runtime/integration-tests/src/test_macros.rs b/runtime/integration-tests/src/test_macros.rs index 702d68874..982f0b7dc 100644 --- a/runtime/integration-tests/src/test_macros.rs +++ b/runtime/integration-tests/src/test_macros.rs @@ -477,7 +477,9 @@ macro_rules! transfer_native_token_from_parachain1_to_parachain2_and_back { use xcm::latest::{ Junction, Junction::AccountId32, Junctions::X2, MultiLocation, WeightLimit, }; - use $parachain1_runtime::CurrencyId; + use $parachain1_runtime::CurrencyId as Parachain1CurrencyId; + use $parachain2_runtime::CurrencyId as Parachain2CurrencyId; + $mocknet::reset(); @@ -486,19 +488,21 @@ macro_rules! transfer_native_token_from_parachain1_to_parachain2_and_back { 1, X2(Junction::Parachain($parachain1_id), Junction::PalletInstance(10)), ); - + // This is needed in order to have the correct mapping regardless of the XCM sender parachain provided + let para1_native_currency_on_para2 = Parachain2CurrencyId::from($parachain1_id); + // Get ALICE's balance on parachain1 before the transfer let native_tokens_before: Balance = units(100); $parachain1::execute_with(|| { assert_eq!( - $parachain1_runtime::Tokens::balance(CurrencyId::Native, &ALICE.into()), + $parachain1_runtime::Tokens::balance(Parachain1CurrencyId::Native, &ALICE.into()), native_tokens_before ); }); $parachain2::execute_with(|| { assert_eq!( - $parachain2_runtime::Tokens::balance(CurrencyId::Native, &BOB.into()), - native_tokens_before + $parachain2_runtime::Tokens::balance(para1_native_currency_on_para2, &BOB.into()), + 0 ); }); @@ -533,15 +537,15 @@ macro_rules! transfer_native_token_from_parachain1_to_parachain2_and_back { // Should increase by the transfer amount $parachain2::execute_with(|| { assert_eq!( - $parachain2_runtime::Tokens::balance(CurrencyId::Native, &BOB.into()), - native_tokens_before + transfer_amount + $parachain2_runtime::Tokens::balance(para1_native_currency_on_para2, &BOB.into()), + transfer_amount ); }); // Verify ALICE's balance on parachain1 after transfer $parachain1::execute_with(|| { assert_eq!( - $parachain1_runtime::Tokens::balance(CurrencyId::Native, &ALICE.into()), + $parachain1_runtime::Tokens::balance(Parachain1CurrencyId::Native, &ALICE.into()), native_tokens_before - transfer_amount ); }); @@ -577,8 +581,8 @@ macro_rules! transfer_native_token_from_parachain1_to_parachain2_and_back { // Should become the same amount as initial balance before both transfers $parachain2::execute_with(|| { assert_eq!( - $parachain2_runtime::Tokens::balance(CurrencyId::Native, &BOB.into()), - native_tokens_before + $parachain2_runtime::Tokens::balance(para1_native_currency_on_para2, &BOB.into()), + 0 ); }); @@ -586,7 +590,7 @@ macro_rules! transfer_native_token_from_parachain1_to_parachain2_and_back { // Should become the same amount as initial balance before both transfers $parachain1::execute_with(|| { assert_eq!( - $parachain1_runtime::Tokens::balance(CurrencyId::Native, &ALICE.into()), + $parachain1_runtime::Tokens::balance(Parachain1CurrencyId::Native, &ALICE.into()), native_tokens_before ); });