1234567891011121314151617use xcm_executor::traits::ShouldExecute;18use xcm::latest::prelude::*;19use logtest::Logger;20use crate::RuntimeCall;21use super::new_test_ext;22use frame_support::pallet_prelude::Weight;2324fn catch_xcm_barrier_log(logger: &mut Logger, expected_msg: &str) -> Result<(), String> {25 for record in logger {26 if record.target() == "xcm::barrier" && record.args() == expected_msg {27 return Ok(());28 }29 }3031 Err(format!(32 "the expected XCM barrier log `{}` is not found",33 expected_msg34 ))35}36373839pub fn barrier_denies_transact<B: ShouldExecute>(logger: &mut Logger) {40 let location = MultiLocation {41 parents: 0,42 interior: Junctions::Here,43 };4445 46 47 let fake_encoded_call = vec![0u8];4849 let transact_inst: Instruction<RuntimeCall> = Transact {50 origin_kind: OriginKind::Superuser,51 require_weight_at_most: Weight::default(),52 call: fake_encoded_call.into(),53 };5455 let mut xcm_program = vec![transact_inst];5657 let max_weight = Weight::from_parts(100_000, 100_000);58 let mut weight_credit = Weight::from_parts(100_000_000, 100_000_000);5960 let result = B::should_execute(&location, &mut xcm_program, max_weight, &mut weight_credit);6162 assert!(63 result.is_err(),64 "the barrier should disallow the XCM transact cmd"65 );6667 catch_xcm_barrier_log(logger, "transact XCM rejected").unwrap();68}6970fn xcm_execute<B: ShouldExecute>(71 self_para_id: u32,72 location: &MultiLocation,73 xcm: &mut [Instruction<RuntimeCall>],74) -> Result<(), ()> {75 new_test_ext(self_para_id).execute_with(|| {76 let max_weight = Weight::from_parts(100_000, 100_000);77 let mut weight_credit = Weight::from_parts(100_000_000, 100_000_000);7879 B::should_execute(&location, xcm, max_weight, &mut weight_credit)80 })81}8283fn make_multiassets(location: &MultiLocation) -> MultiAssets {84 let id = AssetId::Concrete(location.clone());85 let fun = Fungibility::Fungible(42);86 let multiasset = MultiAsset { id, fun };8788 multiasset.into()89}9091fn make_transfer_reserve_asset(location: &MultiLocation) -> Xcm<RuntimeCall> {92 let assets = make_multiassets(location);93 let inst = TransferReserveAsset {94 assets,95 dest: location.clone(),96 xcm: Xcm(vec![]),97 };9899 Xcm::<RuntimeCall>(vec![inst])100}101102fn make_deposit_reserve_asset(location: &MultiLocation) -> Xcm<RuntimeCall> {103 let assets = make_multiassets(location);104 let inst = DepositReserveAsset {105 assets: assets.into(),106 dest: location.clone(),107 xcm: Xcm(vec![]),108 };109110 Xcm::<RuntimeCall>(vec![inst])111}112113fn expect_transfer_location_denied<B: ShouldExecute>(114 logger: &mut Logger,115 self_para_id: u32,116 location: &MultiLocation,117 xcm: &mut [Instruction<RuntimeCall>],118) -> Result<(), String> {119 let result = xcm_execute::<B>(self_para_id, location, xcm);120121 if result.is_ok() {122 return Err("the barrier should deny the unknown location".into());123 }124125 catch_xcm_barrier_log(logger, "Unexpected deposit or transfer location")126}127128129130pub fn barrier_denies_transfer_from_unknown_location<B>(131 logger: &mut Logger,132 self_para_id: u32,133) -> Result<(), String>134where135 B: ShouldExecute,136{137 const UNKNOWN_PARACHAIN_ID: u32 = 4057;138139 let unknown_location = MultiLocation {140 parents: 1,141 interior: X1(Parachain(UNKNOWN_PARACHAIN_ID)),142 };143144 let mut transfer_reserve_asset = make_transfer_reserve_asset(&unknown_location);145 let mut deposit_reserve_asset = make_deposit_reserve_asset(&unknown_location);146147 expect_transfer_location_denied::<B>(148 logger,149 self_para_id,150 &unknown_location,151 &mut transfer_reserve_asset.0,152 )?;153154 expect_transfer_location_denied::<B>(155 logger,156 self_para_id,157 &unknown_location,158 &mut deposit_reserve_asset.0,159 )?;160161 Ok(())162}