diff --git a/pallets/inflation/src/benchmarking.rs b/pallets/inflation/src/benchmarking.rs index 4d617f84da..c4e665dc8a 100644 --- a/pallets/inflation/src/benchmarking.rs +++ b/pallets/inflation/src/benchmarking.rs @@ -19,6 +19,7 @@ use super::*; use frame_benchmarking::v2::*; +use frame_support::traits::tokens::Precision; use frame_system::{Pallet as System, RawOrigin}; use sp_std::prelude::*; @@ -65,7 +66,12 @@ fn initial_config() { // Create some issuance so it's not zero let dummy_account = whitelisted_caller(); - T::Currency::make_free_balance_be(&dummy_account, 1_000_000_000_000_000_000_000); + let _debt = T::Currency::deposit( + &dummy_account, + 1_000_000_000_000_000_000_000, + Precision::Exact, + ) + .expect("Must succeed for benchmarking"); } #[benchmarks] diff --git a/pallets/inflation/src/lib.rs b/pallets/inflation/src/lib.rs index d2a169e99a..72a745c879 100644 --- a/pallets/inflation/src/lib.rs +++ b/pallets/inflation/src/lib.rs @@ -104,7 +104,14 @@ use astar_primitives::{ }, Balance, }; -use frame_support::{pallet_prelude::*, traits::Currency, DefaultNoBound}; +use frame_support::{ + pallet_prelude::*, + traits::{ + fungible::{Balanced, Credit, Inspect}, + tokens::Precision, + }, + DefaultNoBound, +}; use frame_system::{ensure_root, pallet_prelude::*}; use serde::{Deserialize, Serialize}; use sp_runtime::{ @@ -136,19 +143,15 @@ pub mod pallet { pub struct Pallet(PhantomData); // Negative imbalance type of this pallet. - pub(crate) type NegativeImbalanceOf = <::Currency as Currency< - ::AccountId, - >>::NegativeImbalance; + pub(crate) type CreditOf = + Credit<::AccountId, ::Currency>; #[pallet::config] pub trait Config: frame_system::Config { - /// The currency trait. - /// This has been soft-deprecated but it still needs to be used here in order to access `NegativeImbalance` - /// which is defined in the currency trait. - type Currency: Currency; + type Currency: Balanced; /// Handler for 'per-block' payouts. - type PayoutPerBlock: PayoutPerBlock>; + type PayoutPerBlock: PayoutPerBlock>; /// Cycle ('year') configuration - covers periods, subperiods, eras & blocks. type CycleConfiguration: CycleConfiguration; @@ -451,9 +454,11 @@ pub mod pallet { // This can fail only if the amount is below existential deposit & the account doesn't exist, // or if the account has no provider references. + // Another possibility is overflow, but if that happens, we already have a huge problem. + // // In both cases, the reward is lost but this can be ignored since it's extremely unlikely // to appear and doesn't bring any real harm. - let _ = T::Currency::deposit_creating(account, reward); + let _ = T::Currency::deposit(account, reward, Precision::Exact); Ok(()) } } diff --git a/pallets/inflation/src/mock.rs b/pallets/inflation/src/mock.rs index b686d80837..db8c76edef 100644 --- a/pallets/inflation/src/mock.rs +++ b/pallets/inflation/src/mock.rs @@ -17,14 +17,13 @@ // along with Astar. If not, see . use crate::{ - self as pallet_inflation, ActiveInflationConfig, CycleConfiguration, InflationParameters, - InflationParams, NegativeImbalanceOf, PayoutPerBlock, + self as pallet_inflation, ActiveInflationConfig, CreditOf, CycleConfiguration, + InflationParameters, InflationParams, PayoutPerBlock, }; use frame_support::{ construct_runtime, parameter_types, - traits::Currency, - traits::{ConstU128, ConstU32, Hooks}, + traits::{fungible::Balanced, ConstU128, ConstU32, Hooks}, weights::Weight, PalletId, }; @@ -110,13 +109,15 @@ pub(crate) const TREASURY_POT: PalletId = PalletId(*b"moktrsry"); pub(crate) const COLLATOR_POT: PalletId = PalletId(*b"mokcolat"); pub struct DummyPayoutPerBlock; -impl PayoutPerBlock> for DummyPayoutPerBlock { - fn treasury(reward: NegativeImbalanceOf) { - Balances::resolve_creating(&TREASURY_POT.into_account_truncating(), reward); +impl PayoutPerBlock> for DummyPayoutPerBlock { + fn treasury(reward: CreditOf) { + Balances::resolve(&TREASURY_POT.into_account_truncating(), reward) + .expect("Must succeed for test."); } - fn collators(reward: NegativeImbalanceOf) { - Balances::resolve_creating(&COLLATOR_POT.into_account_truncating(), reward); + fn collators(reward: CreditOf) { + Balances::resolve(&COLLATOR_POT.into_account_truncating(), reward) + .expect("Must succeed for test."); } } diff --git a/runtime/astar/src/lib.rs b/runtime/astar/src/lib.rs index 9bcfdee453..710a0cba6c 100644 --- a/runtime/astar/src/lib.rs +++ b/runtime/astar/src/lib.rs @@ -30,6 +30,7 @@ use frame_support::{ genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ + fungible::{Balanced, Credit, HoldConsideration}, AsEnsureOriginWithArg, ConstBool, ConstU32, Contains, Currency, FindAuthor, Get, Imbalance, InstanceFilter, Nothing, OnFinalize, OnUnbalanced, Randomness, WithdrawReasons, }, @@ -402,12 +403,12 @@ impl pallet_dapp_staking_v3::Config for Runtime { } pub struct InflationPayoutPerBlock; -impl pallet_inflation::PayoutPerBlock for InflationPayoutPerBlock { - fn treasury(reward: NegativeImbalance) { - Balances::resolve_creating(&TreasuryPalletId::get().into_account_truncating(), reward); +impl pallet_inflation::PayoutPerBlock> for InflationPayoutPerBlock { + fn treasury(reward: Credit) { + let _ = Balances::resolve(&TreasuryPalletId::get().into_account_truncating(), reward); } - fn collators(reward: NegativeImbalance) { + fn collators(reward: Credit) { ToStakingPot::on_unbalanced(reward); } } @@ -548,7 +549,7 @@ pub struct ToStakingPot; impl OnUnbalanced for ToStakingPot { fn on_nonzero_unbalanced(amount: NegativeImbalance) { let staking_pot = PotId::get().into_account_truncating(); - Balances::resolve_creating(&staking_pot, amount); + Balances::resolve(&staking_pot, amount); } } diff --git a/runtime/local/src/lib.rs b/runtime/local/src/lib.rs index f14a64fb88..b5ffe4bc77 100644 --- a/runtime/local/src/lib.rs +++ b/runtime/local/src/lib.rs @@ -29,7 +29,7 @@ use frame_support::{ genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ - fungible::HoldConsideration, + fungible::{Balanced, Credit, HoldConsideration}, tokens::{PayFromAccount, UnityAssetBalanceConversion}, AsEnsureOriginWithArg, ConstU128, ConstU32, ConstU64, Currency, EqualPrivilegeOnly, FindAuthor, Get, InstanceFilter, LinearStoragePrice, Nothing, OnFinalize, WithdrawReasons, @@ -500,12 +500,12 @@ impl pallet_dapp_staking_v3::Config for Runtime { } pub struct InflationPayoutPerBlock; -impl pallet_inflation::PayoutPerBlock for InflationPayoutPerBlock { - fn treasury(reward: NegativeImbalance) { - Balances::resolve_creating(&TreasuryPalletId::get().into_account_truncating(), reward); +impl pallet_inflation::PayoutPerBlock> for InflationPayoutPerBlock { + fn treasury(reward: Credit) { + let _ = Balances::resolve(&TreasuryPalletId::get().into_account_truncating(), reward); } - fn collators(_reward: NegativeImbalance) { + fn collators(_reward: Credit) { // no collators for local dev node } } diff --git a/runtime/shibuya/src/lib.rs b/runtime/shibuya/src/lib.rs index 726355ad26..7fe22117e9 100644 --- a/runtime/shibuya/src/lib.rs +++ b/runtime/shibuya/src/lib.rs @@ -30,18 +30,18 @@ use frame_support::{ genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ - fungible::HoldConsideration, + fungible::{Balanced, Credit, HoldConsideration}, tokens::{PayFromAccount, UnityAssetBalanceConversion}, - AsEnsureOriginWithArg, ConstU128, ConstU32, ConstU64, Contains, Currency, - EqualPrivilegeOnly, FindAuthor, Get, Imbalance, InstanceFilter, LinearStoragePrice, - Nothing, OnFinalize, OnUnbalanced, WithdrawReasons, + AsEnsureOriginWithArg, ConstU128, ConstU32, ConstU64, Contains, EqualPrivilegeOnly, + FindAuthor, Get, Imbalance, InstanceFilter, LinearStoragePrice, Nothing, OnFinalize, + OnUnbalanced, WithdrawReasons, }, weights::{ constants::{ BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND, }, - ConstantMultiplier, Weight, WeightToFeeCoefficient, WeightToFeeCoefficients, - WeightToFeePolynomial, + ConstantMultiplier, Weight, WeightToFee as WeightToFeeT, WeightToFeeCoefficient, + WeightToFeeCoefficients, WeightToFeePolynomial, }, ConsensusEngineId, PalletId, }; @@ -72,8 +72,8 @@ use sp_runtime::{ }; use sp_std::{collections::btree_map::BTreeMap, prelude::*}; use xcm::{ - latest::prelude::*, IntoVersion, VersionedAssetId, VersionedAssets, VersionedLocation, - VersionedXcm, + v4::{AssetId as XcmAssetId, Location as XcmLocation}, + IntoVersion, VersionedAssetId, VersionedAssets, VersionedLocation, VersionedXcm, }; use xcm_fee_payment_runtime_api::Error as XcmPaymentApiError; @@ -483,12 +483,12 @@ impl pallet_dapp_staking_v3::Config for Runtime { } pub struct InflationPayoutPerBlock; -impl pallet_inflation::PayoutPerBlock for InflationPayoutPerBlock { - fn treasury(reward: NegativeImbalance) { - Balances::resolve_creating(&TreasuryPalletId::get().into_account_truncating(), reward); +impl pallet_inflation::PayoutPerBlock> for InflationPayoutPerBlock { + fn treasury(reward: Credit) { + let _ = Balances::resolve(&TreasuryPalletId::get().into_account_truncating(), reward); } - fn collators(reward: NegativeImbalance) { + fn collators(reward: Credit) { ToStakingPot::on_unbalanced(reward); } } @@ -623,13 +623,11 @@ parameter_types! { pub TreasuryAccountId: AccountId = TreasuryPalletId::get().into_account_truncating(); } -type NegativeImbalance = >::NegativeImbalance; - pub struct ToStakingPot; -impl OnUnbalanced for ToStakingPot { - fn on_nonzero_unbalanced(amount: NegativeImbalance) { +impl OnUnbalanced> for ToStakingPot { + fn on_nonzero_unbalanced(amount: Credit) { let staking_pot = PotId::get().into_account_truncating(); - Balances::resolve_creating(&staking_pot, amount); + let _ = Balances::resolve(&staking_pot, amount); } } @@ -795,7 +793,7 @@ impl WeightToFeePolynomial for WeightToFee { /// /// Similar to standard `WeightToFee` handler, but force uses the minimum multiplier. pub struct XcmWeightToFee; -impl frame_support::weights::WeightToFee for XcmWeightToFee { +impl WeightToFeeT for XcmWeightToFee { type Balance = Balance; fn weight_to_fee(n: &Weight) -> Self::Balance { @@ -804,8 +802,8 @@ impl frame_support::weights::WeightToFee for XcmWeightToFee { } pub struct DealWithFees; -impl OnUnbalanced for DealWithFees { - fn on_unbalanceds(mut fees_then_tips: impl Iterator) { +impl OnUnbalanced> for DealWithFees { + fn on_unbalanceds(mut fees_then_tips: impl Iterator>) { if let Some(fees) = fees_then_tips.next() { // Burn 80% of fees, rest goes to collator, including 100% of the tips. let (to_burn, mut collator) = fees.ration(80, 20); @@ -824,7 +822,7 @@ impl OnUnbalanced for DealWithFees { impl pallet_transaction_payment::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; + type OnChargeTransaction = pallet_transaction_payment::FungibleAdapter; type WeightToFee = WeightToFee; type OperationalFeeMultiplier = OperationalFeeMultiplier; type FeeMultiplierUpdate = TargetedFeeAdjustment< @@ -930,7 +928,7 @@ impl pallet_evm::Config for Runtime { // Ethereum-compatible chain_id: // * Shibuya: 81 type ChainId = EVMChainId; - type OnChargeTransaction = pallet_evm::EVMCurrencyAdapter; + type OnChargeTransaction = pallet_evm::EVMFungibleAdapter; type BlockGasLimit = BlockGasLimit; type Timestamp = Timestamp; type OnCreate = (); @@ -2182,23 +2180,26 @@ impl_runtime_apis! { } // Native asset is always supported - let native_asset_location: Location = Location::try_from(xcm_config::ShibuyaLocation::get()) + 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().map(|asset_location| { - VersionedAssetId::V3(asset_location.into()) - }) + 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| { - ).filter_map(|asset| asset.into_version(xcm_version).ok())) + 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()) } - // TODO: improve this function, reduce code duplication, especially on a such functional level + // 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: Location = Location::try_from(xcm_config::ShibuyaLocation::get()) + let native_asset_location: XcmLocation = XcmLocation::try_from(xcm_config::ShibuyaLocation::get()) .map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?; let native_asset = VersionedAssetId::V4(native_asset_location.into()); @@ -2206,18 +2207,21 @@ impl_runtime_apis! { .into_version(4) .map_err(|_| XcmPaymentApiError::VersionedConversionFailed)?; - if native_asset == asset { - Ok(XcmWeightToFee::weight_to_fee(weight)) - }else { - match pallet_xc_asset_config::AssetLocationUnitsPerSecond::::get(asset.into()) { - 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), + 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::WeightNotComputable), } + } } fn query_xcm_weight(message: VersionedXcm<()>) -> Result { diff --git a/runtime/shiden/src/lib.rs b/runtime/shiden/src/lib.rs index 38dda0c114..67d5517db8 100644 --- a/runtime/shiden/src/lib.rs +++ b/runtime/shiden/src/lib.rs @@ -30,6 +30,7 @@ use frame_support::{ genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ + fungible::{Balanced, Credit, HoldConsideration}, AsEnsureOriginWithArg, ConstU32, Contains, Currency, FindAuthor, Get, Imbalance, InstanceFilter, Nothing, OnFinalize, OnUnbalanced, WithdrawReasons, }, @@ -442,12 +443,12 @@ impl pallet_dapp_staking_v3::Config for Runtime { } pub struct InflationPayoutPerBlock; -impl pallet_inflation::PayoutPerBlock for InflationPayoutPerBlock { - fn treasury(reward: NegativeImbalance) { - Balances::resolve_creating(&TreasuryPalletId::get().into_account_truncating(), reward); +impl pallet_inflation::PayoutPerBlock> for InflationPayoutPerBlock { + fn treasury(reward: Credit) { + let _ = Balances::resolve(&TreasuryPalletId::get().into_account_truncating(), reward); } - fn collators(reward: NegativeImbalance) { + fn collators(reward: Credit) { ToStakingPot::on_unbalanced(reward); } } @@ -592,7 +593,7 @@ pub struct ToStakingPot; impl OnUnbalanced for ToStakingPot { fn on_nonzero_unbalanced(amount: NegativeImbalance) { let staking_pot = PotId::get().into_account_truncating(); - Balances::resolve_creating(&staking_pot, amount); + Balances::resolve(&staking_pot, amount); } }