parachains_runtimes_test_utils/
test_cases.rs1use crate::{
20 AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, ExtBuilder, GovernanceOrigin,
21 RuntimeCallOf, RuntimeOriginOf, ValidatorIdOf,
22};
23use codec::Encode;
24use frame_support::{
25 assert_ok,
26 traits::{Get, OriginTrait},
27 weights::WeightToFee as WeightToFeeT,
28};
29use parachains_common::AccountId;
30use sp_runtime::{
31 traits::{Block as BlockT, SaturatedConversion, StaticLookup},
32 DispatchError, Either,
33};
34use xcm::prelude::InstructionError;
35use xcm_runtime_apis::fees::{
36 runtime_decl_for_xcm_payment_api::XcmPaymentApiV1, Error as XcmPaymentApiError,
37};
38
39type RuntimeHelper<Runtime, AllPalletsWithoutSystem = ()> =
40 crate::RuntimeHelper<Runtime, AllPalletsWithoutSystem>;
41
42pub fn change_storage_constant_by_governance_works<Runtime, StorageConstant, StorageConstantType>(
44 collator_session_key: CollatorSessionKeys<Runtime>,
45 runtime_para_id: u32,
46 governance_origin: GovernanceOrigin<RuntimeOriginOf<Runtime>>,
47 storage_constant_key_value: fn() -> (Vec<u8>, StorageConstantType),
48 new_storage_constant_value: fn(&StorageConstantType) -> StorageConstantType,
49) where
50 Runtime: frame_system::Config
51 + pallet_balances::Config
52 + pallet_session::Config
53 + pallet_xcm::Config
54 + parachain_info::Config
55 + pallet_collator_selection::Config
56 + cumulus_pallet_parachain_system::Config
57 + pallet_timestamp::Config,
58 ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
59 StorageConstant: Get<StorageConstantType>,
60 StorageConstantType: Encode + PartialEq + std::fmt::Debug,
61{
62 ExtBuilder::<Runtime>::default()
63 .with_collators(collator_session_key.collators())
64 .with_session_keys(collator_session_key.session_keys())
65 .with_para_id(runtime_para_id.into())
66 .with_tracing()
67 .build()
68 .execute_with(|| {
69 let (storage_constant_key, storage_constant_init_value): (
70 Vec<u8>,
71 StorageConstantType,
72 ) = storage_constant_key_value();
73
74 assert_eq!(StorageConstant::get(), storage_constant_init_value);
76 assert_eq!(sp_io::storage::get(&storage_constant_key), None);
77
78 let new_storage_constant_value =
79 new_storage_constant_value(&storage_constant_init_value);
80 assert_ne!(new_storage_constant_value, storage_constant_init_value);
81
82 let set_storage_call =
84 RuntimeCallOf::<Runtime>::from(frame_system::Call::<Runtime>::set_storage {
85 items: vec![(
86 storage_constant_key.clone(),
87 new_storage_constant_value.encode(),
88 )],
89 });
90
91 assert_ok!(RuntimeHelper::<Runtime>::execute_as_governance_call(
93 set_storage_call,
94 governance_origin
95 ));
96
97 assert_eq!(StorageConstant::get(), new_storage_constant_value);
99 assert_eq!(
100 sp_io::storage::get(&storage_constant_key),
101 Some(new_storage_constant_value.encode().into())
102 );
103 })
104}
105
106pub fn set_storage_keys_by_governance_works<Runtime>(
108 collator_session_key: CollatorSessionKeys<Runtime>,
109 runtime_para_id: u32,
110 governance_origin: GovernanceOrigin<RuntimeOriginOf<Runtime>>,
111 storage_items: Vec<(Vec<u8>, Vec<u8>)>,
112 initialize_storage: impl FnOnce() -> (),
113 assert_storage: impl FnOnce() -> (),
114) where
115 Runtime: frame_system::Config
116 + pallet_balances::Config
117 + pallet_session::Config
118 + pallet_xcm::Config
119 + parachain_info::Config
120 + pallet_collator_selection::Config
121 + cumulus_pallet_parachain_system::Config
122 + pallet_timestamp::Config,
123 ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
124{
125 let mut runtime = ExtBuilder::<Runtime>::default()
126 .with_collators(collator_session_key.collators())
127 .with_session_keys(collator_session_key.session_keys())
128 .with_para_id(runtime_para_id.into())
129 .with_tracing()
130 .build();
131 runtime.execute_with(|| {
132 initialize_storage();
133 });
134 runtime.execute_with(|| {
135 let kill_storage_call =
137 RuntimeCallOf::<Runtime>::from(frame_system::Call::<Runtime>::set_storage {
138 items: storage_items.clone(),
139 });
140
141 assert_ok!(RuntimeHelper::<Runtime>::execute_as_governance_call(
143 kill_storage_call,
144 governance_origin
145 ));
146 });
147 runtime.execute_with(|| {
148 assert_storage();
149 });
150}
151
152pub fn xcm_payment_api_with_native_token_works<
153 Runtime,
154 RuntimeCall,
155 RuntimeOrigin,
156 Block,
157 WeightToFee,
158>()
159where
160 Runtime: XcmPaymentApiV1<Block>
161 + frame_system::Config<RuntimeOrigin = RuntimeOrigin, AccountId = AccountId>
162 + pallet_balances::Config<Balance = u128>
163 + pallet_session::Config
164 + pallet_xcm::Config
165 + parachain_info::Config
166 + pallet_collator_selection::Config
167 + cumulus_pallet_parachain_system::Config
168 + cumulus_pallet_xcmp_queue::Config
169 + pallet_timestamp::Config,
170 ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
171 RuntimeOrigin: OriginTrait<AccountId = <Runtime as frame_system::Config>::AccountId>,
172 <<Runtime as frame_system::Config>::Lookup as StaticLookup>::Source:
173 From<<Runtime as frame_system::Config>::AccountId>,
174 Block: BlockT,
175 WeightToFee: WeightToFeeT,
176{
177 use xcm::prelude::*;
178 ExtBuilder::<Runtime>::default().build().execute_with(|| {
179 let transfer_amount = 100u128;
180 let xcm_to_weigh = Xcm::<RuntimeCall>::builder_unsafe()
181 .withdraw_asset((Here, transfer_amount))
182 .buy_execution((Here, transfer_amount), Unlimited)
183 .deposit_asset(AllCounted(1), [1u8; 32])
184 .build();
185 let versioned_xcm_to_weigh = VersionedXcm::from(xcm_to_weigh.clone().into());
186
187 let lower_version_xcm_to_weigh =
189 versioned_xcm_to_weigh.clone().into_version(XCM_VERSION - 1).unwrap();
190 let xcm_weight = Runtime::query_xcm_weight(lower_version_xcm_to_weigh)
191 .expect("xcm weight must be computed");
192
193 let expected_weight_fee: u128 = WeightToFee::weight_to_fee(&xcm_weight).saturated_into();
194
195 let native_token: Location = Parent.into();
196 let native_token_versioned = VersionedAssetId::from(AssetId(native_token));
197 let lower_version_native_token =
198 native_token_versioned.clone().into_version(XCM_VERSION - 1).unwrap();
199 let execution_fees =
200 Runtime::query_weight_to_asset_fee(xcm_weight, lower_version_native_token)
201 .expect("weight must be converted to native fee");
202
203 assert_eq!(execution_fees, expected_weight_fee);
204
205 let xcm_weight =
207 Runtime::query_xcm_weight(versioned_xcm_to_weigh).expect("xcm weight must be computed");
208
209 let expected_weight_fee: u128 = WeightToFee::weight_to_fee(&xcm_weight).saturated_into();
210
211 let execution_fees = Runtime::query_weight_to_asset_fee(xcm_weight, native_token_versioned)
212 .expect("weight must be converted to native fee");
213
214 assert_eq!(execution_fees, expected_weight_fee);
215
216 let non_existent_token: Location = Here.into();
218 let non_existent_token_versioned = VersionedAssetId::from(AssetId(non_existent_token));
219 let execution_fees =
220 Runtime::query_weight_to_asset_fee(xcm_weight, non_existent_token_versioned);
221 assert_eq!(execution_fees, Err(XcmPaymentApiError::AssetNotFound));
222 });
223}
224
225pub fn can_governance_authorize_upgrade<Runtime, RuntimeOrigin>(
228 governance_origin: GovernanceOrigin<RuntimeOrigin>,
229) -> Result<(), Either<DispatchError, InstructionError>>
230where
231 Runtime: BasicParachainRuntime
232 + frame_system::Config<RuntimeOrigin = RuntimeOrigin, AccountId = AccountId>,
233{
234 ExtBuilder::<Runtime>::default().build().execute_with(|| {
235 assert!(frame_system::Pallet::<Runtime>::authorized_upgrade().is_none());
237
238 let code_hash = Runtime::Hash::default();
240 let authorize_upgrade_call: <Runtime as frame_system::Config>::RuntimeCall =
241 frame_system::Call::<Runtime>::authorize_upgrade { code_hash }.into();
242 RuntimeHelper::<Runtime>::execute_as_governance_call(
243 authorize_upgrade_call,
244 governance_origin,
245 )?;
246
247 match frame_system::Pallet::<Runtime>::authorized_upgrade() {
249 None => Err(Either::Left(frame_system::Error::<Runtime>::NothingAuthorized.into())),
250 Some(_) => Ok(()),
251 }
252 })
253}