Skip to content

Commit

Permalink
[stable2407] Backport #6459 (#6663)
Browse files Browse the repository at this point in the history
Backport #6459 into `stable2407` from franciscoaguirre.

See the
[documentation](https://github.com/paritytech/polkadot-sdk/blob/master/docs/BACKPORT.md)
on how to use this bot.

<!--
  # To be used by other automation, do not modify:
  original-pr-number: #${pull_number}
-->

---------

Co-authored-by: Francisco Aguirre <[email protected]>
Co-authored-by: Egor_P <[email protected]>
  • Loading branch information
3 people authored Dec 4, 2024
1 parent fb7075d commit 37323c9
Show file tree
Hide file tree
Showing 43 changed files with 667 additions and 242 deletions.
15 changes: 15 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 15 additions & 4 deletions cumulus/parachains/integration-tests/emulated/common/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,12 +464,23 @@ macro_rules! test_xcm_fee_querying_apis_work_for_asset_hub {
type Assets = <$asset_hub as [<$asset_hub Pallet>]>::Assets;
type AssetConversion = <$asset_hub as [<$asset_hub Pallet>]>::AssetConversion;
let wnd = Location::new(1, []);
let wnd_v3 = xcm::v3::Location::parent();
let usdt = Location::new(0, [PalletInstance(ASSETS_PALLET_ID), GeneralIndex(USDT_ID.into())]);
let usdt_v3: xcm::v3::Location = (xcm::v3::Junction::PalletInstance(ASSETS_PALLET_ID), xcm::v3::Junction::GeneralIndex(USDT_ID.into())).into();
let sender = [<$asset_hub Sender>]::get();
// We create USDT if it doesn't exist.
let _ = Assets::force_create(
RuntimeOrigin::root(),
USDT_ID.into(),
sender.clone().into(),
false,
1,
);
// Then we can create a pool with WND.
assert_ok!(AssetConversion::create_pool(
RuntimeOrigin::signed(sender.clone()),
Box::new(wnd.clone()),
Box::new(usdt.clone()),
Box::new(wnd_v3),
Box::new(usdt_v3),
));

type Runtime = <$asset_hub as Chain>::Runtime;
Expand Down Expand Up @@ -502,8 +513,8 @@ macro_rules! test_xcm_fee_querying_apis_work_for_asset_hub {
// We make 1 WND = 4 USDT.
assert_ok!(AssetConversion::add_liquidity(
RuntimeOrigin::signed(sender.clone()),
Box::new(wnd),
Box::new(usdt.clone()),
Box::new(wnd_v3),
Box::new(usdt_v3),
1_000_000_000_000,
4_000_000_000_000,
0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ parachains-common.workspace = true
parachains-common.default-features = true
emulated-integration-tests-common.workspace = true
rococo-system-emulated-network.workspace = true
xcm-runtime-apis.workspace = true
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ mod imports {
// Cumulus
pub use asset_test_utils::xcm_helpers;
pub use emulated_integration_tests_common::{
test_parachain_is_trusted_teleporter, test_parachain_is_trusted_teleporter_for_relay,
test_relay_is_trusted_teleporter, test_xcm_fee_querying_apis_work_for_asset_hub,
test_parachain_is_trusted_teleporter,
test_xcm_fee_querying_apis_work_for_asset_hub,
xcm_emulator::{
assert_expected_events, bx, Chain, Parachain as Para, RelayChain as Relay, Test,
TestArgs, TestContext, TestExt,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ mod imports {
// Cumulus
pub use asset_test_utils::xcm_helpers;
pub use emulated_integration_tests_common::{
test_parachain_is_trusted_teleporter, test_parachain_is_trusted_teleporter_for_relay,
test_relay_is_trusted_teleporter, test_xcm_fee_querying_apis_work_for_asset_hub,
test_parachain_is_trusted_teleporter,
test_xcm_fee_querying_apis_work_for_asset_hub,
xcm_emulator::{
assert_expected_events, bx, Chain, Parachain as Para, RelayChain as Relay, Test,
TestArgs, TestContext, TestExt,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ bp-bridge-hub-westend.workspace = true
snowbridge-router-primitives.workspace = true

[dev-dependencies]
asset-test-utils = { default-features = true, path = "../test-utils" }
asset-test-utils = { workspace = true, default-features = true }
parachains-runtimes-test-utils = { workspace = true, default-features = true }

[build-dependencies]
substrate-wasm-builder = { optional = true, workspace = true, default-features = true }
Expand Down
43 changes: 18 additions & 25 deletions cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1327,47 +1327,40 @@ impl_runtime_apis! {
impl xcm_runtime_apis::fees::XcmPaymentApi<Block> for Runtime {
fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result<Vec<VersionedAssetId>, XcmPaymentApiError> {
let native_token = xcm_config::TokenLocation::get();
let native_token_v3 = xcm_config::TokenLocationV3::get();
// We accept the native token to pay fees.
let mut acceptable_assets = vec![AssetId(native_token.clone())];
// We also accept all assets in a pool with the native token.
let assets_in_pool_with_native = assets_common::get_assets_in_pool_with::<
Runtime,
xcm::v3::Location
>(&native_token_v3).map_err(|()| XcmPaymentApiError::VersionedConversionFailed)?.into_iter();
acceptable_assets.extend(assets_in_pool_with_native);
acceptable_assets.extend(
assets_common::PoolAdapter::<Runtime>::get_assets_in_pool_with(native_token)
.map_err(|()| XcmPaymentApiError::VersionedConversionFailed)?
);
PolkadotXcm::query_acceptable_payment_assets(xcm_version, acceptable_assets)
}

fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
let native_asset = xcm_config::TokenLocationV3::get();
let native_asset_v4 = xcm_config::TokenLocation::get();
let native_asset = xcm_config::TokenLocation::get();
let fee_in_native = WeightToFee::weight_to_fee(&weight);
match asset.try_as::<xcm::v3::AssetId>() {
Ok(xcm::v3::AssetId::Concrete(location)) if *location == native_asset => {
Ok(fee_in_native)
let latest_asset_id: Result<AssetId, ()> = asset.clone().try_into();
match latest_asset_id {
Ok(asset_id) if asset_id.0 == native_asset => {
// for native token
Ok(WeightToFee::weight_to_fee(&weight))
},
Ok(xcm::v3::AssetId::Concrete(location)) => {
let assets_in_pool_with_this_asset: Vec<_> = assets_common::get_assets_in_pool_with::<
Runtime,
xcm::v3::Location
>(&location).map_err(|()| XcmPaymentApiError::VersionedConversionFailed)?;
if assets_in_pool_with_this_asset
.into_iter()
.map(|asset_id| asset_id.0)
.any(|location| location == native_asset_v4) {
pallet_asset_conversion::Pallet::<Runtime>::quote_price_tokens_for_exact_tokens(
*location,
Ok(asset_id) => {
// Try to get current price of `asset_id` in `native_asset`.
if let Ok(Some(swapped_in_native)) = assets_common::PoolAdapter::<Runtime>::quote_price_tokens_for_exact_tokens(
asset_id.0.clone(),
native_asset,
fee_in_native,
true, // We include the fee.
).ok_or(XcmPaymentApiError::AssetNotFound)
) {
Ok(swapped_in_native)
} else {
log::trace!(target: "xcm::xcm_runtime_apis", "query_weight_to_asset_fee - unhandled asset_id: {location:?}!");
log::trace!(target: "xcm::xcm_runtime_apis", "query_weight_to_asset_fee - unhandled asset_id: {asset_id:?}!");
Err(XcmPaymentApiError::AssetNotFound)
}
},
Ok(xcm::v3::AssetId::Abstract(_)) | Err(_) => {
Err(_) => {
log::trace!(target: "xcm::xcm_runtime_apis", "query_weight_to_asset_fee - failed to convert asset: {asset:?}!");
Err(XcmPaymentApiError::VersionedConversionFailed)
}
Expand Down
24 changes: 20 additions & 4 deletions cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ use asset_hub_rococo_runtime::{
ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, ForeignCreatorsSovereignAccountOf,
LocationToAccountId, StakingPot, TokenLocation, TrustBackedAssetsPalletLocation, XcmConfig,
},
AllPalletsWithoutSystem, AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection,
ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase,
MetadataDepositPerByte, ParachainSystem, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin,
SessionKeys, ToWestendXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue,
AllPalletsWithoutSystem, AssetConversion, AssetDeposit, Assets, Balances, Block,
CollatorSelection, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance,
MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, Runtime, RuntimeCall,
RuntimeEvent, RuntimeOrigin, SessionKeys, ToWestendXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue,
};
use asset_test_utils::{
test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys,
Expand Down Expand Up @@ -1473,3 +1473,19 @@ fn change_xcm_bridge_hub_ethereum_base_fee_by_governance_works() {
},
)
}

#[test]
fn xcm_payment_api_works() {
parachains_runtimes_test_utils::test_cases::xcm_payment_api_with_native_token_works::<
Runtime,
RuntimeCall,
RuntimeOrigin,
Block,
>();
asset_test_utils::test_cases::xcm_payment_api_with_pools_works::<
Runtime,
RuntimeCall,
RuntimeOrigin,
Block,
>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ bp-bridge-hub-rococo.workspace = true
bp-bridge-hub-westend.workspace = true

[dev-dependencies]
asset-test-utils = { default-features = true, path = "../test-utils" }
asset-test-utils = { workspace = true, default-features = true }
parachains-runtimes-test-utils = { workspace = true, default-features = true }

[build-dependencies]
substrate-wasm-builder = { optional = true, workspace = true, default-features = true }
Expand Down
42 changes: 17 additions & 25 deletions cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1355,48 +1355,40 @@ impl_runtime_apis! {
impl xcm_runtime_apis::fees::XcmPaymentApi<Block> for Runtime {
fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result<Vec<VersionedAssetId>, XcmPaymentApiError> {
let native_token = xcm_config::WestendLocation::get();
let native_token_v3 = xcm_config::WestendLocationV3::get();
// We accept the native token to pay fees.
let mut acceptable_assets = vec![AssetId(native_token.clone())];
// We also accept all assets in a pool with the native token.
let assets_in_pool_with_native = assets_common::get_assets_in_pool_with::<
Runtime,
xcm::v3::Location
>(&native_token_v3).map_err(|()| XcmPaymentApiError::VersionedConversionFailed)?.into_iter();
acceptable_assets.extend(assets_in_pool_with_native);
acceptable_assets.extend(
assets_common::PoolAdapter::<Runtime>::get_assets_in_pool_with(native_token)
.map_err(|()| XcmPaymentApiError::VersionedConversionFailed)?
);
PolkadotXcm::query_acceptable_payment_assets(xcm_version, acceptable_assets)
}

fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
let native_asset = xcm_config::WestendLocationV3::get();
let native_asset_v4 = xcm_config::WestendLocation::get();
let native_asset = xcm_config::WestendLocation::get();
let fee_in_native = WeightToFee::weight_to_fee(&weight);
match asset.try_as::<xcm::v3::AssetId>() {
Ok(xcm::v3::AssetId::Concrete(location)) if *location == native_asset => {
let latest_asset_id: Result<AssetId, ()> = asset.clone().try_into();
match latest_asset_id {
Ok(asset_id) if asset_id.0 == native_asset => {
// for native asset
Ok(fee_in_native)
},
Ok(xcm::v3::AssetId::Concrete(location)) => {
// We recognize assets in a pool with the native one.
let assets_in_pool_with_this_asset: Vec<_> = assets_common::get_assets_in_pool_with::<
Runtime,
xcm::v3::Location
>(&location).map_err(|()| XcmPaymentApiError::VersionedConversionFailed)?;
if assets_in_pool_with_this_asset
.into_iter()
.map(|asset_id| asset_id.0)
.any(|location| location == native_asset_v4) {
pallet_asset_conversion::Pallet::<Runtime>::quote_price_tokens_for_exact_tokens(
*location,
Ok(asset_id) => {
// Try to get current price of `asset_id` in `native_asset`.
if let Ok(Some(swapped_in_native)) = assets_common::PoolAdapter::<Runtime>::quote_price_tokens_for_exact_tokens(
asset_id.0.clone(),
native_asset,
fee_in_native,
true, // We include the fee.
).ok_or(XcmPaymentApiError::AssetNotFound)
) {
Ok(swapped_in_native)
} else {
log::trace!(target: "xcm::xcm_runtime_apis", "query_weight_to_asset_fee - unhandled asset_id: {location:?}!");
log::trace!(target: "xcm::xcm_runtime_apis", "query_weight_to_asset_fee - unhandled asset_id: {asset_id:?}!");
Err(XcmPaymentApiError::AssetNotFound)
}
},
Ok(xcm::v3::AssetId::Abstract(_)) | Err(_) => {
Err(_) => {
log::trace!(target: "xcm::xcm_runtime_apis", "query_weight_to_asset_fee - failed to convert asset: {asset:?}!");
Err(XcmPaymentApiError::VersionedConversionFailed)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use asset_hub_westend_runtime::{
LocationToAccountId, StakingPot, TrustBackedAssetsPalletLocation, WestendLocation,
XcmConfig,
},
AllPalletsWithoutSystem, Assets, Balances, ExistentialDeposit, ForeignAssets,
AllPalletsWithoutSystem, Assets, Balances, Block, ExistentialDeposit, ForeignAssets,
ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem,
PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys,
ToRococoXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue,
Expand Down Expand Up @@ -1419,3 +1419,19 @@ fn reserve_transfer_native_asset_to_non_teleport_para_works() {
WeightLimit::Unlimited,
);
}

#[test]
fn xcm_payment_api_works() {
parachains_runtimes_test_utils::test_cases::xcm_payment_api_with_native_token_works::<
Runtime,
RuntimeCall,
RuntimeOrigin,
Block,
>();
asset_test_utils::test_cases::xcm_payment_api_with_pools_works::<
Runtime,
RuntimeCall,
RuntimeOrigin,
Block,
>();
}
Loading

0 comments on commit 37323c9

Please sign in to comment.