diff --git a/traits/src/lib.rs b/traits/src/lib.rs index ea5231dd9..672c58231 100644 --- a/traits/src/lib.rs +++ b/traits/src/lib.rs @@ -24,7 +24,7 @@ pub use rewards::RewardHandler; use scale_info::TypeInfo; #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; -pub use xcm_transfer::XcmTransfer; +pub use xcm_transfer::{XcmTransfer, XtokensWeightInfo}; pub mod arithmetic; pub mod asset_registry; diff --git a/traits/src/xcm_transfer.rs b/traits/src/xcm_transfer.rs index cb6d2443b..4426c67cf 100644 --- a/traits/src/xcm_transfer.rs +++ b/traits/src/xcm_transfer.rs @@ -1,7 +1,9 @@ use frame_support::dispatch::DispatchError; use sp_std::vec::Vec; -use xcm::v3::prelude::*; - +use xcm::{ + v3::{prelude::*, Weight}, + VersionedMultiAsset, VersionedMultiAssets, VersionedMultiLocation, +}; pub struct Transferred { pub sender: AccountId, pub assets: MultiAssets, @@ -65,3 +67,18 @@ pub trait XcmTransfer { dest_weight_limit: WeightLimit, ) -> Result, DispatchError>; } + +pub trait XtokensWeightInfo { + fn weight_of_transfer_multiasset(asset: &VersionedMultiAsset, dest: &VersionedMultiLocation) -> Weight; + fn weight_of_transfer(currency_id: CurrencyId, amount: Balance, dest: &VersionedMultiLocation) -> Weight; + fn weight_of_transfer_multicurrencies( + currencies: &[(CurrencyId, Balance)], + fee_item: &u32, + dest: &VersionedMultiLocation, + ) -> Weight; + fn weight_of_transfer_multiassets( + assets: &VersionedMultiAssets, + fee_item: &u32, + dest: &VersionedMultiLocation, + ) -> Weight; +} diff --git a/xtokens/src/lib.rs b/xtokens/src/lib.rs index acac5520a..1ffb04dfb 100644 --- a/xtokens/src/lib.rs +++ b/xtokens/src/lib.rs @@ -55,7 +55,7 @@ use xcm_executor::traits::WeightBounds; pub use module::*; use orml_traits::{ location::{Parse, Reserve}, - xcm_transfer::Transferred, + xcm_transfer::{Transferred, XtokensWeightInfo}, GetByKey, XcmTransfer, }; @@ -211,7 +211,7 @@ pub mod module { /// by the network, and if the receiving chain would handle /// messages correctly. #[pallet::call_index(0)] - #[pallet::weight(Pallet::::weight_of_transfer(currency_id.clone(), *amount, dest))] + #[pallet::weight(XtokensWeight::::weight_of_transfer(currency_id.clone(), *amount, dest))] pub fn transfer( origin: OriginFor, currency_id: T::CurrencyId, @@ -237,7 +237,7 @@ pub mod module { /// by the network, and if the receiving chain would handle /// messages correctly. #[pallet::call_index(1)] - #[pallet::weight(Pallet::::weight_of_transfer_multiasset(asset, dest))] + #[pallet::weight(XtokensWeight::::weight_of_transfer_multiasset(asset, dest))] pub fn transfer_multiasset( origin: OriginFor, asset: Box, @@ -272,7 +272,7 @@ pub mod module { /// by the network, and if the receiving chain would handle /// messages correctly. #[pallet::call_index(2)] - #[pallet::weight(Pallet::::weight_of_transfer(currency_id.clone(), *amount, dest))] + #[pallet::weight(XtokensWeight::::weight_of_transfer(currency_id.clone(), *amount, dest))] pub fn transfer_with_fee( origin: OriginFor, currency_id: T::CurrencyId, @@ -309,7 +309,7 @@ pub mod module { /// by the network, and if the receiving chain would handle /// messages correctly. #[pallet::call_index(3)] - #[pallet::weight(Pallet::::weight_of_transfer_multiasset(asset, dest))] + #[pallet::weight(XtokensWeight::::weight_of_transfer_multiasset(asset, dest))] pub fn transfer_multiasset_with_fee( origin: OriginFor, asset: Box, @@ -341,7 +341,7 @@ pub mod module { /// by the network, and if the receiving chain would handle /// messages correctly. #[pallet::call_index(4)] - #[pallet::weight(Pallet::::weight_of_transfer_multicurrencies(currencies, fee_item, dest))] + #[pallet::weight(XtokensWeight::::weight_of_transfer_multicurrencies(currencies, fee_item, dest))] pub fn transfer_multicurrencies( origin: OriginFor, currencies: Vec<(T::CurrencyId, T::Balance)>, @@ -371,7 +371,7 @@ pub mod module { /// by the network, and if the receiving chain would handle /// messages correctly. #[pallet::call_index(5)] - #[pallet::weight(Pallet::::weight_of_transfer_multiassets(assets, fee_item, dest))] + #[pallet::weight(XtokensWeight::::weight_of_transfer_multiassets(assets, fee_item, dest))] pub fn transfer_multiassets( origin: OriginFor, assets: Box, @@ -831,17 +831,31 @@ pub mod module { }; Ok((transfer_kind, dest, reserve, recipient)) } + + /// Get reserve location by `assets` and `fee_item`. the `assets` + /// includes fee asset and non fee asset. make sure assets have ge one + /// asset. all non fee asset should share same reserve location. + fn get_reserve_location(assets: &MultiAssets, fee_item: &u32) -> Option { + let reserve_idx = if assets.len() == 1 { + 0 + } else { + (*fee_item == 0) as usize + }; + let asset = assets.get(reserve_idx); + asset.and_then(T::ReserveProvider::reserve) + } } + pub struct XtokensWeight(PhantomData); // weights - impl Pallet { + impl XtokensWeightInfo for XtokensWeight { /// Returns weight of `transfer_multiasset` call. fn weight_of_transfer_multiasset(asset: &VersionedMultiAsset, dest: &VersionedMultiLocation) -> Weight { let asset: Result = asset.clone().try_into(); let dest = dest.clone().try_into(); if let (Ok(asset), Ok(dest)) = (asset, dest) { if let Ok((transfer_kind, dest, _, reserve)) = - Self::transfer_kind(T::ReserveProvider::reserve(&asset), &dest) + Pallet::::transfer_kind(T::ReserveProvider::reserve(&asset), &dest) { let mut msg = match transfer_kind { SelfReserveAsset => Xcm(vec![TransferReserveAsset { @@ -904,8 +918,8 @@ pub mod module { let assets: Result = assets.clone().try_into(); let dest = dest.clone().try_into(); if let (Ok(assets), Ok(dest)) = (assets, dest) { - let reserve_location = Self::get_reserve_location(&assets, fee_item); - if let Ok((transfer_kind, dest, _, reserve)) = Self::transfer_kind(reserve_location, &dest) { + let reserve_location = Pallet::::get_reserve_location(&assets, fee_item); + if let Ok((transfer_kind, dest, _, reserve)) = Pallet::::transfer_kind(reserve_location, &dest) { let mut msg = match transfer_kind { SelfReserveAsset => Xcm(vec![TransferReserveAsset { assets, @@ -928,19 +942,6 @@ pub mod module { } Weight::zero() } - - /// Get reserve location by `assets` and `fee_item`. the `assets` - /// includes fee asset and non fee asset. make sure assets have ge one - /// asset. all non fee asset should share same reserve location. - fn get_reserve_location(assets: &MultiAssets, fee_item: &u32) -> Option { - let reserve_idx = if assets.len() == 1 { - 0 - } else { - (*fee_item == 0) as usize - }; - let asset = assets.get(reserve_idx); - asset.and_then(T::ReserveProvider::reserve) - } } impl XcmTransfer for Pallet {