diff --git a/polkadot/node/service/src/fake_runtime_api.rs b/polkadot/node/service/src/fake_runtime_api.rs index 34111d007beb..15c245829b09 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 for Runtime { - fn query_acceptable_payment_assets(_: xcm::Version) -> Result, xcm_payment_runtime_api::Error> { unimplemented!() } @@ -412,5 +411,9 @@ sp_api::impl_runtime_apis! { fn query_xcm_weight(_: VersionedXcm) -> Result { unimplemented!() } + + fn query_delivery_fees(_: VersionedLocation, _: VersionedXcm<()>) -> Result { + unimplemented!() + } } } diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index bd4b8cd2dd76..61d00cfdd013 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! { ::Weigher::weight(&mut message) .map_err(|_| XcmPaymentApiError::WeightNotComputable) } + + fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>) -> Result { + 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 for Runtime { diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 41d0460f3cc7..5a4c4e7fdc39 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -2287,6 +2287,20 @@ sp_api::impl_runtime_apis! { ::Weigher::weight(&mut message) .map_err(|_| XcmPaymentApiError::WeightNotComputable) } + + fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>) -> Result { + 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 38c95606ee39..c551e7c2edc2 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 ef55dda51a7f..e5af1d7048be 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; + + /// 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; } } @@ -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, }