@@ -2057,6 +2057,9 @@ type Migrations = (RemoveXTokensMigrationStatus<Runtime>);
20572057
20582058#[ cfg( feature = "runtime-benchmarks" ) ]
20592059mod benches {
2060+ use super :: * ;
2061+ use alloc:: boxed:: Box ;
2062+
20602063 frame_benchmarking:: define_benchmarks!(
20612064 [ module_aggregated_dex, AggregatedDex ]
20622065 [ module_asset_registry, AssetRegistry ]
@@ -2090,14 +2093,181 @@ mod benches {
20902093 // Acala Ecosystem Modules
20912094 [ nutsfinance_stable_asset, StableAsset ]
20922095 // XCM
2093- // [pallet_xcm, PalletXcmExtrinsicsBenchmark::<Runtime>]
2096+ [ pallet_xcm, PalletXcmExtrinsicsBenchmark :: <Runtime >]
20942097 ) ;
20952098
2099+ use crate :: xcm_config:: AssetHubLocation ;
2100+ use cumulus_primitives_core:: { Asset , Assets , Fungible , GeneralKey , Location , ParaId , Parachain , ParentThen } ;
2101+ use frame_benchmarking:: BenchmarkError ;
2102+
2103+ const DOT_UNITS : Balance = 10_000_000_000 ;
2104+ const DOT_CENTS : Balance = DOT_UNITS / 100 ;
2105+
2106+ parameter_types ! {
2107+ pub AssetHubParaId : ParaId = ParaId :: from( parachains:: asset_hub_polkadot:: ID ) ;
2108+ pub FeeAssetId : AssetId = AssetId ( Location :: parent( ) ) ;
2109+ pub const ToSiblingBaseDeliveryFee : u128 = DOT_CENTS . saturating_mul( 3 ) ;
2110+ }
2111+
2112+ pub type PriceForSiblingParachainDelivery = polkadot_runtime_common:: xcm_sender:: ExponentialPrice <
2113+ FeeAssetId ,
2114+ ToSiblingBaseDeliveryFee ,
2115+ TransactionByteFee ,
2116+ XcmpQueue ,
2117+ > ;
2118+
2119+ parameter_types ! {
2120+ pub ExistentialDepositAsset : Option <Asset > = Some ( (
2121+ Location :: parent( ) ,
2122+ NativeTokenExistentialDeposit :: get( )
2123+ ) . into( ) ) ;
2124+ pub const RandomParaId : ParaId = ParaId :: new( 43211234 ) ;
2125+ }
2126+
2127+ impl pallet_xcm:: benchmarking:: Config for Runtime {
2128+ type DeliveryHelper = (
2129+ polkadot_runtime_common:: xcm_sender:: ToParachainDeliveryHelper <
2130+ xcm_config:: XcmConfig ,
2131+ ExistentialDepositAsset ,
2132+ PriceForSiblingParachainDelivery ,
2133+ RandomParaId ,
2134+ ParachainSystem ,
2135+ > ,
2136+ polkadot_runtime_common:: xcm_sender:: ToParachainDeliveryHelper <
2137+ xcm_config:: XcmConfig ,
2138+ ExistentialDepositAsset ,
2139+ PriceForSiblingParachainDelivery ,
2140+ AssetHubParaId ,
2141+ ParachainSystem ,
2142+ > ,
2143+ ) ;
2144+
2145+ fn reachable_dest ( ) -> Option < Location > {
2146+ Some ( AssetHubLocation :: get ( ) )
2147+ }
2148+
2149+ fn teleportable_asset_and_dest ( ) -> Option < ( Asset , Location ) > {
2150+ // XcmTeleportFilter is Nothing
2151+ None
2152+ }
2153+
2154+ fn reserve_transferable_asset_and_dest ( ) -> Option < ( Asset , Location ) > {
2155+ ParachainSystem :: open_outbound_hrmp_channel_for_benchmarks_or_tests ( RandomParaId :: get ( ) ) ;
2156+
2157+ let encoded = ACA . encode ( ) ;
2158+ let mut data = [ 0u8 ; 32 ] ;
2159+ let len = encoded. len ( ) . min ( 32 ) ;
2160+ data[ ..len] . copy_from_slice ( & encoded[ ..len] ) ;
2161+
2162+ Some ( (
2163+ Asset {
2164+ id : AssetId ( Location :: new (
2165+ 0 ,
2166+ GeneralKey {
2167+ data : data,
2168+ length : encoded. len ( ) as u8 ,
2169+ } ,
2170+ ) ) ,
2171+ fun : Fungible ( NativeTokenExistentialDeposit :: get ( ) * 100 ) ,
2172+ } ,
2173+ ParentThen ( Parachain ( RandomParaId :: get ( ) . into ( ) ) . into ( ) ) . into ( ) ,
2174+ ) )
2175+ }
2176+
2177+ fn set_up_complex_asset_transfer ( ) -> Option < ( Assets , u32 , Location , Box < dyn FnOnce ( ) > ) > {
2178+ // transfer AUSD from this parachain to RandomParaId parachain
2179+ ParachainSystem :: open_outbound_hrmp_channel_for_benchmarks_or_tests ( RandomParaId :: get ( ) ) ;
2180+
2181+ let dest = Location :: new ( 1 , Parachain ( RandomParaId :: get ( ) . into ( ) ) ) ;
2182+
2183+ // fee asset
2184+ let fee_amount = NativeTokenExistentialDeposit :: get ( ) ;
2185+ let aca_encoded = ACA . encode ( ) ;
2186+ let mut aca_data = [ 0u8 ; 32 ] ;
2187+ let len = aca_encoded. len ( ) . min ( 32 ) ;
2188+ aca_data[ ..len] . copy_from_slice ( & aca_encoded[ ..len] ) ;
2189+ let fee_location = Location :: new (
2190+ 0 ,
2191+ GeneralKey {
2192+ data : aca_data,
2193+ length : aca_encoded. len ( ) as u8 ,
2194+ } ,
2195+ ) ;
2196+ let fee_asset: Asset = ( fee_location, fee_amount) . into ( ) ;
2197+
2198+ // asset to transfer
2199+ let asset_amount = 1_000_000_000_000u128 ;
2200+ let asset_balance = asset_amount * 10 ;
2201+ let ausd_encoded = AUSD . encode ( ) ;
2202+ let mut ausd_data = [ 0u8 ; 32 ] ;
2203+ let len = ausd_encoded. len ( ) . min ( 32 ) ;
2204+ ausd_data[ ..len] . copy_from_slice ( & ausd_encoded[ ..len] ) ;
2205+ let asset_location = Location :: new (
2206+ 0 ,
2207+ GeneralKey {
2208+ data : ausd_data,
2209+ length : ausd_encoded. len ( ) as u8 ,
2210+ } ,
2211+ ) ;
2212+ let transfer_asset: Asset = ( asset_location, asset_amount) . into ( ) ;
2213+
2214+ let assets: Assets = vec ! [ fee_asset. clone( ) , transfer_asset] . into ( ) ;
2215+
2216+ let who = frame_benchmarking:: whitelisted_caller ( ) ;
2217+ // Give some multiple of the existential deposit
2218+ let native_balance = NativeTokenExistentialDeposit :: get ( ) * 1000 ;
2219+ let _ = <Balances as frame_support:: traits:: Currency < _ > >:: make_free_balance_be ( & who, native_balance) ;
2220+ let _ = Tokens :: deposit ( AUSD , & who, asset_balance) ;
2221+ // verify initial balance
2222+ assert_eq ! ( Balances :: free_balance( & who) , native_balance) ;
2223+ assert_eq ! ( Tokens :: free_balance( AUSD , & who) , asset_balance) ;
2224+
2225+ let fee_index = if assets. get ( 0 ) . unwrap ( ) . eq ( & fee_asset) { 0 } else { 1 } ;
2226+
2227+ // verify transferred successfully
2228+ let verify = Box :: new ( move || {
2229+ // verify native balance after transfer, decreased by transferred fee amount
2230+ // (plus transport fees)
2231+ assert ! ( Balances :: free_balance( & who) <= native_balance - fee_amount) ;
2232+ // verify asset balance after transfer, decreased by transferred asset amount
2233+ assert_eq ! ( Tokens :: free_balance( AUSD , & who) , asset_balance - asset_amount) ;
2234+ } ) ;
2235+ Some ( ( assets, fee_index as u32 , dest, verify) )
2236+ }
2237+
2238+ fn get_asset ( ) -> Asset {
2239+ Asset {
2240+ id : AssetId ( Location :: parent ( ) ) ,
2241+ fun : Fungible ( DOT_UNITS ) ,
2242+ }
2243+ }
2244+ }
2245+
2246+ impl pallet_xcm_benchmarks:: Config for Runtime {
2247+ type XcmConfig = xcm_config:: XcmConfig ;
2248+ type AccountIdConverter = xcm_config:: LocationToAccountId ;
2249+ type DeliveryHelper = polkadot_runtime_common:: xcm_sender:: ToParachainDeliveryHelper <
2250+ xcm_config:: XcmConfig ,
2251+ ExistentialDepositAsset ,
2252+ PriceForSiblingParachainDelivery ,
2253+ AssetHubParaId ,
2254+ ParachainSystem ,
2255+ > ;
2256+ fn valid_destination ( ) -> Result < Location , BenchmarkError > {
2257+ Ok ( AssetHubLocation :: get ( ) )
2258+ }
2259+ fn worst_case_holding ( _depositable_count : u32 ) -> Assets {
2260+ let assets: Vec < Asset > = vec ! [ Asset {
2261+ id: AssetId ( Location :: parent( ) ) ,
2262+ fun: Fungible ( 1_000 * DOT_UNITS ) ,
2263+ } ] ;
2264+ assets. into ( )
2265+ }
2266+ }
2267+
20962268 pub use frame_benchmarking:: { BenchmarkBatch , BenchmarkList } ;
20972269 pub use frame_support:: traits:: { StorageInfoTrait , WhitelistedStorageKeys } ;
2098- // pub use frame_system_benchmarking::{
2099- // extensions::Pallet as SystemExtensionsBench, Pallet as SystemBench,
2100- // };
2270+ pub use pallet_xcm:: benchmarking:: Pallet as PalletXcmExtrinsicsBenchmark ;
21012271 pub use sp_storage:: TrackedStorageKey ;
21022272}
21032273
0 commit comments