Skip to content

Commit

Permalink
Utilize SDK types for native asset balance conversion (#424)
Browse files Browse the repository at this point in the history
Utilize SDK types for native asset balance conversion in the Treasury
pallet setup.

This change does not introduce any behavioral changes; it simply updates
the code to use common types from the SDK.

- [x] Does not require a CHANGELOG entry

---------

Co-authored-by: Bastian Köcher <git@kchr.de>
Co-authored-by: fellowship-merge-bot[bot] <151052383+fellowship-merge-bot[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Aug 25, 2024
1 parent 421f303 commit 7157d41
Show file tree
Hide file tree
Showing 14 changed files with 362 additions and 180 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 0 additions & 58 deletions relay/kusama/src/impls.rs

This file was deleted.

28 changes: 20 additions & 8 deletions relay/kusama/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ use polkadot_primitives::{
use polkadot_runtime_common::{
auctions, claims, crowdloan, impl_runtime_weights,
impls::{
DealWithFees, LocatableAssetConverter, VersionedLocatableAsset, VersionedLocationConverter,
ContainsParts as ContainsLocationParts, DealWithFees, LocatableAssetConverter,
VersionedLocatableAsset, VersionedLocationConverter,
},
paras_registrar, prod_or_fast, slots, BalanceToU256, BlockHashCount, BlockLength,
CurrencyToVote, SlowAdjustingFeeUpdate, U256ToBalance,
Expand Down Expand Up @@ -86,9 +87,10 @@ use frame_support::{
genesis_builder_helper::{build_state, get_preset},
parameter_types,
traits::{
fungible::HoldConsideration, ConstU32, Contains, EitherOf, EitherOfDiverse, Everything,
InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, PrivilegeCmp, ProcessMessage,
ProcessMessageError, StorageMapShim, WithdrawReasons,
fungible::HoldConsideration, tokens::UnityOrOuterConversion, ConstU32, ConstU8, EitherOf,
EitherOfDiverse, Everything, FromContains, InstanceFilter, KeyOwnerProofSystem,
LinearStoragePrice, PrivilegeCmp, ProcessMessage, ProcessMessageError, StorageMapShim,
WithdrawReasons,
},
weights::{ConstantMultiplier, WeightMeter, WeightToFee as _},
PalletId,
Expand Down Expand Up @@ -154,9 +156,6 @@ use governance::{
Treasurer, TreasurySpender,
};

// Implemented types.
pub mod impls;

#[cfg(test)]
mod tests;

Expand Down Expand Up @@ -860,7 +859,7 @@ impl pallet_treasury::Config for Runtime {
LocatableAssetConverter,
VersionedLocationConverter,
>;
type BalanceConverter = impls::NativeOnSystemParachain<AssetRate>;
type BalanceConverter = AssetRateWithNative;
type PayoutPeriod = PayoutSpendPeriod;
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = polkadot_runtime_common::impls::benchmarks::TreasuryArguments;
Expand Down Expand Up @@ -1614,6 +1613,19 @@ impl pallet_nomination_pools::Config for Runtime {
type AdminOrigin = EitherOf<EnsureRoot<AccountId>, StakingAdmin>;
}

/// The [frame_support::traits::tokens::ConversionFromAssetBalance] implementation provided by the
/// `AssetRate` pallet instance, with additional decoration to identify different IDs/locations of
/// native asset and provide a one-to-one balance conversion for them.
pub type AssetRateWithNative = UnityOrOuterConversion<
ContainsLocationParts<
FromContains<
xcm_builder::IsChildSystemParachain<ParaId>,
xcm_builder::IsParentsOnly<ConstU8<1>>,
>,
>,
AssetRate,
>;

impl pallet_asset_rate::Config for Runtime {
type WeightInfo = weights::pallet_asset_rate::WeightInfo<Runtime>;
type RuntimeEvent = RuntimeEvent;
Expand Down
96 changes: 96 additions & 0 deletions relay/kusama/tests/asset_rate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright (C) Parity Technologies (UK) Ltd.
// This file is part of Polkadot.

// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.

//! AssetRate pallet instance tests.

use frame_support::traits::tokens::ConversionFromAssetBalance;
use polkadot_runtime_common::impls::VersionedLocatableAsset;
use staging_kusama_runtime::AssetRateWithNative;
use xcm::prelude::*;

#[test]
fn native_asset_rate_works() {
sp_io::TestExternalities::default().execute_with(|| {
// success: native asset on Asset Hub as xcm v4 location
let native = VersionedLocatableAsset::V4 {
location: Location::new(0, [Parachain(1000)]),
asset_id: Location::parent().into(),
};
let actual = AssetRateWithNative::from_asset_balance(100, native).unwrap();
assert_eq!(actual, 100);

// success: native asset on Asset Hub as xcm v3 location
let native = VersionedLocatableAsset::V3 {
location: xcm::v3::Location::new(
0,
xcm::v3::Junctions::X1(xcm::v3::Junction::Parachain(1000)),
),
asset_id: xcm::v3::Location::parent().into(),
};
let actual = AssetRateWithNative::from_asset_balance(100, native).unwrap();
assert_eq!(actual, 100);

// success: native asset on People as xcm v4 location
let native = VersionedLocatableAsset::V4 {
location: Location::new(0, [Parachain(1004)]),
asset_id: Location::parent().into(),
};
let actual = AssetRateWithNative::from_asset_balance(100, native).unwrap();
assert_eq!(actual, 100);

// success: native asset on People as xcm v3 location
let native = VersionedLocatableAsset::V3 {
location: xcm::v3::Location::new(
0,
xcm::v3::Junctions::X1(xcm::v3::Junction::Parachain(1004)),
),
asset_id: xcm::v3::Location::parent().into(),
};
let actual = AssetRateWithNative::from_asset_balance(100, native).unwrap();
assert_eq!(actual, 100);

// failure: native asset on non system chain as xcm v4 location
let native_non_system = VersionedLocatableAsset::V4 {
location: Location::new(0, [Parachain(2000)]),
asset_id: Location::parent().into(),
};
assert!(AssetRateWithNative::from_asset_balance(100, native_non_system).is_err());

// failure: native asset on non system chain as xcm v3 location
let native_non_system = VersionedLocatableAsset::V3 {
location: xcm::v3::Location::new(
0,
xcm::v3::Junctions::X1(xcm::v3::Junction::Parachain(2000)),
),
asset_id: xcm::v3::Location::parent().into(),
};
assert!(AssetRateWithNative::from_asset_balance(100, native_non_system).is_err());

// failure: some asset on Asset Hub as xcm v4 location
let non_native = VersionedLocatableAsset::V4 {
location: Location::new(0, [Parachain(2000)]),
asset_id: Location::new(0, [PalletInstance(50), GeneralIndex(1984)]).into(),
};
assert!(AssetRateWithNative::from_asset_balance(100, non_native).is_err());

// failure: native asset with invalid system chain location as xcm v4 location
let native_non_system = VersionedLocatableAsset::V4 {
location: Location::new(1, [Parachain(1000)]),
asset_id: Location::parent().into(),
};
assert!(AssetRateWithNative::from_asset_balance(100, native_non_system).is_err());
});
}
46 changes: 1 addition & 45 deletions relay/polkadot/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,53 +14,9 @@
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.

use super::*;
use core::marker::PhantomData;
use frame_support::traits::{tokens::ConversionFromAssetBalance, Contains};
use polkadot_primitives::Id as ParaId;
use xcm_builder::IsChildSystemParachain;

// TODO: replace by types from polkadot-sdk https://github.com/paritytech/polkadot-sdk/pull/3659
/// Determines if the given `asset_kind` is a native asset. If it is, returns the balance without
/// conversion; otherwise, delegates to the implementation specified by `I`.
///
/// Example where the `asset_kind` represents the native asset:
/// - location: (1, Parachain(1000)), // location of a Sibling Parachain;
/// - asset_id: (1, Here), // the asset id in the context of `asset_kind.location`;
pub struct NativeOnSystemParachain<I>(PhantomData<I>);
impl<I> ConversionFromAssetBalance<Balance, VersionedLocatableAsset, Balance>
for NativeOnSystemParachain<I>
where
I: ConversionFromAssetBalance<Balance, VersionedLocatableAsset, Balance>,
{
type Error = ();
fn from_asset_balance(
balance: Balance,
asset_kind: VersionedLocatableAsset,
) -> Result<Balance, Self::Error> {
use VersionedLocatableAsset::*;
let (location, asset_id) = match asset_kind.clone() {
V3 { location, asset_id } => (location.try_into()?, asset_id.try_into()?),
V4 { location, asset_id } => (location, asset_id),
};
if asset_id.0.contains_parents_only(1) &&
IsChildSystemParachain::<ParaId>::contains(&location)
{
Ok(balance)
} else {
I::from_asset_balance(balance, asset_kind).map_err(|_| ())
}
}
#[cfg(feature = "runtime-benchmarks")]
fn ensure_successful(asset_kind: VersionedLocatableAsset) {
I::ensure_successful(asset_kind)
}
}

#[cfg(feature = "runtime-benchmarks")]
pub mod benchmarks {
use super::{xcm_config::CheckAccount, ExistentialDeposit};
use crate::Balances;
use crate::{xcm_config::CheckAccount, Balances, ExistentialDeposit};
use frame_support::{
dispatch::RawOrigin,
traits::{Currency, EnsureOrigin},
Expand Down
25 changes: 20 additions & 5 deletions relay/polkadot/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ use pallet_transaction_payment::FungibleAdapter;
use polkadot_runtime_common::{
auctions, claims, crowdloan, impl_runtime_weights,
impls::{
DealWithFees, LocatableAssetConverter, VersionedLocatableAsset, VersionedLocationConverter,
ContainsParts as ContainsLocationParts, DealWithFees, LocatableAssetConverter,
VersionedLocatableAsset, VersionedLocationConverter,
},
paras_registrar, prod_or_fast, slots,
traits::OnSwap,
Expand Down Expand Up @@ -62,9 +63,10 @@ use frame_support::{
genesis_builder_helper::{build_state, get_preset},
parameter_types,
traits::{
fungible::HoldConsideration, ConstU32, EitherOf, EitherOfDiverse, Everything, Get,
InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice, OnRuntimeUpgrade, PrivilegeCmp,
ProcessMessage, ProcessMessageError, WithdrawReasons,
fungible::HoldConsideration, tokens::UnityOrOuterConversion, ConstU32, ConstU8, EitherOf,
EitherOfDiverse, Everything, FromContains, Get, InstanceFilter, KeyOwnerProofSystem,
LinearStoragePrice, OnRuntimeUpgrade, PrivilegeCmp, ProcessMessage, ProcessMessageError,
WithdrawReasons,
},
weights::{
constants::{WEIGHT_PROOF_SIZE_PER_KB, WEIGHT_REF_TIME_PER_MICROS},
Expand Down Expand Up @@ -826,7 +828,7 @@ impl pallet_treasury::Config for Runtime {
LocatableAssetConverter,
VersionedLocationConverter,
>;
type BalanceConverter = impls::NativeOnSystemParachain<AssetRate>;
type BalanceConverter = AssetRateWithNative;
type PayoutPeriod = PayoutSpendPeriod;
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = polkadot_runtime_common::impls::benchmarks::TreasuryArguments;
Expand Down Expand Up @@ -1554,6 +1556,19 @@ impl pallet_state_trie_migration::Config for Runtime {
type MaxKeyLen = MigrationMaxKeyLen;
}

/// The [frame_support::traits::tokens::ConversionFromAssetBalance] implementation provided by the
/// `AssetRate` pallet instance, with additional decoration to identify different IDs/locations of
/// native asset and provide a one-to-one balance conversion for them.
pub type AssetRateWithNative = UnityOrOuterConversion<
ContainsLocationParts<
FromContains<
xcm_builder::IsChildSystemParachain<ParaId>,
xcm_builder::IsParentsOnly<ConstU8<1>>,
>,
>,
AssetRate,
>;

impl pallet_asset_rate::Config for Runtime {
type WeightInfo = weights::pallet_asset_rate::WeightInfo<Runtime>;
type RuntimeEvent = RuntimeEvent;
Expand Down
Loading

0 comments on commit 7157d41

Please sign in to comment.