Skip to content

Commit

Permalink
Implement XcmPaymentApi and DryRunApi on all system parachains (#…
Browse files Browse the repository at this point in the history
…4634)

Depends on #4621.

Implemented the
[`XcmPaymentApi`](#3607)
and [`DryRunApi`](#3872)
on all system parachains.

More scenarios can be tested on both rococo and westend if all system
parachains implement this APIs.
The objective is for all XCM-enabled runtimes to implement them.
After demonstrating fee estimation in a UI on the testnets, come the
fellowship runtimes.

Step towards #690.
  • Loading branch information
franciscoaguirre authored May 31, 2024
1 parent 8d8c0e1 commit fc6c318
Show file tree
Hide file tree
Showing 24 changed files with 481 additions and 74 deletions.
8 changes: 8 additions & 0 deletions Cargo.lock

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

13 changes: 3 additions & 10 deletions cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ use xcm::latest::prelude::{
};
use xcm::{
latest::prelude::{AssetId, BodyId},
IntoVersion, VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm,
VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm,
};
use xcm_fee_payment_runtime_api::{
dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
Expand Down Expand Up @@ -1295,15 +1295,8 @@ impl_runtime_apis! {

impl xcm_fee_payment_runtime_api::fees::XcmPaymentApi<Block> for Runtime {
fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result<Vec<VersionedAssetId>, XcmPaymentApiError> {
let acceptable = vec![
// native token
VersionedAssetId::from(AssetId(xcm_config::TokenLocation::get()))
];

Ok(acceptable
.into_iter()
.filter_map(|asset| asset.into_version(xcm_version).ok())
.collect())
let acceptable_assets = vec![AssetId(xcm_config::TokenLocation::get())];
PolkadotXcm::query_acceptable_payment_assets(xcm_version, acceptable_assets)
}

fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
Expand Down
16 changes: 3 additions & 13 deletions cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,7 @@ pub use sp_runtime::BuildStorage;

use assets_common::{foreign_creators::ForeignCreators, matching::FromSiblingParachain};
use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate};
use xcm::{
prelude::{VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm},
IntoVersion,
};
use xcm::prelude::{VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm};

// We exclude `Assets` since it's the name of a pallet
use xcm::latest::prelude::AssetId;
Expand Down Expand Up @@ -1331,15 +1328,8 @@ impl_runtime_apis! {

impl xcm_fee_payment_runtime_api::fees::XcmPaymentApi<Block> for Runtime {
fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result<Vec<VersionedAssetId>, XcmPaymentApiError> {
let acceptable = vec![
// native token
VersionedAssetId::from(AssetId(xcm_config::WestendLocation::get()))
];

Ok(acceptable
.into_iter()
.filter_map(|asset| asset.into_version(xcm_version).ok())
.collect())
let acceptable_assets = vec![AssetId(xcm_config::WestendLocation::get())];
PolkadotXcm::query_acceptable_payment_assets(xcm_version, acceptable_assets)
}

fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ polkadot-runtime-common = { path = "../../../../../polkadot/runtime/common", def
xcm = { package = "staging-xcm", path = "../../../../../polkadot/xcm", default-features = false }
xcm-builder = { package = "staging-xcm-builder", path = "../../../../../polkadot/xcm/xcm-builder", default-features = false }
xcm-executor = { package = "staging-xcm-executor", path = "../../../../../polkadot/xcm/xcm-executor", default-features = false }
xcm-fee-payment-runtime-api = { path = "../../../../../polkadot/xcm/xcm-fee-payment-runtime-api", default-features = false }

# Cumulus
cumulus-pallet-aura-ext = { path = "../../../../pallets/aura-ext", default-features = false }
Expand Down Expand Up @@ -220,6 +221,7 @@ std = [
"tuplex/std",
"xcm-builder/std",
"xcm-executor/std",
"xcm-fee-payment-runtime-api/std",
"xcm/std",
]

Expand Down Expand Up @@ -262,6 +264,7 @@ runtime-benchmarks = [
"sp-runtime/runtime-benchmarks",
"xcm-builder/runtime-benchmarks",
"xcm-executor/runtime-benchmarks",
"xcm-fee-payment-runtime-api/runtime-benchmarks",
]

try-runtime = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ use frame_support::{
genesis_builder_helper::{build_state, get_preset},
parameter_types,
traits::{ConstBool, ConstU32, ConstU64, ConstU8, Get, TransformOrigin},
weights::{ConstantMultiplier, Weight},
weights::{ConstantMultiplier, Weight, WeightToFee as _},
PalletId,
};
use frame_system::{
Expand All @@ -97,7 +97,11 @@ pub use sp_runtime::BuildStorage;

use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate};
use rococo_runtime_constants::system_parachain::{ASSET_HUB_ID, BRIDGE_HUB_ID};
use xcm::latest::prelude::*;
use xcm::prelude::*;
use xcm_fee_payment_runtime_api::{
dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
fees::Error as XcmPaymentApiError,
};

use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight};

Expand Down Expand Up @@ -962,6 +966,48 @@ impl_runtime_apis! {
}
}

impl xcm_fee_payment_runtime_api::fees::XcmPaymentApi<Block> for Runtime {
fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result<Vec<VersionedAssetId>, XcmPaymentApiError> {
let acceptable_assets = vec![AssetId(xcm_config::TokenLocation::get())];
PolkadotXcm::query_acceptable_payment_assets(xcm_version, acceptable_assets)
}

fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
match asset.try_as::<AssetId>() {
Ok(asset_id) if asset_id.0 == xcm_config::TokenLocation::get() => {
// for native token
Ok(WeightToFee::weight_to_fee(&weight))
},
Ok(asset_id) => {
log::trace!(target: "xcm::xcm_fee_payment_runtime_api", "query_weight_to_asset_fee - unhandled asset_id: {asset_id:?}!");
Err(XcmPaymentApiError::AssetNotFound)
},
Err(_) => {
log::trace!(target: "xcm::xcm_fee_payment_runtime_api", "query_weight_to_asset_fee - failed to convert asset: {asset:?}!");
Err(XcmPaymentApiError::VersionedConversionFailed)
}
}
}

fn query_xcm_weight(message: VersionedXcm<()>) -> Result<Weight, XcmPaymentApiError> {
PolkadotXcm::query_xcm_weight(message)
}

fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>) -> Result<VersionedAssets, XcmPaymentApiError> {
PolkadotXcm::query_delivery_fees(destination, message)
}
}

impl xcm_fee_payment_runtime_api::dry_run::DryRunApi<Block, RuntimeCall, RuntimeEvent, OriginCaller> for Runtime {
fn dry_run_call(origin: OriginCaller, call: RuntimeCall) -> Result<CallDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
PolkadotXcm::dry_run_call::<Runtime, xcm_config::XcmRouter, OriginCaller, RuntimeCall>(origin, call)
}

fn dry_run_xcm(origin_location: VersionedLocation, xcm: VersionedXcm<RuntimeCall>) -> Result<XcmDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
PolkadotXcm::dry_run_xcm::<Runtime, xcm_config::XcmRouter, RuntimeCall, xcm_config::XcmConfig>(origin_location, xcm)
}
}

impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
ParachainSystem::collect_collation_info(header)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ polkadot-runtime-common = { path = "../../../../../polkadot/runtime/common", def
xcm = { package = "staging-xcm", path = "../../../../../polkadot/xcm", default-features = false }
xcm-builder = { package = "staging-xcm-builder", path = "../../../../../polkadot/xcm/xcm-builder", default-features = false }
xcm-executor = { package = "staging-xcm-executor", path = "../../../../../polkadot/xcm/xcm-executor", default-features = false }
xcm-fee-payment-runtime-api = { path = "../../../../../polkadot/xcm/xcm-fee-payment-runtime-api", default-features = false }

# Cumulus
cumulus-pallet-aura-ext = { path = "../../../../pallets/aura-ext", default-features = false }
Expand Down Expand Up @@ -185,6 +186,7 @@ std = [
"westend-runtime-constants/std",
"xcm-builder/std",
"xcm-executor/std",
"xcm-fee-payment-runtime-api/std",
"xcm/std",
]

Expand Down Expand Up @@ -219,6 +221,7 @@ runtime-benchmarks = [
"sp-runtime/runtime-benchmarks",
"xcm-builder/runtime-benchmarks",
"xcm-executor/runtime-benchmarks",
"xcm-fee-payment-runtime-api/runtime-benchmarks",
]

try-runtime = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ use frame_support::{
genesis_builder_helper::{build_state, get_preset},
parameter_types,
traits::{ConstBool, ConstU32, ConstU64, ConstU8, Get, TransformOrigin},
weights::{ConstantMultiplier, Weight},
weights::{ConstantMultiplier, Weight, WeightToFee as _},
PalletId,
};
use frame_system::{
Expand All @@ -75,13 +75,18 @@ pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
pub use sp_runtime::{MultiAddress, Perbill, Permill};
use xcm_config::{XcmOriginToTransactDispatchOrigin, XcmRouter};

use xcm_fee_payment_runtime_api::{
dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
fees::Error as XcmPaymentApiError,
};

use bp_runtime::HeaderId;

#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;

use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate};
use xcm::latest::prelude::*;
use xcm::prelude::*;

use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight};

Expand Down Expand Up @@ -711,6 +716,48 @@ impl_runtime_apis! {
}
}

impl xcm_fee_payment_runtime_api::fees::XcmPaymentApi<Block> for Runtime {
fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result<Vec<VersionedAssetId>, XcmPaymentApiError> {
let acceptable_assets = vec![AssetId(xcm_config::WestendLocation::get())];
PolkadotXcm::query_acceptable_payment_assets(xcm_version, acceptable_assets)
}

fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result<u128, XcmPaymentApiError> {
match asset.try_as::<AssetId>() {
Ok(asset_id) if asset_id.0 == xcm_config::WestendLocation::get() => {
// for native token
Ok(WeightToFee::weight_to_fee(&weight))
},
Ok(asset_id) => {
log::trace!(target: "xcm::xcm_fee_payment_runtime_api", "query_weight_to_asset_fee - unhandled asset_id: {asset_id:?}!");
Err(XcmPaymentApiError::AssetNotFound)
},
Err(_) => {
log::trace!(target: "xcm::xcm_fee_payment_runtime_api", "query_weight_to_asset_fee - failed to convert asset: {asset:?}!");
Err(XcmPaymentApiError::VersionedConversionFailed)
}
}
}

fn query_xcm_weight(message: VersionedXcm<()>) -> Result<Weight, XcmPaymentApiError> {
PolkadotXcm::query_xcm_weight(message)
}

fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>) -> Result<VersionedAssets, XcmPaymentApiError> {
PolkadotXcm::query_delivery_fees(destination, message)
}
}

impl xcm_fee_payment_runtime_api::dry_run::DryRunApi<Block, RuntimeCall, RuntimeEvent, OriginCaller> for Runtime {
fn dry_run_call(origin: OriginCaller, call: RuntimeCall) -> Result<CallDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
PolkadotXcm::dry_run_call::<Runtime, xcm_config::XcmRouter, OriginCaller, RuntimeCall>(origin, call)
}

fn dry_run_xcm(origin_location: VersionedLocation, xcm: VersionedXcm<RuntimeCall>) -> Result<XcmDryRunEffects<RuntimeEvent>, XcmDryRunApiError> {
PolkadotXcm::dry_run_xcm::<Runtime, xcm_config::XcmRouter, RuntimeCall, xcm_config::XcmConfig>(origin_location, xcm)
}
}

impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
ParachainSystem::collect_collation_info(header)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ polkadot-runtime-common = { path = "../../../../../polkadot/runtime/common", def
xcm = { package = "staging-xcm", path = "../../../../../polkadot/xcm", default-features = false }
xcm-builder = { package = "staging-xcm-builder", path = "../../../../../polkadot/xcm/xcm-builder", default-features = false }
xcm-executor = { package = "staging-xcm-executor", path = "../../../../../polkadot/xcm/xcm-executor", default-features = false }
xcm-fee-payment-runtime-api = { path = "../../../../../polkadot/xcm/xcm-fee-payment-runtime-api", default-features = false }
westend-runtime-constants = { path = "../../../../../polkadot/runtime/westend/constants", default-features = false }

# Cumulus
Expand Down Expand Up @@ -130,6 +131,7 @@ runtime-benchmarks = [
"sp-runtime/runtime-benchmarks",
"xcm-builder/runtime-benchmarks",
"xcm-executor/runtime-benchmarks",
"xcm-fee-payment-runtime-api/runtime-benchmarks",
]
try-runtime = [
"cumulus-pallet-aura-ext/try-runtime",
Expand Down Expand Up @@ -236,6 +238,7 @@ std = [
"westend-runtime-constants/std",
"xcm-builder/std",
"xcm-executor/std",
"xcm-fee-payment-runtime-api/std",
"xcm/std",
]

Expand Down
Loading

0 comments on commit fc6c318

Please sign in to comment.