Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add XcmPaymentApi and DryRunApi to all runtimes #359

Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added

- Polkadot chains: allow arbitrary XCM execution ([polkadot-fellows/runtimes#345](https://github.com/polkadot-fellows/runtimes/pull/345))
- All runtimes: XcmPaymentApi and DryRunApi ([polkadot-fellows/runtimes#359](https://github.com/polkadot-fellows/runtimes/pull/359))

## [1.2.7] 14.06.2024

Expand Down
9 changes: 9 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ xcm = { version = "14.0.0", default-features = false, package = "staging-xcm" }
xcm-builder = { version = "14.0.0", default-features = false, package = "staging-xcm-builder" }
xcm-emulator = { version = "0.12.0" }
xcm-executor = { version = "14.0.0", default-features = false, package = "staging-xcm-executor" }
xcm-fee-payment-runtime-api = { version = "0.4.0", default-features = false }
anyhow = { version = "1.0.82" }
subxt = { version = "0.35.0", default-features = false }
tracing-subscriber = { version = "0.3.18" }
Expand Down
3 changes: 3 additions & 0 deletions relay/kusama/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ polkadot-primitives = { workspace = true }
xcm = { workspace = true }
xcm-executor = { workspace = true }
xcm-builder = { workspace = true }
xcm-fee-payment-runtime-api = { workspace = true }

sp-debug-derive = { workspace = true }

Expand Down Expand Up @@ -208,6 +209,7 @@ std = [
"xcm-builder/std",
"xcm-executor/std",
"xcm/std",
"xcm-fee-payment-runtime-api/std",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
Expand Down Expand Up @@ -258,6 +260,7 @@ runtime-benchmarks = [
"sp-staking/runtime-benchmarks",
"xcm-builder/runtime-benchmarks",
"xcm-executor/runtime-benchmarks",
"xcm-fee-payment-runtime-api/runtime-benchmarks",
]
try-runtime = [
"frame-election-provider-support/try-runtime",
Expand Down
53 changes: 48 additions & 5 deletions relay/kusama/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ use frame_support::{
InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, PrivilegeCmp, ProcessMessage,
ProcessMessageError, StorageMapShim, WithdrawReasons,
},
weights::{ConstantMultiplier, WeightMeter},
weights::{ConstantMultiplier, WeightMeter, WeightToFee as _},
PalletId,
};
use frame_system::EnsureRoot;
Expand All @@ -105,11 +105,12 @@ use sp_staking::SessionIndex;
#[cfg(any(feature = "std", test))]
use sp_version::NativeVersion;
use sp_version::RuntimeVersion;
use xcm::{
latest::{InteriorLocation, Junction, Junction::PalletInstance},
VersionedLocation,
};
use xcm::prelude::*;
use xcm_builder::PayOverXcm;
use xcm_fee_payment_runtime_api::{
dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
fees::Error as XcmPaymentApiError,
};

pub use frame_system::Call as SystemCall;
pub use pallet_balances::Call as BalancesCall;
Expand Down Expand Up @@ -2741,6 +2742,48 @@ sp_api::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())];
XcmPallet::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> {
XcmPallet::query_xcm_weight(message)
}

fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>) -> Result<VersionedAssets, XcmPaymentApiError> {
XcmPallet::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> {
XcmPallet::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> {
XcmPallet::dry_run_xcm::<Runtime, xcm_config::XcmRouter, RuntimeCall, xcm_config::XcmConfig>(origin_location, xcm)
}
}

impl pallet_nomination_pools_runtime_api::NominationPoolsApi<
Block,
AccountId,
Expand Down
3 changes: 3 additions & 0 deletions relay/polkadot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ polkadot-primitives = { workspace = true }
xcm = { workspace = true }
xcm-executor = { workspace = true }
xcm-builder = { workspace = true }
xcm-fee-payment-runtime-api = { workspace = true }

sp-debug-derive = { workspace = true }

Expand Down Expand Up @@ -205,6 +206,7 @@ std = [
"xcm-builder/std",
"xcm-executor/std",
"xcm/std",
"xcm-fee-payment-runtime-api/std",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
Expand Down Expand Up @@ -253,6 +255,7 @@ runtime-benchmarks = [
"sp-staking/runtime-benchmarks",
"xcm-builder/runtime-benchmarks",
"xcm-executor/runtime-benchmarks",
"xcm-fee-payment-runtime-api/runtime-benchmarks",
]
try-runtime = [
"frame-election-provider-support/try-runtime",
Expand Down
1 change: 0 additions & 1 deletion relay/polkadot/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ use frame_system::RawOrigin;
use polkadot_primitives::Id as ParaId;
use polkadot_runtime_common::identity_migrator::{OnReapIdentity, WeightInfo};
use polkadot_runtime_constants::system_parachain::PEOPLE_ID;
use xcm::{latest::prelude::*, VersionedXcm};
use xcm_builder::IsChildSystemParachain;
use xcm_executor::traits::TransactAsset;

Expand Down
53 changes: 48 additions & 5 deletions relay/polkadot/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ use frame_support::{
Get, InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, PrivilegeCmp, ProcessMessage,
ProcessMessageError, WithdrawReasons,
},
weights::{ConstantMultiplier, WeightMeter},
weights::{ConstantMultiplier, WeightMeter, WeightToFee as _},
PalletId,
};
use frame_system::EnsureRoot;
Expand Down Expand Up @@ -103,11 +103,12 @@ use sp_std::{
#[cfg(any(feature = "std", test))]
use sp_version::NativeVersion;
use sp_version::RuntimeVersion;
use xcm::{
latest::{InteriorLocation, Junction, Junction::PalletInstance},
VersionedLocation,
};
use xcm::prelude::*;
use xcm_builder::PayOverXcm;
use xcm_fee_payment_runtime_api::{
dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
fees::Error as XcmPaymentApiError,
};

pub use frame_system::Call as SystemCall;
pub use pallet_balances::Call as BalancesCall;
Expand Down Expand Up @@ -2534,6 +2535,48 @@ sp_api::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())];
XcmPallet::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> {
XcmPallet::query_xcm_weight(message)
}

fn query_delivery_fees(destination: VersionedLocation, message: VersionedXcm<()>) -> Result<VersionedAssets, XcmPaymentApiError> {
XcmPallet::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> {
XcmPallet::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> {
XcmPallet::dry_run_xcm::<Runtime, xcm_config::XcmRouter, RuntimeCall, xcm_config::XcmConfig>(origin_location, xcm)
}
}

impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
build_state::<RuntimeGenesisConfig>(config)
Expand Down
3 changes: 3 additions & 0 deletions system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ polkadot-runtime-common = { workspace = true }
xcm = { workspace = true }
xcm-builder = { workspace = true }
xcm-executor = { workspace = true }
xcm-fee-payment-runtime-api = { workspace = true }

# Cumulus
cumulus-pallet-aura-ext = { workspace = true }
Expand Down Expand Up @@ -156,6 +157,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 @@ -270,6 +272,7 @@ std = [
"xcm-builder/std",
"xcm-executor/std",
"xcm/std",
"xcm-fee-payment-runtime-api/std",
]

# Enable metadata hash generation at compile time for the `CheckMetadataHash` extension.
Expand Down
53 changes: 51 additions & 2 deletions system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ use frame_support::{
ConstU128, ConstU32, ConstU64, ConstU8, EitherOfDiverse, EnsureOrigin, EnsureOriginWithArg,
Equals, InstanceFilter, TransformOrigin, WithdrawReasons,
},
weights::{ConstantMultiplier, Weight},
weights::{ConstantMultiplier, Weight, WeightToFee as _},
BoundedVec, PalletId,
};
use frame_system::{
Expand All @@ -81,12 +81,19 @@ use system_parachains_constants::{
kusama::{consensus::*, currency::*, fee::WeightToFee},
AVERAGE_ON_INITIALIZE_RATIO, DAYS, HOURS, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO,
};
use xcm::latest::prelude::{AssetId, BodyId};
use xcm::{
latest::prelude::{AssetId, BodyId},
VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm,
};
use xcm_config::{
FellowshipLocation, ForeignAssetsConvertedConcreteId, ForeignCreatorsSovereignAccountOf,
GovernanceLocation, KsmLocation, KsmLocationV3, PoolAssetsConvertedConcreteId,
TrustBackedAssetsConvertedConcreteId, TrustBackedAssetsPalletLocationV3,
};
use xcm_fee_payment_runtime_api::{
dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects},
fees::Error as XcmPaymentApiError,
};

#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;
Expand Down Expand Up @@ -1283,6 +1290,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::KsmLocation::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::KsmLocation::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 assets_common::runtime_api::FungiblesApi<
Block,
AccountId,
Expand Down
Loading
Loading