Skip to content
This repository was archived by the owner on May 21, 2024. It is now read-only.

Commit 2529ee2

Browse files
valentinfernandez1Valentin Fernandez
andauthored
Backport Drop Assets (#189)
Backport PR #165 (cherry picked from commit 3f1c483) in Trappist v0.9.40 and updates it to match the changes included in polkadot v0.9.38 to v0.9.40. Weights were re benchmarked to match weightsV2. --------- Co-authored-by: Valentin Fernandez <[email protected]>
1 parent 6cd2ee6 commit 2529ee2

File tree

12 files changed

+335
-47
lines changed

12 files changed

+335
-47
lines changed

Cargo.lock

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pallets/asset-registry/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ pub mod pallet {
136136
AssetIdMultiLocation::<T>::get(asset_id)
137137
}
138138

139-
fn get_asset_id(asset_type: MultiLocation) -> Option<AssetIdOf<T>> {
139+
fn get_asset_id(asset_type: &MultiLocation) -> Option<AssetIdOf<T>> {
140140
AssetMultiLocationId::<T>::get(asset_type)
141141
}
142142
}

pallets/benchmarks/Cargo.toml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
[package]
2+
name = "trappist-runtime-benchmarks"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[package.metadata.docs.rs]
7+
targets = ["x86_64-unknown-linux-gnu"]
8+
9+
[dependencies]
10+
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive", ] }
11+
scale-info = { version = "2.3.1", default-features = false, features = ["derive"] }
12+
sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40" }
13+
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.40" }
14+
frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.40" }
15+
frame-support = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.40" }
16+
frame-system = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.40" }
17+
18+
xcm = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.40" }
19+
xcm-executor = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.40" }
20+
21+
[dev-dependencies]
22+
sp-core = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.40" }
23+
24+
[features]
25+
default = ["std"]
26+
std = [
27+
"codec/std",
28+
"frame-benchmarking/std",
29+
"frame-support/std",
30+
"frame-system/std",
31+
"sp-runtime/std",
32+
"sp-std/std",
33+
"xcm-executor/std"
34+
]
35+
runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"]
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use frame_benchmarking::benchmarks;
2+
use sp_runtime::SaturatedConversion;
3+
use xcm::prelude::AssetId as XcmAssetId;
4+
5+
use crate::*;
6+
7+
benchmarks! {
8+
drop_assets_fungible {
9+
let origin = MultiLocation::default();
10+
let asset_id = 1;
11+
let location: MultiLocation = Parachain(asset_id).into();
12+
T::register_asset(asset_id.into(), location.clone());
13+
let asset = MultiAsset { id: XcmAssetId::Concrete(location), fun: Fungibility::Fungible(100) };
14+
} : {
15+
T::DropAssets::drop_assets(
16+
&origin,
17+
asset.into(),
18+
&XcmContext {
19+
origin: Some(origin.clone()),
20+
message_hash: [0; 32],
21+
topic: None,
22+
},
23+
);
24+
}
25+
26+
drop_assets_native {
27+
let origin = MultiLocation::default();
28+
let location = MultiLocation { parents: 0, interior: Here };
29+
let amount = T::ExistentialDeposit::get().saturated_into();
30+
let asset = MultiAsset { id: XcmAssetId::Concrete(location), fun: Fungibility::Fungible(amount) };
31+
} : {
32+
T::DropAssets::drop_assets(
33+
&origin,
34+
asset.into(),
35+
&XcmContext {
36+
origin: Some(origin.clone()),
37+
message_hash: [0; 32],
38+
topic: None,
39+
},
40+
);
41+
}
42+
43+
drop_assets_default {
44+
let origin = MultiLocation::default();
45+
let asset = MultiAsset { id: XcmAssetId::Abstract(Default::default()), fun: Fungibility::Fungible(0) };
46+
} : {
47+
T::DropAssets::drop_assets(
48+
&origin,
49+
asset.into(),
50+
&XcmContext {
51+
origin: Some(origin.clone()),
52+
message_hash: [0; 32],
53+
topic: None,
54+
},
55+
);
56+
}
57+
}

pallets/benchmarks/src/lib.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//! Pallet for benchmarking.
2+
3+
#![cfg_attr(not(feature = "std"), no_std)]
4+
5+
use codec::Codec;
6+
use frame_support::{pallet_prelude::*, traits::tokens::AssetId};
7+
use sp_runtime::traits::AtLeast32BitUnsigned;
8+
use xcm::prelude::*;
9+
use xcm_executor::traits::DropAssets;
10+
11+
pub use pallet::*;
12+
pub use weights::*;
13+
14+
#[cfg(feature = "runtime-benchmarks")]
15+
pub mod benchmarking;
16+
pub mod weights;
17+
18+
#[frame_support::pallet]
19+
pub mod pallet {
20+
use super::*;
21+
22+
#[pallet::config]
23+
pub trait Config: frame_system::Config {
24+
/// Identifier for the class of asset.
25+
type AssetId: AssetId + From<u32>;
26+
27+
/// The balance of an account.
28+
type Balance: Parameter + Member + AtLeast32BitUnsigned + Codec + TypeInfo;
29+
30+
/// The minimum amount required to keep an account open.
31+
#[pallet::constant]
32+
type ExistentialDeposit: Get<Self::Balance>;
33+
34+
/// Handler for when some non-empty `Assets` value should be dropped.
35+
type DropAssets: DropAssets;
36+
37+
/// Handler to register an asset.
38+
fn register_asset(asset_id: Self::AssetId, location: MultiLocation);
39+
}
40+
41+
#[pallet::pallet]
42+
pub struct Pallet<T>(_);
43+
}

pallets/benchmarks/src/weights.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
use frame_support::weights::Weight;
2+
3+
pub trait WeightInfo {
4+
fn drop_assets_fungible() -> Weight;
5+
fn drop_assets_native() -> Weight;
6+
fn drop_assets_default() -> Weight;
7+
}

primitives/xcm/src/lib.rs

Lines changed: 59 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
use frame_support::{
44
sp_runtime::SaturatedConversion,
55
traits::{fungibles::Inspect, Currency},
6+
weights::Weight,
67
};
7-
use sp_std::{borrow::Borrow, marker::PhantomData, vec::Vec};
8+
use sp_std::{borrow::Borrow, marker::PhantomData};
89
use xcm::{
910
latest::{
1011
AssetId::Concrete, Fungibility::Fungible, Junctions::Here, MultiAsset, MultiLocation,
11-
Weight,
1212
},
1313
v3::XcmContext,
1414
};
@@ -27,7 +27,7 @@ where
2727
AssetIdInfoGetter: AssetMultiLocationGetter<AssetId>,
2828
{
2929
fn convert_ref(asset_multi_location: impl Borrow<MultiLocation>) -> Result<AssetId, ()> {
30-
AssetIdInfoGetter::get_asset_id(asset_multi_location.borrow().clone()).ok_or(())
30+
AssetIdInfoGetter::get_asset_id(asset_multi_location.borrow()).ok_or(())
3131
}
3232

3333
fn reverse_ref(asset_id: impl Borrow<AssetId>) -> Result<MultiLocation, ()> {
@@ -37,7 +37,7 @@ where
3737

3838
pub trait AssetMultiLocationGetter<AssetId> {
3939
fn get_asset_multi_location(asset_id: AssetId) -> Option<MultiLocation>;
40-
fn get_asset_id(asset_multi_location: MultiLocation) -> Option<AssetId>;
40+
fn get_asset_id(asset_multi_location: &MultiLocation) -> Option<AssetId>;
4141
}
4242

4343
pub struct ConvertedRegisteredAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>(
@@ -63,68 +63,88 @@ impl<
6363
}
6464
}
6565

66+
pub trait DropAssetsWeigher {
67+
fn fungible() -> Weight;
68+
fn native() -> Weight;
69+
fn default() -> Weight;
70+
}
71+
6672
pub struct TrappistDropAssets<
6773
AssetId,
6874
AssetIdInfoGetter,
6975
AssetsPallet,
7076
BalancesPallet,
7177
XcmPallet,
72-
AccoundId,
73-
>(PhantomData<(AssetId, AssetIdInfoGetter, AssetsPallet, BalancesPallet, XcmPallet, AccoundId)>);
74-
impl<AssetId, AssetIdInfoGetter, AssetsPallet, BalancesPallet, XcmPallet, AccountId> DropAssets
78+
AccountId,
79+
Weigher,
80+
>(
81+
PhantomData<(
82+
AssetId,
83+
AssetIdInfoGetter,
84+
AssetsPallet,
85+
BalancesPallet,
86+
XcmPallet,
87+
AccountId,
88+
Weigher,
89+
)>,
90+
);
91+
92+
impl<AssetId, AssetIdInfoGetter, AssetsPallet, BalancesPallet, XcmPallet, AccountId, Weigher>
93+
DropAssets
7594
for TrappistDropAssets<
7695
AssetId,
7796
AssetIdInfoGetter,
7897
AssetsPallet,
7998
BalancesPallet,
8099
XcmPallet,
81100
AccountId,
101+
Weigher,
82102
> where
83103
AssetId: Clone,
84104
AssetIdInfoGetter: AssetMultiLocationGetter<AssetId>,
85105
AssetsPallet: Inspect<AccountId, AssetId = AssetId>,
86106
BalancesPallet: Currency<AccountId>,
87107
XcmPallet: DropAssets,
108+
Weigher: DropAssetsWeigher,
88109
{
89110
// assets are whatever the Holding Register had when XCVM halts
90-
fn drop_assets(origin: &MultiLocation, assets: Assets, context: &XcmContext) -> Weight {
91-
let multi_assets: Vec<MultiAsset> = assets.into();
92-
let mut trap: Vec<MultiAsset> = Vec::new();
111+
fn drop_assets(origin: &MultiLocation, mut assets: Assets, context: &XcmContext) -> Weight {
112+
const NATIVE_LOCATION: MultiLocation = MultiLocation { parents: 0, interior: Here };
93113

94-
for asset in multi_assets {
95-
if let MultiAsset { id: Concrete(location), fun: Fungible(amount) } = asset.clone() {
96-
// is location a fungible on AssetRegistry?
97-
if let Some(asset_id) = AssetIdInfoGetter::get_asset_id(location.clone()) {
98-
let min_balance = AssetsPallet::minimum_balance(asset_id);
114+
let mut weight: Weight = {
115+
assets.non_fungible.clear();
116+
Weigher::default()
117+
};
99118

100-
// only trap if amount ≥ min_balance
101-
// do nothing otherwise (asset is lost)
102-
if min_balance <= amount.saturated_into::<AssetsPallet::Balance>() {
103-
trap.push(asset);
104-
}
119+
assets.fungible.retain(|id, &mut amount| {
120+
if let Concrete(location) = id {
121+
match AssetIdInfoGetter::get_asset_id(location) {
122+
Some(asset_id) => {
123+
weight.saturating_accrue(Weigher::fungible());
105124

106-
// is location the native token?
107-
} else if location == (MultiLocation { parents: 0, interior: Here }) {
108-
let min_balance = BalancesPallet::minimum_balance();
125+
// only trap if amount ≥ min_balance
126+
// do nothing otherwise (asset is lost)
127+
amount.saturated_into::<AssetsPallet::Balance>() >=
128+
AssetsPallet::minimum_balance(asset_id)
129+
},
130+
None => {
131+
weight.saturating_accrue(Weigher::native());
109132

110-
// only trap if amount ≥ min_balance
111-
// do nothing otherwise (asset is lost)
112-
if min_balance <= amount.saturated_into::<BalancesPallet::Balance>() {
113-
trap.push(asset);
114-
}
133+
// only trap if native token and amount ≥ min_balance
134+
// do nothing otherwise (asset is lost)
135+
*location == NATIVE_LOCATION &&
136+
amount.saturated_into::<BalancesPallet::Balance>() >=
137+
BalancesPallet::minimum_balance()
138+
},
115139
}
140+
} else {
141+
weight.saturating_accrue(Weigher::default());
142+
false
116143
}
117-
}
118-
119-
// TODO: put real weight of execution up until this point here
120-
let mut weight: Weight = Weight::from_parts(0, 0);
121-
122-
if !trap.is_empty() {
123-
// we have filtered out non-compliant assets
124-
// insert valid assets into the asset trap implemented by XcmPallet
125-
weight += XcmPallet::drop_assets(origin, trap.into(), context);
126-
}
144+
});
127145

128-
weight
146+
// we have filtered out non-compliant assets
147+
// insert valid assets into the asset trap implemented by XcmPallet
148+
weight.saturating_add(XcmPallet::drop_assets(origin, assets, context))
129149
}
130150
}

runtime/trappist/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ pallet-dex-rpc-runtime-api = { version = "0.0.1", git = "https://github.com/pari
104104
pallet-chess = { git = "https://github.com/SubstrateChess/pallet-chess.git", default-features = false, branch = "polkadot-v0.9.40" }
105105

106106
# Trappist Pallets
107-
pallet-asset-registry = { version = "0.0.1", default-features = false, path = "../../pallets/asset-registry" }
107+
pallet-asset-registry = { default-features = false, path = "../../pallets/asset-registry" }
108+
trappist-runtime-benchmarks = { default-features = false, path = "../../pallets/benchmarks" }
108109

109110
[features]
110111
default = ["std"]
@@ -180,6 +181,7 @@ runtime-benchmarks = [
180181
"frame-system-benchmarking/runtime-benchmarks",
181182
"frame-support/runtime-benchmarks",
182183
"frame-system/runtime-benchmarks",
184+
"trappist-runtime-benchmarks/runtime-benchmarks",
183185
"pallet-assets/runtime-benchmarks",
184186
"pallet-asset-registry/runtime-benchmarks",
185187
"pallet-balances/runtime-benchmarks",

0 commit comments

Comments
 (0)