From 9d646f64c5574f8ea6b4e61d7893c9216bb31a8d Mon Sep 17 00:00:00 2001 From: bogdanS98 Date: Fri, 27 Oct 2023 18:23:45 +0300 Subject: [PATCH 01/20] Add PEN token to MultiLocation (and viceversa) conversions in XCM config --- runtime/pendulum/src/xcm_config.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/runtime/pendulum/src/xcm_config.rs b/runtime/pendulum/src/xcm_config.rs index a6d68269b..57f4e5d96 100644 --- a/runtime/pendulum/src/xcm_config.rs +++ b/runtime/pendulum/src/xcm_config.rs @@ -17,7 +17,7 @@ use polkadot_parachain::primitives::Sibling; use polkadot_runtime_common::impls::ToAuthor; use runtime_common::parachains::polkadot::asset_hub; use sp_runtime::traits::Convert; -use xcm::latest::{prelude::*, Weight as XCMWeight}; +use xcm::{latest::{prelude::*, Weight as XCMWeight}}; use xcm_builder::{ AccountId32Aliases, AllowUnpaidExecutionFrom, ConvertedConcreteId, EnsureXcmOrigin, FixedWeightBounds, FungiblesAdapter, NoChecking, ParentIsPreset, RelayChainAsNative, @@ -76,6 +76,7 @@ impl Convert> for CurrencyIdConvert { )), _ => None, }, + CurrencyId::Native => Some(MultiLocation::new(1, X2(Parachain(ParachainInfo::parachain_id().into()), PalletInstance(10)))), _ => None, } } @@ -95,6 +96,14 @@ impl Convert> for CurrencyIdConvert { GeneralIndex(asset_hub::USDT_ASSET_ID), ), } => Some(CurrencyId::XCM(XCM_ASSET_ASSETHUB_USDT)), + MultiLocation { + parents: 1, + interior: + X2( + Parachain(id), + PalletInstance(10), + ), + } if id == u32::from(ParachainInfo::parachain_id()) => Some(CurrencyId::Native), _ => None, } } From 11b1ab40e2188c64f370462b26e51ac2f5d6f95a Mon Sep 17 00:00:00 2001 From: bogdanS98 Date: Fri, 27 Oct 2023 19:15:25 +0300 Subject: [PATCH 02/20] Add test for transferring PEN to AssetHub through XCM --- runtime/integration-tests/src/mock.rs | 3 +- .../integration-tests/src/pendulum_tests.rs | 14 ++++ runtime/integration-tests/src/test_macros.rs | 82 +++++++++++++++++++ 3 files changed, 98 insertions(+), 1 deletion(-) diff --git a/runtime/integration-tests/src/mock.rs b/runtime/integration-tests/src/mock.rs index cfb316560..afbffd2c3 100644 --- a/runtime/integration-tests/src/mock.rs +++ b/runtime/integration-tests/src/mock.rs @@ -69,7 +69,8 @@ macro_rules! build_parachain_with_orml { .unwrap(); orml_tokens::GenesisConfig::<$runtime> { - balances: vec![(AccountId::from(BOB), CurrencyId::XCM(0), units($orml_balance))], + //Changed this temporarily in order to have PEN into BOB's account + balances: vec![(AccountId::from(BOB), CurrencyId::Native, units($orml_balance))], } .assimilate_storage(&mut t) .unwrap(); diff --git a/runtime/integration-tests/src/pendulum_tests.rs b/runtime/integration-tests/src/pendulum_tests.rs index 4476245c4..e2490feab 100644 --- a/runtime/integration-tests/src/pendulum_tests.rs +++ b/runtime/integration-tests/src/pendulum_tests.rs @@ -5,6 +5,7 @@ use crate::{ parachain1_transfer_incorrect_asset_to_parachain2_should_fail, transfer_10_relay_token_from_parachain_to_relay_chain, transfer_20_relay_token_from_relay_chain_to_parachain, + transfer_native_token_from_pendulum_to_assethub, }, PENDULUM_ID, POLKADOT_ASSETHUB_ID, }; @@ -116,3 +117,16 @@ fn assethub_transfer_asset_to_pendulum_and_back() { network_id ); } + +#[test] +fn transfer_native_token_to_assethub() { + transfer_native_token_from_pendulum_to_assethub!( + PolkadotMockNet, + pendulum_runtime, + PendulumParachain, + polkadot_asset_hub_runtime, + AssetHubParachain, + PENDULUM_ID, + POLKADOT_ASSETHUB_ID + ); +} diff --git a/runtime/integration-tests/src/test_macros.rs b/runtime/integration-tests/src/test_macros.rs index 8b68195e1..88c352d15 100644 --- a/runtime/integration-tests/src/test_macros.rs +++ b/runtime/integration-tests/src/test_macros.rs @@ -461,9 +461,91 @@ macro_rules! parachain1_transfer_asset_to_parachain2_and_back { }}; } +macro_rules! transfer_native_token_from_pendulum_to_assethub { + ( + $mocknet:ident, + $pendulum_runtime:ident, + $pendulum_chain:ident, + $assethub_runtime:ident, + $assethub_chain:ident, + $pendulum_id:ident, + $assethub_id:ident + ) => {{ + use crate::mock::{BOB, units}; + use frame_support::traits::fungibles::Inspect; + use polkadot_core_primitives::Balance; + use xcm::latest::{Junction, Junction::AccountId32, Junctions::{X1, X2}, MultiLocation, WeightLimit}; + use $pendulum_runtime::CurrencyId; + + $mocknet::reset(); + + let transfer_amount: Balance = units(10); + let asset_location = MultiLocation::new( + 1, + X2( + Junction::Parachain($pendulum_id), + Junction::PalletInstance(10), + ) + ); + + // Get BOB's balance before the transfer on Pendulum chain + let mut pendulum_tokens_before: Balance = units(100); + $pendulum_chain::execute_with(|| { + assert_eq!($pendulum_runtime::Tokens::balance(CurrencyId::Native, &BOB.into()), pendulum_tokens_before); + }); + + // Execute the transfer from Pendulum chain to AssetHub + $pendulum_chain::execute_with(|| { + use $pendulum_runtime::XTokens; + + assert_ok!( + XTokens::transfer_multiasset( + $pendulum_runtime::RuntimeOrigin::signed(BOB.into()), + Box::new((asset_location.clone(), transfer_amount).into()), + Box::new( + MultiLocation { parents: 1, interior: X1(AccountId32 { network: None, id: BOB }) } + .into() + ), + WeightLimit::Unlimited) + ); + }); + + + $pendulum_chain::execute_with(|| { + use $pendulum_runtime::{System, RuntimeEvent}; + + assert!(System::events().iter().any(|r| matches!( + r.event, + RuntimeEvent::XTokens(orml_xtokens::Event::TransferredMultiAssets { .. }) + ))); + }); + + // Can't get this to work though + // Verify the balance on the AssetHub chain after transfer + // $assethub_chain::execute_with(|| { + // // I need ForeignAssets here instead of Assets + // use $assethub_runtime::Assets; + + // assert_eq!( + // Assets::balance(asset_location, &BOB.into()), + // transfer_amount + // ); + // }); + + // Verify the balance on the Pendulum chain after transfer + $pendulum_chain::execute_with(|| { + assert_eq!( + $pendulum_runtime::Tokens::balance(CurrencyId::Native, &BOB.into()), + pendulum_tokens_before - transfer_amount + ); + }); + }}; +} + // macros defined at the bottom of this file to prevent unresolved imports pub(super) use parachain1_transfer_asset_to_parachain2; pub(super) use parachain1_transfer_asset_to_parachain2_and_back; pub(super) use parachain1_transfer_incorrect_asset_to_parachain2_should_fail; pub(super) use transfer_10_relay_token_from_parachain_to_relay_chain; pub(super) use transfer_20_relay_token_from_relay_chain_to_parachain; +pub(super) use transfer_native_token_from_pendulum_to_assethub; From d05479bcb33f122d65d681743c7a1e5cd92c76e4 Mon Sep 17 00:00:00 2001 From: bogdanS98 Date: Fri, 27 Oct 2023 19:24:28 +0300 Subject: [PATCH 03/20] fmt --- runtime/pendulum/src/xcm_config.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/runtime/pendulum/src/xcm_config.rs b/runtime/pendulum/src/xcm_config.rs index 57f4e5d96..35ec76de2 100644 --- a/runtime/pendulum/src/xcm_config.rs +++ b/runtime/pendulum/src/xcm_config.rs @@ -17,7 +17,7 @@ use polkadot_parachain::primitives::Sibling; use polkadot_runtime_common::impls::ToAuthor; use runtime_common::parachains::polkadot::asset_hub; use sp_runtime::traits::Convert; -use xcm::{latest::{prelude::*, Weight as XCMWeight}}; +use xcm::latest::{prelude::*, Weight as XCMWeight}; use xcm_builder::{ AccountId32Aliases, AllowUnpaidExecutionFrom, ConvertedConcreteId, EnsureXcmOrigin, FixedWeightBounds, FungiblesAdapter, NoChecking, ParentIsPreset, RelayChainAsNative, @@ -76,7 +76,10 @@ impl Convert> for CurrencyIdConvert { )), _ => None, }, - CurrencyId::Native => Some(MultiLocation::new(1, X2(Parachain(ParachainInfo::parachain_id().into()), PalletInstance(10)))), + CurrencyId::Native => Some(MultiLocation::new( + 1, + X2(Parachain(ParachainInfo::parachain_id().into()), PalletInstance(10)), + )), _ => None, } } @@ -96,14 +99,9 @@ impl Convert> for CurrencyIdConvert { GeneralIndex(asset_hub::USDT_ASSET_ID), ), } => Some(CurrencyId::XCM(XCM_ASSET_ASSETHUB_USDT)), - MultiLocation { - parents: 1, - interior: - X2( - Parachain(id), - PalletInstance(10), - ), - } if id == u32::from(ParachainInfo::parachain_id()) => Some(CurrencyId::Native), + MultiLocation { parents: 1, interior: X2(Parachain(id), PalletInstance(10)) } + if id == u32::from(ParachainInfo::parachain_id()) => + Some(CurrencyId::Native), _ => None, } } From 9d5791f2b12db461b3d7594f2a9e61d7d534ac10 Mon Sep 17 00:00:00 2001 From: bogdanS98 Date: Fri, 27 Oct 2023 19:25:02 +0300 Subject: [PATCH 04/20] fmt --- .../integration-tests/src/pendulum_tests.rs | 18 +-- runtime/integration-tests/src/test_macros.rs | 116 +++++++++--------- 2 files changed, 70 insertions(+), 64 deletions(-) diff --git a/runtime/integration-tests/src/pendulum_tests.rs b/runtime/integration-tests/src/pendulum_tests.rs index e2490feab..0a5517c5e 100644 --- a/runtime/integration-tests/src/pendulum_tests.rs +++ b/runtime/integration-tests/src/pendulum_tests.rs @@ -120,13 +120,13 @@ fn assethub_transfer_asset_to_pendulum_and_back() { #[test] fn transfer_native_token_to_assethub() { - transfer_native_token_from_pendulum_to_assethub!( - PolkadotMockNet, - pendulum_runtime, - PendulumParachain, - polkadot_asset_hub_runtime, - AssetHubParachain, - PENDULUM_ID, - POLKADOT_ASSETHUB_ID - ); + transfer_native_token_from_pendulum_to_assethub!( + PolkadotMockNet, + pendulum_runtime, + PendulumParachain, + polkadot_asset_hub_runtime, + AssetHubParachain, + PENDULUM_ID, + POLKADOT_ASSETHUB_ID + ); } diff --git a/runtime/integration-tests/src/test_macros.rs b/runtime/integration-tests/src/test_macros.rs index 88c352d15..03ea4a6ef 100644 --- a/runtime/integration-tests/src/test_macros.rs +++ b/runtime/integration-tests/src/test_macros.rs @@ -462,7 +462,7 @@ macro_rules! parachain1_transfer_asset_to_parachain2_and_back { } macro_rules! transfer_native_token_from_pendulum_to_assethub { - ( + ( $mocknet:ident, $pendulum_runtime:ident, $pendulum_chain:ident, @@ -471,48 +471,54 @@ macro_rules! transfer_native_token_from_pendulum_to_assethub { $pendulum_id:ident, $assethub_id:ident ) => {{ - use crate::mock::{BOB, units}; - use frame_support::traits::fungibles::Inspect; + use crate::mock::{units, BOB}; + use frame_support::traits::fungibles::Inspect; use polkadot_core_primitives::Balance; - use xcm::latest::{Junction, Junction::AccountId32, Junctions::{X1, X2}, MultiLocation, WeightLimit}; - use $pendulum_runtime::CurrencyId; - - $mocknet::reset(); - - let transfer_amount: Balance = units(10); - let asset_location = MultiLocation::new( - 1, - X2( - Junction::Parachain($pendulum_id), - Junction::PalletInstance(10), - ) - ); - - // Get BOB's balance before the transfer on Pendulum chain - let mut pendulum_tokens_before: Balance = units(100); - $pendulum_chain::execute_with(|| { - assert_eq!($pendulum_runtime::Tokens::balance(CurrencyId::Native, &BOB.into()), pendulum_tokens_before); - }); - - // Execute the transfer from Pendulum chain to AssetHub + use xcm::latest::{ + Junction, + Junction::AccountId32, + Junctions::{X1, X2}, + MultiLocation, WeightLimit, + }; + use $pendulum_runtime::CurrencyId; + + $mocknet::reset(); + + let transfer_amount: Balance = units(10); + let asset_location = MultiLocation::new( + 1, + X2(Junction::Parachain($pendulum_id), Junction::PalletInstance(10)), + ); + + // Get BOB's balance before the transfer on Pendulum chain + let mut pendulum_tokens_before: Balance = units(100); + $pendulum_chain::execute_with(|| { + assert_eq!( + $pendulum_runtime::Tokens::balance(CurrencyId::Native, &BOB.into()), + pendulum_tokens_before + ); + }); + + // Execute the transfer from Pendulum chain to AssetHub $pendulum_chain::execute_with(|| { use $pendulum_runtime::XTokens; - assert_ok!( - XTokens::transfer_multiasset( - $pendulum_runtime::RuntimeOrigin::signed(BOB.into()), - Box::new((asset_location.clone(), transfer_amount).into()), - Box::new( - MultiLocation { parents: 1, interior: X1(AccountId32 { network: None, id: BOB }) } - .into() - ), - WeightLimit::Unlimited) - ); + assert_ok!(XTokens::transfer_multiasset( + $pendulum_runtime::RuntimeOrigin::signed(BOB.into()), + Box::new((asset_location.clone(), transfer_amount).into()), + Box::new( + MultiLocation { + parents: 1, + interior: X1(AccountId32 { network: None, id: BOB }) + } + .into() + ), + WeightLimit::Unlimited + )); }); - - $pendulum_chain::execute_with(|| { - use $pendulum_runtime::{System, RuntimeEvent}; + $pendulum_chain::execute_with(|| { + use $pendulum_runtime::{RuntimeEvent, System}; assert!(System::events().iter().any(|r| matches!( r.event, @@ -521,25 +527,25 @@ macro_rules! transfer_native_token_from_pendulum_to_assethub { }); // Can't get this to work though - // Verify the balance on the AssetHub chain after transfer - // $assethub_chain::execute_with(|| { + // Verify the balance on the AssetHub chain after transfer + // $assethub_chain::execute_with(|| { // // I need ForeignAssets here instead of Assets - // use $assethub_runtime::Assets; - - // assert_eq!( - // Assets::balance(asset_location, &BOB.into()), - // transfer_amount - // ); - // }); - - // Verify the balance on the Pendulum chain after transfer - $pendulum_chain::execute_with(|| { - assert_eq!( - $pendulum_runtime::Tokens::balance(CurrencyId::Native, &BOB.into()), - pendulum_tokens_before - transfer_amount - ); - }); - }}; + // use $assethub_runtime::Assets; + + // assert_eq!( + // Assets::balance(asset_location, &BOB.into()), + // transfer_amount + // ); + // }); + + // Verify the balance on the Pendulum chain after transfer + $pendulum_chain::execute_with(|| { + assert_eq!( + $pendulum_runtime::Tokens::balance(CurrencyId::Native, &BOB.into()), + pendulum_tokens_before - transfer_amount + ); + }); + }}; } // macros defined at the bottom of this file to prevent unresolved imports From 70ceec5d498cdaf319b8b935938aacbae8a2e905 Mon Sep 17 00:00:00 2001 From: bogdanS98 Date: Tue, 31 Oct 2023 17:49:31 +0200 Subject: [PATCH 05/20] Add conversions for Amplitude and Foucoco - tests still in progress --- .../integration-tests/src/amplitude_tests.rs | 1 + runtime/integration-tests/src/mock.rs | 33 +++++- .../integration-tests/src/pendulum_tests.rs | 26 ++++- runtime/integration-tests/src/test_macros.rs | 106 +++++++++++------- 4 files changed, 116 insertions(+), 50 deletions(-) diff --git a/runtime/integration-tests/src/amplitude_tests.rs b/runtime/integration-tests/src/amplitude_tests.rs index 2ad863dc3..45248ae2e 100644 --- a/runtime/integration-tests/src/amplitude_tests.rs +++ b/runtime/integration-tests/src/amplitude_tests.rs @@ -5,6 +5,7 @@ use crate::{ parachain1_transfer_incorrect_asset_to_parachain2_should_fail, transfer_10_relay_token_from_parachain_to_relay_chain, transfer_20_relay_token_from_relay_chain_to_parachain, + transfer_native_token_from_parachain1_to_parachain2, }, AMPLITUDE_ID, KUSAMA_ASSETHUB_ID, }; diff --git a/runtime/integration-tests/src/mock.rs b/runtime/integration-tests/src/mock.rs index afbffd2c3..a8035c1a1 100644 --- a/runtime/integration-tests/src/mock.rs +++ b/runtime/integration-tests/src/mock.rs @@ -1,4 +1,4 @@ -use crate::{AMPLITUDE_ID, PENDULUM_ID, KUSAMA_ASSETHUB_ID, POLKADOT_ASSETHUB_ID}; +use crate::{AMPLITUDE_ID, KUSAMA_ASSETHUB_ID, PENDULUM_ID, POLKADOT_ASSETHUB_ID}; use frame_support::traits::GenesisBuild; use pendulum_runtime::CurrencyId; use polkadot_core_primitives::{AccountId, Balance, BlockNumber}; @@ -7,10 +7,11 @@ 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 statemint_runtime as polkadot_asset_hub_runtime; use statemine_runtime as kusama_asset_hub_runtime; +use statemint_runtime as polkadot_asset_hub_runtime; pub const ALICE: [u8; 32] = [4u8; 32]; pub const BOB: [u8; 32] = [5u8; 32]; @@ -61,6 +62,8 @@ 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(); + 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)], @@ -69,8 +72,10 @@ macro_rules! build_parachain_with_orml { .unwrap(); orml_tokens::GenesisConfig::<$runtime> { - //Changed this temporarily in order to have PEN into BOB's account - balances: vec![(AccountId::from(BOB), CurrencyId::Native, units($orml_balance))], + balances: vec![ + (AccountId::from(BOB), CurrencyId::XCM(0), units($orml_balance)), + (AccountId::from(ALICE), CurrencyId::Native, units($orml_balance)), + ], } .assimilate_storage(&mut t) .unwrap(); @@ -110,6 +115,7 @@ pub enum ParachainType { PolkadotAssetHub, KusamaAssetHub, Pendulum, + Pendulum2, Amplitude, } @@ -181,6 +187,9 @@ pub fn para_ext(chain: ParachainType) -> sp_io::TestExternalities { ParachainType::KusamaAssetHub => ExtBuilderParachain::kusama_asset_hub_default().balances(vec![]).build(), ParachainType::Pendulum => ExtBuilderParachain::pendulum_default().balances(vec![]).build(), + // for second Pendulum instance used for transferring native token + ParachainType::Pendulum2 => + ExtBuilderParachain::pendulum2_default().balances(vec![]).build(), ParachainType::Amplitude => ExtBuilderParachain::amplitude_default().balances(vec![]).build(), } @@ -192,6 +201,7 @@ impl ExtBuilderParachain { ParachainType::PolkadotAssetHub => POLKADOT_ASSETHUB_ID, ParachainType::KusamaAssetHub => KUSAMA_ASSETHUB_ID, ParachainType::Pendulum => PENDULUM_ID, + ParachainType::Pendulum2 => PENDULUM_ID + 1, ParachainType::Amplitude => AMPLITUDE_ID, } } @@ -202,6 +212,10 @@ impl ExtBuilderParachain { pub fn pendulum_default() -> Self { Self { balances: vec![], chain: ParachainType::Pendulum } } + // for second Pendulum instance used for transferring native token + pub fn pendulum2_default() -> Self { + Self { balances: vec![], chain: ParachainType::Pendulum2 } + } pub fn amplitude_default() -> Self { Self { balances: vec![], chain: ParachainType::Amplitude } @@ -226,6 +240,17 @@ impl Builder for ExtBuilderParachain { ORML_INITIAL_BALANCE ) }, + // for second Pendulum instance used for transferring native token + ParachainType::Pendulum2 => { + use pendulum_runtime::{Runtime, System}; + build_parachain_with_orml!( + self, + Runtime, + System, + INITIAL_BALANCE, + ORML_INITIAL_BALANCE + ) + }, ParachainType::Amplitude => { use amplitude_runtime::{Runtime, System}; build_parachain_with_orml!( diff --git a/runtime/integration-tests/src/pendulum_tests.rs b/runtime/integration-tests/src/pendulum_tests.rs index 0a5517c5e..35e5b5086 100644 --- a/runtime/integration-tests/src/pendulum_tests.rs +++ b/runtime/integration-tests/src/pendulum_tests.rs @@ -5,7 +5,7 @@ use crate::{ parachain1_transfer_incorrect_asset_to_parachain2_should_fail, transfer_10_relay_token_from_parachain_to_relay_chain, transfer_20_relay_token_from_relay_chain_to_parachain, - transfer_native_token_from_pendulum_to_assethub, + transfer_native_token_from_parachain1_to_parachain2, }, PENDULUM_ID, POLKADOT_ASSETHUB_ID, }; @@ -35,6 +35,16 @@ decl_test_parachain! { } } +decl_test_parachain! { + pub struct Pendulum2Parachain { + Runtime = pendulum_runtime::Runtime, + RuntimeOrigin = pendulum_runtime::RuntimeOrigin, + XcmpMessageHandler = pendulum_runtime::XcmpQueue, + DmpMessageHandler = pendulum_runtime::DmpQueue, + new_ext = para_ext(ParachainType::Pendulum2), + } +} + decl_test_parachain! { pub struct AssetHubParachain { Runtime = polkadot_asset_hub_runtime::Runtime, @@ -51,6 +61,7 @@ decl_test_network! { parachains = vec![ (1000, AssetHubParachain), (2094, PendulumParachain), + (2095, Pendulum2Parachain), ], } } @@ -119,14 +130,17 @@ fn assethub_transfer_asset_to_pendulum_and_back() { } #[test] -fn transfer_native_token_to_assethub() { - transfer_native_token_from_pendulum_to_assethub!( +fn transfer_pendulum_native_token_to_pendulum() { + // ID for Pendulum's second instance + pub const PENDULUM2_ID: u32 = PENDULUM_ID + 1; + + transfer_native_token_from_parachain1_to_parachain2!( PolkadotMockNet, pendulum_runtime, PendulumParachain, - polkadot_asset_hub_runtime, - AssetHubParachain, + pendulum_runtime, + Pendulum2Parachain, PENDULUM_ID, - POLKADOT_ASSETHUB_ID + PENDULUM2_ID ); } diff --git a/runtime/integration-tests/src/test_macros.rs b/runtime/integration-tests/src/test_macros.rs index 03ea4a6ef..15253a388 100644 --- a/runtime/integration-tests/src/test_macros.rs +++ b/runtime/integration-tests/src/test_macros.rs @@ -461,64 +461,90 @@ macro_rules! parachain1_transfer_asset_to_parachain2_and_back { }}; } -macro_rules! transfer_native_token_from_pendulum_to_assethub { +macro_rules! transfer_native_token_from_parachain1_to_parachain2 { ( $mocknet:ident, - $pendulum_runtime:ident, - $pendulum_chain:ident, - $assethub_runtime:ident, - $assethub_chain:ident, - $pendulum_id:ident, - $assethub_id:ident + $parachain1_runtime:ident, + $parachain1:ident, + $parachain2_runtime:ident, + $parachain2:ident, + $parachain1_id:ident, + $parachain2_id:ident ) => {{ - use crate::mock::{units, BOB}; - use frame_support::traits::fungibles::Inspect; + use crate::mock::{units, ALICE, BOB}; + use frame_support::{log::info, traits::fungibles::Inspect}; use polkadot_core_primitives::Balance; + use sp_tracing; use xcm::latest::{ Junction, Junction::AccountId32, - Junctions::{X1, X2}, + Junctions::{X2, X3}, MultiLocation, WeightLimit, }; - use $pendulum_runtime::CurrencyId; + use $parachain1_runtime::CurrencyId; $mocknet::reset(); + sp_tracing::try_init_simple(); + let transfer_amount: Balance = units(10); let asset_location = MultiLocation::new( 1, - X2(Junction::Parachain($pendulum_id), Junction::PalletInstance(10)), + X2(Junction::Parachain($parachain1_id), Junction::PalletInstance(10)), ); - // Get BOB's balance before the transfer on Pendulum chain - let mut pendulum_tokens_before: Balance = units(100); - $pendulum_chain::execute_with(|| { + // Get ALICE's balance on parachain1 before the transfer + let native_tokens_before: Balance = units(100); + $parachain1::execute_with(|| { assert_eq!( - $pendulum_runtime::Tokens::balance(CurrencyId::Native, &BOB.into()), - pendulum_tokens_before + $parachain1_runtime::Tokens::balance(CurrencyId::Native, &ALICE.into()), + native_tokens_before ); }); - // Execute the transfer from Pendulum chain to AssetHub - $pendulum_chain::execute_with(|| { - use $pendulum_runtime::XTokens; + // Execute the transfer from parachain1 to parachain2 + $parachain1::execute_with(|| { + use $parachain1_runtime::XTokens; + // transfer using multilocation assert_ok!(XTokens::transfer_multiasset( - $pendulum_runtime::RuntimeOrigin::signed(BOB.into()), + $parachain1_runtime::RuntimeOrigin::signed(ALICE.into()), Box::new((asset_location.clone(), transfer_amount).into()), Box::new( MultiLocation { parents: 1, - interior: X1(AccountId32 { network: None, id: BOB }) + interior: X2( + Junction::Parachain($parachain2_id), + AccountId32 { network: None, id: BOB } + ) } .into() ), WeightLimit::Unlimited )); + + // transfer using currency id + // assert_ok!(XTokens::transfer( + // $parachain1_runtime::RuntimeOrigin::signed(ALICE.into()), + // CurrencyId::Native, + // transfer_amount, + // Box::new( + // MultiLocation::new( + // 1, + // X3( + // Junction::Parachain($parachain2_id), + // Junction::PalletInstance(10), + // Junction::AccountId32 { network: None, id: BOB.into() } + // ) + // ) + // .into() + // ), + // WeightLimit::Unlimited + // )); }); - $pendulum_chain::execute_with(|| { - use $pendulum_runtime::{RuntimeEvent, System}; + $parachain1::execute_with(|| { + use $parachain1_runtime::{RuntimeEvent, System}; assert!(System::events().iter().any(|r| matches!( r.event, @@ -526,23 +552,23 @@ macro_rules! transfer_native_token_from_pendulum_to_assethub { ))); }); - // Can't get this to work though - // Verify the balance on the AssetHub chain after transfer - // $assethub_chain::execute_with(|| { - // // I need ForeignAssets here instead of Assets - // use $assethub_runtime::Assets; - - // assert_eq!( - // Assets::balance(asset_location, &BOB.into()), - // transfer_amount - // ); - // }); + // Verify the balance on the parachain2 after transfer + $parachain2::execute_with(|| { + // Currently failing + // assert_eq!( + // $parachain2_runtime::Tokens::balance(CurrencyId::Native, &BOB.into()), + // transfer_amount + // ); + + // log BOB's balance to see if there's any amount + info!("{:?}", $parachain2_runtime::Tokens::balance(CurrencyId::Native, &BOB.into())); + }); - // Verify the balance on the Pendulum chain after transfer - $pendulum_chain::execute_with(|| { + // Verify the balance on the parachain1 after transfer + $parachain1::execute_with(|| { assert_eq!( - $pendulum_runtime::Tokens::balance(CurrencyId::Native, &BOB.into()), - pendulum_tokens_before - transfer_amount + $parachain1_runtime::Tokens::balance(CurrencyId::Native, &ALICE.into()), + native_tokens_before - transfer_amount ); }); }}; @@ -554,4 +580,4 @@ pub(super) use parachain1_transfer_asset_to_parachain2_and_back; pub(super) use parachain1_transfer_incorrect_asset_to_parachain2_should_fail; pub(super) use transfer_10_relay_token_from_parachain_to_relay_chain; pub(super) use transfer_20_relay_token_from_relay_chain_to_parachain; -pub(super) use transfer_native_token_from_pendulum_to_assethub; +pub(super) use transfer_native_token_from_parachain1_to_parachain2; From 8f12d5aa1a1d357a4f9376abf230ab422e5c1217 Mon Sep 17 00:00:00 2001 From: Marcel Ebert Date: Tue, 31 Oct 2023 17:50:30 +0100 Subject: [PATCH 06/20] Add 'sibling' runtime --- runtime/integration-tests/src/lib.rs | 2 + runtime/integration-tests/src/sibling.rs | 478 +++++++++++++++++++++++ 2 files changed, 480 insertions(+) create mode 100644 runtime/integration-tests/src/sibling.rs diff --git a/runtime/integration-tests/src/lib.rs b/runtime/integration-tests/src/lib.rs index 3dd931dec..074a05fc3 100644 --- a/runtime/integration-tests/src/lib.rs +++ b/runtime/integration-tests/src/lib.rs @@ -10,6 +10,8 @@ mod amplitude_tests; #[cfg(test)] mod test_macros; +mod sibling; + pub const PENDULUM_ID: u32 = 2094; pub const POLKADOT_ASSETHUB_ID: u32 = 1000; diff --git a/runtime/integration-tests/src/sibling.rs b/runtime/integration-tests/src/sibling.rs new file mode 100644 index 000000000..87576a6d3 --- /dev/null +++ b/runtime/integration-tests/src/sibling.rs @@ -0,0 +1,478 @@ +// Based on https://github.com/open-web3-stack/open-runtime-module-library/blob/83a76c2bf66c0b1236c31077e6fb24bb760a3535/xtokens/src/mock/para.rs + +use frame_support::{ + construct_runtime, match_types, parameter_types, + traits::{ConstU128, ConstU32, ConstU64, Everything, Get, Nothing}, + weights::constants::WEIGHT_REF_TIME_PER_SECOND, +}; +use frame_system::EnsureRoot; +use sp_core::H256; +use sp_runtime::traits::{Convert, IdentityLookup}; + +use scale_info::TypeInfo; +use serde::{Deserialize, Serialize}; +use sp_runtime::{AccountId32, BoundedVec, BuildStorage}; +use xcm_builder::{CreateMatcher, MatchXcm}; +use xcm_executor::{ + traits::{ShouldExecute, WeightTrader}, + Assets, +}; + +use cumulus_primitives_core::{ChannelStatus, GetChannelInfo, ParaId}; +use pallet_xcm::XcmPassthrough; +use xcm::v3::{prelude::*, Weight}; +use xcm_builder::{ + AccountId32Aliases, EnsureXcmOrigin, FixedWeightBounds, NativeAsset, ParentIsPreset, + RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, + SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, +}; +use xcm_executor::{Config, XcmExecutor}; + +use orml_traits::{location::AbsoluteReserveProvider, parameter_type_with_key}; +use orml_xcm_support::{IsNativeConcrete, MultiCurrencyAdapter, MultiNativeAsset}; + +pub type AccountId = AccountId32; + +#[derive( + Encode, + Decode, + Eq, + PartialEq, + Copy, + Clone, + RuntimeDebug, + PartialOrd, + Ord, + parity_scale_codec::MaxEncodedLen, + TypeInfo, +)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub enum CurrencyId { + /// Relay chain token. + R, + /// Parachain A token. + A, + /// Parachain A A1 token. + A1, + /// Parachain B token. + B, + /// Parachain B B1 token + B1, + /// Parachain B B2 token + B2, + /// Parachain C token + C, + /// Parachain D token + D, +} + +pub struct CurrencyIdConvert; +impl Convert> for CurrencyIdConvert { + fn convert(id: CurrencyId) -> Option { + match id { + CurrencyId::R => Some(Parent.into()), + CurrencyId::A => Some( + ( + Parent, + Parachain(1), + Junction::from(BoundedVec::try_from(b"A".to_vec()).unwrap()), + ) + .into(), + ), + CurrencyId::A1 => Some( + ( + Parent, + Parachain(1), + Junction::from(BoundedVec::try_from(b"A1".to_vec()).unwrap()), + ) + .into(), + ), + CurrencyId::B => Some( + ( + Parent, + Parachain(2), + Junction::from(BoundedVec::try_from(b"B".to_vec()).unwrap()), + ) + .into(), + ), + CurrencyId::B1 => Some( + ( + Parent, + Parachain(2), + Junction::from(BoundedVec::try_from(b"B1".to_vec()).unwrap()), + ) + .into(), + ), + CurrencyId::B2 => Some( + ( + Parent, + Parachain(2), + Junction::from(BoundedVec::try_from(b"B2".to_vec()).unwrap()), + ) + .into(), + ), + CurrencyId::C => Some( + ( + Parent, + Parachain(3), + Junction::from(BoundedVec::try_from(b"C".to_vec()).unwrap()), + ) + .into(), + ), + CurrencyId::D => Some( + ( + Parent, + Parachain(4), + Junction::from(BoundedVec::try_from(b"D".to_vec()).unwrap()), + ) + .into(), + ), + } + } +} +impl Convert> for CurrencyIdConvert { + fn convert(l: MultiLocation) -> Option { + let mut a: Vec = "A".into(); + a.resize(32, 0); + let mut a1: Vec = "A1".into(); + a1.resize(32, 0); + let mut b: Vec = "B".into(); + b.resize(32, 0); + let mut b1: Vec = "B1".into(); + b1.resize(32, 0); + let mut b2: Vec = "B2".into(); + b2.resize(32, 0); + let mut c: Vec = "C".into(); + c.resize(32, 0); + let mut d: Vec = "D".into(); + d.resize(32, 0); + if l == MultiLocation::parent() { + return Some(CurrencyId::R) + } + match l { + MultiLocation { parents, interior } if parents == 1 => match interior { + X2(Parachain(1), GeneralKey { data, .. }) if data.to_vec() == a => + Some(CurrencyId::A), + X2(Parachain(1), GeneralKey { data, .. }) if data.to_vec() == a1 => + Some(CurrencyId::A1), + X2(Parachain(2), GeneralKey { data, .. }) if data.to_vec() == b => + Some(CurrencyId::B), + X2(Parachain(2), GeneralKey { data, .. }) if data.to_vec() == b1 => + Some(CurrencyId::B1), + X2(Parachain(2), GeneralKey { data, .. }) if data.to_vec() == b2 => + Some(CurrencyId::B2), + X2(Parachain(3), GeneralKey { data, .. }) if data.to_vec() == c => + Some(CurrencyId::C), + X2(Parachain(4), GeneralKey { data, .. }) if data.to_vec() == d => + Some(CurrencyId::D), + _ => None, + }, + MultiLocation { parents, interior } if parents == 0 => match interior { + X1(GeneralKey { data, .. }) if data.to_vec() == a => Some(CurrencyId::A), + X1(GeneralKey { data, .. }) if data.to_vec() == b => Some(CurrencyId::B), + X1(GeneralKey { data, .. }) if data.to_vec() == a1 => Some(CurrencyId::A1), + X1(GeneralKey { data, .. }) if data.to_vec() == b1 => Some(CurrencyId::B1), + X1(GeneralKey { data, .. }) if data.to_vec() == b2 => Some(CurrencyId::B2), + X1(GeneralKey { data, .. }) if data.to_vec() == c => Some(CurrencyId::C), + X1(GeneralKey { data, .. }) if data.to_vec() == d => Some(CurrencyId::D), + _ => None, + }, + _ => None, + } + } +} +impl Convert> for CurrencyIdConvert { + fn convert(a: MultiAsset) -> Option { + if let MultiAsset { fun: Fungible(_), id: Concrete(id) } = a { + Self::convert(id) + } else { + Option::None + } + } +} + +pub type Balance = u128; +pub type Amount = i128; + +impl frame_system::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = ConstU64<250>; + type BlockWeights = (); + type BlockLength = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type DbWeight = (); + type BaseCallFilter = Everything; + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = ConstU32<16>; +} + +impl pallet_balances::Config for Runtime { + type MaxLocks = ConstU32<50>; + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ConstU128<1>; + type AccountStore = System; + type WeightInfo = (); + type MaxReserves = ConstU32<50>; + type ReserveIdentifier = [u8; 8]; + type RuntimeHoldReason = RuntimeHoldReason; + type FreezeIdentifier = [u8; 8]; + type MaxHolds = (); + type MaxFreezes = (); +} + +parameter_type_with_key! { + pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { + Default::default() + }; +} + +impl orml_tokens::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Balance = Balance; + type Amount = Amount; + type CurrencyId = CurrencyId; + type WeightInfo = (); + type ExistentialDeposits = ExistentialDeposits; + type CurrencyHooks = (); + type MaxLocks = ConstU32<50>; + type MaxReserves = ConstU32<50>; + type ReserveIdentifier = [u8; 8]; + type DustRemovalWhitelist = Everything; +} + +parameter_types! { + pub const ReservedXcmpWeight: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_div(4), 0); + pub const ReservedDmpWeight: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_div(4), 0); +} + +impl parachain_info::Config for Runtime {} + +parameter_types! { + pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RelayNetwork: NetworkId = NetworkId::Kusama; + pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); + pub UniversalLocation: InteriorMultiLocation = + X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())); +} + +pub type LocationToAccountId = ( + ParentIsPreset, + SiblingParachainConvertsVia, + AccountId32Aliases, +); + +pub type XcmOriginToCallOrigin = ( + SovereignSignedViaLocation, + RelayChainAsNative, + SiblingParachainAsNative, + SignedAccountId32AsNative, + XcmPassthrough, +); + +pub type LocalAssetTransactor = MultiCurrencyAdapter< + Tokens, + (), + IsNativeConcrete, + AccountId, + LocationToAccountId, + CurrencyId, + CurrencyIdConvert, + (), +>; + +pub type XcmRouter = ParachainXcmRouter; +pub type Barrier = (TakeWeightCredit, AllowTopLevelPaidExecution); + +parameter_types! { + pub const UnitWeightCost: Weight = Weight::from_parts(10, 10); + pub const BaseXcmWeight: Weight = Weight::from_parts(100_000_000, 100_000_000); + pub const MaxInstructions: u32 = 100; + pub const MaxAssetsIntoHolding: u32 = 64; +} + +pub struct XcmConfig; +impl Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = XcmRouter; + type AssetTransactor = LocalAssetTransactor; + type OriginConverter = XcmOriginToCallOrigin; + type IsReserve = MultiNativeAsset; + type IsTeleporter = NativeAsset; + type UniversalLocation = UniversalLocation; + type Barrier = Barrier; + type Weigher = FixedWeightBounds; + type Trader = (); + type ResponseHandler = (); + type AssetTrap = PolkadotXcm; + type AssetClaims = PolkadotXcm; + type SubscriptionService = PolkadotXcm; + type AssetLocker = PolkadotXcm; + type AssetExchanger = (); + type PalletInstancesInfo = (); + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type FeeManager = (); + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = RuntimeCall; + type SafeCallFilter = Everything; +} + +pub struct ChannelInfo; +impl GetChannelInfo for ChannelInfo { + fn get_channel_status(_id: ParaId) -> ChannelStatus { + ChannelStatus::Ready(10, 10) + } + fn get_channel_max(_id: ParaId) -> Option { + Some(usize::max_value()) + } +} + +impl cumulus_pallet_xcmp_queue::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type XcmExecutor = XcmExecutor; + type ChannelInfo = ChannelInfo; + type VersionWrapper = (); + type ExecuteOverweightOrigin = EnsureRoot; + type ControllerOrigin = EnsureRoot; + type ControllerOriginConverter = XcmOriginToCallOrigin; + type WeightInfo = (); + type PriceForSiblingDelivery = (); +} + +impl cumulus_pallet_dmp_queue::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type XcmExecutor = XcmExecutor; + type ExecuteOverweightOrigin = EnsureRoot; +} + +impl cumulus_pallet_xcm::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type XcmExecutor = XcmExecutor; +} + +pub type LocalOriginToLocation = SignedToAccountId32; + +#[cfg(feature = "runtime-benchmarks")] +parameter_types! { + pub ReachableDest: Option = Some(Parent.into()); +} + +impl pallet_xcm::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type SendXcmOrigin = EnsureXcmOrigin; + type XcmRouter = XcmRouter; + type ExecuteXcmOrigin = EnsureXcmOrigin; + type XcmExecuteFilter = Everything; + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = Nothing; + type XcmReserveTransferFilter = Everything; + type Weigher = FixedWeightBounds; + type UniversalLocation = UniversalLocation; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; + type Currency = Balances; + type CurrencyMatcher = (); + type TrustedLockers = (); + type SovereignAccountOf = (); + type MaxLockers = ConstU32<8>; + type WeightInfo = pallet_xcm::TestWeightInfo; + type AdminOrigin = EnsureRoot; + type MaxRemoteLockConsumers = ConstU32<0>; + type RemoteLockConsumerIdentifier = (); + #[cfg(feature = "runtime-benchmarks")] + type ReachableDest = ReachableDest; +} + +pub struct AccountIdToMultiLocation; +impl Convert for AccountIdToMultiLocation { + fn convert(account: AccountId) -> MultiLocation { + X1(Junction::AccountId32 { network: None, id: account.into() }).into() + } +} + +parameter_types! { + pub SelfLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into()))); + pub const MaxAssetsForTransfer: usize = 3; +} + +match_types! { + pub type ParentOrParachains: impl Contains = { + MultiLocation { parents: 0, interior: X1(Junction::AccountId32 { .. }) } | + MultiLocation { parents: 1, interior: X1(Junction::AccountId32 { .. }) } | + MultiLocation { parents: 1, interior: X2(Parachain(1), Junction::AccountId32 { .. }) } | + MultiLocation { parents: 1, interior: X2(Parachain(2), Junction::AccountId32 { .. }) } | + MultiLocation { parents: 1, interior: X2(Parachain(3), Junction::AccountId32 { .. }) } | + MultiLocation { parents: 1, interior: X2(Parachain(4), Junction::AccountId32 { .. }) } | + MultiLocation { parents: 1, interior: X2(Parachain(100), Junction::AccountId32 { .. }) } + }; +} + +parameter_type_with_key! { + pub ParachainMinFee: |location: MultiLocation| -> Option { + #[allow(clippy::match_ref_pats)] // false positive + match (location.parents, location.first_interior()) { + (1, Some(Parachain(3))) => Some(40), + _ => None, + } + }; +} + +impl orml_xtokens::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Balance = Balance; + type CurrencyId = CurrencyId; + type CurrencyIdConvert = CurrencyIdConvert; + type AccountIdToMultiLocation = AccountIdToMultiLocation; + type SelfLocation = SelfLocation; + type MultiLocationsFilter = ParentOrParachains; + type MinXcmFee = ParachainMinFee; + type XcmExecutor = XcmExecutor; + type Weigher = FixedWeightBounds; + type BaseXcmWeight = BaseXcmWeight; + type UniversalLocation = UniversalLocation; + type MaxAssetsForTransfer = MaxAssetsForTransfer; + type ReserveProvider = AbsoluteReserveProvider; +} + +impl orml_xcm::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type SovereignOrigin = EnsureRoot; +} + +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub enum Runtime { + System: frame_system, + Balances: pallet_balances, + + ParachainInfo: parachain_info, + XcmpQueue: cumulus_pallet_xcmp_queue, + DmpQueue: cumulus_pallet_dmp_queue, + CumulusXcm: cumulus_pallet_xcm, + + Tokens: orml_tokens, + XTokens: orml_xtokens, + + PolkadotXcm: pallet_xcm, + OrmlXcm: orml_xcm, + } +); From a9466554b2d2dc751e4049b2192786b9aaa08297 Mon Sep 17 00:00:00 2001 From: Marcel Ebert Date: Tue, 31 Oct 2023 17:52:33 +0100 Subject: [PATCH 07/20] Add dependencies --- Cargo.lock | 20 ++++++++++++++++++++ runtime/integration-tests/Cargo.toml | 6 ++++++ runtime/integration-tests/src/mock.rs | 23 ++++++++++------------- runtime/integration-tests/src/sibling.rs | 9 --------- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3dd708eec..5c9b7f469 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6185,6 +6185,20 @@ dependencies = [ "sp-std", ] +[[package]] +name = "orml-xcm" +version = "0.4.1-dev" +source = "git+https://github.com/open-web3-stack/open-runtime-module-library.git?branch=polkadot-v0.9.40#19afb58a300faac6ceb0e6e4e341859282897c53" +dependencies = [ + "frame-support", + "frame-system", + "pallet-xcm", + "parity-scale-codec", + "scale-info", + "sp-std", + "xcm", +] + [[package]] name = "orml-xcm-support" version = "0.4.1-dev" @@ -9947,11 +9961,16 @@ version = "0.1.0" dependencies = [ "amplitude-runtime", "cumulus-pallet-dmp-queue", + "cumulus-pallet-xcm", "cumulus-pallet-xcmp-queue", + "cumulus-primitives-core", "frame-support", "frame-system", "kusama-runtime", "orml-tokens", + "orml-traits", + "orml-xcm", + "orml-xcm-support", "orml-xtokens", "pallet-assets", "pallet-balances", @@ -9970,6 +9989,7 @@ dependencies = [ "sp-io", "sp-runtime", "sp-std", + "sp-tracing", "statemine-runtime", "statemint-runtime", "xcm", diff --git a/runtime/integration-tests/Cargo.toml b/runtime/integration-tests/Cargo.toml index 1ccea787d..8bf29961b 100644 --- a/runtime/integration-tests/Cargo.toml +++ b/runtime/integration-tests/Cargo.toml @@ -17,6 +17,7 @@ sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40" } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40" } sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40" } +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40" } xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.40" } xcm-executor = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.40" } @@ -34,11 +35,16 @@ xcm-emulator = { git = "https://github.com/shaunxw/xcm-simulator", rev = "bea35c cumulus-pallet-dmp-queue = {git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.40"} cumulus-pallet-xcmp-queue = {git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.40"} +cumulus-pallet-xcm = {git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.40"} +cumulus-primitives-core = {git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.40"} parachain-info = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.40" } statemint-runtime = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.40" } statemine-runtime = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.40" } +orml-xcm = {git = "https://github.com/open-web3-stack/open-runtime-module-library.git", branch = "polkadot-v0.9.40" } +orml-xcm-support = {git = "https://github.com/open-web3-stack/open-runtime-module-library.git", branch = "polkadot-v0.9.40" } +orml-traits = {git = "https://github.com/open-web3-stack/open-runtime-module-library.git", branch = "polkadot-v0.9.40" } orml-tokens = {git = "https://github.com/open-web3-stack/open-runtime-module-library.git", branch = "polkadot-v0.9.40" } orml-xtokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.40" } diff --git a/runtime/integration-tests/src/mock.rs b/runtime/integration-tests/src/mock.rs index a8035c1a1..fe68daacd 100644 --- a/runtime/integration-tests/src/mock.rs +++ b/runtime/integration-tests/src/mock.rs @@ -115,8 +115,8 @@ pub enum ParachainType { PolkadotAssetHub, KusamaAssetHub, Pendulum, - Pendulum2, Amplitude, + Sibling, } pub struct ExtBuilderParachain { @@ -187,11 +187,9 @@ pub fn para_ext(chain: ParachainType) -> sp_io::TestExternalities { ParachainType::KusamaAssetHub => ExtBuilderParachain::kusama_asset_hub_default().balances(vec![]).build(), ParachainType::Pendulum => ExtBuilderParachain::pendulum_default().balances(vec![]).build(), - // for second Pendulum instance used for transferring native token - ParachainType::Pendulum2 => - ExtBuilderParachain::pendulum2_default().balances(vec![]).build(), ParachainType::Amplitude => ExtBuilderParachain::amplitude_default().balances(vec![]).build(), + ParachainType::Sibling => ExtBuilderParachain::sibling_default().balances(vec![]).build(), } } @@ -212,14 +210,14 @@ impl ExtBuilderParachain { pub fn pendulum_default() -> Self { Self { balances: vec![], chain: ParachainType::Pendulum } } - // for second Pendulum instance used for transferring native token - pub fn pendulum2_default() -> Self { - Self { balances: vec![], chain: ParachainType::Pendulum2 } - } 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 { @@ -240,9 +238,8 @@ impl Builder for ExtBuilderParachain { ORML_INITIAL_BALANCE ) }, - // for second Pendulum instance used for transferring native token - ParachainType::Pendulum2 => { - use pendulum_runtime::{Runtime, System}; + ParachainType::Amplitude => { + use amplitude_runtime::{Runtime, System}; build_parachain_with_orml!( self, Runtime, @@ -251,8 +248,8 @@ impl Builder for ExtBuilderParachain { ORML_INITIAL_BALANCE ) }, - ParachainType::Amplitude => { - use amplitude_runtime::{Runtime, System}; + ParachainType::Sibling => { + use pendulum_runtime::{Runtime, System}; build_parachain_with_orml!( self, Runtime, diff --git a/runtime/integration-tests/src/sibling.rs b/runtime/integration-tests/src/sibling.rs index 87576a6d3..16d57d299 100644 --- a/runtime/integration-tests/src/sibling.rs +++ b/runtime/integration-tests/src/sibling.rs @@ -197,12 +197,10 @@ pub type Amount = i128; impl frame_system::Config for Runtime { type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; - type Nonce = u64; type Hash = H256; type Hashing = ::sp_runtime::traits::BlakeTwo256; type AccountId = AccountId; type Lookup = IdentityLookup; - type Block = Block; type RuntimeEvent = RuntimeEvent; type BlockHashCount = ConstU64<250>; type BlockWeights = (); @@ -230,10 +228,6 @@ impl pallet_balances::Config for Runtime { type WeightInfo = (); type MaxReserves = ConstU32<50>; type ReserveIdentifier = [u8; 8]; - type RuntimeHoldReason = RuntimeHoldReason; - type FreezeIdentifier = [u8; 8]; - type MaxHolds = (); - type MaxFreezes = (); } parameter_type_with_key! { @@ -394,9 +388,6 @@ impl pallet_xcm::Config for Runtime { type SovereignAccountOf = (); type MaxLockers = ConstU32<8>; type WeightInfo = pallet_xcm::TestWeightInfo; - type AdminOrigin = EnsureRoot; - type MaxRemoteLockConsumers = ConstU32<0>; - type RemoteLockConsumerIdentifier = (); #[cfg(feature = "runtime-benchmarks")] type ReachableDest = ReachableDest; } From 0c2b5870af20d8d6edffabfb19a7166769fa972b Mon Sep 17 00:00:00 2001 From: bogdanS98 Date: Thu, 2 Nov 2023 13:58:07 +0200 Subject: [PATCH 08/20] Try to get sibling to compile for the minimal configuration - failed --- runtime/integration-tests/Cargo.toml | 2 + runtime/integration-tests/src/lib.rs | 1 + runtime/integration-tests/src/mock.rs | 2 +- .../integration-tests/src/pendulum_tests.rs | 12 +- runtime/integration-tests/src/sibling.rs | 438 ++++++++++-------- 5 files changed, 258 insertions(+), 197 deletions(-) diff --git a/runtime/integration-tests/Cargo.toml b/runtime/integration-tests/Cargo.toml index 8bf29961b..473c98fe1 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"] } frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40" } frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40" } @@ -18,6 +19,7 @@ sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot- sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40" } sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40" } sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40" } +sp-debug-derive = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40" } xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.40" } xcm-executor = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.40" } diff --git a/runtime/integration-tests/src/lib.rs b/runtime/integration-tests/src/lib.rs index 074a05fc3..e9f3ca5bd 100644 --- a/runtime/integration-tests/src/lib.rs +++ b/runtime/integration-tests/src/lib.rs @@ -10,6 +10,7 @@ mod amplitude_tests; #[cfg(test)] mod test_macros; +#[cfg(test)] mod sibling; pub const PENDULUM_ID: u32 = 2094; diff --git a/runtime/integration-tests/src/mock.rs b/runtime/integration-tests/src/mock.rs index fe68daacd..2860597ce 100644 --- a/runtime/integration-tests/src/mock.rs +++ b/runtime/integration-tests/src/mock.rs @@ -199,7 +199,7 @@ impl ExtBuilderParachain { ParachainType::PolkadotAssetHub => POLKADOT_ASSETHUB_ID, ParachainType::KusamaAssetHub => KUSAMA_ASSETHUB_ID, ParachainType::Pendulum => PENDULUM_ID, - ParachainType::Pendulum2 => PENDULUM_ID + 1, + ParachainType::Sibling => PENDULUM_ID + 1, ParachainType::Amplitude => AMPLITUDE_ID, } } diff --git a/runtime/integration-tests/src/pendulum_tests.rs b/runtime/integration-tests/src/pendulum_tests.rs index 35e5b5086..d6d54442c 100644 --- a/runtime/integration-tests/src/pendulum_tests.rs +++ b/runtime/integration-tests/src/pendulum_tests.rs @@ -36,12 +36,12 @@ decl_test_parachain! { } decl_test_parachain! { - pub struct Pendulum2Parachain { + pub struct SiblingParachain { Runtime = pendulum_runtime::Runtime, RuntimeOrigin = pendulum_runtime::RuntimeOrigin, XcmpMessageHandler = pendulum_runtime::XcmpQueue, DmpMessageHandler = pendulum_runtime::DmpQueue, - new_ext = para_ext(ParachainType::Pendulum2), + new_ext = para_ext(ParachainType::Sibling), } } @@ -61,7 +61,7 @@ decl_test_network! { parachains = vec![ (1000, AssetHubParachain), (2094, PendulumParachain), - (2095, Pendulum2Parachain), + (2095, SiblingParachain), ], } } @@ -132,15 +132,15 @@ fn assethub_transfer_asset_to_pendulum_and_back() { #[test] fn transfer_pendulum_native_token_to_pendulum() { // ID for Pendulum's second instance - pub const PENDULUM2_ID: u32 = PENDULUM_ID + 1; + pub const SIBLING_ID: u32 = PENDULUM_ID + 1; transfer_native_token_from_parachain1_to_parachain2!( PolkadotMockNet, pendulum_runtime, PendulumParachain, pendulum_runtime, - Pendulum2Parachain, + SiblingParachain, PENDULUM_ID, - PENDULUM2_ID + SIBLING_ID ); } diff --git a/runtime/integration-tests/src/sibling.rs b/runtime/integration-tests/src/sibling.rs index 16d57d299..f7ed86be0 100644 --- a/runtime/integration-tests/src/sibling.rs +++ b/runtime/integration-tests/src/sibling.rs @@ -1,23 +1,33 @@ // Based on https://github.com/open-web3-stack/open-runtime-module-library/blob/83a76c2bf66c0b1236c31077e6fb24bb760a3535/xtokens/src/mock/para.rs +// This is temporary until successful compiling +#![allow(warnings)] +#![cfg(test)] + use frame_support::{ construct_runtime, match_types, parameter_types, traits::{ConstU128, ConstU32, ConstU64, Everything, Get, Nothing}, weights::constants::WEIGHT_REF_TIME_PER_SECOND, }; +use crate:: + mock::{para_ext, polkadot_relay_ext, ParachainType}; use frame_system::EnsureRoot; +use pendulum_runtime::{ParachainInfo, Tokens}; use sp_core::H256; use sp_runtime::traits::{Convert, IdentityLookup}; - +use codec::{Encode, Decode, MaxEncodedLen}; use scale_info::TypeInfo; use serde::{Deserialize, Serialize}; use sp_runtime::{AccountId32, BoundedVec, BuildStorage}; -use xcm_builder::{CreateMatcher, MatchXcm}; +use xcm::CreateMatcher; +use xcm::MatchXcm; use xcm_executor::{ traits::{ShouldExecute, WeightTrader}, Assets, }; - +use xcm_emulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain, TestExt}; +use frame_support::traits::ProcessMessageError; +use sp_debug_derive::RuntimeDebug; use cumulus_primitives_core::{ChannelStatus, GetChannelInfo, ParaId}; use pallet_xcm::XcmPassthrough; use xcm::v3::{prelude::*, Weight}; @@ -27,12 +37,33 @@ use xcm_builder::{ SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, }; use xcm_executor::{Config, XcmExecutor}; - use orml_traits::{location::AbsoluteReserveProvider, parameter_type_with_key}; use orml_xcm_support::{IsNativeConcrete, MultiCurrencyAdapter, MultiNativeAsset}; - +use sp_io::TestExternalities; pub type AccountId = AccountId32; +type Block = frame_system::mocking::MockBlock; +//type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; + +construct_runtime!( + pub enum Runtime + { + System: frame_system, + Balances: pallet_balances, + + //ParachainInfo: parachain_info, + // XcmpQueue: cumulus_pallet_xcmp_queue, + // DmpQueue: cumulus_pallet_dmp_queue, + // CumulusXcm: cumulus_pallet_xcm, + + // Tokens: orml_tokens, + // XTokens: orml_xtokens, + + // PolkadotXcm: pallet_xcm, + // OrmlXcm: orml_xcm, + } +); + #[derive( Encode, Decode, @@ -43,7 +74,7 @@ pub type AccountId = AccountId32; RuntimeDebug, PartialOrd, Ord, - parity_scale_codec::MaxEncodedLen, + MaxEncodedLen, TypeInfo, )] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] @@ -194,6 +225,47 @@ impl Convert> for CurrencyIdConvert { pub type Balance = u128; pub type Amount = i128; +// decl_test_parachain! { +// pub struct SiblingParachain { +// Runtime = Runtime, +// RuntimeOrigin = RuntimeOrigin, +// XcmpMessageHandler = XcmpQueue, +// DmpMessageHandler = DmpQueue, +// new_ext = para_ext(ParachainType::Sibling), +// } +// } + +// I think we're not going to use this but our relay mock instead +// I'll just leave it here in case we need something from it +// decl_test_relay_chain! { +// pub struct Relay { +// Runtime = Runtime, +// RuntimeCall = relay::RuntimeCall, +// RuntimeEvent = relay::RuntimeEvent, +// //XcmConfig = relay::XcmConfig, +// //MessageQueue = relay::MessageQueue, +// System = relay::System, +// new_ext = relay_ext(), +// } +// } + +// decl_test_relay_chain! { +// pub struct PolkadotRelay { +// Runtime = polkadot_runtime::Runtime, +// XcmConfig = polkadot_runtime::xcm_config::XcmConfig, +// new_ext = polkadot_relay_ext(), +// } +// } + +// decl_test_network! { +// pub struct TestNet { +// relay_chain = PolkadotRelay, +// parachains = vec![ +// (1, SiblingParachain), +// ], +// } +// } + impl frame_system::Config for Runtime { type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; @@ -201,6 +273,7 @@ impl frame_system::Config for Runtime { type Hashing = ::sp_runtime::traits::BlakeTwo256; type AccountId = AccountId; type Lookup = IdentityLookup; + type Block = Block; type RuntimeEvent = RuntimeEvent; type BlockHashCount = ConstU64<250>; type BlockWeights = (); @@ -236,161 +309,161 @@ parameter_type_with_key! { }; } -impl orml_tokens::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type Balance = Balance; - type Amount = Amount; - type CurrencyId = CurrencyId; - type WeightInfo = (); - type ExistentialDeposits = ExistentialDeposits; - type CurrencyHooks = (); - type MaxLocks = ConstU32<50>; - type MaxReserves = ConstU32<50>; - type ReserveIdentifier = [u8; 8]; - type DustRemovalWhitelist = Everything; -} - -parameter_types! { - pub const ReservedXcmpWeight: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_div(4), 0); - pub const ReservedDmpWeight: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_div(4), 0); -} - -impl parachain_info::Config for Runtime {} - -parameter_types! { - pub const RelayLocation: MultiLocation = MultiLocation::parent(); - pub const RelayNetwork: NetworkId = NetworkId::Kusama; - pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())); -} - -pub type LocationToAccountId = ( - ParentIsPreset, - SiblingParachainConvertsVia, - AccountId32Aliases, -); - -pub type XcmOriginToCallOrigin = ( - SovereignSignedViaLocation, - RelayChainAsNative, - SiblingParachainAsNative, - SignedAccountId32AsNative, - XcmPassthrough, -); - -pub type LocalAssetTransactor = MultiCurrencyAdapter< - Tokens, - (), - IsNativeConcrete, - AccountId, - LocationToAccountId, - CurrencyId, - CurrencyIdConvert, - (), ->; - -pub type XcmRouter = ParachainXcmRouter; -pub type Barrier = (TakeWeightCredit, AllowTopLevelPaidExecution); - -parameter_types! { - pub const UnitWeightCost: Weight = Weight::from_parts(10, 10); - pub const BaseXcmWeight: Weight = Weight::from_parts(100_000_000, 100_000_000); - pub const MaxInstructions: u32 = 100; - pub const MaxAssetsIntoHolding: u32 = 64; -} - -pub struct XcmConfig; -impl Config for XcmConfig { - type RuntimeCall = RuntimeCall; - type XcmSender = XcmRouter; - type AssetTransactor = LocalAssetTransactor; - type OriginConverter = XcmOriginToCallOrigin; - type IsReserve = MultiNativeAsset; - type IsTeleporter = NativeAsset; - type UniversalLocation = UniversalLocation; - type Barrier = Barrier; - type Weigher = FixedWeightBounds; - type Trader = (); - type ResponseHandler = (); - type AssetTrap = PolkadotXcm; - type AssetClaims = PolkadotXcm; - type SubscriptionService = PolkadotXcm; - type AssetLocker = PolkadotXcm; - type AssetExchanger = (); - type PalletInstancesInfo = (); - type MaxAssetsIntoHolding = MaxAssetsIntoHolding; - type FeeManager = (); - type MessageExporter = (); - type UniversalAliases = Nothing; - type CallDispatcher = RuntimeCall; - type SafeCallFilter = Everything; -} - -pub struct ChannelInfo; -impl GetChannelInfo for ChannelInfo { - fn get_channel_status(_id: ParaId) -> ChannelStatus { - ChannelStatus::Ready(10, 10) - } - fn get_channel_max(_id: ParaId) -> Option { - Some(usize::max_value()) - } -} - -impl cumulus_pallet_xcmp_queue::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type XcmExecutor = XcmExecutor; - type ChannelInfo = ChannelInfo; - type VersionWrapper = (); - type ExecuteOverweightOrigin = EnsureRoot; - type ControllerOrigin = EnsureRoot; - type ControllerOriginConverter = XcmOriginToCallOrigin; - type WeightInfo = (); - type PriceForSiblingDelivery = (); -} - -impl cumulus_pallet_dmp_queue::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type XcmExecutor = XcmExecutor; - type ExecuteOverweightOrigin = EnsureRoot; -} - -impl cumulus_pallet_xcm::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type XcmExecutor = XcmExecutor; -} - -pub type LocalOriginToLocation = SignedToAccountId32; +// impl orml_tokens::Config for Runtime { +// type RuntimeEvent = RuntimeEvent; +// type Balance = Balance; +// type Amount = Amount; +// type CurrencyId = CurrencyId; +// type WeightInfo = (); +// type ExistentialDeposits = ExistentialDeposits; +// type CurrencyHooks = (); +// type MaxLocks = ConstU32<50>; +// type MaxReserves = ConstU32<50>; +// type ReserveIdentifier = [u8; 8]; +// type DustRemovalWhitelist = Everything; +// } + +// parameter_types! { +// pub const ReservedXcmpWeight: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_div(4), 0); +// pub const ReservedDmpWeight: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_div(4), 0); +// } + +// impl parachain_info::Config for Runtime {} + +// parameter_types! { +// pub const RelayLocation: MultiLocation = MultiLocation::parent(); +// pub const RelayNetwork: NetworkId = NetworkId::Kusama; +// pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); +// pub UniversalLocation: InteriorMultiLocation = +// X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())); +// } + +// pub type LocationToAccountId = ( +// ParentIsPreset, +// SiblingParachainConvertsVia, +// AccountId32Aliases, +// ); + +// pub type XcmOriginToCallOrigin = ( +// SovereignSignedViaLocation, +// RelayChainAsNative, +// SiblingParachainAsNative, +// SignedAccountId32AsNative, +// XcmPassthrough, +// ); + +// pub type LocalAssetTransactor = MultiCurrencyAdapter< +// Tokens, +// (), +// IsNativeConcrete, +// AccountId, +// LocationToAccountId, +// CurrencyId, +// CurrencyIdConvert, +// (), +// >; + +// pub type XcmRouter = ParachainXcmRouter; +// pub type Barrier = (TakeWeightCredit, AllowTopLevelPaidExecution); + +// parameter_types! { +// pub const UnitWeightCost: Weight = Weight::from_parts(10, 10); +// pub const BaseXcmWeight: Weight = Weight::from_parts(100_000_000, 100_000_000); +// pub const MaxInstructions: u32 = 100; +// pub const MaxAssetsIntoHolding: u32 = 64; +// } + +// pub struct XcmConfig; +// impl Config for XcmConfig { +// type RuntimeCall = RuntimeCall; +// type XcmSender = XcmRouter; +// type AssetTransactor = LocalAssetTransactor; +// type OriginConverter = XcmOriginToCallOrigin; +// type IsReserve = MultiNativeAsset; +// type IsTeleporter = NativeAsset; +// type UniversalLocation = UniversalLocation; +// type Barrier = Barrier; +// type Weigher = FixedWeightBounds; +// type Trader = (); +// type ResponseHandler = (); +// type AssetTrap = PolkadotXcm; +// type AssetClaims = PolkadotXcm; +// type SubscriptionService = PolkadotXcm; +// type AssetLocker = PolkadotXcm; +// type AssetExchanger = (); +// type PalletInstancesInfo = (); +// type MaxAssetsIntoHolding = MaxAssetsIntoHolding; +// type FeeManager = (); +// type MessageExporter = (); +// type UniversalAliases = Nothing; +// type CallDispatcher = RuntimeCall; +// type SafeCallFilter = Everything; +// } + +// pub struct ChannelInfo; +// impl GetChannelInfo for ChannelInfo { +// fn get_channel_status(_id: ParaId) -> ChannelStatus { +// ChannelStatus::Ready(10, 10) +// } +// fn get_channel_max(_id: ParaId) -> Option { +// Some(usize::max_value()) +// } +// } + +// impl cumulus_pallet_xcmp_queue::Config for Runtime { +// type RuntimeEvent = RuntimeEvent; +// type XcmExecutor = XcmExecutor; +// type ChannelInfo = ChannelInfo; +// type VersionWrapper = (); +// type ExecuteOverweightOrigin = EnsureRoot; +// type ControllerOrigin = EnsureRoot; +// type ControllerOriginConverter = XcmOriginToCallOrigin; +// type WeightInfo = (); +// type PriceForSiblingDelivery = (); +// } + +// impl cumulus_pallet_dmp_queue::Config for Runtime { +// type RuntimeEvent = RuntimeEvent; +// type XcmExecutor = XcmExecutor; +// type ExecuteOverweightOrigin = EnsureRoot; +// } + +// impl cumulus_pallet_xcm::Config for Runtime { +// type RuntimeEvent = RuntimeEvent; +// type XcmExecutor = XcmExecutor; +// } + +//pub type LocalOriginToLocation = SignedToAccountId32; #[cfg(feature = "runtime-benchmarks")] parameter_types! { pub ReachableDest: Option = Some(Parent.into()); } -impl pallet_xcm::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type SendXcmOrigin = EnsureXcmOrigin; - type XcmRouter = XcmRouter; - type ExecuteXcmOrigin = EnsureXcmOrigin; - type XcmExecuteFilter = Everything; - type XcmExecutor = XcmExecutor; - type XcmTeleportFilter = Nothing; - type XcmReserveTransferFilter = Everything; - type Weigher = FixedWeightBounds; - type UniversalLocation = UniversalLocation; - type RuntimeOrigin = RuntimeOrigin; - type RuntimeCall = RuntimeCall; - const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; - type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; - type Currency = Balances; - type CurrencyMatcher = (); - type TrustedLockers = (); - type SovereignAccountOf = (); - type MaxLockers = ConstU32<8>; - type WeightInfo = pallet_xcm::TestWeightInfo; - #[cfg(feature = "runtime-benchmarks")] - type ReachableDest = ReachableDest; -} +// impl pallet_xcm::Config for Runtime { +// type RuntimeEvent = RuntimeEvent; +// type SendXcmOrigin = EnsureXcmOrigin; +// type XcmRouter = XcmRouter; +// type ExecuteXcmOrigin = EnsureXcmOrigin; +// type XcmExecuteFilter = Everything; +// type XcmExecutor = XcmExecutor; +// type XcmTeleportFilter = Nothing; +// type XcmReserveTransferFilter = Everything; +// type Weigher = FixedWeightBounds; +// type UniversalLocation = UniversalLocation; +// type RuntimeOrigin = RuntimeOrigin; +// type RuntimeCall = RuntimeCall; +// const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; +// type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; +// type Currency = Balances; +// type CurrencyMatcher = (); +// type TrustedLockers = (); +// type SovereignAccountOf = (); +// type MaxLockers = ConstU32<8>; +// type WeightInfo = pallet_xcm::TestWeightInfo; +// #[cfg(feature = "runtime-benchmarks")] +// type ReachableDest = ReachableDest; +// } pub struct AccountIdToMultiLocation; impl Convert for AccountIdToMultiLocation { @@ -426,44 +499,29 @@ parameter_type_with_key! { }; } -impl orml_xtokens::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type Balance = Balance; - type CurrencyId = CurrencyId; - type CurrencyIdConvert = CurrencyIdConvert; - type AccountIdToMultiLocation = AccountIdToMultiLocation; - type SelfLocation = SelfLocation; - type MultiLocationsFilter = ParentOrParachains; - type MinXcmFee = ParachainMinFee; - type XcmExecutor = XcmExecutor; - type Weigher = FixedWeightBounds; - type BaseXcmWeight = BaseXcmWeight; - type UniversalLocation = UniversalLocation; - type MaxAssetsForTransfer = MaxAssetsForTransfer; - type ReserveProvider = AbsoluteReserveProvider; -} +// impl orml_xtokens::Config for Runtime { +// type RuntimeEvent = RuntimeEvent; +// type Balance = Balance; +// type CurrencyId = CurrencyId; +// type CurrencyIdConvert = CurrencyIdConvert; +// type AccountIdToMultiLocation = AccountIdToMultiLocation; +// type SelfLocation = SelfLocation; +// type MultiLocationsFilter = ParentOrParachains; +// type MinXcmFee = ParachainMinFee; +// type XcmExecutor = XcmExecutor; +// type Weigher = FixedWeightBounds; +// type BaseXcmWeight = BaseXcmWeight; +// type UniversalLocation = UniversalLocation; +// type MaxAssetsForTransfer = MaxAssetsForTransfer; +// type ReserveProvider = AbsoluteReserveProvider; +// } -impl orml_xcm::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type SovereignOrigin = EnsureRoot; -} +// impl orml_xcm::Config for Runtime { +// type RuntimeEvent = RuntimeEvent; +// type SovereignOrigin = EnsureRoot; +// } -type Block = frame_system::mocking::MockBlock; -construct_runtime!( - pub enum Runtime { - System: frame_system, - Balances: pallet_balances, - ParachainInfo: parachain_info, - XcmpQueue: cumulus_pallet_xcmp_queue, - DmpQueue: cumulus_pallet_dmp_queue, - CumulusXcm: cumulus_pallet_xcm, - Tokens: orml_tokens, - XTokens: orml_xtokens, - PolkadotXcm: pallet_xcm, - OrmlXcm: orml_xcm, - } -); From 0ac5f523834845ea2bfbe376dd3e0f8141b8da49 Mon Sep 17 00:00:00 2001 From: Marcel Ebert Date: Thu, 2 Nov 2023 15:57:03 +0100 Subject: [PATCH 09/20] Almost fix sibling runtime --- Cargo.lock | 2 + runtime/integration-tests/src/sibling.rs | 220 +++++++++++++---------- 2 files changed, 125 insertions(+), 97 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c9b7f469..4fa0f3723 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9985,7 +9985,9 @@ dependencies = [ "polkadot-runtime-common", "polkadot-runtime-parachains", "scale-info", + "serde", "sp-core", + "sp-debug-derive", "sp-io", "sp-runtime", "sp-std", diff --git a/runtime/integration-tests/src/sibling.rs b/runtime/integration-tests/src/sibling.rs index f7ed86be0..9b630a481 100644 --- a/runtime/integration-tests/src/sibling.rs +++ b/runtime/integration-tests/src/sibling.rs @@ -3,66 +3,32 @@ #![allow(warnings)] #![cfg(test)] - +use codec::{Decode, Encode, MaxEncodedLen}; +use cumulus_primitives_core::GetChannelInfo; use frame_support::{ - construct_runtime, match_types, parameter_types, - traits::{ConstU128, ConstU32, ConstU64, Everything, Get, Nothing}, - weights::constants::WEIGHT_REF_TIME_PER_SECOND, + match_types, parameter_types, + traits::{ConstU32, Everything, Get}, }; -use crate:: - mock::{para_ext, polkadot_relay_ext, ParachainType}; -use frame_system::EnsureRoot; -use pendulum_runtime::{ParachainInfo, Tokens}; -use sp_core::H256; -use sp_runtime::traits::{Convert, IdentityLookup}; -use codec::{Encode, Decode, MaxEncodedLen}; +use orml_traits::parameter_type_with_key; use scale_info::TypeInfo; use serde::{Deserialize, Serialize}; -use sp_runtime::{AccountId32, BoundedVec, BuildStorage}; -use xcm::CreateMatcher; -use xcm::MatchXcm; +use sp_core::H256; +use sp_debug_derive::RuntimeDebug; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, Convert, IdentityLookup}, + AccountId32, BoundedVec, BuildStorage, +}; +use xcm::{v3::prelude::*, CreateMatcher, MatchXcm}; +use xcm_emulator::TestExt; use xcm_executor::{ traits::{ShouldExecute, WeightTrader}, - Assets, -}; -use xcm_emulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain, TestExt}; -use frame_support::traits::ProcessMessageError; -use sp_debug_derive::RuntimeDebug; -use cumulus_primitives_core::{ChannelStatus, GetChannelInfo, ParaId}; -use pallet_xcm::XcmPassthrough; -use xcm::v3::{prelude::*, Weight}; -use xcm_builder::{ - AccountId32Aliases, EnsureXcmOrigin, FixedWeightBounds, NativeAsset, ParentIsPreset, - RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, - SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, + Config, }; -use xcm_executor::{Config, XcmExecutor}; -use orml_traits::{location::AbsoluteReserveProvider, parameter_type_with_key}; -use orml_xcm_support::{IsNativeConcrete, MultiCurrencyAdapter, MultiNativeAsset}; -use sp_io::TestExternalities; -pub type AccountId = AccountId32; - -type Block = frame_system::mocking::MockBlock; -//type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; - -construct_runtime!( - pub enum Runtime - { - System: frame_system, - Balances: pallet_balances, - - //ParachainInfo: parachain_info, - // XcmpQueue: cumulus_pallet_xcmp_queue, - // DmpQueue: cumulus_pallet_dmp_queue, - // CumulusXcm: cumulus_pallet_xcm, - // Tokens: orml_tokens, - // XTokens: orml_xtokens, +use pendulum_runtime::ParachainInfo; - // PolkadotXcm: pallet_xcm, - // OrmlXcm: orml_xcm, - } -); +pub type AccountId = AccountId32; #[derive( Encode, @@ -222,9 +188,6 @@ impl Convert> for CurrencyIdConvert { } } -pub type Balance = u128; -pub type Amount = i128; - // decl_test_parachain! { // pub struct SiblingParachain { // Runtime = Runtime, @@ -266,49 +229,6 @@ pub type Amount = i128; // } // } -impl frame_system::Config for Runtime { - type RuntimeOrigin = RuntimeOrigin; - type RuntimeCall = RuntimeCall; - type Hash = H256; - type Hashing = ::sp_runtime::traits::BlakeTwo256; - type AccountId = AccountId; - type Lookup = IdentityLookup; - type Block = Block; - type RuntimeEvent = RuntimeEvent; - type BlockHashCount = ConstU64<250>; - type BlockWeights = (); - type BlockLength = (); - type Version = (); - type PalletInfo = PalletInfo; - type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type DbWeight = (); - type BaseCallFilter = Everything; - type SystemWeightInfo = (); - type SS58Prefix = (); - type OnSetCode = (); - type MaxConsumers = ConstU32<16>; -} - -impl pallet_balances::Config for Runtime { - type MaxLocks = ConstU32<50>; - type Balance = Balance; - type RuntimeEvent = RuntimeEvent; - type DustRemoval = (); - type ExistentialDeposit = ConstU128<1>; - type AccountStore = System; - type WeightInfo = (); - type MaxReserves = ConstU32<50>; - type ReserveIdentifier = [u8; 8]; -} - -parameter_type_with_key! { - pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { - Default::default() - }; -} - // impl orml_tokens::Config for Runtime { // type RuntimeEvent = RuntimeEvent; // type Balance = Balance; @@ -521,7 +441,113 @@ parameter_type_with_key! { // type SovereignOrigin = EnsureRoot; // } +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; +// Configure a mock runtime to test the pallet. +frame_support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + Tokens: orml_tokens::{Pallet, Storage, Config, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Event}, + } +); +pub type Balance = u128; +pub type BlockNumber = u64; +pub type Index = u64; +pub type Amount = i64; + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const SS58Prefix: u8 = 42; +} +impl frame_system::Config for Test { + type BaseCallFilter = Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Index = Index; + type BlockNumber = BlockNumber; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = Header; + type RuntimeEvent = TestEvent; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = SS58Prefix; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} +pub type TestEvent = RuntimeEvent; +parameter_types! { + pub const MaxLocks: u32 = 50; +} + +parameter_type_with_key! { + pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { + 0 + }; +} + +pub struct CurrencyHooks(sp_std::marker::PhantomData); +impl + orml_traits::currency::MutationHooks for CurrencyHooks +{ + type OnDust = orml_tokens::BurnDust; + type OnSlash = (); + type PreDeposit = (); + type PostDeposit = (); + type PreTransfer = (); + type PostTransfer = (); + type OnNewTokenAccount = (); + type OnKilledTokenAccount = (); +} + +impl orml_tokens::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Balance = Balance; + type Amount = Amount; + type CurrencyId = CurrencyId; + type WeightInfo = (); + type ExistentialDeposits = ExistentialDeposits; + type CurrencyHooks = CurrencyHooks; + type MaxLocks = MaxLocks; + type MaxReserves = ConstU32<0>; + type ReserveIdentifier = (); + type DustRemovalWhitelist = Everything; +} + +parameter_types! { + pub const ExistentialDeposit: Balance = 1000; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Test { + type MaxLocks = MaxLocks; + /// The type for recording an account's balance. + type Balance = Balance; + /// The ubiquitous event type. + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = pallet_balances::weights::SubstrateWeight; + type MaxReserves = MaxReserves; + type ReserveIdentifier = (); +} From e961df059ce93698ee1bedd534dc9db3bdc74791 Mon Sep 17 00:00:00 2001 From: Marcel Ebert Date: Thu, 2 Nov 2023 16:01:03 +0100 Subject: [PATCH 10/20] Add `std` feature --- runtime/integration-tests/Cargo.toml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/runtime/integration-tests/Cargo.toml b/runtime/integration-tests/Cargo.toml index 473c98fe1..28d03507e 100644 --- a/runtime/integration-tests/Cargo.toml +++ b/runtime/integration-tests/Cargo.toml @@ -52,3 +52,9 @@ orml-xtokens = { git = "https://github.com/open-web3-stack/open-runtime-module-l pendulum-runtime = { path = "../pendulum" } amplitude-runtime = {path = "../amplitude" } + +[features] +default = ["std"] +std = [ + "codec/std", +] From ccd187e463ce1fda95e5d5525e3ffb1afd27ad2d Mon Sep 17 00:00:00 2001 From: bogdanS98 Date: Fri, 3 Nov 2023 14:45:08 +0200 Subject: [PATCH 11/20] Fix sibling runtime, integration tests and update xcm configs for all runtimes with the correct multilocations --- runtime/integration-tests/Cargo.toml | 9 + .../integration-tests/src/amplitude_tests.rs | 29 +- runtime/integration-tests/src/lib.rs | 2 + runtime/integration-tests/src/mock.rs | 10 +- .../integration-tests/src/pendulum_tests.rs | 24 +- runtime/integration-tests/src/sibling.rs | 794 +++++++++--------- runtime/integration-tests/src/test_macros.rs | 103 ++- 7 files changed, 522 insertions(+), 449 deletions(-) diff --git a/runtime/integration-tests/Cargo.toml b/runtime/integration-tests/Cargo.toml index 28d03507e..92081583e 100644 --- a/runtime/integration-tests/Cargo.toml +++ b/runtime/integration-tests/Cargo.toml @@ -9,6 +9,11 @@ version = "0.1.0" codec = { package = "parity-scale-codec", version = "3.0.0" } scale-info = { version = "2.1.2", features = ["derive"] } serde = { version = "1.0.144", features = ["derive"] } +log = { version = "0.4.17", default-features = false } +smallvec = "1.9.0" + +# Spacewalk libraries +spacewalk-primitives = { git = "https://github.com/pendulum-chain/spacewalk", default-features = false, rev = "58983d2695c309665c9c017a022436aaee088f3d"} frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40" } frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40" } @@ -39,6 +44,7 @@ cumulus-pallet-dmp-queue = {git = "https://github.com/paritytech/cumulus", branc cumulus-pallet-xcmp-queue = {git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.40"} cumulus-pallet-xcm = {git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.40"} cumulus-primitives-core = {git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.40"} +cumulus-primitives-utility = {git = "https://github.com/paritytech/cumulus", default-features = false, branch = "polkadot-v0.9.40"} parachain-info = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.40" } statemint-runtime = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.40" } @@ -50,6 +56,9 @@ orml-traits = {git = "https://github.com/open-web3-stack/open-runtime-module-lib orml-tokens = {git = "https://github.com/open-web3-stack/open-runtime-module-library.git", branch = "polkadot-v0.9.40" } orml-xtokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.40" } +# Local +runtime-common = {path = "../common", default-features = false} + pendulum-runtime = { path = "../pendulum" } amplitude-runtime = {path = "../amplitude" } diff --git a/runtime/integration-tests/src/amplitude_tests.rs b/runtime/integration-tests/src/amplitude_tests.rs index 45248ae2e..8e165bd5d 100644 --- a/runtime/integration-tests/src/amplitude_tests.rs +++ b/runtime/integration-tests/src/amplitude_tests.rs @@ -1,13 +1,14 @@ use crate::{ mock::{kusama_relay_ext, para_ext, ParachainType, USDT_ASSET_ID}, + sibling, test_macros::{ parachain1_transfer_asset_to_parachain2, parachain1_transfer_asset_to_parachain2_and_back, parachain1_transfer_incorrect_asset_to_parachain2_should_fail, transfer_10_relay_token_from_parachain_to_relay_chain, transfer_20_relay_token_from_relay_chain_to_parachain, - transfer_native_token_from_parachain1_to_parachain2, + transfer_native_token_from_parachain1_to_parachain2_and_back, }, - AMPLITUDE_ID, KUSAMA_ASSETHUB_ID, + AMPLITUDE_ID, KUSAMA_ASSETHUB_ID, SIBLING_ID, }; use frame_support::assert_ok; @@ -35,6 +36,16 @@ decl_test_parachain! { } } +decl_test_parachain! { + pub struct SiblingParachain { + Runtime = sibling::Runtime, + RuntimeOrigin = sibling::RuntimeOrigin, + XcmpMessageHandler = sibling::XcmpQueue, + DmpMessageHandler = sibling::DmpQueue, + new_ext = para_ext(ParachainType::Sibling), + } +} + decl_test_parachain! { pub struct AssetHubParachain { Runtime = kusama_asset_hub_runtime::Runtime, @@ -51,6 +62,7 @@ decl_test_network! { parachains = vec![ (1000, AssetHubParachain), (2124, AmplitudeParachain), + (9999, SiblingParachain), ], } } @@ -117,3 +129,16 @@ fn assethub_transfer_asset_to_amplitude_and_back() { network_id ); } + +#[test] +fn transfer_native_token_to_sibling_parachain_and_back() { + transfer_native_token_from_parachain1_to_parachain2_and_back!( + KusamaMockNet, + amplitude_runtime, + AmplitudeParachain, + sibling, + SiblingParachain, + AMPLITUDE_ID, + SIBLING_ID + ); +} diff --git a/runtime/integration-tests/src/lib.rs b/runtime/integration-tests/src/lib.rs index e9f3ca5bd..e015a378b 100644 --- a/runtime/integration-tests/src/lib.rs +++ b/runtime/integration-tests/src/lib.rs @@ -18,3 +18,5 @@ pub const POLKADOT_ASSETHUB_ID: u32 = 1000; pub const AMPLITUDE_ID: u32 = 2124; pub const KUSAMA_ASSETHUB_ID: u32 = 1000; + +pub const SIBLING_ID: u32 = 9999; diff --git a/runtime/integration-tests/src/mock.rs b/runtime/integration-tests/src/mock.rs index 2860597ce..6ac7f863a 100644 --- a/runtime/integration-tests/src/mock.rs +++ b/runtime/integration-tests/src/mock.rs @@ -1,4 +1,6 @@ -use crate::{AMPLITUDE_ID, KUSAMA_ASSETHUB_ID, PENDULUM_ID, POLKADOT_ASSETHUB_ID}; +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 polkadot_core_primitives::{AccountId, Balance, BlockNumber}; @@ -74,6 +76,8 @@ macro_rules! build_parachain_with_orml { orml_tokens::GenesisConfig::<$runtime> { balances: vec![ (AccountId::from(BOB), CurrencyId::XCM(0), units($orml_balance)), + (AccountId::from(ALICE), CurrencyId::XCM(0), units($orml_balance)), + (AccountId::from(BOB), CurrencyId::Native, units($orml_balance)), (AccountId::from(ALICE), CurrencyId::Native, units($orml_balance)), ], } @@ -199,7 +203,7 @@ impl ExtBuilderParachain { ParachainType::PolkadotAssetHub => POLKADOT_ASSETHUB_ID, ParachainType::KusamaAssetHub => KUSAMA_ASSETHUB_ID, ParachainType::Pendulum => PENDULUM_ID, - ParachainType::Sibling => PENDULUM_ID + 1, + ParachainType::Sibling => SIBLING_ID, ParachainType::Amplitude => AMPLITUDE_ID, } } @@ -249,7 +253,7 @@ impl Builder for ExtBuilderParachain { ) }, ParachainType::Sibling => { - use pendulum_runtime::{Runtime, System}; + use sibling::{Runtime, System}; build_parachain_with_orml!( self, Runtime, diff --git a/runtime/integration-tests/src/pendulum_tests.rs b/runtime/integration-tests/src/pendulum_tests.rs index d6d54442c..c312bad4b 100644 --- a/runtime/integration-tests/src/pendulum_tests.rs +++ b/runtime/integration-tests/src/pendulum_tests.rs @@ -1,13 +1,14 @@ use crate::{ mock::{para_ext, polkadot_relay_ext, ParachainType, USDT_ASSET_ID}, + sibling, test_macros::{ parachain1_transfer_asset_to_parachain2, parachain1_transfer_asset_to_parachain2_and_back, parachain1_transfer_incorrect_asset_to_parachain2_should_fail, transfer_10_relay_token_from_parachain_to_relay_chain, transfer_20_relay_token_from_relay_chain_to_parachain, - transfer_native_token_from_parachain1_to_parachain2, + transfer_native_token_from_parachain1_to_parachain2_and_back, }, - PENDULUM_ID, POLKADOT_ASSETHUB_ID, + PENDULUM_ID, POLKADOT_ASSETHUB_ID, SIBLING_ID, }; use frame_support::assert_ok; @@ -37,10 +38,10 @@ decl_test_parachain! { decl_test_parachain! { pub struct SiblingParachain { - Runtime = pendulum_runtime::Runtime, - RuntimeOrigin = pendulum_runtime::RuntimeOrigin, - XcmpMessageHandler = pendulum_runtime::XcmpQueue, - DmpMessageHandler = pendulum_runtime::DmpQueue, + Runtime = sibling::Runtime, + RuntimeOrigin = sibling::RuntimeOrigin, + XcmpMessageHandler = sibling::XcmpQueue, + DmpMessageHandler = sibling::DmpQueue, new_ext = para_ext(ParachainType::Sibling), } } @@ -61,7 +62,7 @@ decl_test_network! { parachains = vec![ (1000, AssetHubParachain), (2094, PendulumParachain), - (2095, SiblingParachain), + (9999, SiblingParachain), ], } } @@ -130,15 +131,12 @@ fn assethub_transfer_asset_to_pendulum_and_back() { } #[test] -fn transfer_pendulum_native_token_to_pendulum() { - // ID for Pendulum's second instance - pub const SIBLING_ID: u32 = PENDULUM_ID + 1; - - transfer_native_token_from_parachain1_to_parachain2!( +fn transfer_native_token_to_sibling_parachain_and_back() { + transfer_native_token_from_parachain1_to_parachain2_and_back!( PolkadotMockNet, pendulum_runtime, PendulumParachain, - pendulum_runtime, + sibling, SiblingParachain, PENDULUM_ID, SIBLING_ID diff --git a/runtime/integration-tests/src/sibling.rs b/runtime/integration-tests/src/sibling.rs index 9b630a481..cf523f6d4 100644 --- a/runtime/integration-tests/src/sibling.rs +++ b/runtime/integration-tests/src/sibling.rs @@ -1,400 +1,372 @@ // Based on https://github.com/open-web3-stack/open-runtime-module-library/blob/83a76c2bf66c0b1236c31077e6fb24bb760a3535/xtokens/src/mock/para.rs -// This is temporary until successful compiling -#![allow(warnings)] #![cfg(test)] -use codec::{Decode, Encode, MaxEncodedLen}; -use cumulus_primitives_core::GetChannelInfo; +use core::marker::PhantomData; use frame_support::{ - match_types, parameter_types, - traits::{ConstU32, Everything, Get}, + log, match_types, parameter_types, + traits::{ConstU32, ContainsPair, Everything, Nothing}, }; -use orml_traits::parameter_type_with_key; -use scale_info::TypeInfo; -use serde::{Deserialize, Serialize}; +use frame_system::EnsureRoot; +use orml_traits::{ + location::{RelativeReserveProvider, Reserve}, + parameter_type_with_key, +}; +use pallet_xcm::XcmPassthrough; +use polkadot_parachain::primitives::Sibling; +use polkadot_runtime_common::MAXIMUM_BLOCK_WEIGHT; use sp_core::H256; -use sp_debug_derive::RuntimeDebug; use sp_runtime::{ testing::Header, - traits::{BlakeTwo256, Convert, IdentityLookup}, - AccountId32, BoundedVec, BuildStorage, + traits::{BlakeTwo256, Convert, IdentityLookup, Zero}, + AccountId32, +}; +use xcm::v3::prelude::*; +use xcm_emulator::{ + cumulus_pallet_parachain_system::{self, RelayNumberStrictlyIncreases}, + Weight, }; -use xcm::{v3::prelude::*, CreateMatcher, MatchXcm}; -use xcm_emulator::TestExt; use xcm_executor::{ - traits::{ShouldExecute, WeightTrader}, - Config, + traits::{JustTry, ShouldExecute, WeightTrader}, + Assets, XcmExecutor, }; -use pendulum_runtime::ParachainInfo; +use spacewalk_primitives::CurrencyId; +use xcm::latest::Weight as XCMWeight; +use xcm_builder::{ + AccountId32Aliases, AllowUnpaidExecutionFrom, ConvertedConcreteId, EnsureXcmOrigin, + FixedWeightBounds, FungiblesAdapter, NoChecking, ParentIsPreset, RelayChainAsNative, + SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, + SignedToAccountId32, SovereignSignedViaLocation, +}; pub type AccountId = AccountId32; -#[derive( - Encode, - Decode, - Eq, - PartialEq, - Copy, - Clone, - RuntimeDebug, - PartialOrd, - Ord, - MaxEncodedLen, - TypeInfo, -)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub enum CurrencyId { - /// Relay chain token. - R, - /// Parachain A token. - A, - /// Parachain A A1 token. - A1, - /// Parachain B token. - B, - /// Parachain B B1 token - B1, - /// Parachain B B2 token - B2, - /// Parachain C token - C, - /// Parachain D token - D, +parameter_types! { + pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RelayNetwork: NetworkId = NetworkId::Polkadot; + pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); + pub CheckingAccount: AccountId = PolkadotXcm::check_account(); + pub UniversalLocation: InteriorMultiLocation = + X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())); + } +/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used +/// when determining ownership of accounts for asset transacting and when attempting to use XCM +/// `Transact` in order to determine the dispatch Origin. +pub type LocationToAccountId = ( + // The parent (Relay-chain) origin converts to the parent `AccountId`. + ParentIsPreset, + // Sibling parachain origins convert to AccountId via the `ParaId::into`. + SiblingParachainConvertsVia, + // Straight up local `AccountId32` origins just alias directly to `AccountId`. + AccountId32Aliases, +); + +/// 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 +/// in the form of a `MultiLocation`, in this case a pCfg (Para-Id, Currency-Id). pub struct CurrencyIdConvert; + +// Only supports native currency for now impl Convert> for CurrencyIdConvert { fn convert(id: CurrencyId) -> Option { match id { - CurrencyId::R => Some(Parent.into()), - CurrencyId::A => Some( - ( - Parent, - Parachain(1), - Junction::from(BoundedVec::try_from(b"A".to_vec()).unwrap()), - ) - .into(), - ), - CurrencyId::A1 => Some( - ( - Parent, - Parachain(1), - Junction::from(BoundedVec::try_from(b"A1".to_vec()).unwrap()), - ) - .into(), - ), - CurrencyId::B => Some( - ( - Parent, - Parachain(2), - Junction::from(BoundedVec::try_from(b"B".to_vec()).unwrap()), - ) - .into(), - ), - CurrencyId::B1 => Some( - ( - Parent, - Parachain(2), - Junction::from(BoundedVec::try_from(b"B1".to_vec()).unwrap()), - ) - .into(), - ), - CurrencyId::B2 => Some( - ( - Parent, - Parachain(2), - Junction::from(BoundedVec::try_from(b"B2".to_vec()).unwrap()), - ) - .into(), - ), - CurrencyId::C => Some( - ( - Parent, - Parachain(3), - Junction::from(BoundedVec::try_from(b"C".to_vec()).unwrap()), - ) - .into(), - ), - CurrencyId::D => Some( - ( - Parent, - Parachain(4), - Junction::from(BoundedVec::try_from(b"D".to_vec()).unwrap()), - ) - .into(), - ), + CurrencyId::Native => Some(MultiLocation::new( + 1, + X2(Parachain(ParachainInfo::parachain_id().into()), PalletInstance(10)), + )), + _ => None, } } } + impl Convert> for CurrencyIdConvert { - fn convert(l: MultiLocation) -> Option { - let mut a: Vec = "A".into(); - a.resize(32, 0); - let mut a1: Vec = "A1".into(); - a1.resize(32, 0); - let mut b: Vec = "B".into(); - b.resize(32, 0); - let mut b1: Vec = "B1".into(); - b1.resize(32, 0); - let mut b2: Vec = "B2".into(); - b2.resize(32, 0); - let mut c: Vec = "C".into(); - c.resize(32, 0); - let mut d: Vec = "D".into(); - d.resize(32, 0); - if l == MultiLocation::parent() { - return Some(CurrencyId::R) - } - match l { - MultiLocation { parents, interior } if parents == 1 => match interior { - X2(Parachain(1), GeneralKey { data, .. }) if data.to_vec() == a => - Some(CurrencyId::A), - X2(Parachain(1), GeneralKey { data, .. }) if data.to_vec() == a1 => - Some(CurrencyId::A1), - X2(Parachain(2), GeneralKey { data, .. }) if data.to_vec() == b => - Some(CurrencyId::B), - X2(Parachain(2), GeneralKey { data, .. }) if data.to_vec() == b1 => - Some(CurrencyId::B1), - X2(Parachain(2), GeneralKey { data, .. }) if data.to_vec() == b2 => - Some(CurrencyId::B2), - X2(Parachain(3), GeneralKey { data, .. }) if data.to_vec() == c => - Some(CurrencyId::C), - X2(Parachain(4), GeneralKey { data, .. }) if data.to_vec() == d => - Some(CurrencyId::D), - _ => None, - }, - MultiLocation { parents, interior } if parents == 0 => match interior { - X1(GeneralKey { data, .. }) if data.to_vec() == a => Some(CurrencyId::A), - X1(GeneralKey { data, .. }) if data.to_vec() == b => Some(CurrencyId::B), - X1(GeneralKey { data, .. }) if data.to_vec() == a1 => Some(CurrencyId::A1), - X1(GeneralKey { data, .. }) if data.to_vec() == b1 => Some(CurrencyId::B1), - X1(GeneralKey { data, .. }) if data.to_vec() == b2 => Some(CurrencyId::B2), - X1(GeneralKey { data, .. }) if data.to_vec() == c => Some(CurrencyId::C), - X1(GeneralKey { data, .. }) if data.to_vec() == d => Some(CurrencyId::D), - _ => None, - }, + 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: 0, interior: X1(PalletInstance(10)) } => + Some(CurrencyId::Native), _ => None, } } } + impl Convert> for CurrencyIdConvert { fn convert(a: MultiAsset) -> Option { - if let MultiAsset { fun: Fungible(_), id: Concrete(id) } = a { + if let MultiAsset { id: AssetId::Concrete(id), fun: _ } = a { Self::convert(id) } else { - Option::None + None } } } -// decl_test_parachain! { -// pub struct SiblingParachain { -// Runtime = Runtime, -// RuntimeOrigin = RuntimeOrigin, -// XcmpMessageHandler = XcmpQueue, -// DmpMessageHandler = DmpQueue, -// new_ext = para_ext(ParachainType::Sibling), -// } -// } - -// I think we're not going to use this but our relay mock instead -// I'll just leave it here in case we need something from it -// decl_test_relay_chain! { -// pub struct Relay { -// Runtime = Runtime, -// RuntimeCall = relay::RuntimeCall, -// RuntimeEvent = relay::RuntimeEvent, -// //XcmConfig = relay::XcmConfig, -// //MessageQueue = relay::MessageQueue, -// System = relay::System, -// new_ext = relay_ext(), -// } -// } - -// decl_test_relay_chain! { -// pub struct PolkadotRelay { -// Runtime = polkadot_runtime::Runtime, -// XcmConfig = polkadot_runtime::xcm_config::XcmConfig, -// new_ext = polkadot_relay_ext(), -// } -// } - -// decl_test_network! { -// pub struct TestNet { -// relay_chain = PolkadotRelay, -// parachains = vec![ -// (1, SiblingParachain), -// ], -// } -// } - -// impl orml_tokens::Config for Runtime { -// type RuntimeEvent = RuntimeEvent; -// type Balance = Balance; -// type Amount = Amount; -// type CurrencyId = CurrencyId; -// type WeightInfo = (); -// type ExistentialDeposits = ExistentialDeposits; -// type CurrencyHooks = (); -// type MaxLocks = ConstU32<50>; -// type MaxReserves = ConstU32<50>; -// type ReserveIdentifier = [u8; 8]; -// type DustRemovalWhitelist = Everything; -// } - -// parameter_types! { -// pub const ReservedXcmpWeight: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_div(4), 0); -// pub const ReservedDmpWeight: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_div(4), 0); -// } - -// impl parachain_info::Config for Runtime {} - -// parameter_types! { -// pub const RelayLocation: MultiLocation = MultiLocation::parent(); -// pub const RelayNetwork: NetworkId = NetworkId::Kusama; -// pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); -// pub UniversalLocation: InteriorMultiLocation = -// X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())); -// } - -// pub type LocationToAccountId = ( -// ParentIsPreset, -// SiblingParachainConvertsVia, -// AccountId32Aliases, -// ); - -// pub type XcmOriginToCallOrigin = ( -// SovereignSignedViaLocation, -// RelayChainAsNative, -// SiblingParachainAsNative, -// SignedAccountId32AsNative, -// XcmPassthrough, -// ); - -// pub type LocalAssetTransactor = MultiCurrencyAdapter< -// Tokens, -// (), -// IsNativeConcrete, -// AccountId, -// LocationToAccountId, -// CurrencyId, -// CurrencyIdConvert, -// (), -// >; - -// pub type XcmRouter = ParachainXcmRouter; -// pub type Barrier = (TakeWeightCredit, AllowTopLevelPaidExecution); - -// parameter_types! { -// pub const UnitWeightCost: Weight = Weight::from_parts(10, 10); -// pub const BaseXcmWeight: Weight = Weight::from_parts(100_000_000, 100_000_000); -// pub const MaxInstructions: u32 = 100; -// pub const MaxAssetsIntoHolding: u32 = 64; -// } - -// pub struct XcmConfig; -// impl Config for XcmConfig { -// type RuntimeCall = RuntimeCall; -// type XcmSender = XcmRouter; -// type AssetTransactor = LocalAssetTransactor; -// type OriginConverter = XcmOriginToCallOrigin; -// type IsReserve = MultiNativeAsset; -// type IsTeleporter = NativeAsset; -// type UniversalLocation = UniversalLocation; -// type Barrier = Barrier; -// type Weigher = FixedWeightBounds; -// type Trader = (); -// type ResponseHandler = (); -// type AssetTrap = PolkadotXcm; -// type AssetClaims = PolkadotXcm; -// type SubscriptionService = PolkadotXcm; -// type AssetLocker = PolkadotXcm; -// type AssetExchanger = (); -// type PalletInstancesInfo = (); -// type MaxAssetsIntoHolding = MaxAssetsIntoHolding; -// type FeeManager = (); -// type MessageExporter = (); -// type UniversalAliases = Nothing; -// type CallDispatcher = RuntimeCall; -// type SafeCallFilter = Everything; -// } - -// pub struct ChannelInfo; -// impl GetChannelInfo for ChannelInfo { -// fn get_channel_status(_id: ParaId) -> ChannelStatus { -// ChannelStatus::Ready(10, 10) -// } -// fn get_channel_max(_id: ParaId) -> Option { -// Some(usize::max_value()) -// } -// } - -// impl cumulus_pallet_xcmp_queue::Config for Runtime { -// type RuntimeEvent = RuntimeEvent; -// type XcmExecutor = XcmExecutor; -// type ChannelInfo = ChannelInfo; -// type VersionWrapper = (); -// type ExecuteOverweightOrigin = EnsureRoot; -// type ControllerOrigin = EnsureRoot; -// type ControllerOriginConverter = XcmOriginToCallOrigin; -// type WeightInfo = (); -// type PriceForSiblingDelivery = (); -// } - -// impl cumulus_pallet_dmp_queue::Config for Runtime { -// type RuntimeEvent = RuntimeEvent; -// type XcmExecutor = XcmExecutor; -// type ExecuteOverweightOrigin = EnsureRoot; -// } - -// impl cumulus_pallet_xcm::Config for Runtime { -// type RuntimeEvent = RuntimeEvent; -// type XcmExecutor = XcmExecutor; -// } - -//pub type LocalOriginToLocation = SignedToAccountId32; +/// Convert an incoming `MultiLocation` into a `CurrencyId` if possible. +/// Here we need to know the canonical representation of all the tokens we handle in order to +/// correctly convert their `MultiLocation` representation into our internal `CurrencyId` type. +impl xcm_executor::traits::Convert for CurrencyIdConvert { + fn convert(location: MultiLocation) -> Result { + >>::convert(location.clone()) + .ok_or(location) + } +} + +/// A `FilterAssetLocation` implementation. Filters multi native assets whose +/// reserve is same with `origin`. +pub struct MultiNativeAsset(PhantomData); +impl ContainsPair for MultiNativeAsset +where + ReserveProvider: Reserve, +{ + fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + if let Some(ref reserve) = ReserveProvider::reserve(asset) { + if reserve == origin { + return true + } + } + false + } +} + +/// Means for transacting the fungibles assets of ths parachain. +pub type FungiblesTransactor = FungiblesAdapter< + // Use this fungibles implementation + Tokens, + // This means that this adapter should handle any token that `CurrencyIdConvert` can convert + // to `CurrencyId`, the `CurrencyId` type of `Tokens`, the fungibles implementation it uses. + ConvertedConcreteId, + // Convert an XCM MultiLocation into a local account id + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly) + AccountId, + // We dont allow teleports. + NoChecking, + // The account to use for tracking teleports. + CheckingAccount, +>; + +/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, +/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can +/// biases the kind of local `Origin` it will become. +pub type XcmOriginToTransactDispatchOrigin = ( + // Sovereign account converter; this attempts to derive an `AccountId` from the origin location + // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for + // foreign chains who want to have a local sovereign account on this chain which they control. + SovereignSignedViaLocation, + // Native converter for Relay-chain (Parent) location; will converts to a `Relay` origin when + // recognized. + RelayChainAsNative, + // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when + // recognized. + SiblingParachainAsNative, + // Native signed account converter; this just converts an `AccountId32` origin into a normal + // `Origin::Signed` origin of the same 32-byte value. + SignedAccountId32AsNative, + // Xcm origins can be represented natively under the Xcm pallet's Xcm origin. + XcmPassthrough, +); + +parameter_types! { + // One XCM operation is 1_000_000_000 weight - almost certainly a conservative estimate. + pub UnitWeightCost: XCMWeight = XCMWeight::from_parts(1_000_000_000, 0); + pub const MaxInstructions: u32 = 100; + pub SelfLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(ParachainInfo::parachain_id().into()))); + pub const BaseXcmWeight: XCMWeight = XCMWeight::from_parts(150_000_000, 0); + pub const MaxAssetsForTransfer: usize = 2; +} + +match_types! { + pub type ParentOrParentsExecutivePlurality: impl Contains = { + MultiLocation { parents: 1, interior: Here } | + MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Executive, .. }) } + }; +} + +//TODO: move DenyThenTry to polkadot's xcm module. +/// Deny executing the xcm message if it matches any of the Deny filter regardless of anything else. +/// If it passes the Deny, and matches one of the Allow cases then it is let through. +pub struct DenyThenTry(PhantomData, PhantomData) +where + Deny: ShouldExecute, + Allow: ShouldExecute; + +impl ShouldExecute for DenyThenTry +where + Deny: ShouldExecute, + Allow: ShouldExecute, +{ + fn should_execute( + origin: &MultiLocation, + instructions: &mut [Instruction], + max_weight: XCMWeight, + weight_credit: &mut XCMWeight, + ) -> Result<(), ()> { + Deny::should_execute(origin, instructions, max_weight, weight_credit)?; + Allow::should_execute(origin, instructions, max_weight, weight_credit) + } +} + +// See issue #5233 +pub struct DenyReserveTransferToRelayChain; +impl ShouldExecute for DenyReserveTransferToRelayChain { + fn should_execute( + origin: &MultiLocation, + instructions: &mut [Instruction], + _max_weight: XCMWeight, + _weight_credit: &mut XCMWeight, + ) -> Result<(), ()> { + if instructions.iter().any(|inst| { + matches!( + inst, + InitiateReserveWithdraw { + reserve: MultiLocation { parents: 1, interior: Here }, + .. + } | DepositReserveAsset { dest: MultiLocation { parents: 1, interior: Here }, .. } | + TransferReserveAsset { + dest: MultiLocation { parents: 1, interior: Here }, + .. + } + ) + }) { + return Err(()) // Deny + } + + // allow reserve transfers to arrive from relay chain + if matches!(origin, MultiLocation { parents: 1, interior: Here }) && + instructions.iter().any(|inst| matches!(inst, ReserveAssetDeposited { .. })) + { + log::warn!( + target: "xcm::barriers", + "Unexpected ReserveAssetDeposited from the relay chain", + ); + } + // Permit everything else + Ok(()) + } +} + +pub type Barrier = AllowUnpaidExecutionFrom; + +pub struct XcmConfig; +impl xcm_executor::Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = XcmRouter; + // How to withdraw and deposit an asset. + type AssetTransactor = FungiblesTransactor; + type OriginConverter = XcmOriginToTransactDispatchOrigin; + type IsReserve = MultiNativeAsset; + // Teleporting is disabled. + type IsTeleporter = (); + type UniversalLocation = UniversalLocation; + type Barrier = Barrier; + type Weigher = FixedWeightBounds; + type Trader = AllTokensAreCreatedEqualToWeight; + type ResponseHandler = PolkadotXcm; + type AssetTrap = PolkadotXcm; + type AssetLocker = (); + type AssetExchanger = (); + type AssetClaims = PolkadotXcm; + type SubscriptionService = PolkadotXcm; + type PalletInstancesInfo = AllPalletsWithSystem; + type MaxAssetsIntoHolding = ConstU32<8>; + type FeeManager = (); + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = RuntimeCall; + type SafeCallFilter = Everything; +} + +/// No local origins on this chain are allowed to dispatch XCM sends/executions. +pub type LocalOriginToLocation = SignedToAccountId32; + +/// The means for routing XCM messages which are not for local execution into the right message +/// queues. +pub type XcmRouter = ( + // Two routers - use UMP to communicate with the relay chain: + cumulus_primitives_utility::ParentAsUmp, + // ..and XCMP to communicate with the sibling chains. + XcmpQueue, +); + +impl pallet_xcm::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type CurrencyMatcher = (); + type SendXcmOrigin = EnsureXcmOrigin; + type XcmRouter = XcmRouter; + type ExecuteXcmOrigin = EnsureXcmOrigin; + type XcmExecuteFilter = Everything; + // ^ Disable dispatchable execute on the XCM pallet. + // Needs to be `Everything` for local testing. + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = Nothing; + type XcmReserveTransferFilter = Everything; + type Weigher = FixedWeightBounds; + type UniversalLocation = UniversalLocation; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + // ^ Override for AdvertisedXcmVersion default + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; + type TrustedLockers = (); + type SovereignAccountOf = LocationToAccountId; + type MaxLockers = ConstU32<8>; + type WeightInfo = pallet_xcm::TestWeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type ReachableDest = ReachableDest; +} #[cfg(feature = "runtime-benchmarks")] parameter_types! { pub ReachableDest: Option = Some(Parent.into()); } -// impl pallet_xcm::Config for Runtime { -// type RuntimeEvent = RuntimeEvent; -// type SendXcmOrigin = EnsureXcmOrigin; -// type XcmRouter = XcmRouter; -// type ExecuteXcmOrigin = EnsureXcmOrigin; -// type XcmExecuteFilter = Everything; -// type XcmExecutor = XcmExecutor; -// type XcmTeleportFilter = Nothing; -// type XcmReserveTransferFilter = Everything; -// type Weigher = FixedWeightBounds; -// type UniversalLocation = UniversalLocation; -// type RuntimeOrigin = RuntimeOrigin; -// type RuntimeCall = RuntimeCall; -// const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; -// type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; -// type Currency = Balances; -// type CurrencyMatcher = (); -// type TrustedLockers = (); -// type SovereignAccountOf = (); -// type MaxLockers = ConstU32<8>; -// type WeightInfo = pallet_xcm::TestWeightInfo; -// #[cfg(feature = "runtime-benchmarks")] -// type ReachableDest = ReachableDest; -// } +parameter_type_with_key! { + pub ParachainMinFee: |_location: MultiLocation| -> Option { + None + }; +} + +impl orml_xtokens::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Balance = Balance; + type CurrencyId = CurrencyId; + type CurrencyIdConvert = CurrencyIdConvert; + type AccountIdToMultiLocation = AccountIdToMultiLocation; + type SelfLocation = SelfLocation; + type XcmExecutor = XcmExecutor; + type Weigher = FixedWeightBounds; + type BaseXcmWeight = BaseXcmWeight; + type MaxAssetsForTransfer = MaxAssetsForTransfer; + type MinXcmFee = ParachainMinFee; //TODO to support hrmp transfer beetween parachain adjust this parameter + type MultiLocationsFilter = Everything; + type ReserveProvider = RelativeReserveProvider; + type UniversalLocation = UniversalLocation; +} pub struct AccountIdToMultiLocation; impl Convert for AccountIdToMultiLocation { fn convert(account: AccountId) -> MultiLocation { - X1(Junction::AccountId32 { network: None, id: account.into() }).into() + MultiLocation { + parents: 0, + interior: X1(xcm::v3::Junction::AccountId32 { network: None, id: account.into() }), + } } } +impl cumulus_pallet_xcm::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type XcmExecutor = XcmExecutor; +} + +#[cfg(feature = "runtime-benchmarks")] parameter_types! { - pub SelfLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into()))); - pub const MaxAssetsForTransfer: usize = 3; + pub ReachableDest: Option = Some(Parent.into()); } match_types! { @@ -409,51 +381,28 @@ match_types! { }; } -parameter_type_with_key! { - pub ParachainMinFee: |location: MultiLocation| -> Option { - #[allow(clippy::match_ref_pats)] // false positive - match (location.parents, location.first_interior()) { - (1, Some(Parachain(3))) => Some(40), - _ => None, - } - }; -} - -// impl orml_xtokens::Config for Runtime { -// type RuntimeEvent = RuntimeEvent; -// type Balance = Balance; -// type CurrencyId = CurrencyId; -// type CurrencyIdConvert = CurrencyIdConvert; -// type AccountIdToMultiLocation = AccountIdToMultiLocation; -// type SelfLocation = SelfLocation; -// type MultiLocationsFilter = ParentOrParachains; -// type MinXcmFee = ParachainMinFee; -// type XcmExecutor = XcmExecutor; -// type Weigher = FixedWeightBounds; -// type BaseXcmWeight = BaseXcmWeight; -// type UniversalLocation = UniversalLocation; -// type MaxAssetsForTransfer = MaxAssetsForTransfer; -// type ReserveProvider = AbsoluteReserveProvider; -// } - -// impl orml_xcm::Config for Runtime { -// type RuntimeEvent = RuntimeEvent; -// type SovereignOrigin = EnsureRoot; -// } - -type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; -type Block = frame_system::mocking::MockBlock; +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; // Configure a mock runtime to test the pallet. frame_support::construct_runtime!( - pub enum Test where + pub enum Runtime where Block = Block, NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system::{Pallet, Call, Storage, Config, Event}, Tokens: orml_tokens::{Pallet, Storage, Config, Event}, + XTokens: orml_xtokens::{Pallet, Storage, Call, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Event}, + PolkadotXcm: pallet_xcm, + ParachainSystem: cumulus_pallet_parachain_system::{ + Pallet, Call, Config, Storage, Inherent, Event, ValidateUnsigned, + }, + ParachainInfo: parachain_info::{Pallet, Storage, Config}, + XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event}, + DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event}, + CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin}, } ); @@ -466,7 +415,7 @@ parameter_types! { pub const BlockHashCount: u64 = 250; pub const SS58Prefix: u8 = 42; } -impl frame_system::Config for Test { +impl frame_system::Config for Runtime { type BaseCallFilter = Everything; type BlockWeights = (); type BlockLength = (); @@ -480,7 +429,7 @@ impl frame_system::Config for Test { type AccountId = AccountId; type Lookup = IdentityLookup; type Header = Header; - type RuntimeEvent = TestEvent; + type RuntimeEvent = RuntimeEvent; type BlockHashCount = BlockHashCount; type Version = (); type PalletInfo = PalletInfo; @@ -489,12 +438,10 @@ impl frame_system::Config for Test { type OnKilledAccount = (); type SystemWeightInfo = (); type SS58Prefix = SS58Prefix; - type OnSetCode = (); + type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; type MaxConsumers = frame_support::traits::ConstU32<16>; } -pub type TestEvent = RuntimeEvent; - parameter_types! { pub const MaxLocks: u32 = 50; } @@ -519,7 +466,7 @@ impl type OnKilledTokenAccount = (); } -impl orml_tokens::Config for Test { +impl orml_tokens::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type Amount = Amount; @@ -538,7 +485,7 @@ parameter_types! { pub const MaxReserves: u32 = 50; } -impl pallet_balances::Config for Test { +impl pallet_balances::Config for Runtime { type MaxLocks = MaxLocks; /// The type for recording an account's balance. type Balance = Balance; @@ -547,7 +494,76 @@ impl pallet_balances::Config for Test { type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; - type WeightInfo = pallet_balances::weights::SubstrateWeight; + type WeightInfo = pallet_balances::weights::SubstrateWeight; type MaxReserves = MaxReserves; type ReserveIdentifier = (); } + +parameter_types! { + pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); + pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); +} + +impl cumulus_pallet_parachain_system::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type OnSystemEvent = (); + type SelfParaId = parachain_info::Pallet; + type DmpMessageHandler = DmpQueue; + type ReservedDmpWeight = ReservedDmpWeight; + type OutboundXcmpMessageSource = XcmpQueue; + type XcmpMessageHandler = XcmpQueue; + type ReservedXcmpWeight = ReservedXcmpWeight; + type CheckAssociatedRelayNumber = RelayNumberStrictlyIncreases; +} + +impl parachain_info::Config for Runtime {} + +impl cumulus_pallet_xcmp_queue::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type XcmExecutor = XcmExecutor; + type ChannelInfo = ParachainSystem; + type VersionWrapper = (); + type ExecuteOverweightOrigin = EnsureRoot; + type ControllerOrigin = EnsureRoot; + type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin; + type PriceForSiblingDelivery = (); + type WeightInfo = cumulus_pallet_xcmp_queue::weights::SubstrateWeight; +} + +impl cumulus_pallet_dmp_queue::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type XcmExecutor = XcmExecutor; + type ExecuteOverweightOrigin = EnsureRoot; +} + +/// A trader who believes all tokens are created equal to "weight" of any chain, +/// which is not true, but good enough to mock the fee payment of XCM execution. +/// +/// This mock will always trade `n` amount of weight to `n` amount of tokens. +pub struct AllTokensAreCreatedEqualToWeight(MultiLocation); +impl WeightTrader for AllTokensAreCreatedEqualToWeight { + fn new() -> Self { + Self(MultiLocation::parent()) + } + + fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result { + let asset_id = payment.fungible.iter().next().expect("Payment must be something; qed").0; + let required = + MultiAsset { id: asset_id.clone(), fun: Fungible(weight.ref_time() as u128) }; + + if let MultiAsset { fun: _, id: Concrete(ref id) } = &required { + self.0 = id.clone(); + } + + let unused = payment.checked_sub(required).map_err(|_| XcmError::TooExpensive)?; + Ok(unused) + } + + fn refund_weight(&mut self, weight: Weight) -> Option { + if weight.is_zero() { + None + } else { + Some((self.0.clone(), weight.ref_time() as u128).into()) + } + } +} diff --git a/runtime/integration-tests/src/test_macros.rs b/runtime/integration-tests/src/test_macros.rs index 15253a388..702d68874 100644 --- a/runtime/integration-tests/src/test_macros.rs +++ b/runtime/integration-tests/src/test_macros.rs @@ -461,7 +461,7 @@ macro_rules! parachain1_transfer_asset_to_parachain2_and_back { }}; } -macro_rules! transfer_native_token_from_parachain1_to_parachain2 { +macro_rules! transfer_native_token_from_parachain1_to_parachain2_and_back { ( $mocknet:ident, $parachain1_runtime:ident, @@ -472,21 +472,15 @@ macro_rules! transfer_native_token_from_parachain1_to_parachain2 { $parachain2_id:ident ) => {{ use crate::mock::{units, ALICE, BOB}; - use frame_support::{log::info, traits::fungibles::Inspect}; + use frame_support::traits::fungibles::Inspect; use polkadot_core_primitives::Balance; - use sp_tracing; use xcm::latest::{ - Junction, - Junction::AccountId32, - Junctions::{X2, X3}, - MultiLocation, WeightLimit, + Junction, Junction::AccountId32, Junctions::X2, MultiLocation, WeightLimit, }; use $parachain1_runtime::CurrencyId; $mocknet::reset(); - sp_tracing::try_init_simple(); - let transfer_amount: Balance = units(10); let asset_location = MultiLocation::new( 1, @@ -501,12 +495,18 @@ macro_rules! transfer_native_token_from_parachain1_to_parachain2 { native_tokens_before ); }); + $parachain2::execute_with(|| { + assert_eq!( + $parachain2_runtime::Tokens::balance(CurrencyId::Native, &BOB.into()), + native_tokens_before + ); + }); // Execute the transfer from parachain1 to parachain2 $parachain1::execute_with(|| { - use $parachain1_runtime::XTokens; + use $parachain1_runtime::{RuntimeEvent, System, XTokens}; - // transfer using multilocation + // Transfer using multilocation assert_ok!(XTokens::transfer_multiasset( $parachain1_runtime::RuntimeOrigin::signed(ALICE.into()), Box::new((asset_location.clone(), transfer_amount).into()), @@ -523,28 +523,49 @@ macro_rules! transfer_native_token_from_parachain1_to_parachain2 { WeightLimit::Unlimited )); - // transfer using currency id - // assert_ok!(XTokens::transfer( - // $parachain1_runtime::RuntimeOrigin::signed(ALICE.into()), - // CurrencyId::Native, - // transfer_amount, - // Box::new( - // MultiLocation::new( - // 1, - // X3( - // Junction::Parachain($parachain2_id), - // Junction::PalletInstance(10), - // Junction::AccountId32 { network: None, id: BOB.into() } - // ) - // ) - // .into() - // ), - // WeightLimit::Unlimited - // )); + assert!(System::events().iter().any(|r| matches!( + r.event, + RuntimeEvent::XTokens(orml_xtokens::Event::TransferredMultiAssets { .. }) + ))); + }); + + // Verify BOB's balance on parachain2 after receiving + // Should increase by the transfer amount + $parachain2::execute_with(|| { + assert_eq!( + $parachain2_runtime::Tokens::balance(CurrencyId::Native, &BOB.into()), + native_tokens_before + transfer_amount + ); }); + // Verify ALICE's balance on parachain1 after transfer $parachain1::execute_with(|| { - use $parachain1_runtime::{RuntimeEvent, System}; + assert_eq!( + $parachain1_runtime::Tokens::balance(CurrencyId::Native, &ALICE.into()), + native_tokens_before - transfer_amount + ); + }); + + // Send same amount back to ALICE on parachain1 + $parachain2::execute_with(|| { + use $parachain2_runtime::{RuntimeEvent, System, XTokens}; + + // Transfer using the same multilocation + assert_ok!(XTokens::transfer_multiasset( + $parachain2_runtime::RuntimeOrigin::signed(BOB.into()), + Box::new((asset_location.clone(), transfer_amount).into()), + Box::new( + MultiLocation { + parents: 1, + interior: X2( + Junction::Parachain($parachain1_id), + AccountId32 { network: None, id: ALICE } + ) + } + .into() + ), + WeightLimit::Unlimited + )); assert!(System::events().iter().any(|r| matches!( r.event, @@ -552,23 +573,21 @@ macro_rules! transfer_native_token_from_parachain1_to_parachain2 { ))); }); - // Verify the balance on the parachain2 after transfer + // Verify BOB's balance on parachain2 after transfer + // Should become the same amount as initial balance before both transfers $parachain2::execute_with(|| { - // Currently failing - // assert_eq!( - // $parachain2_runtime::Tokens::balance(CurrencyId::Native, &BOB.into()), - // transfer_amount - // ); - - // log BOB's balance to see if there's any amount - info!("{:?}", $parachain2_runtime::Tokens::balance(CurrencyId::Native, &BOB.into())); + assert_eq!( + $parachain2_runtime::Tokens::balance(CurrencyId::Native, &BOB.into()), + native_tokens_before + ); }); - // Verify the balance on the parachain1 after transfer + // Verify ALICE's balance on parachain1 after receiving + // Should become the same amount as initial balance before both transfers $parachain1::execute_with(|| { assert_eq!( $parachain1_runtime::Tokens::balance(CurrencyId::Native, &ALICE.into()), - native_tokens_before - transfer_amount + native_tokens_before ); }); }}; @@ -580,4 +599,4 @@ pub(super) use parachain1_transfer_asset_to_parachain2_and_back; pub(super) use parachain1_transfer_incorrect_asset_to_parachain2_should_fail; pub(super) use transfer_10_relay_token_from_parachain_to_relay_chain; pub(super) use transfer_20_relay_token_from_relay_chain_to_parachain; -pub(super) use transfer_native_token_from_parachain1_to_parachain2; +pub(super) use transfer_native_token_from_parachain1_to_parachain2_and_back; From 30c8c408e01c94aa9e18476bfbb8510891baf9ae Mon Sep 17 00:00:00 2001 From: bogdanS98 Date: Fri, 3 Nov 2023 14:54:15 +0200 Subject: [PATCH 12/20] Add xcm config updates for all runtimes --- runtime/amplitude/src/xcm_config.rs | 18 ++++++++++++++---- runtime/foucoco/src/xcm_config.rs | 9 +++++++++ runtime/pendulum/src/xcm_config.rs | 2 ++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/runtime/amplitude/src/xcm_config.rs b/runtime/amplitude/src/xcm_config.rs index d4a5ea3d0..a7539271d 100644 --- a/runtime/amplitude/src/xcm_config.rs +++ b/runtime/amplitude/src/xcm_config.rs @@ -15,6 +15,7 @@ use orml_traits::{ use pallet_xcm::XcmPassthrough; use polkadot_parachain::primitives::Sibling; use polkadot_runtime_common::impls::ToAuthor; +use runtime_common::parachains::kusama::asset_hub; use sp_runtime::traits::Convert; use xcm::latest::{prelude::*, Weight as XCMWeight}; use xcm_builder::{ @@ -27,7 +28,6 @@ use xcm_executor::{ traits::{JustTry, ShouldExecute}, XcmExecutor, }; -use runtime_common::parachains::kusama::asset_hub; const XCM_ASSET_RELAY_KSM: u8 = 0; const XCM_ASSET_ASSETHUB_USDT: u8 = 1; @@ -75,6 +75,10 @@ impl Convert> for CurrencyIdConvert { )), _ => None, }, + CurrencyId::Native => Some(MultiLocation::new( + 1, + X2(Parachain(ParachainInfo::parachain_id().into()), PalletInstance(10)), + )), _ => None, } } @@ -83,16 +87,22 @@ impl Convert> for CurrencyIdConvert { impl Convert> for CurrencyIdConvert { fn convert(location: MultiLocation) -> Option { match location { - MultiLocation { parents: 1, interior: Here } => Some(CurrencyId::XCM(XCM_ASSET_RELAY_KSM)), + MultiLocation { parents: 1, interior: Here } => + Some(CurrencyId::XCM(XCM_ASSET_RELAY_KSM)), MultiLocation { parents: 1, interior: X3( Parachain(asset_hub::PARA_ID), PalletInstance(asset_hub::ASSET_PALLET_ID), - GeneralIndex(asset_hub::USDT_ASSET_ID) - ) + GeneralIndex(asset_hub::USDT_ASSET_ID), + ), } => Some(CurrencyId::XCM(XCM_ASSET_ASSETHUB_USDT)), + MultiLocation { parents: 1, interior: X2(Parachain(id), PalletInstance(10)) } + if id == u32::from(ParachainInfo::parachain_id()) => + Some(CurrencyId::Native), + MultiLocation { parents: 0, interior: X1(PalletInstance(10)) } => + Some(CurrencyId::Native), _ => None, } } diff --git a/runtime/foucoco/src/xcm_config.rs b/runtime/foucoco/src/xcm_config.rs index 6f16a76fb..8f2915bb3 100644 --- a/runtime/foucoco/src/xcm_config.rs +++ b/runtime/foucoco/src/xcm_config.rs @@ -63,6 +63,10 @@ impl Convert> for CurrencyIdConvert { 0 => Some(MultiLocation::parent()), _ => None, }, + CurrencyId::Native => Some(MultiLocation::new( + 1, + X2(Parachain(ParachainInfo::parachain_id().into()), PalletInstance(10)), + )), _ => None, } } @@ -72,6 +76,11 @@ impl Convert> for CurrencyIdConvert { fn convert(location: MultiLocation) -> Option { match location { MultiLocation { parents: 1, interior: Here } => Some(CurrencyId::XCM(0)), + MultiLocation { parents: 1, interior: X2(Parachain(id), PalletInstance(10)) } + if id == u32::from(ParachainInfo::parachain_id()) => + Some(CurrencyId::Native), + MultiLocation { parents: 0, interior: X1(PalletInstance(10)) } => + Some(CurrencyId::Native), _ => None, } } diff --git a/runtime/pendulum/src/xcm_config.rs b/runtime/pendulum/src/xcm_config.rs index 35ec76de2..cf20fdf82 100644 --- a/runtime/pendulum/src/xcm_config.rs +++ b/runtime/pendulum/src/xcm_config.rs @@ -102,6 +102,8 @@ impl Convert> for CurrencyIdConvert { MultiLocation { parents: 1, interior: X2(Parachain(id), PalletInstance(10)) } if id == u32::from(ParachainInfo::parachain_id()) => Some(CurrencyId::Native), + MultiLocation { parents: 0, interior: X1(PalletInstance(10)) } => + Some(CurrencyId::Native), _ => None, } } From 8b0decd7f5cb14105e1b2e7d1098506f4c96b76a Mon Sep 17 00:00:00 2001 From: bogdanS98 Date: Fri, 3 Nov 2023 14:57:05 +0200 Subject: [PATCH 13/20] Cargo lock --- Cargo.lock | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 4fa0f3723..dcd7b1a56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9964,9 +9964,11 @@ dependencies = [ "cumulus-pallet-xcm", "cumulus-pallet-xcmp-queue", "cumulus-primitives-core", + "cumulus-primitives-utility", "frame-support", "frame-system", "kusama-runtime", + "log", "orml-tokens", "orml-traits", "orml-xcm", @@ -9984,14 +9986,17 @@ dependencies = [ "polkadot-runtime", "polkadot-runtime-common", "polkadot-runtime-parachains", + "runtime-common", "scale-info", "serde", + "smallvec", "sp-core", "sp-debug-derive", "sp-io", "sp-runtime", "sp-std", "sp-tracing", + "spacewalk-primitives", "statemine-runtime", "statemint-runtime", "xcm", From 57e88e59cd2e15b3ee204506d2f22f5f2f01f03e Mon Sep 17 00:00:00 2001 From: bogdanS98 Date: Fri, 3 Nov 2023 15:22:39 +0200 Subject: [PATCH 14/20] Remove unused dependencies and sibling cleanup --- Cargo.lock | 3 --- runtime/integration-tests/Cargo.toml | 3 --- runtime/integration-tests/src/sibling.rs | 12 ------------ 3 files changed, 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dcd7b1a56..4630fea95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9968,7 +9968,6 @@ dependencies = [ "frame-support", "frame-system", "kusama-runtime", - "log", "orml-tokens", "orml-traits", "orml-xcm", @@ -9988,8 +9987,6 @@ dependencies = [ "polkadot-runtime-parachains", "runtime-common", "scale-info", - "serde", - "smallvec", "sp-core", "sp-debug-derive", "sp-io", diff --git a/runtime/integration-tests/Cargo.toml b/runtime/integration-tests/Cargo.toml index 92081583e..9eb10acbf 100644 --- a/runtime/integration-tests/Cargo.toml +++ b/runtime/integration-tests/Cargo.toml @@ -8,9 +8,6 @@ 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"] } -log = { version = "0.4.17", default-features = false } -smallvec = "1.9.0" # Spacewalk libraries spacewalk-primitives = { git = "https://github.com/pendulum-chain/spacewalk", default-features = false, rev = "58983d2695c309665c9c017a022436aaee088f3d"} diff --git a/runtime/integration-tests/src/sibling.rs b/runtime/integration-tests/src/sibling.rs index cf523f6d4..abe0f5430 100644 --- a/runtime/integration-tests/src/sibling.rs +++ b/runtime/integration-tests/src/sibling.rs @@ -369,18 +369,6 @@ parameter_types! { pub ReachableDest: Option = Some(Parent.into()); } -match_types! { - pub type ParentOrParachains: impl Contains = { - MultiLocation { parents: 0, interior: X1(Junction::AccountId32 { .. }) } | - MultiLocation { parents: 1, interior: X1(Junction::AccountId32 { .. }) } | - MultiLocation { parents: 1, interior: X2(Parachain(1), Junction::AccountId32 { .. }) } | - MultiLocation { parents: 1, interior: X2(Parachain(2), Junction::AccountId32 { .. }) } | - MultiLocation { parents: 1, interior: X2(Parachain(3), Junction::AccountId32 { .. }) } | - MultiLocation { parents: 1, interior: X2(Parachain(4), Junction::AccountId32 { .. }) } | - MultiLocation { parents: 1, interior: X2(Parachain(100), Junction::AccountId32 { .. }) } - }; -} - type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; From a30506dd04bf22639a5b9c0ec7f15f11a082b66b Mon Sep 17 00:00:00 2001 From: bogdanS98 Date: Mon, 6 Nov 2023 13:50:56 +0200 Subject: [PATCH 15/20] Address change request --- Cargo.lock | 1 + runtime/integration-tests/Cargo.toml | 1 + .../integration-tests/src/amplitude_tests.rs | 2 +- runtime/integration-tests/src/mock.rs | 48 +++++++++----- .../integration-tests/src/pendulum_tests.rs | 2 +- runtime/integration-tests/src/sibling.rs | 64 +++++++++++++++++-- runtime/integration-tests/src/test_macros.rs | 26 ++++---- 7 files changed, 112 insertions(+), 32 deletions(-) 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 ); }); From c32ae79026955ec4f5883cffe169a992d2e763ec Mon Sep 17 00:00:00 2001 From: bogdanS98 Date: Mon, 6 Nov 2023 13:52:50 +0200 Subject: [PATCH 16/20] fmt --- runtime/integration-tests/src/mock.rs | 2 +- runtime/integration-tests/src/sibling.rs | 44 ++++++++++---------- runtime/integration-tests/src/test_macros.rs | 2 +- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/runtime/integration-tests/src/mock.rs b/runtime/integration-tests/src/mock.rs index 29f8e8090..6977ef0ed 100644 --- a/runtime/integration-tests/src/mock.rs +++ b/runtime/integration-tests/src/mock.rs @@ -3,11 +3,11 @@ use crate::{ }; use frame_support::traits::GenesisBuild; 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 sibling::CurrencyId as SiblingCurrencyId; use sp_io::TestExternalities; use sp_runtime::traits::AccountIdConversion; use xcm_emulator::Weight; diff --git a/runtime/integration-tests/src/sibling.rs b/runtime/integration-tests/src/sibling.rs index 23891f07c..fc10cb344 100644 --- a/runtime/integration-tests/src/sibling.rs +++ b/runtime/integration-tests/src/sibling.rs @@ -1,10 +1,8 @@ // Based on https://github.com/open-web3-stack/open-runtime-module-library/blob/83a76c2bf66c0b1236c31077e6fb24bb760a3535/xtokens/src/mock/para.rs #![cfg(test)] +use codec::{Decode, Encode, MaxEncodedLen}; 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}, @@ -17,7 +15,9 @@ use orml_traits::{ use pallet_xcm::XcmPassthrough; use polkadot_parachain::primitives::Sibling; use polkadot_runtime_common::MAXIMUM_BLOCK_WEIGHT; +use runtime_common::parachains::kusama::asset_hub; use scale_info::TypeInfo; +use serde::{Deserialize, Serialize}; use sp_core::H256; use sp_debug_derive::RuntimeDebug; use sp_runtime::{ @@ -43,7 +43,7 @@ use xcm_builder::{ SignedToAccountId32, SovereignSignedViaLocation, }; -use crate::{AMPLITUDE_ID, PENDULUM_ID, KUSAMA_ASSETHUB_ID, POLKADOT_ASSETHUB_ID}; +use crate::{AMPLITUDE_ID, KUSAMA_ASSETHUB_ID, PENDULUM_ID, POLKADOT_ASSETHUB_ID}; const XCM_ASSET_RELAY_DOT: u8 = 0; const XCM_ASSET_ASSETHUB_USDT: u8 = 1; @@ -96,16 +96,16 @@ pub enum CurrencyId { // 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, + 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 @@ -122,14 +122,10 @@ 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)), - )), + 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, } @@ -139,10 +135,14 @@ impl Convert> for CurrencyIdConvert { impl Convert> for CurrencyIdConvert { fn convert(location: MultiLocation) -> Option { match location { - 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: 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 diff --git a/runtime/integration-tests/src/test_macros.rs b/runtime/integration-tests/src/test_macros.rs index 982f0b7dc..714b0294d 100644 --- a/runtime/integration-tests/src/test_macros.rs +++ b/runtime/integration-tests/src/test_macros.rs @@ -490,7 +490,7 @@ macro_rules! transfer_native_token_from_parachain1_to_parachain2_and_back { ); // 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(|| { From 9baa2229148b3fb99c791212448458f6a3a59d67 Mon Sep 17 00:00:00 2001 From: bogdanS98 Date: Mon, 6 Nov 2023 14:12:28 +0200 Subject: [PATCH 17/20] Add comment in test macro --- runtime/integration-tests/src/test_macros.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/integration-tests/src/test_macros.rs b/runtime/integration-tests/src/test_macros.rs index 714b0294d..09c23780b 100644 --- a/runtime/integration-tests/src/test_macros.rs +++ b/runtime/integration-tests/src/test_macros.rs @@ -489,6 +489,7 @@ macro_rules! transfer_native_token_from_parachain1_to_parachain2_and_back { 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 + // Used for checking BOB's balance let para1_native_currency_on_para2 = Parachain2CurrencyId::from($parachain1_id); // Get ALICE's balance on parachain1 before the transfer From 1f7f5af54f0fccf6160ada67c75896a9e96139e2 Mon Sep 17 00:00:00 2001 From: bogdanS98 Date: Mon, 6 Nov 2023 14:14:57 +0200 Subject: [PATCH 18/20] Remove unused import --- runtime/integration-tests/src/sibling.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/runtime/integration-tests/src/sibling.rs b/runtime/integration-tests/src/sibling.rs index fc10cb344..8fe4cb475 100644 --- a/runtime/integration-tests/src/sibling.rs +++ b/runtime/integration-tests/src/sibling.rs @@ -15,7 +15,6 @@ use orml_traits::{ use pallet_xcm::XcmPassthrough; use polkadot_parachain::primitives::Sibling; use polkadot_runtime_common::MAXIMUM_BLOCK_WEIGHT; -use runtime_common::parachains::kusama::asset_hub; use scale_info::TypeInfo; use serde::{Deserialize, Serialize}; use sp_core::H256; From ab5160cc310e55ddfc11c18330e4497c6950caaf Mon Sep 17 00:00:00 2001 From: bogdanS98 Date: Mon, 6 Nov 2023 18:09:48 +0200 Subject: [PATCH 19/20] Support XCM transfers for AssetHub USDT and relay dot on sibling runtime --- .../integration-tests/src/amplitude_tests.rs | 4 +-- runtime/integration-tests/src/lib.rs | 5 +-- runtime/integration-tests/src/mock.rs | 8 ++--- .../integration-tests/src/pendulum_tests.rs | 4 +-- runtime/integration-tests/src/sibling.rs | 33 ++++++++++++++++--- 5 files changed, 36 insertions(+), 18 deletions(-) diff --git a/runtime/integration-tests/src/amplitude_tests.rs b/runtime/integration-tests/src/amplitude_tests.rs index 9ecad6ce6..25aad2601 100644 --- a/runtime/integration-tests/src/amplitude_tests.rs +++ b/runtime/integration-tests/src/amplitude_tests.rs @@ -8,7 +8,7 @@ use crate::{ transfer_20_relay_token_from_relay_chain_to_parachain, transfer_native_token_from_parachain1_to_parachain2_and_back, }, - AMPLITUDE_ID, KUSAMA_ASSETHUB_ID, SIBLING_ID, + AMPLITUDE_ID, ASSETHUB_ID, SIBLING_ID, }; use frame_support::assert_ok; @@ -121,7 +121,7 @@ fn assethub_transfer_asset_to_amplitude_and_back() { parachain1_transfer_asset_to_parachain2_and_back!( kusama_asset_hub_runtime, AssetHubParachain, - KUSAMA_ASSETHUB_ID, + ASSETHUB_ID, USDT_ASSET_ID, amplitude_runtime, AmplitudeParachain, diff --git a/runtime/integration-tests/src/lib.rs b/runtime/integration-tests/src/lib.rs index e015a378b..9c48c76e8 100644 --- a/runtime/integration-tests/src/lib.rs +++ b/runtime/integration-tests/src/lib.rs @@ -14,9 +14,6 @@ mod test_macros; mod sibling; pub const PENDULUM_ID: u32 = 2094; -pub const POLKADOT_ASSETHUB_ID: u32 = 1000; - pub const AMPLITUDE_ID: u32 = 2124; -pub const KUSAMA_ASSETHUB_ID: u32 = 1000; - +pub const ASSETHUB_ID: u32 = 1000; pub const SIBLING_ID: u32 = 9999; diff --git a/runtime/integration-tests/src/mock.rs b/runtime/integration-tests/src/mock.rs index 6977ef0ed..75e1a39a5 100644 --- a/runtime/integration-tests/src/mock.rs +++ b/runtime/integration-tests/src/mock.rs @@ -1,6 +1,4 @@ -use crate::{ - sibling, AMPLITUDE_ID, KUSAMA_ASSETHUB_ID, PENDULUM_ID, POLKADOT_ASSETHUB_ID, SIBLING_ID, -}; +use crate::{sibling, AMPLITUDE_ID, ASSETHUB_ID, PENDULUM_ID, SIBLING_ID}; use frame_support::traits::GenesisBuild; use pendulum_runtime::CurrencyId as PendulumCurrencyId; use polkadot_core_primitives::{AccountId, Balance, BlockNumber}; @@ -199,8 +197,8 @@ pub fn para_ext(chain: ParachainType) -> sp_io::TestExternalities { impl ExtBuilderParachain { fn get_parachain_id(&self) -> u32 { match self.chain { - ParachainType::PolkadotAssetHub => POLKADOT_ASSETHUB_ID, - ParachainType::KusamaAssetHub => KUSAMA_ASSETHUB_ID, + ParachainType::PolkadotAssetHub => ASSETHUB_ID, + ParachainType::KusamaAssetHub => ASSETHUB_ID, ParachainType::Pendulum => PENDULUM_ID, ParachainType::Sibling => SIBLING_ID, ParachainType::Amplitude => AMPLITUDE_ID, diff --git a/runtime/integration-tests/src/pendulum_tests.rs b/runtime/integration-tests/src/pendulum_tests.rs index 690c3da12..79caa871c 100644 --- a/runtime/integration-tests/src/pendulum_tests.rs +++ b/runtime/integration-tests/src/pendulum_tests.rs @@ -8,7 +8,7 @@ use crate::{ transfer_20_relay_token_from_relay_chain_to_parachain, transfer_native_token_from_parachain1_to_parachain2_and_back, }, - PENDULUM_ID, POLKADOT_ASSETHUB_ID, SIBLING_ID, + ASSETHUB_ID, PENDULUM_ID, SIBLING_ID, }; use frame_support::assert_ok; @@ -121,7 +121,7 @@ fn assethub_transfer_asset_to_pendulum_and_back() { parachain1_transfer_asset_to_parachain2_and_back!( polkadot_asset_hub_runtime, AssetHubParachain, - POLKADOT_ASSETHUB_ID, + ASSETHUB_ID, USDT_ASSET_ID, pendulum_runtime, PendulumParachain, diff --git a/runtime/integration-tests/src/sibling.rs b/runtime/integration-tests/src/sibling.rs index 8fe4cb475..90c565489 100644 --- a/runtime/integration-tests/src/sibling.rs +++ b/runtime/integration-tests/src/sibling.rs @@ -15,6 +15,7 @@ use orml_traits::{ use pallet_xcm::XcmPassthrough; use polkadot_parachain::primitives::Sibling; use polkadot_runtime_common::MAXIMUM_BLOCK_WEIGHT; +use runtime_common::parachains::polkadot::asset_hub; use scale_info::TypeInfo; use serde::{Deserialize, Serialize}; use sp_core::H256; @@ -42,7 +43,7 @@ use xcm_builder::{ SignedToAccountId32, SovereignSignedViaLocation, }; -use crate::{AMPLITUDE_ID, KUSAMA_ASSETHUB_ID, PENDULUM_ID, POLKADOT_ASSETHUB_ID}; +use crate::{AMPLITUDE_ID, ASSETHUB_ID, PENDULUM_ID}; const XCM_ASSET_RELAY_DOT: u8 = 0; const XCM_ASSET_ASSETHUB_USDT: u8 = 1; @@ -99,7 +100,7 @@ impl From for CurrencyId { match id { PENDULUM_ID => CurrencyId::Pendulum, AMPLITUDE_ID => CurrencyId::Amplitude, - KUSAMA_ASSETHUB_ID | POLKADOT_ASSETHUB_ID => CurrencyId::XCM(XCM_ASSET_ASSETHUB_USDT), + 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), @@ -125,8 +126,19 @@ impl Convert> for CurrencyIdConvert { 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, + CurrencyId::XCM(f) => match f { + XCM_ASSET_RELAY_DOT => Some(MultiLocation::parent()), + // Handles both Kusama and Polkadot asset hub + XCM_ASSET_ASSETHUB_USDT => Some(MultiLocation::new( + 1, + X3( + Parachain(asset_hub::PARA_ID), + PalletInstance(asset_hub::ASSET_PALLET_ID), + GeneralIndex(asset_hub::USDT_ASSET_ID), + ), + )), + _ => None, + }, } } } @@ -144,7 +156,18 @@ impl Convert> for CurrencyIdConvert { } => 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 + // Handles both Kusama and Polkadot asset hub + MultiLocation { + parents: 1, + interior: + X3( + Parachain(asset_hub::PARA_ID), + PalletInstance(asset_hub::ASSET_PALLET_ID), + GeneralIndex(asset_hub::USDT_ASSET_ID), + ), + } => Some(CurrencyId::XCM(XCM_ASSET_ASSETHUB_USDT)), + MultiLocation { parents: 1, interior: Here } => + Some(CurrencyId::XCM(XCM_ASSET_RELAY_DOT)), _ => None, } } From 8fc4194b5c87856fcfa898f554252465ba1bb8d0 Mon Sep 17 00:00:00 2001 From: Marcel Ebert Date: Mon, 6 Nov 2023 17:25:19 +0100 Subject: [PATCH 20/20] Add comments --- runtime/amplitude/src/xcm_config.rs | 3 +++ runtime/foucoco/src/xcm_config.rs | 3 +++ runtime/pendulum/src/xcm_config.rs | 3 +++ 3 files changed, 9 insertions(+) diff --git a/runtime/amplitude/src/xcm_config.rs b/runtime/amplitude/src/xcm_config.rs index a7539271d..473b3ca5b 100644 --- a/runtime/amplitude/src/xcm_config.rs +++ b/runtime/amplitude/src/xcm_config.rs @@ -98,9 +98,12 @@ impl Convert> for CurrencyIdConvert { GeneralIndex(asset_hub::USDT_ASSET_ID), ), } => Some(CurrencyId::XCM(XCM_ASSET_ASSETHUB_USDT)), + // Our native currency location without re-anchoring MultiLocation { parents: 1, interior: X2(Parachain(id), PalletInstance(10)) } if id == u32::from(ParachainInfo::parachain_id()) => Some(CurrencyId::Native), + // Our native currency location with re-anchoring + // The XCM pallet will try to re-anchor the location before it reaches here MultiLocation { parents: 0, interior: X1(PalletInstance(10)) } => Some(CurrencyId::Native), _ => None, diff --git a/runtime/foucoco/src/xcm_config.rs b/runtime/foucoco/src/xcm_config.rs index 8f2915bb3..0486e76dc 100644 --- a/runtime/foucoco/src/xcm_config.rs +++ b/runtime/foucoco/src/xcm_config.rs @@ -76,9 +76,12 @@ impl Convert> for CurrencyIdConvert { fn convert(location: MultiLocation) -> Option { match location { MultiLocation { parents: 1, interior: Here } => Some(CurrencyId::XCM(0)), + // Our native currency location without re-anchoring MultiLocation { parents: 1, interior: X2(Parachain(id), PalletInstance(10)) } if id == u32::from(ParachainInfo::parachain_id()) => Some(CurrencyId::Native), + // Our native currency location with re-anchoring + // The XCM pallet will try to re-anchor the location before it reaches here MultiLocation { parents: 0, interior: X1(PalletInstance(10)) } => Some(CurrencyId::Native), _ => None, diff --git a/runtime/pendulum/src/xcm_config.rs b/runtime/pendulum/src/xcm_config.rs index cf20fdf82..dd16d4f26 100644 --- a/runtime/pendulum/src/xcm_config.rs +++ b/runtime/pendulum/src/xcm_config.rs @@ -99,9 +99,12 @@ impl Convert> for CurrencyIdConvert { GeneralIndex(asset_hub::USDT_ASSET_ID), ), } => Some(CurrencyId::XCM(XCM_ASSET_ASSETHUB_USDT)), + // Our native currency location without re-anchoring MultiLocation { parents: 1, interior: X2(Parachain(id), PalletInstance(10)) } if id == u32::from(ParachainInfo::parachain_id()) => Some(CurrencyId::Native), + // Our native currency location with re-anchoring + // The XCM pallet will try to re-anchor the location before it reaches here MultiLocation { parents: 0, interior: X1(PalletInstance(10)) } => Some(CurrencyId::Native), _ => None,