From 71020d8e66324d8a53e363afbc418341aedd044a Mon Sep 17 00:00:00 2001 From: Juan Ignacio Rios Date: Fri, 4 Oct 2024 11:13:27 +0200 Subject: [PATCH] usdt-fee-pjs-compatibility --- Cargo.lock | 1 + .../src/tests/transaction_payment.rs | 16 +++++--- runtimes/polimec/Cargo.toml | 2 +- .../src/custom_migrations/funding_holds.rs | 2 +- runtimes/polimec/src/lib.rs | 41 +++++++++++++------ runtimes/shared-configuration/Cargo.toml | 9 ++-- runtimes/shared-configuration/src/fee.rs | 16 +++++--- 7 files changed, 56 insertions(+), 31 deletions(-) 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 0d847f002..d089ef089 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; @@ -79,10 +81,12 @@ fn fee_paid_with_foreign_assets() { let paid_call_len = paid_call.encode().len(); type TxPaymentExtension = pallet_asset_tx_payment::ChargeAssetTxPayment; - // Tips are always defined in the native asset, and then converted to the fee asset if the second field is `Some`. - // Here a user wants to tip 10 PLMC in USDT. - let signed_extension = - pallet_asset_tx_payment::ChargeAssetTxPayment::::from(10 * plmc_unit, Some(usdt_id)); + // Tips are always defined in the native asset, and then converted to the fee asset if the second field is `Some`. + // Here a user wants to tip 10 PLMC in USDT. + 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 } = @@ -126,7 +130,7 @@ fn fee_paid_with_foreign_assets() { let post_block_author_plmc_balance = PolimecBalances::balance(&block_author.clone()); assert_eq!(prev_alice_usdt_balance - post_alice_usdt_balance, expected_usd_fee + expected_usd_tip); - assert_eq!(post_alice_plmc_balance, prev_alice_plmc_balance,); + assert_eq!(post_alice_plmc_balance, prev_alice_plmc_balance); assert_eq!( post_blockchain_operation_treasury_usdt_balance - prev_blockchain_operation_treasury_usdt_balance, expected_usd_fee diff --git a/runtimes/polimec/Cargo.toml b/runtimes/polimec/Cargo.toml index 5daf1dec0..64f8fda52 100644 --- a/runtimes/polimec/Cargo.toml +++ b/runtimes/polimec/Cargo.toml @@ -206,6 +206,7 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "on-slash-vesting/runtime-benchmarks", "orml-oracle/runtime-benchmarks", + "pallet-asset-tx-payment/runtime-benchmarks", "pallet-assets/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-collective/runtime-benchmarks", @@ -237,7 +238,6 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", - "pallet-asset-tx-payment/runtime-benchmarks" ] try-runtime = [ 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..6e9b29220 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 = [] @@ -50,6 +50,7 @@ std = [ "frame-support/std", "frame-system/std", "orml-traits/std", + "pallet-asset-tx-payment/std", "pallet-authorship/std", "pallet-balances/std", "pallet-funding/std", @@ -64,11 +65,12 @@ std = [ "sp-arithmetic/std", "sp-runtime/std", "sp-std/std", - "pallet-asset-tx-payment/std" + "xcm/std", ] runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", + "pallet-asset-tx-payment/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-funding/runtime-benchmarks", "pallet-oracle-ocw/runtime-benchmarks", @@ -77,11 +79,11 @@ runtime-benchmarks = [ "parachains-common/runtime-benchmarks", "polimec-common/runtime-benchmarks", "sp-runtime/runtime-benchmarks", - "pallet-asset-tx-payment/runtime-benchmarks" ] try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", + "pallet-asset-tx-payment/try-runtime", "pallet-authorship/try-runtime", "pallet-balances/try-runtime", "pallet-funding/try-runtime", @@ -91,6 +93,5 @@ try-runtime = [ "pallet-treasury?/try-runtime", "polimec-common/try-runtime", "sp-runtime/try-runtime", - "pallet-asset-tx-payment/try-runtime" ] development-settings = [] 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))?