1use super::*;
18use frame_benchmarking::v2::*;
19use frame_support::{assert_ok, weights::Weight};
20use frame_system::RawOrigin;
21use xcm::{latest::prelude::*, MAX_INSTRUCTIONS_TO_DECODE};
22use xcm_builder::EnsureDelivery;
23use xcm_executor::traits::FeeReason;
24
25type RuntimeOrigin<T> = <T as frame_system::Config>::RuntimeOrigin;
26
27pub struct Pallet<T: Config>(crate::Pallet<T>);
29
30pub trait Config: crate::Config + pallet_balances::Config {
32 type DeliveryHelper: EnsureDelivery;
34
35 fn reachable_dest() -> Option<Location> {
39 None
40 }
41
42 fn teleportable_asset_and_dest() -> Option<(Asset, Location)> {
49 None
50 }
51
52 fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> {
59 None
60 }
61
62 fn set_up_complex_asset_transfer() -> Option<(Assets, u32, Location, Box<dyn FnOnce()>)> {
75 None
76 }
77
78 fn get_asset() -> Asset;
84}
85
86#[benchmarks]
87mod benchmarks {
88 use super::*;
89
90 #[benchmark]
91 fn send() -> Result<(), BenchmarkError> {
92 let send_origin =
93 T::SendXcmOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
94 if T::SendXcmOrigin::try_origin(send_origin.clone()).is_err() {
95 return Err(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))
96 }
97 let msg = Xcm(vec![ClearOrigin]);
98 let versioned_dest: VersionedLocation = T::reachable_dest()
99 .ok_or(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?
100 .into();
101 let versioned_msg = VersionedXcm::from(msg);
102
103 T::DeliveryHelper::ensure_successful_delivery(
106 &Default::default(),
107 &versioned_dest.clone().try_into().unwrap(),
108 FeeReason::ChargeFees,
109 );
110
111 #[extrinsic_call]
112 _(send_origin as RuntimeOrigin<T>, Box::new(versioned_dest), Box::new(versioned_msg));
113
114 Ok(())
115 }
116
117 #[benchmark]
118 fn teleport_assets() -> Result<(), BenchmarkError> {
119 let (asset, destination) = T::teleportable_asset_and_dest()
120 .ok_or(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?;
121
122 let assets: Assets = asset.clone().into();
123
124 let caller: T::AccountId = whitelisted_caller();
125 let send_origin = RawOrigin::Signed(caller.clone());
126 let origin_location = T::ExecuteXcmOrigin::try_origin(send_origin.clone().into())
127 .map_err(|_| BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?;
128 if !T::XcmTeleportFilter::contains(&(origin_location.clone(), assets.clone().into_inner()))
129 {
130 return Err(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))
131 }
132
133 let (_, _) = T::DeliveryHelper::ensure_successful_delivery(
136 &origin_location,
137 &destination,
138 FeeReason::ChargeFees,
139 );
140
141 match &asset.fun {
142 Fungible(amount) => {
143 <T::XcmExecutor as XcmAssetTransfers>::AssetTransactor::deposit_asset(
145 &Asset { fun: Fungible(*amount), id: asset.id },
146 &origin_location,
147 None,
148 )
149 .map_err(|error| {
150 tracing::error!("Fungible asset couldn't be deposited, error: {:?}", error);
151 BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX))
152 })?;
153 },
154 NonFungible(_instance) => {
155 <T::XcmExecutor as XcmAssetTransfers>::AssetTransactor::deposit_asset(
156 &asset,
157 &origin_location,
158 None,
159 )
160 .map_err(|error| {
161 tracing::error!("Nonfungible asset couldn't be deposited, error: {:?}", error);
162 BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX))
163 })?;
164 },
165 };
166
167 let recipient = [0u8; 32];
168 let versioned_dest: VersionedLocation = destination.into();
169 let versioned_beneficiary: VersionedLocation =
170 AccountId32 { network: None, id: recipient.into() }.into();
171 let versioned_assets: VersionedAssets = assets.into();
172
173 #[extrinsic_call]
174 _(
175 send_origin,
176 Box::new(versioned_dest),
177 Box::new(versioned_beneficiary),
178 Box::new(versioned_assets),
179 0,
180 );
181
182 Ok(())
183 }
184
185 #[benchmark]
186 fn reserve_transfer_assets() -> Result<(), BenchmarkError> {
187 let (asset, destination) = T::reserve_transferable_asset_and_dest()
188 .ok_or(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?;
189
190 let assets: Assets = asset.clone().into();
191
192 let caller: T::AccountId = whitelisted_caller();
193 let send_origin = RawOrigin::Signed(caller.clone());
194 let origin_location = T::ExecuteXcmOrigin::try_origin(send_origin.clone().into())
195 .map_err(|_| BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?;
196 if !T::XcmReserveTransferFilter::contains(&(
197 origin_location.clone(),
198 assets.clone().into_inner(),
199 )) {
200 return Err(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))
201 }
202
203 let (_, _) = T::DeliveryHelper::ensure_successful_delivery(
206 &origin_location,
207 &destination,
208 FeeReason::ChargeFees,
209 );
210
211 match &asset.fun {
212 Fungible(amount) => {
213 <T::XcmExecutor as XcmAssetTransfers>::AssetTransactor::deposit_asset(
215 &Asset { fun: Fungible(*amount), id: asset.id.clone() },
216 &origin_location,
217 None,
218 )
219 .map_err(|error| {
220 tracing::error!("Fungible asset couldn't be deposited, error: {:?}", error);
221 BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX))
222 })?;
223 },
224 NonFungible(_instance) => {
225 <T::XcmExecutor as XcmAssetTransfers>::AssetTransactor::deposit_asset(
226 &asset,
227 &origin_location,
228 None,
229 )
230 .map_err(|error| {
231 tracing::error!("Nonfungible asset couldn't be deposited, error: {:?}", error);
232 BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX))
233 })?;
234 },
235 };
236
237 let recipient = [0u8; 32];
238 let versioned_dest: VersionedLocation = destination.clone().into();
239 let versioned_beneficiary: VersionedLocation =
240 AccountId32 { network: None, id: recipient.into() }.into();
241 let versioned_assets: VersionedAssets = assets.into();
242
243 #[extrinsic_call]
244 _(
245 send_origin,
246 Box::new(versioned_dest),
247 Box::new(versioned_beneficiary),
248 Box::new(versioned_assets),
249 0,
250 );
251
252 match &asset.fun {
253 Fungible(amount) => {
254 assert_ok!(<T::XcmExecutor as XcmAssetTransfers>::AssetTransactor::withdraw_asset(
255 &Asset { fun: Fungible(*amount), id: asset.id },
256 &destination,
257 None,
258 ));
259 },
260 NonFungible(_instance) => {
261 assert_ok!(<T::XcmExecutor as XcmAssetTransfers>::AssetTransactor::withdraw_asset(
262 &asset,
263 &destination,
264 None,
265 ));
266 },
267 };
268
269 Ok(())
270 }
271
272 #[benchmark]
273 fn transfer_assets() -> Result<(), BenchmarkError> {
274 let (assets, _fee_index, destination, verify_fn) = T::set_up_complex_asset_transfer()
275 .ok_or(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?;
276 let caller: T::AccountId = whitelisted_caller();
277 let send_origin = RawOrigin::Signed(caller.clone());
278 let recipient = [0u8; 32];
279 let versioned_dest: VersionedLocation = destination.into();
280 let versioned_beneficiary: VersionedLocation =
281 AccountId32 { network: None, id: recipient.into() }.into();
282 let versioned_assets: VersionedAssets = assets.into();
283
284 T::DeliveryHelper::ensure_successful_delivery(
287 &Default::default(),
288 &versioned_dest.clone().try_into().unwrap(),
289 FeeReason::ChargeFees,
290 );
291
292 #[extrinsic_call]
293 _(
294 send_origin,
295 Box::new(versioned_dest),
296 Box::new(versioned_beneficiary),
297 Box::new(versioned_assets),
298 0,
299 WeightLimit::Unlimited,
300 );
301
302 verify_fn();
304 Ok(())
305 }
306
307 #[benchmark]
308 fn execute() -> Result<(), BenchmarkError> {
309 let execute_origin =
310 T::ExecuteXcmOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
311 let origin_location = T::ExecuteXcmOrigin::try_origin(execute_origin.clone())
312 .map_err(|_| BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?;
313 let msg = Xcm(vec![ClearOrigin]);
314 if !T::XcmExecuteFilter::contains(&(origin_location, msg.clone())) {
315 return Err(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))
316 }
317 let versioned_msg = VersionedXcm::from(msg);
318
319 #[extrinsic_call]
320 _(execute_origin as RuntimeOrigin<T>, Box::new(versioned_msg), Weight::MAX);
321
322 Ok(())
323 }
324
325 #[benchmark]
326 fn force_xcm_version() -> Result<(), BenchmarkError> {
327 let loc = T::reachable_dest()
328 .ok_or(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?;
329 let xcm_version = 2;
330
331 #[extrinsic_call]
332 _(RawOrigin::Root, Box::new(loc), xcm_version);
333
334 Ok(())
335 }
336
337 #[benchmark]
338 fn force_default_xcm_version() {
339 #[extrinsic_call]
340 _(RawOrigin::Root, Some(2))
341 }
342
343 #[benchmark]
344 fn force_subscribe_version_notify() -> Result<(), BenchmarkError> {
345 let versioned_loc: VersionedLocation = T::reachable_dest()
346 .ok_or(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?
347 .into();
348
349 T::DeliveryHelper::ensure_successful_delivery(
352 &Default::default(),
353 &versioned_loc.clone().try_into().unwrap(),
354 FeeReason::ChargeFees,
355 );
356
357 #[extrinsic_call]
358 _(RawOrigin::Root, Box::new(versioned_loc));
359
360 Ok(())
361 }
362
363 #[benchmark]
364 fn force_unsubscribe_version_notify() -> Result<(), BenchmarkError> {
365 let loc = T::reachable_dest()
366 .ok_or(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?;
367 let versioned_loc: VersionedLocation = loc.clone().into();
368
369 T::DeliveryHelper::ensure_successful_delivery(
372 &Default::default(),
373 &versioned_loc.clone().try_into().unwrap(),
374 FeeReason::ChargeFees,
375 );
376
377 let _ = crate::Pallet::<T>::request_version_notify(loc);
378
379 #[extrinsic_call]
380 _(RawOrigin::Root, Box::new(versioned_loc));
381
382 Ok(())
383 }
384
385 #[benchmark]
386 fn force_suspension() {
387 #[extrinsic_call]
388 _(RawOrigin::Root, true)
389 }
390
391 #[benchmark]
392 fn migrate_supported_version() {
393 let old_version = XCM_VERSION - 1;
394 let loc = VersionedLocation::from(Location::from(Parent));
395 SupportedVersion::<T>::insert(old_version, loc, old_version);
396
397 #[block]
398 {
399 crate::Pallet::<T>::lazy_migration(
400 VersionMigrationStage::MigrateSupportedVersion,
401 Weight::zero(),
402 );
403 }
404 }
405
406 #[benchmark]
407 fn migrate_version_notifiers() {
408 let old_version = XCM_VERSION - 1;
409 let loc = VersionedLocation::from(Location::from(Parent));
410 VersionNotifiers::<T>::insert(old_version, loc, 0);
411
412 #[block]
413 {
414 crate::Pallet::<T>::lazy_migration(
415 VersionMigrationStage::MigrateVersionNotifiers,
416 Weight::zero(),
417 );
418 }
419 }
420
421 #[benchmark]
422 fn already_notified_target() -> Result<(), BenchmarkError> {
423 let loc = T::reachable_dest().ok_or(BenchmarkError::Override(
424 BenchmarkResult::from_weight(T::DbWeight::get().reads(1)),
425 ))?;
426 let loc = VersionedLocation::from(loc);
427 let current_version = T::AdvertisedXcmVersion::get();
428 VersionNotifyTargets::<T>::insert(
429 current_version,
430 loc,
431 (0, Weight::zero(), current_version),
432 );
433
434 #[block]
435 {
436 crate::Pallet::<T>::lazy_migration(
437 VersionMigrationStage::NotifyCurrentTargets(None),
438 Weight::zero(),
439 );
440 }
441
442 Ok(())
443 }
444
445 #[benchmark]
446 fn notify_current_targets() -> Result<(), BenchmarkError> {
447 let loc = T::reachable_dest().ok_or(BenchmarkError::Override(
448 BenchmarkResult::from_weight(T::DbWeight::get().reads_writes(1, 3)),
449 ))?;
450 let loc = VersionedLocation::from(loc);
451 let current_version = T::AdvertisedXcmVersion::get();
452 let old_version = current_version - 1;
453 VersionNotifyTargets::<T>::insert(current_version, loc, (0, Weight::zero(), old_version));
454
455 #[block]
456 {
457 crate::Pallet::<T>::lazy_migration(
458 VersionMigrationStage::NotifyCurrentTargets(None),
459 Weight::zero(),
460 );
461 }
462
463 Ok(())
464 }
465
466 #[benchmark]
467 fn notify_target_migration_fail() {
468 let newer_xcm_version = xcm::prelude::XCM_VERSION;
469 let older_xcm_version = newer_xcm_version - 1;
470 let bad_location: Location = Plurality { id: BodyId::Unit, part: BodyPart::Voice }.into();
471 let bad_location = VersionedLocation::from(bad_location)
472 .into_version(older_xcm_version)
473 .expect("Version conversion should work");
474 let current_version = T::AdvertisedXcmVersion::get();
475 VersionNotifyTargets::<T>::insert(
476 current_version,
477 bad_location,
478 (0, Weight::zero(), current_version),
479 );
480
481 #[block]
482 {
483 crate::Pallet::<T>::lazy_migration(
484 VersionMigrationStage::MigrateAndNotifyOldTargets,
485 Weight::zero(),
486 );
487 }
488 }
489
490 #[benchmark]
491 fn migrate_version_notify_targets() {
492 let current_version = T::AdvertisedXcmVersion::get();
493 let old_version = current_version - 1;
494 let loc = VersionedLocation::from(Location::from(Parent));
495 VersionNotifyTargets::<T>::insert(old_version, loc, (0, Weight::zero(), current_version));
496
497 #[block]
498 {
499 crate::Pallet::<T>::lazy_migration(
500 VersionMigrationStage::MigrateAndNotifyOldTargets,
501 Weight::zero(),
502 );
503 }
504 }
505
506 #[benchmark]
507 fn migrate_and_notify_old_targets() -> Result<(), BenchmarkError> {
508 let loc = T::reachable_dest().ok_or(BenchmarkError::Override(
509 BenchmarkResult::from_weight(T::DbWeight::get().reads_writes(1, 3)),
510 ))?;
511 let loc = VersionedLocation::from(loc);
512 let old_version = T::AdvertisedXcmVersion::get() - 1;
513 VersionNotifyTargets::<T>::insert(old_version, loc, (0, Weight::zero(), old_version));
514
515 #[block]
516 {
517 crate::Pallet::<T>::lazy_migration(
518 VersionMigrationStage::MigrateAndNotifyOldTargets,
519 Weight::zero(),
520 );
521 }
522
523 Ok(())
524 }
525
526 #[benchmark]
527 fn new_query() {
528 let responder = Location::from(Parent);
529 let timeout = 1u32.into();
530 let match_querier = Location::from(Here);
531
532 #[block]
533 {
534 crate::Pallet::<T>::new_query(responder, timeout, match_querier);
535 }
536 }
537
538 #[benchmark]
539 fn take_response() {
540 let responder = Location::from(Parent);
541 let timeout = 1u32.into();
542 let match_querier = Location::from(Here);
543 let query_id = crate::Pallet::<T>::new_query(responder, timeout, match_querier);
544 let infos = (0..xcm::v3::MaxPalletsInfo::get())
545 .map(|_| {
546 PalletInfo::new(
547 u32::MAX,
548 (0..xcm::v3::MaxPalletNameLen::get())
549 .map(|_| 97u8)
550 .collect::<Vec<_>>()
551 .try_into()
552 .unwrap(),
553 (0..xcm::v3::MaxPalletNameLen::get())
554 .map(|_| 97u8)
555 .collect::<Vec<_>>()
556 .try_into()
557 .unwrap(),
558 u32::MAX,
559 u32::MAX,
560 u32::MAX,
561 )
562 .unwrap()
563 })
564 .collect::<Vec<_>>();
565 crate::Pallet::<T>::expect_response(
566 query_id,
567 Response::PalletsInfo(infos.try_into().unwrap()),
568 );
569
570 #[block]
571 {
572 <crate::Pallet<T> as QueryHandler>::take_response(query_id);
573 }
574 }
575
576 #[benchmark]
577 fn claim_assets() -> Result<(), BenchmarkError> {
578 let claim_origin = RawOrigin::Signed(whitelisted_caller());
579 let claim_location = T::ExecuteXcmOrigin::try_origin(claim_origin.clone().into())
580 .map_err(|_| BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?;
581 let asset: Asset = T::get_asset();
582 crate::Pallet::<T>::drop_assets(
584 &claim_location,
585 asset.clone().into(),
586 &XcmContext { origin: None, message_id: [0u8; 32], topic: None },
587 );
588 let versioned_assets = VersionedAssets::from(Assets::from(asset));
589
590 #[extrinsic_call]
591 _(
592 claim_origin,
593 Box::new(versioned_assets),
594 Box::new(VersionedLocation::from(claim_location)),
595 );
596
597 Ok(())
598 }
599
600 #[benchmark]
601 fn add_authorized_alias() -> Result<(), BenchmarkError> {
602 let who: T::AccountId = whitelisted_caller();
603 let origin = RawOrigin::Signed(who.clone());
604 let origin_location: VersionedLocation =
605 T::ExecuteXcmOrigin::try_origin(origin.clone().into())
606 .map_err(|_| {
607 tracing::error!(
608 target: "xcm::benchmarking::pallet_xcm::add_authorized_alias",
609 ?origin,
610 "try_origin failed",
611 );
612 BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX))
613 })?
614 .into();
615
616 let balance = T::ExistentialDeposit::get() * 1000000u32.into();
618 let _ =
619 <pallet_balances::Pallet::<T> as frame_support::traits::Currency<_>>::make_free_balance_be(&who, balance);
620
621 let mut existing_aliases = BoundedVec::<OriginAliaser, MaxAuthorizedAliases>::new();
622 for i in 1..MaxAuthorizedAliases::get() {
624 let alias =
625 Location::new(1, [Parachain(i), AccountId32 { network: None, id: [42_u8; 32] }])
626 .into();
627 let aliaser = OriginAliaser { location: alias, expiry: None };
628 existing_aliases.try_push(aliaser).unwrap()
629 }
630 let footprint = aliasers_footprint(existing_aliases.len());
631 let ticket = TicketOf::<T>::new(&who, footprint).map_err(|e| {
632 tracing::error!(
633 target: "xcm::benchmarking::pallet_xcm::add_authorized_alias",
634 ?who,
635 ?footprint,
636 error=?e,
637 "could not create ticket",
638 );
639 BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX))
640 })?;
641 let entry = AuthorizedAliasesEntry { aliasers: existing_aliases, ticket };
642 AuthorizedAliases::<T>::insert(&origin_location, entry);
643
644 let aliaser: VersionedLocation =
646 Location::new(1, [Parachain(1234), AccountId32 { network: None, id: [42_u8; 32] }])
647 .into();
648
649 #[extrinsic_call]
650 _(origin, Box::new(aliaser), None);
651
652 Ok(())
653 }
654
655 #[benchmark]
656 fn remove_authorized_alias() -> Result<(), BenchmarkError> {
657 let who: T::AccountId = whitelisted_caller();
658 let origin = RawOrigin::Signed(who.clone());
659 let error = BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX));
660 let origin_location =
661 T::ExecuteXcmOrigin::try_origin(origin.clone().into()).map_err(|_| {
662 tracing::error!(
663 target: "xcm::benchmarking::pallet_xcm::remove_authorized_alias",
664 ?origin,
665 "try_origin failed",
666 );
667 error.clone()
668 })?;
669 let origin_location: VersionedLocation = match origin_location.unpack() {
672 (0, [AccountId32 { network: _, id }]) =>
673 Location::new(0, [AccountId32 { network: None, id: *id }]).into(),
674 _ => {
675 tracing::error!(
676 target: "xcm::benchmarking::pallet_xcm::remove_authorized_alias",
677 ?origin_location,
678 "unexpected origin failed",
679 );
680 return Err(error.clone())
681 },
682 };
683
684 let balance = T::ExistentialDeposit::get() * 1000000u32.into();
686 let _ =
687 <pallet_balances::Pallet::<T> as frame_support::traits::Currency<_>>::make_free_balance_be(&who, balance);
688
689 let mut existing_aliases = BoundedVec::<OriginAliaser, MaxAuthorizedAliases>::new();
690 for i in 1..MaxAuthorizedAliases::get() + 1 {
692 let alias =
693 Location::new(1, [Parachain(i), AccountId32 { network: None, id: [42_u8; 32] }])
694 .into();
695 let aliaser = OriginAliaser { location: alias, expiry: None };
696 existing_aliases.try_push(aliaser).unwrap()
697 }
698 let footprint = aliasers_footprint(existing_aliases.len());
699 let ticket = TicketOf::<T>::new(&who, footprint).map_err(|e| {
700 tracing::error!(
701 target: "xcm::benchmarking::pallet_xcm::remove_authorized_alias",
702 ?who,
703 ?footprint,
704 error=?e,
705 "could not create ticket",
706 );
707 error
708 })?;
709 let entry = AuthorizedAliasesEntry { aliasers: existing_aliases, ticket };
710 AuthorizedAliases::<T>::insert(&origin_location, entry);
711
712 let aliaser_to_remove: VersionedLocation =
714 Location::new(1, [Parachain(1), AccountId32 { network: None, id: [42_u8; 32] }]).into();
715
716 #[extrinsic_call]
717 _(origin, Box::new(aliaser_to_remove));
718
719 Ok(())
720 }
721
722 #[benchmark]
723 fn weigh_message() -> Result<(), BenchmarkError> {
724 let msg = Xcm(vec![ClearOrigin; MAX_INSTRUCTIONS_TO_DECODE.into()]);
725 let versioned_msg = VersionedXcm::from(msg);
726
727 #[block]
728 {
729 crate::Pallet::<T>::query_xcm_weight(versioned_msg)
730 .map_err(|_| BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?;
731 }
732
733 Ok(())
734 }
735
736 impl_benchmark_test_suite!(
737 Pallet,
738 crate::mock::new_test_ext_with_balances(Vec::new()),
739 crate::mock::Test
740 );
741}
742
743pub mod helpers {
744 use super::*;
745 pub fn native_teleport_as_asset_transfer<T>(
746 native_asset_location: Location,
747 destination: Location,
748 ) -> Option<(Assets, u32, Location, Box<dyn FnOnce()>)>
749 where
750 T: Config + pallet_balances::Config,
751 u128: From<<T as pallet_balances::Config>::Balance>,
752 {
753 let amount = T::ExistentialDeposit::get() * 100u32.into();
755 let assets: Assets =
756 Asset { fun: Fungible(amount.into()), id: AssetId(native_asset_location) }.into();
757 let fee_index = 0u32;
758
759 let balance = amount * 10u32.into();
761 let who = whitelisted_caller();
762 let _ =
763 <pallet_balances::Pallet::<T> as frame_support::traits::Currency<_>>::make_free_balance_be(&who, balance);
764 assert_eq!(pallet_balances::Pallet::<T>::free_balance(&who), balance);
766
767 let verify = Box::new(move || {
769 assert!(pallet_balances::Pallet::<T>::free_balance(&who) <= balance - amount);
771 });
772 Some((assets, fee_index, destination, verify))
773 }
774}