From 18e54e7a7315653136ffaf91752f51d14173cf69 Mon Sep 17 00:00:00 2001 From: Francisco Aguirre <franciscoaguirreperez@gmail.com> Date: Mon, 18 Mar 2024 15:01:37 +0100 Subject: [PATCH] feat(xcm-fee-payment-api): add query_delivery_fees function --- polkadot/node/service/src/fake_runtime_api.rs | 7 +++++-- polkadot/runtime/rococo/src/lib.rs | 16 +++++++++++++++- polkadot/runtime/westend/src/lib.rs | 14 ++++++++++++++ .../xcm-payment-runtime-api/Cargo.toml | 1 + .../xcm-payment-runtime-api/src/lib.rs | 14 +++++++++++++- 5 files changed, 48 insertions(+), 4 deletions(-) diff --git a/polkadot/node/service/src/fake_runtime_api.rs b/polkadot/node/service/src/fake_runtime_api.rs index 34111d007beb8..15c245829b099 100644 --- a/polkadot/node/service/src/fake_runtime_api.rs +++ b/polkadot/node/service/src/fake_runtime_api.rs @@ -41,7 +41,7 @@ use sp_runtime::{ use sp_version::RuntimeVersion; use sp_weights::Weight; use std::collections::BTreeMap; -use xcm::{VersionedAssetId, VersionedXcm}; +use xcm::{VersionedAssetId, VersionedXcm, VersionedLocation, VersionedAssets}; sp_api::decl_runtime_apis! { /// This runtime API is only implemented for the test runtime! pub trait GetLastTimestamp { @@ -400,7 +400,6 @@ sp_api::impl_runtime_apis! { } impl xcm_payment_runtime_api::XcmPaymentApi<Block, RuntimeCall> for Runtime { - fn query_acceptable_payment_assets(_: xcm::Version) -> Result<Vec<VersionedAssetId>, xcm_payment_runtime_api::Error> { unimplemented!() } @@ -412,5 +411,9 @@ sp_api::impl_runtime_apis! { fn query_xcm_weight(_: VersionedXcm<RuntimeCall>) -> Result<Weight, xcm_payment_runtime_api::Error> { unimplemented!() } + + fn query_delivery_fees(_: VersionedLocation, _: VersionedXcm<()>) -> Result<VersionedAssets, xcm_payment_runtime_api::Error> { + unimplemented!() + } } } diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index bd4b8cd2dd769..61d00cfdd0134 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -98,7 +98,7 @@ use sp_staking::SessionIndex; #[cfg(any(feature = "std", test))] use sp_version::NativeVersion; use sp_version::RuntimeVersion; -use xcm::{latest::prelude::*, IntoVersion, VersionedAssetId, VersionedLocation, VersionedXcm}; +use xcm::{latest::prelude::*, IntoVersion, VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm}; use xcm_builder::PayOverXcm; pub use frame_system::Call as SystemCall; @@ -1830,6 +1830,20 @@ sp_api::impl_runtime_apis! { <xcm_config::XcmConfig as xcm_executor::Config>::Weigher::weight(&mut message) .map_err(|_| XcmPaymentApiError::WeightNotComputable) } + + fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>) -> Result<VersionedAssets, XcmPaymentApiError> { + let destination = destination + .try_into() + .map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?; + let message = message + .try_into() + .map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?; + let (_, fees) = xcm_config::XcmRouter::validate(&mut Some(destination), &mut Some(message)).map_err(|error| { + log::error!("Error when querying delivery fees: {:?}", error); + XcmPaymentApiError::Unroutable + })?; + Ok(VersionedAssets::from(fees)) + } } impl sp_api::Metadata<Block> for Runtime { diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 41d0460f3cc7d..5a4c4e7fdc39a 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -2287,6 +2287,20 @@ sp_api::impl_runtime_apis! { <xcm_config::XcmConfig as xcm_executor::Config>::Weigher::weight(&mut message) .map_err(|_| XcmPaymentApiError::WeightNotComputable) } + + fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>) -> Result<VersionedAssets, XcmPaymentApiError> { + let destination = destination + .try_into() + .map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?; + let message = message + .try_into() + .map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?; + let (_, fees) = xcm_config::XcmRouter::validate(&mut Some(destination), &mut Some(message)).map_err(|error| { + log::error!("Error when querying delivery fees: {:?}", error); + XcmPaymentApiError::Unroutable + })?; + Ok(VersionedAssets::from(fees)) + } } impl pallet_nomination_pools_runtime_api::NominationPoolsApi< diff --git a/polkadot/xcm/xcm-builder/xcm-payment-runtime-api/Cargo.toml b/polkadot/xcm/xcm-builder/xcm-payment-runtime-api/Cargo.toml index 38c95606ee393..c551e7c2edc26 100644 --- a/polkadot/xcm/xcm-builder/xcm-payment-runtime-api/Cargo.toml +++ b/polkadot/xcm/xcm-builder/xcm-payment-runtime-api/Cargo.toml @@ -26,6 +26,7 @@ sp-runtime = { path = "../../../../substrate/primitives/runtime", default-featur sp-weights = { path = "../../../../substrate/primitives/weights", default-features = false } xcm = { package = "staging-xcm", path = "../..", default-features = false } frame-support = { path = "../../../../substrate/frame/support", default-features = false } + [features] default = ["std"] std = [ diff --git a/polkadot/xcm/xcm-builder/xcm-payment-runtime-api/src/lib.rs b/polkadot/xcm/xcm-builder/xcm-payment-runtime-api/src/lib.rs index ef55dda51a7f6..e5af1d7048be2 100644 --- a/polkadot/xcm/xcm-builder/xcm-payment-runtime-api/src/lib.rs +++ b/polkadot/xcm/xcm-builder/xcm-payment-runtime-api/src/lib.rs @@ -22,7 +22,7 @@ use codec::{Codec, Decode, Encode}; use frame_support::pallet_prelude::TypeInfo; use sp_std::vec::Vec; use sp_weights::Weight; -use xcm::{Version, VersionedAssetId, VersionedXcm}; +use xcm::{Version, VersionedAssetId, VersionedXcm, VersionedLocation, VersionedAssets}; sp_api::decl_runtime_apis! { /// A trait of XCM payment API. @@ -60,6 +60,16 @@ sp_api::decl_runtime_apis! { /// * `weight`: convertible `Weight`. /// * `asset`: `VersionedAssetId`. fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, Error>; + + /// Get delivery fees for sending a specific `message` to a `destination`. + /// These always come in a specific asset, defined by the chain. + /// + /// # Arguments + /// * `message`: The message that'll be sent, necessary because most delivery fees are based on the + /// size of the message. + /// * `destination`: The destination to send the message to. Different destinations may use + /// different senders that charge different fees. + fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>) -> Result<VersionedAssets, Error>; } } @@ -79,4 +89,6 @@ pub enum Error { /// The given asset is not handled(as a fee payment). #[codec(index = 4)] AssetNotFound, + #[codec(index = 5)] + Unroutable, }