diff --git a/parachains/runtimes/assets/statemine/src/weights/xcm/mod.rs b/parachains/runtimes/assets/statemine/src/weights/xcm/mod.rs index ba2370bf055..0e560099310 100644 --- a/parachains/runtimes/assets/statemine/src/weights/xcm/mod.rs +++ b/parachains/runtimes/assets/statemine/src/weights/xcm/mod.rs @@ -28,7 +28,7 @@ trait WeighMultiAssets { fn weigh_multi_assets(&self, weight: Weight) -> Weight; } -const MAX_ASSETS: u32 = 100; +const MAX_ASSETS: u64 = 100; impl WeighMultiAssets for MultiAssetFilter { fn weigh_multi_assets(&self, weight: Weight) -> Weight { @@ -36,7 +36,7 @@ impl WeighMultiAssets for MultiAssetFilter { Self::Definite(assets) => weight.saturating_mul(assets.inner().into_iter().count() as u64), Self::Wild(asset) => match asset { - All => weight.saturating_mul(MAX_ASSETS as u64), + All => weight.saturating_mul(MAX_ASSETS), AllOf { fun, .. } => match fun { WildFungibility::Fungible => weight, // Magic number 2 has to do with the fact that we could have up to 2 times @@ -44,8 +44,8 @@ impl WeighMultiAssets for MultiAssetFilter { WildFungibility::NonFungible => weight.saturating_mul((MaxAssetsIntoHolding::get() * 2) as u64), }, - AllCounted(count) => weight.saturating_mul(*count as u64), - AllOfCounted { count, .. } => weight.saturating_mul(*count as u64), + AllCounted(count) => weight.saturating_mul(MAX_ASSETS.min(*count as u64)), + AllOfCounted { count, .. } => weight.saturating_mul(MAX_ASSETS.min(*count as u64)), }, } } diff --git a/parachains/runtimes/assets/statemine/tests/tests.rs b/parachains/runtimes/assets/statemine/tests/tests.rs index 9614fd80062..9c9b23f77e4 100644 --- a/parachains/runtimes/assets/statemine/tests/tests.rs +++ b/parachains/runtimes/assets/statemine/tests/tests.rs @@ -1,7 +1,8 @@ use asset_test_utils::{ExtBuilder, RuntimeHelper}; +use codec::Encode; use cumulus_primitives_utility::ChargeWeightInFungibles; use frame_support::{ - assert_noop, assert_ok, + assert_noop, assert_ok, sp_io, traits::PalletInfo, weights::{Weight, WeightToFee as WeightToFeeT}, }; @@ -9,10 +10,10 @@ use parachains_common::{AccountId, AuraId}; use statemine_runtime::xcm_config::AssetFeeAsExistentialDepositMultiplierFeeCharger; pub use statemine_runtime::{ constants::fee::WeightToFee, xcm_config::XcmConfig, Assets, Balances, ExistentialDeposit, - Runtime, SessionKeys, System, + ReservedDmpWeight, Runtime, SessionKeys, System, }; use xcm::latest::prelude::*; -use xcm_executor::traits::WeightTrader; +use xcm_executor::{traits::WeightTrader, XcmExecutor}; pub const ALICE: [u8; 32] = [1u8; 32]; @@ -388,3 +389,51 @@ fn test_asset_xcm_trader_not_possible_for_non_sufficient_assets() { assert_eq!(Assets::total_supply(1), minimum_asset_balance); }); } + +#[test] +fn receive_teleported_asset_works() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + let xcm = Xcm(vec![ + ReceiveTeleportedAsset(MultiAssets::from(vec![MultiAsset { + id: Concrete(MultiLocation { parents: 1, interior: Here }), + fun: Fungible(10000000000000), + }])), + ClearOrigin, + BuyExecution { + fees: MultiAsset { + id: Concrete(MultiLocation { parents: 1, interior: Here }), + fun: Fungible(10000000000000), + }, + weight_limit: Limited(Weight::from_parts(303531000, 65536)), + }, + DepositAsset { + assets: Wild(AllCounted(1)), + beneficiary: MultiLocation { + parents: 0, + interior: X1(AccountId32 { + network: None, + id: [ + 18, 153, 85, 112, 1, 245, 88, 21, 211, 252, 181, 60, 116, 70, 58, + 203, 12, 246, 209, 77, 70, 57, 179, 64, 152, 44, 96, 135, 127, 56, + 70, 9, + ], + }), + }, + }, + ]); + let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + + let weight_limit = ReservedDmpWeight::get(); + + let outcome = XcmExecutor::::execute_xcm(Parent, xcm, hash, weight_limit); + assert_eq!(outcome.ensure_complete(), Ok(())); + }) +} diff --git a/parachains/runtimes/assets/statemint/src/weights/xcm/mod.rs b/parachains/runtimes/assets/statemint/src/weights/xcm/mod.rs index cf9423bc28e..b2c4cebe6e7 100644 --- a/parachains/runtimes/assets/statemint/src/weights/xcm/mod.rs +++ b/parachains/runtimes/assets/statemint/src/weights/xcm/mod.rs @@ -28,7 +28,7 @@ trait WeighMultiAssets { fn weigh_multi_assets(&self, weight: Weight) -> Weight; } -const MAX_ASSETS: u32 = 100; +const MAX_ASSETS: u64 = 100; impl WeighMultiAssets for MultiAssetFilter { fn weigh_multi_assets(&self, weight: Weight) -> Weight { @@ -36,7 +36,7 @@ impl WeighMultiAssets for MultiAssetFilter { Self::Definite(assets) => weight.saturating_mul(assets.inner().into_iter().count() as u64), Self::Wild(asset) => match asset { - All => weight.saturating_mul(MAX_ASSETS as u64), + All => weight.saturating_mul(MAX_ASSETS), AllOf { fun, .. } => match fun { WildFungibility::Fungible => weight, // Magic number 2 has to do with the fact that we could have up to 2 times @@ -44,8 +44,8 @@ impl WeighMultiAssets for MultiAssetFilter { WildFungibility::NonFungible => weight.saturating_mul((MaxAssetsIntoHolding::get() * 2) as u64), }, - AllCounted(count) => weight.saturating_mul(*count as u64), - AllOfCounted { count, .. } => weight.saturating_mul(*count as u64), + AllCounted(count) => weight.saturating_mul(MAX_ASSETS.min(*count as u64)), + AllOfCounted { count, .. } => weight.saturating_mul(MAX_ASSETS.min(*count as u64)), }, } } diff --git a/parachains/runtimes/assets/statemint/tests/tests.rs b/parachains/runtimes/assets/statemint/tests/tests.rs index b52383f3d3e..371a442a449 100644 --- a/parachains/runtimes/assets/statemint/tests/tests.rs +++ b/parachains/runtimes/assets/statemint/tests/tests.rs @@ -1,7 +1,8 @@ use asset_test_utils::{ExtBuilder, RuntimeHelper}; +use codec::Encode; use cumulus_primitives_utility::ChargeWeightInFungibles; use frame_support::{ - assert_noop, assert_ok, + assert_noop, assert_ok, sp_io, traits::PalletInfo, weights::{Weight, WeightToFee as WeightToFeeT}, }; @@ -9,10 +10,10 @@ use parachains_common::{AccountId, StatemintAuraId as AuraId}; use statemint_runtime::xcm_config::AssetFeeAsExistentialDepositMultiplierFeeCharger; pub use statemint_runtime::{ constants::fee::WeightToFee, xcm_config::XcmConfig, Assets, Balances, ExistentialDeposit, - Runtime, SessionKeys, System, + ReservedDmpWeight, Runtime, SessionKeys, System, }; use xcm::latest::prelude::*; -use xcm_executor::traits::WeightTrader; +use xcm_executor::{traits::WeightTrader, XcmExecutor}; pub const ALICE: [u8; 32] = [1u8; 32]; @@ -400,3 +401,51 @@ fn test_asset_xcm_trader_not_possible_for_non_sufficient_assets() { assert_eq!(Assets::total_supply(1), minimum_asset_balance); }); } + +#[test] +fn receive_teleported_asset_works() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::ed25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + let xcm = Xcm(vec![ + ReceiveTeleportedAsset(MultiAssets::from(vec![MultiAsset { + id: Concrete(MultiLocation { parents: 1, interior: Here }), + fun: Fungible(10000000000000), + }])), + ClearOrigin, + BuyExecution { + fees: MultiAsset { + id: Concrete(MultiLocation { parents: 1, interior: Here }), + fun: Fungible(10000000000000), + }, + weight_limit: Limited(Weight::from_parts(303531000, 65536)), + }, + DepositAsset { + assets: Wild(AllCounted(1)), + beneficiary: MultiLocation { + parents: 0, + interior: X1(AccountId32 { + network: None, + id: [ + 18, 153, 85, 112, 1, 245, 88, 21, 211, 252, 181, 60, 116, 70, 58, + 203, 12, 246, 209, 77, 70, 57, 179, 64, 152, 44, 96, 135, 127, 56, + 70, 9, + ], + }), + }, + }, + ]); + let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + + let weight_limit = ReservedDmpWeight::get(); + + let outcome = XcmExecutor::::execute_xcm(Parent, xcm, hash, weight_limit); + assert_eq!(outcome.ensure_complete(), Ok(())); + }) +} diff --git a/parachains/runtimes/assets/westmint/src/weights/xcm/mod.rs b/parachains/runtimes/assets/westmint/src/weights/xcm/mod.rs index 7c2454b6443..28d34f453ad 100644 --- a/parachains/runtimes/assets/westmint/src/weights/xcm/mod.rs +++ b/parachains/runtimes/assets/westmint/src/weights/xcm/mod.rs @@ -28,7 +28,7 @@ trait WeighMultiAssets { fn weigh_multi_assets(&self, weight: Weight) -> Weight; } -const MAX_ASSETS: u32 = 100; +const MAX_ASSETS: u64 = 100; impl WeighMultiAssets for MultiAssetFilter { fn weigh_multi_assets(&self, weight: Weight) -> Weight { @@ -36,7 +36,7 @@ impl WeighMultiAssets for MultiAssetFilter { Self::Definite(assets) => weight.saturating_mul(assets.inner().into_iter().count() as u64), Self::Wild(asset) => match asset { - All => weight.saturating_mul(MAX_ASSETS as u64), + All => weight.saturating_mul(MAX_ASSETS), AllOf { fun, .. } => match fun { WildFungibility::Fungible => weight, // Magic number 2 has to do with the fact that we could have up to 2 times @@ -44,8 +44,8 @@ impl WeighMultiAssets for MultiAssetFilter { WildFungibility::NonFungible => weight.saturating_mul((MaxAssetsIntoHolding::get() * 2) as u64), }, - AllCounted(count) => weight.saturating_mul(*count as u64), - AllOfCounted { count, .. } => weight.saturating_mul(*count as u64), + AllCounted(count) => weight.saturating_mul(MAX_ASSETS.min(*count as u64)), + AllOfCounted { count, .. } => weight.saturating_mul(MAX_ASSETS.min(*count as u64)), }, } } diff --git a/parachains/runtimes/assets/westmint/tests/tests.rs b/parachains/runtimes/assets/westmint/tests/tests.rs index 68c6cf670d5..d6b8c6eb0cb 100644 --- a/parachains/runtimes/assets/westmint/tests/tests.rs +++ b/parachains/runtimes/assets/westmint/tests/tests.rs @@ -1,18 +1,19 @@ use asset_test_utils::{ExtBuilder, RuntimeHelper}; +use codec::{DecodeLimit, Encode}; use cumulus_primitives_utility::ChargeWeightInFungibles; use frame_support::{ - assert_noop, assert_ok, + assert_noop, assert_ok, sp_io, traits::PalletInfo, weights::{Weight, WeightToFee as WeightToFeeT}, }; use parachains_common::{AccountId, AuraId}; -use westmint_runtime::xcm_config::AssetFeeAsExistentialDepositMultiplierFeeCharger; pub use westmint_runtime::{ constants::fee::WeightToFee, xcm_config::XcmConfig, Assets, Balances, ExistentialDeposit, - Runtime, SessionKeys, System, + ReservedDmpWeight, Runtime, SessionKeys, System, }; -use xcm::latest::prelude::*; -use xcm_executor::traits::WeightTrader; +use westmint_runtime::{xcm_config::AssetFeeAsExistentialDepositMultiplierFeeCharger, RuntimeCall}; +use xcm::{latest::prelude::*, VersionedXcm, MAX_XCM_DECODE_DEPTH}; +use xcm_executor::{traits::WeightTrader, XcmExecutor}; pub const ALICE: [u8; 32] = [1u8; 32]; @@ -386,3 +387,79 @@ fn test_asset_xcm_trader_not_possible_for_non_sufficient_assets() { assert_eq!(Assets::total_supply(1), minimum_asset_balance); }); } + +#[test] +fn receive_teleported_asset_works() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + let xcm = Xcm(vec![ + ReceiveTeleportedAsset(MultiAssets::from(vec![MultiAsset { + id: Concrete(MultiLocation { parents: 1, interior: Here }), + fun: Fungible(10000000000000), + }])), + ClearOrigin, + BuyExecution { + fees: MultiAsset { + id: Concrete(MultiLocation { parents: 1, interior: Here }), + fun: Fungible(10000000000000), + }, + weight_limit: Limited(Weight::from_parts(303531000, 65536)), + }, + DepositAsset { + assets: Wild(AllCounted(1)), + beneficiary: MultiLocation { + parents: 0, + interior: X1(AccountId32 { + network: None, + id: [ + 18, 153, 85, 112, 1, 245, 88, 21, 211, 252, 181, 60, 116, 70, 58, + 203, 12, 246, 209, 77, 70, 57, 179, 64, 152, 44, 96, 135, 127, 56, + 70, 9, + ], + }), + }, + }, + ]); + let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + + let weight_limit = ReservedDmpWeight::get(); + + let outcome = XcmExecutor::::execute_xcm(Parent, xcm, hash, weight_limit); + assert_eq!(outcome.ensure_complete(), Ok(())); + }) +} + +#[test] +fn plain_receive_teleported_asset_works() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + let data = hex_literal::hex!("02100204000100000b00a0724e18090a13000100000b00a0724e180901e20f5e480d010004000101001299557001f55815d3fcb53c74463acb0cf6d14d4639b340982c60877f384609").to_vec(); + let message_id = sp_io::hashing::blake2_256(&data); + + let maybe_msg = VersionedXcm::::decode_all_with_depth_limit( + MAX_XCM_DECODE_DEPTH, + &mut data.as_ref(), + ) + .map(xcm::v3::Xcm::::try_from).expect("failed").expect("failed"); + + let weight_limit = ReservedDmpWeight::get(); + + let outcome = + XcmExecutor::::execute_xcm(Parent, maybe_msg, message_id, weight_limit); + assert_eq!(outcome.ensure_complete(), Ok(())); + }) +} diff --git a/parachains/runtimes/bridge-hubs/bridge-hub-kusama/src/weights/xcm/mod.rs b/parachains/runtimes/bridge-hubs/bridge-hub-kusama/src/weights/xcm/mod.rs index 53ceaa231d9..f903639f3d2 100644 --- a/parachains/runtimes/bridge-hubs/bridge-hub-kusama/src/weights/xcm/mod.rs +++ b/parachains/runtimes/bridge-hubs/bridge-hub-kusama/src/weights/xcm/mod.rs @@ -28,7 +28,7 @@ trait WeighMultiAssets { fn weigh_multi_assets(&self, weight: Weight) -> Weight; } -const MAX_ASSETS: u32 = 100; +const MAX_ASSETS: u64 = 100; impl WeighMultiAssets for MultiAssetFilter { fn weigh_multi_assets(&self, weight: Weight) -> Weight { @@ -36,7 +36,7 @@ impl WeighMultiAssets for MultiAssetFilter { Self::Definite(assets) => weight.saturating_mul(assets.inner().into_iter().count() as u64), Self::Wild(asset) => match asset { - All => weight.saturating_mul(MAX_ASSETS as u64), + All => weight.saturating_mul(MAX_ASSETS), AllOf { fun, .. } => match fun { WildFungibility::Fungible => weight, // Magic number 2 has to do with the fact that we could have up to 2 times @@ -44,8 +44,8 @@ impl WeighMultiAssets for MultiAssetFilter { WildFungibility::NonFungible => weight.saturating_mul((MaxAssetsIntoHolding::get() * 2) as u64), }, - AllCounted(count) => weight.saturating_mul(*count as u64), - AllOfCounted { count, .. } => weight.saturating_mul(*count as u64), + AllCounted(count) => weight.saturating_mul(MAX_ASSETS.min(*count as u64)), + AllOfCounted { count, .. } => weight.saturating_mul(MAX_ASSETS.min(*count as u64)), }, } } diff --git a/parachains/runtimes/bridge-hubs/bridge-hub-polkadot/src/weights/xcm/mod.rs b/parachains/runtimes/bridge-hubs/bridge-hub-polkadot/src/weights/xcm/mod.rs index 133339e1119..9b350df5195 100644 --- a/parachains/runtimes/bridge-hubs/bridge-hub-polkadot/src/weights/xcm/mod.rs +++ b/parachains/runtimes/bridge-hubs/bridge-hub-polkadot/src/weights/xcm/mod.rs @@ -28,7 +28,7 @@ trait WeighMultiAssets { fn weigh_multi_assets(&self, weight: Weight) -> Weight; } -const MAX_ASSETS: u32 = 100; +const MAX_ASSETS: u64 = 100; impl WeighMultiAssets for MultiAssetFilter { fn weigh_multi_assets(&self, weight: Weight) -> Weight { @@ -36,7 +36,7 @@ impl WeighMultiAssets for MultiAssetFilter { Self::Definite(assets) => weight.saturating_mul(assets.inner().into_iter().count() as u64), Self::Wild(asset) => match asset { - All => weight.saturating_mul(MAX_ASSETS as u64), + All => weight.saturating_mul(MAX_ASSETS), AllOf { fun, .. } => match fun { WildFungibility::Fungible => weight, // Magic number 2 has to do with the fact that we could have up to 2 times @@ -44,8 +44,8 @@ impl WeighMultiAssets for MultiAssetFilter { WildFungibility::NonFungible => weight.saturating_mul((MaxAssetsIntoHolding::get() * 2) as u64), }, - AllCounted(count) => weight.saturating_mul(*count as u64), - AllOfCounted { count, .. } => weight.saturating_mul(*count as u64), + AllCounted(count) => weight.saturating_mul(MAX_ASSETS.min(*count as u64)), + AllOfCounted { count, .. } => weight.saturating_mul(MAX_ASSETS.min(*count as u64)), }, } } diff --git a/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs b/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs index e1aa203fbf2..d32604baaf2 100644 --- a/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs +++ b/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/mod.rs @@ -28,7 +28,7 @@ trait WeighMultiAssets { fn weigh_multi_assets(&self, weight: Weight) -> Weight; } -const MAX_ASSETS: u32 = 100; +const MAX_ASSETS: u64 = 100; impl WeighMultiAssets for MultiAssetFilter { fn weigh_multi_assets(&self, weight: Weight) -> Weight { @@ -36,7 +36,7 @@ impl WeighMultiAssets for MultiAssetFilter { Self::Definite(assets) => weight.saturating_mul(assets.inner().into_iter().count() as u64), Self::Wild(asset) => match asset { - All => weight.saturating_mul(MAX_ASSETS as u64), + All => weight.saturating_mul(MAX_ASSETS), AllOf { fun, .. } => match fun { WildFungibility::Fungible => weight, // Magic number 2 has to do with the fact that we could have up to 2 times @@ -44,8 +44,8 @@ impl WeighMultiAssets for MultiAssetFilter { WildFungibility::NonFungible => weight.saturating_mul((MaxAssetsIntoHolding::get() * 2) as u64), }, - AllCounted(count) => weight.saturating_mul(*count as u64), - AllOfCounted { count, .. } => weight.saturating_mul(*count as u64), + AllCounted(count) => weight.saturating_mul(MAX_ASSETS.min(*count as u64)), + AllOfCounted { count, .. } => weight.saturating_mul(MAX_ASSETS.min(*count as u64)), }, } }