From 6d63a790eb07858ac8db14f4d8d3465157827d78 Mon Sep 17 00:00:00 2001 From: Igor Papandinas <26460174+ipapandinas@users.noreply.github.com> Date: Thu, 5 Sep 2024 21:33:57 +0200 Subject: [PATCH] XcmPaymentApi refactored, DryRunApi implemented --- runtime/astar/src/lib.rs | 85 ++++++++++++++++++++----------------- runtime/shibuya/src/lib.rs | 86 +++++++++++++++++++++----------------- runtime/shiden/src/lib.rs | 85 ++++++++++++++++++++----------------- 3 files changed, 141 insertions(+), 115 deletions(-) diff --git a/runtime/astar/src/lib.rs b/runtime/astar/src/lib.rs index b9f1b3919..fa5b8513f 100644 --- a/runtime/astar/src/lib.rs +++ b/runtime/astar/src/lib.rs @@ -69,9 +69,12 @@ use sp_runtime::{ use sp_std::{collections::btree_map::BTreeMap, prelude::*}; use xcm::{ v4::{AssetId as XcmAssetId, Location as XcmLocation}, - IntoVersion, VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm, + VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm, +}; +use xcm_fee_payment_runtime_api::{ + dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects}, + fees::Error as XcmPaymentApiError, }; -use xcm_fee_payment_runtime_api::Error as XcmPaymentApiError; use astar_primitives::{ dapp_staking::{ @@ -1907,52 +1910,48 @@ impl_runtime_apis! { } } - impl xcm_fee_payment_runtime_api::XcmPaymentApi for Runtime { + impl xcm_fee_payment_runtime_api::fees::XcmPaymentApi for Runtime { fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result, XcmPaymentApiError> { if !matches!(xcm_version, xcm::v3::VERSION | xcm::v4::VERSION) { return Err(XcmPaymentApiError::UnhandledXcmVersion); } // Native asset is always supported - let native_asset_location: XcmLocation = XcmLocation::try_from(xcm_config::AstarLocation::get()) - .map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?; - - Ok([VersionedAssetId::V4(native_asset_location.into())] - .into_iter() - // Acquire foreign assets which have 'units per second' configured - .chain( - pallet_xc_asset_config::AssetLocationUnitsPerSecond::::iter_keys().filter_map(|asset_location| { - - match XcmLocation::try_from(asset_location) { - Ok(asset) => Some(VersionedAssetId::V4(asset.into())), - Err(_) => None, - } - }) - ).filter_map(|asset| asset.into_version(xcm_version).ok()).collect()) + let mut acceptable_assets = vec![XcmAssetId::from(xcm_config::AstarLocation::get())]; + + // Add foreign assets that have 'units per second' configured + acceptable_assets.extend( + pallet_xc_asset_config::AssetLocationUnitsPerSecond::::iter_keys().filter_map( + |asset_location| match XcmLocation::try_from(asset_location) { + Ok(location) => Some(XcmAssetId::from(location)), + Err(_) => None, + }, + ), + ); + + PolkadotXcm::query_acceptable_payment_assets(xcm_version, acceptable_assets) } fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result { - let native_asset_location = XcmLocation::try_from(xcm_config::AstarLocation::get()) - .map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?; - let native_asset = VersionedAssetId::V4(native_asset_location.into()); - - let asset = asset - .into_version(xcm::v4::VERSION) - .map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?; - - if native_asset == asset { - Ok(XcmWeightToFee::weight_to_fee(&weight)) - } else { - let asset_id: XcmAssetId = asset.try_into().map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?; - let versioned_location = VersionedLocation::V4(asset_id.0); - - match pallet_xc_asset_config::AssetLocationUnitsPerSecond::::get(versioned_location) { - Some(units_per_sec) => { - Ok(units_per_sec.saturating_mul(weight.ref_time() as u128) - / (WEIGHT_REF_TIME_PER_SECOND as u128)) - } - None => Err(XcmPaymentApiError::AssetNotFound), + match asset.try_as::() { + // for native token + Ok(asset_id) if asset_id.0 == xcm_config::AstarLocation::get() => { + Ok(WeightToFee::weight_to_fee(&weight)) } + // for foreign assets that have 'units per second' configured + Ok(asset_id) => { + let versioned_location = VersionedLocation::V4(asset_id.0.clone()); + + match pallet_xc_asset_config::AssetLocationUnitsPerSecond::::get(versioned_location) { + Some(units_per_sec) => { + Ok(units_per_sec.saturating_mul(weight.ref_time() as u128) + / (WEIGHT_REF_TIME_PER_SECOND as u128)) + }, + None => Err(XcmPaymentApiError::AssetNotFound), + } + }, + // for failed asset conversion + Err(_) => Err(XcmPaymentApiError::VersionedConversionFailed) } } @@ -1965,6 +1964,16 @@ impl_runtime_apis! { } } + impl xcm_fee_payment_runtime_api::dry_run::DryRunApi for Runtime { + fn dry_run_call(origin: OriginCaller, call: RuntimeCall) -> Result, XcmDryRunApiError> { + PolkadotXcm::dry_run_call::(origin, call) + } + + fn dry_run_xcm(origin_location: VersionedLocation, xcm: VersionedXcm) -> Result, XcmDryRunApiError> { + PolkadotXcm::dry_run_xcm::(origin_location, xcm) + } + } + impl sp_genesis_builder::GenesisBuilder for Runtime { fn build_state(config: Vec) -> sp_genesis_builder::Result { diff --git a/runtime/shibuya/src/lib.rs b/runtime/shibuya/src/lib.rs index c5ed92c76..ff00c5629 100644 --- a/runtime/shibuya/src/lib.rs +++ b/runtime/shibuya/src/lib.rs @@ -71,9 +71,12 @@ use sp_runtime::{ use sp_std::{collections::btree_map::BTreeMap, prelude::*}; use xcm::{ v4::{AssetId as XcmAssetId, Location as XcmLocation}, - IntoVersion, VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm, + VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm, +}; +use xcm_fee_payment_runtime_api::{ + dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects}, + fees::Error as XcmPaymentApiError, }; -use xcm_fee_payment_runtime_api::Error as XcmPaymentApiError; use astar_primitives::{ dapp_staking::{ @@ -2238,53 +2241,48 @@ impl_runtime_apis! { } } - impl xcm_fee_payment_runtime_api::XcmPaymentApi for Runtime { + impl xcm_fee_payment_runtime_api::fees::XcmPaymentApi for Runtime { fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result, XcmPaymentApiError> { if !matches!(xcm_version, xcm::v3::VERSION | xcm::v4::VERSION) { return Err(XcmPaymentApiError::UnhandledXcmVersion); } // Native asset is always supported - let native_asset_location: XcmLocation = XcmLocation::try_from(xcm_config::ShibuyaLocation::get()) - .map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?; - - Ok([VersionedAssetId::V4(native_asset_location.into())] - .into_iter() - // Acquire foreign assets which have 'units per second' configured - .chain( - pallet_xc_asset_config::AssetLocationUnitsPerSecond::::iter_keys().filter_map(|asset_location| { - - match XcmLocation::try_from(asset_location) { - Ok(asset) => Some(VersionedAssetId::V4(asset.into())), - Err(_) => None, - } - }) - ).filter_map(|asset| asset.into_version(xcm_version).ok()).collect()) + let mut acceptable_assets = vec![XcmAssetId::from(xcm_config::ShibuyaLocation::get())]; + + // Add foreign assets that have 'units per second' configured + acceptable_assets.extend( + pallet_xc_asset_config::AssetLocationUnitsPerSecond::::iter_keys().filter_map( + |asset_location| match XcmLocation::try_from(asset_location) { + Ok(location) => Some(XcmAssetId::from(location)), + Err(_) => None, + }, + ), + ); + + PolkadotXcm::query_acceptable_payment_assets(xcm_version, acceptable_assets) } - // TODO: improve this function, reduce code duplication, especially on a such a functional level fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result { - let native_asset_location = XcmLocation::try_from(xcm_config::ShibuyaLocation::get()) - .map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?; - let native_asset = VersionedAssetId::V4(native_asset_location.into()); - - let asset = asset - .into_version(xcm::v4::VERSION) - .map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?; - - if native_asset == asset { - Ok(XcmWeightToFee::weight_to_fee(&weight)) - } else { - let asset_id: XcmAssetId = asset.try_into().map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?; - let versioned_location = VersionedLocation::V4(asset_id.0); - - match pallet_xc_asset_config::AssetLocationUnitsPerSecond::::get(versioned_location) { - Some(units_per_sec) => { - Ok(units_per_sec.saturating_mul(weight.ref_time() as u128) - / (WEIGHT_REF_TIME_PER_SECOND as u128)) - } - None => Err(XcmPaymentApiError::AssetNotFound), + match asset.try_as::() { + // for native token + Ok(asset_id) if asset_id.0 == xcm_config::ShibuyaLocation::get() => { + Ok(WeightToFee::weight_to_fee(&weight)) } + // for foreign assets that have 'units per second' configured + Ok(asset_id) => { + let versioned_location = VersionedLocation::V4(asset_id.0.clone()); + + match pallet_xc_asset_config::AssetLocationUnitsPerSecond::::get(versioned_location) { + Some(units_per_sec) => { + Ok(units_per_sec.saturating_mul(weight.ref_time() as u128) + / (WEIGHT_REF_TIME_PER_SECOND as u128)) + }, + None => Err(XcmPaymentApiError::AssetNotFound), + } + }, + // for failed asset conversion + Err(_) => Err(XcmPaymentApiError::VersionedConversionFailed) } } @@ -2297,6 +2295,16 @@ impl_runtime_apis! { } } + impl xcm_fee_payment_runtime_api::dry_run::DryRunApi for Runtime { + fn dry_run_call(origin: OriginCaller, call: RuntimeCall) -> Result, XcmDryRunApiError> { + PolkadotXcm::dry_run_call::(origin, call) + } + + fn dry_run_xcm(origin_location: VersionedLocation, xcm: VersionedXcm) -> Result, XcmDryRunApiError> { + PolkadotXcm::dry_run_xcm::(origin_location, xcm) + } + } + impl sp_genesis_builder::GenesisBuilder for Runtime { fn build_state(config: Vec) -> sp_genesis_builder::Result { diff --git a/runtime/shiden/src/lib.rs b/runtime/shiden/src/lib.rs index fa110b427..8394e0fa9 100644 --- a/runtime/shiden/src/lib.rs +++ b/runtime/shiden/src/lib.rs @@ -68,9 +68,12 @@ use sp_runtime::{ use sp_std::{collections::btree_map::BTreeMap, prelude::*}; use xcm::{ v4::{AssetId as XcmAssetId, Location as XcmLocation}, - IntoVersion, VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm, + VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm, +}; +use xcm_fee_payment_runtime_api::{ + dry_run::{CallDryRunEffects, Error as XcmDryRunApiError, XcmDryRunEffects}, + fees::Error as XcmPaymentApiError, }; -use xcm_fee_payment_runtime_api::Error as XcmPaymentApiError; use astar_primitives::{ dapp_staking::{ @@ -1908,52 +1911,48 @@ impl_runtime_apis! { } } - impl xcm_fee_payment_runtime_api::XcmPaymentApi for Runtime { + impl xcm_fee_payment_runtime_api::fees::XcmPaymentApi for Runtime { fn query_acceptable_payment_assets(xcm_version: xcm::Version) -> Result, XcmPaymentApiError> { if !matches!(xcm_version, xcm::v3::VERSION | xcm::v4::VERSION) { return Err(XcmPaymentApiError::UnhandledXcmVersion); } // Native asset is always supported - let native_asset_location: XcmLocation = XcmLocation::try_from(xcm_config::ShidenLocation::get()) - .map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?; - - Ok([VersionedAssetId::V4(native_asset_location.into())] - .into_iter() - // Acquire foreign assets which have 'units per second' configured - .chain( - pallet_xc_asset_config::AssetLocationUnitsPerSecond::::iter_keys().filter_map(|asset_location| { - - match XcmLocation::try_from(asset_location) { - Ok(asset) => Some(VersionedAssetId::V4(asset.into())), - Err(_) => None, - } - }) - ).filter_map(|asset| asset.into_version(xcm_version).ok()).collect()) + let mut acceptable_assets = vec![XcmAssetId::from(xcm_config::ShidenLocation::get())]; + + // Add foreign assets that have 'units per second' configured + acceptable_assets.extend( + pallet_xc_asset_config::AssetLocationUnitsPerSecond::::iter_keys().filter_map( + |asset_location| match XcmLocation::try_from(asset_location) { + Ok(location) => Some(XcmAssetId::from(location)), + Err(_) => None, + }, + ), + ); + + PolkadotXcm::query_acceptable_payment_assets(xcm_version, acceptable_assets) } fn query_weight_to_asset_fee(weight: Weight, asset: VersionedAssetId) -> Result { - let native_asset_location = XcmLocation::try_from(xcm_config::ShidenLocation::get()) - .map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?; - let native_asset = VersionedAssetId::V4(native_asset_location.into()); - - let asset = asset - .into_version(xcm::v4::VERSION) - .map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?; - - if native_asset == asset { - Ok(XcmWeightToFee::weight_to_fee(&weight)) - } else { - let asset_id: XcmAssetId = asset.try_into().map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?; - let versioned_location = VersionedLocation::V4(asset_id.0); - - match pallet_xc_asset_config::AssetLocationUnitsPerSecond::::get(versioned_location) { - Some(units_per_sec) => { - Ok(units_per_sec.saturating_mul(weight.ref_time() as u128) - / (WEIGHT_REF_TIME_PER_SECOND as u128)) - } - None => Err(XcmPaymentApiError::AssetNotFound), + match asset.try_as::() { + // for native token + Ok(asset_id) if asset_id.0 == xcm_config::ShidenLocation::get() => { + Ok(WeightToFee::weight_to_fee(&weight)) } + // for foreign assets that have 'units per second' configured + Ok(asset_id) => { + let versioned_location = VersionedLocation::V4(asset_id.0.clone()); + + match pallet_xc_asset_config::AssetLocationUnitsPerSecond::::get(versioned_location) { + Some(units_per_sec) => { + Ok(units_per_sec.saturating_mul(weight.ref_time() as u128) + / (WEIGHT_REF_TIME_PER_SECOND as u128)) + }, + None => Err(XcmPaymentApiError::AssetNotFound), + } + }, + // for failed asset conversion + Err(_) => Err(XcmPaymentApiError::VersionedConversionFailed) } } @@ -1966,6 +1965,16 @@ impl_runtime_apis! { } } + impl xcm_fee_payment_runtime_api::dry_run::DryRunApi for Runtime { + fn dry_run_call(origin: OriginCaller, call: RuntimeCall) -> Result, XcmDryRunApiError> { + PolkadotXcm::dry_run_call::(origin, call) + } + + fn dry_run_xcm(origin_location: VersionedLocation, xcm: VersionedXcm) -> Result, XcmDryRunApiError> { + PolkadotXcm::dry_run_xcm::(origin_location, xcm) + } + } + impl sp_genesis_builder::GenesisBuilder for Runtime { fn build_state(config: Vec) -> sp_genesis_builder::Result {