diff --git a/Cargo.lock b/Cargo.lock index a15f7a2b8..f7ef0fc63 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13216,6 +13216,7 @@ dependencies = [ "sp-arithmetic", "sp-runtime", "sp-std", + "staging-xcm", ] [[package]] diff --git a/integration-tests/src/tests/transaction_payment.rs b/integration-tests/src/tests/transaction_payment.rs index 6b0df250d..3f37684a5 100644 --- a/integration-tests/src/tests/transaction_payment.rs +++ b/integration-tests/src/tests/transaction_payment.rs @@ -21,7 +21,7 @@ use sp_runtime::{ use xcm_emulator::TestExt; generate_accounts!(ALICE, AUTHOR); use frame_support::traits::fungible::Inspect; - +use xcm::v3::{Junction::*, Junctions::*, MultiLocation}; // Setup code inspired by pallet-authorship tests fn seal_header(mut header: Header, aura_index: u64) -> Header { { @@ -60,6 +60,8 @@ fn fee_paid_with_foreign_assets() { assert_eq!(polimec_runtime::Authorship::author(), Some(block_author.clone())); let usdt_id = AcceptedFundingAsset::USDT.id(); + let usdt_multilocation = + MultiLocation { parents: 1, interior: X3(Parachain(1000), PalletInstance(50), GeneralIndex(1984)) }; let usdt_decimals = >::decimals(usdt_id); let usdt_unit = 10u128.pow(usdt_decimals as u32); let plmc_decimals = PLMC_DECIMALS; @@ -78,8 +80,10 @@ fn fee_paid_with_foreign_assets() { let paid_call = PolimecCall::System(frame_system::Call::remark { remark: vec![69, 69] }); type TxPaymentExtension = pallet_asset_tx_payment::ChargeAssetTxPayment; - let signed_extension = - pallet_asset_tx_payment::ChargeAssetTxPayment::::from(10 * plmc_unit, Some(usdt_id)); + let signed_extension = pallet_asset_tx_payment::ChargeAssetTxPayment::::from( + 10 * plmc_unit, + Some(usdt_multilocation), + ); let dispatch_info = paid_call.get_dispatch_info(); let FeeDetails { inclusion_fee, tip } = diff --git a/runtimes/polimec/src/custom_migrations/funding_holds.rs b/runtimes/polimec/src/custom_migrations/funding_holds.rs index dba8c7526..f32b1a905 100644 --- a/runtimes/polimec/src/custom_migrations/funding_holds.rs +++ b/runtimes/polimec/src/custom_migrations/funding_holds.rs @@ -1,5 +1,4 @@ use crate::{Balance, Funding, Runtime, RuntimeHoldReason}; -use alloc::vec::Vec; use frame_support::traits::{GetStorageVersion, OnRuntimeUpgrade, VariantCount, VariantCountOf}; use pallet_balances::IdAmount; use pallet_funding::ProjectId; @@ -7,6 +6,7 @@ use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_core::{MaxEncodedLen, RuntimeDebug}; use sp_runtime::BoundedVec; +use sp_std::vec::Vec; #[derive(Clone, Copy, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub enum OldFundingHoldReason { diff --git a/runtimes/polimec/src/lib.rs b/runtimes/polimec/src/lib.rs index 428b98c82..e2937fe46 100644 --- a/runtimes/polimec/src/lib.rs +++ b/runtimes/polimec/src/lib.rs @@ -15,10 +15,11 @@ // along with this program. If not, see . #![cfg_attr(not(feature = "std"), no_std)] -// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. #![recursion_limit = "256"] -extern crate alloc; +// Make the WASM binary available. +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); use core::ops::RangeInclusive; use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; @@ -50,7 +51,10 @@ use parachains_common::{ AssetIdForTrustBackedAssets as AssetId, }; use parity_scale_codec::Encode; -use polimec_common::credentials::{Did, EnsureInvestor}; +use polimec_common::{ + credentials::{Did, EnsureInvestor}, + ProvideAssetPrice, USD_UNIT, +}; use polkadot_runtime_common::{BlockHashCount, CurrencyToVote, SlowAdjustingFeeUpdate}; use shared_configuration::proxy; use sp_api::impl_runtime_apis; @@ -61,38 +65,37 @@ use sp_runtime::{ AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, Convert, ConvertBack, ConvertInto, IdentifyAccount, IdentityLookup, OpaqueKeys, Verify, }, - transaction_validity::{TransactionSource, TransactionValidity}, + transaction_validity::{InvalidTransaction, TransactionSource, TransactionValidity}, ApplyExtrinsicResult, FixedPointNumber, FixedU128, MultiSignature, SaturatedConversion, }; use sp_std::{cmp::Ordering, prelude::*}; use sp_version::RuntimeVersion; // XCM Imports -use xcm_config::XcmOriginToTransactDispatchOrigin; +use xcm::v3::{ + Junction::{GeneralIndex, PalletInstance, Parachain}, + Junctions::{Here, X3}, + MultiLocation, +}; +use xcm_config::{PriceForSiblingParachainDelivery, XcmOriginToTransactDispatchOrigin}; #[cfg(not(feature = "runtime-benchmarks"))] use xcm_config::XcmConfig; -pub use pallet_parachain_staking; // Polimec Shared Imports +pub use pallet_parachain_staking; pub use shared_configuration::{ assets::*, currency::*, fee::*, funding::*, governance::*, identity::*, proxy::*, staking::*, time::*, weights::*, }; pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; pub use sp_runtime::{MultiAddress, Perbill, Permill}; -// Make the WASM binary available. -#[cfg(feature = "std")] -include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); - #[cfg(feature = "std")] use sp_version::NativeVersion; -use crate::xcm_config::PriceForSiblingParachainDelivery; -use polimec_common::{ProvideAssetPrice, USD_UNIT}; -use sp_runtime::transaction_validity::InvalidTransaction; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; + #[cfg(feature = "runtime-benchmarks")] mod benchmark_helpers; mod custom_migrations; @@ -1153,6 +1156,17 @@ impl pallet_dispenser::Config for Runtime { type WhitelistedPolicy = DispenserWhitelistedPolicy; } +pub struct ConvertMultilocationToAssetId; +impl Convert for ConvertMultilocationToAssetId { + fn convert(location: MultiLocation) -> AssetId { + match location { + MultiLocation { parents: 1, interior: Here } => 10, + MultiLocation { parents: 1, interior: X3(Parachain(1000), PalletInstance(50), GeneralIndex(1337)) } => 1337, + MultiLocation { parents: 1, interior: X3(Parachain(1000), PalletInstance(50), GeneralIndex(1984)) } => 1984, + _ => 0, + } + } +} pub struct PLMCToFundingAssetBalance; impl ConversionToAssetBalance for PLMCToFundingAssetBalance { type Error = InvalidTransaction; @@ -1175,6 +1189,7 @@ impl pallet_asset_tx_payment::Config for Runtime { type Fungibles = ForeignAssets; type OnChargeAssetTransaction = TxFeeFungiblesAdapter< PLMCToFundingAssetBalance, + ConvertMultilocationToAssetId, CreditFungiblesToAccount, AssetsToBlockAuthor, >; diff --git a/runtimes/shared-configuration/Cargo.toml b/runtimes/shared-configuration/Cargo.toml index 17ffa3dcc..3d4e8680e 100644 --- a/runtimes/shared-configuration/Cargo.toml +++ b/runtimes/shared-configuration/Cargo.toml @@ -41,7 +41,7 @@ pallet-parachain-staking.workspace = true pallet-oracle-ocw.workspace = true pallet-treasury = {workspace = true, optional = true} pallet-asset-tx-payment.workspace = true - +xcm.workspace = true [features] default = [ "std" ] fast-mode = [] diff --git a/runtimes/shared-configuration/src/fee.rs b/runtimes/shared-configuration/src/fee.rs index 74c530cf3..265afdd8f 100644 --- a/runtimes/shared-configuration/src/fee.rs +++ b/runtimes/shared-configuration/src/fee.rs @@ -43,9 +43,10 @@ use scale_info::{prelude::vec, TypeInfo}; use smallvec::smallvec; use sp_arithmetic::Perbill; use sp_runtime::{ - traits::{DispatchInfoOf, Get, One, PostDispatchInfoOf, Zero}, + traits::{Convert, DispatchInfoOf, Get, One, PostDispatchInfoOf, Zero}, transaction_validity::{InvalidTransaction, TransactionValidityError}, }; +use xcm::v3::MultiLocation; #[allow(clippy::module_name_repetitions)] pub struct WeightToFee; @@ -171,22 +172,24 @@ type AssetBalanceOf = /// [`ConversionToAssetBalance`]) and 2 credit handlers (implementing [`HandleCredit`]). /// /// First handler does the fee, second the tip. -pub struct TxFeeFungiblesAdapter( - PhantomData<(Converter, FeeCreditor, TipCreditor)>, +pub struct TxFeeFungiblesAdapter( + PhantomData<(Converter, MultiLocationToAssetId, FeeCreditor, TipCreditor)>, ); /// Default implementation for a runtime instantiating this pallet, a balance to asset converter and /// a credit handler. -impl OnChargeAssetTransaction - for TxFeeFungiblesAdapter +impl OnChargeAssetTransaction + for TxFeeFungiblesAdapter where Runtime: pallet_asset_tx_payment::Config, + MultiLocationToAssetId: Convert>, Converter: ConversionToAssetBalance, AssetIdOf, AssetBalanceOf>, FeeCreditor: HandleCredit, TipCreditor: HandleCredit, AssetIdOf: FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default + Eq + TypeInfo, { - type AssetId = AssetIdOf; + // Note: We stick to `v3::MultiLocation`` because `v4::Location`` doesn't implement `Copy`. + type AssetId = MultiLocation; type Balance = BalanceOf; type LiquidityInfo = fungibles::Credit; @@ -202,6 +205,7 @@ where // We don't know the precision of the underlying asset. Because the converted fee could be // less than one (e.g. 0.5) but gets rounded down by integer division we introduce a minimum // fee. + let asset_id = MultiLocationToAssetId::convert(asset_id); let min_converted_fee = if fee.is_zero() { Zero::zero() } else { One::one() }; let converted_fee = Converter::to_asset_balance(fee, asset_id) .map_err(|_| TransactionValidityError::from(InvalidTransaction::Payment))?