use crate::{
AccountIdOf, BasicTeyrchainRuntime, CollatorSessionKeys, ExtBuilder, GovernanceOrigin,
RuntimeCallOf, RuntimeOriginOf, ValidatorIdOf,
};
use codec::Encode;
use pezframe_support::{
assert_ok,
traits::{Get, OriginTrait},
weights::WeightToFee as WeightToFeeT,
};
use pezsp_runtime::{
traits::{Block as BlockT, SaturatedConversion, StaticLookup},
DispatchError, Either,
};
use teyrchains_common::AccountId;
use xcm::prelude::InstructionError;
use xcm_runtime_pezapis::fees::{
runtime_decl_for_xcm_payment_api::XcmPaymentApiV2, Error as XcmPaymentApiError,
};
type RuntimeHelper<Runtime, AllPalletsWithoutSystem = ()> =
crate::RuntimeHelper<Runtime, AllPalletsWithoutSystem>;
pub fn change_storage_constant_by_governance_works<Runtime, StorageConstant, StorageConstantType>(
collator_session_key: CollatorSessionKeys<Runtime>,
runtime_para_id: u32,
governance_origin: GovernanceOrigin<RuntimeOriginOf<Runtime>>,
storage_constant_key_value: fn() -> (Vec<u8>, StorageConstantType),
new_storage_constant_value: fn(&StorageConstantType) -> StorageConstantType,
) where
Runtime: pezframe_system::Config
+ pezpallet_balances::Config
+ pezpallet_session::Config
+ pezpallet_xcm::Config
+ teyrchain_info::Config
+ pezpallet_collator_selection::Config
+ pezcumulus_pezpallet_teyrchain_system::Config
+ pezpallet_timestamp::Config,
ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
StorageConstant: Get<StorageConstantType>,
StorageConstantType: Encode + PartialEq + std::fmt::Debug,
{
ExtBuilder::<Runtime>::default()
.with_collators(collator_session_key.collators())
.with_session_keys(collator_session_key.session_keys())
.with_para_id(runtime_para_id.into())
.with_tracing()
.build()
.execute_with(|| {
let (storage_constant_key, storage_constant_init_value): (
Vec<u8>,
StorageConstantType,
) = storage_constant_key_value();
assert_eq!(StorageConstant::get(), storage_constant_init_value);
assert_eq!(pezsp_io::storage::get(&storage_constant_key), None);
let new_storage_constant_value =
new_storage_constant_value(&storage_constant_init_value);
assert_ne!(new_storage_constant_value, storage_constant_init_value);
let set_storage_call =
RuntimeCallOf::<Runtime>::from(pezframe_system::Call::<Runtime>::set_storage {
items: vec![(
storage_constant_key.clone(),
new_storage_constant_value.encode(),
)],
});
assert_ok!(RuntimeHelper::<Runtime>::execute_as_governance_call(
set_storage_call,
governance_origin
));
assert_eq!(StorageConstant::get(), new_storage_constant_value);
assert_eq!(
pezsp_io::storage::get(&storage_constant_key),
Some(new_storage_constant_value.encode().into())
);
})
}
pub fn set_storage_keys_by_governance_works<Runtime>(
collator_session_key: CollatorSessionKeys<Runtime>,
runtime_para_id: u32,
governance_origin: GovernanceOrigin<RuntimeOriginOf<Runtime>>,
storage_items: Vec<(Vec<u8>, Vec<u8>)>,
initialize_storage: impl FnOnce() -> (),
assert_storage: impl FnOnce() -> (),
) where
Runtime: pezframe_system::Config
+ pezpallet_balances::Config
+ pezpallet_session::Config
+ pezpallet_xcm::Config
+ teyrchain_info::Config
+ pezpallet_collator_selection::Config
+ pezcumulus_pezpallet_teyrchain_system::Config
+ pezpallet_timestamp::Config,
ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
{
let mut runtime = ExtBuilder::<Runtime>::default()
.with_collators(collator_session_key.collators())
.with_session_keys(collator_session_key.session_keys())
.with_para_id(runtime_para_id.into())
.with_tracing()
.build();
runtime.execute_with(|| {
initialize_storage();
});
runtime.execute_with(|| {
let kill_storage_call =
RuntimeCallOf::<Runtime>::from(pezframe_system::Call::<Runtime>::set_storage {
items: storage_items.clone(),
});
assert_ok!(RuntimeHelper::<Runtime>::execute_as_governance_call(
kill_storage_call,
governance_origin
));
});
runtime.execute_with(|| {
assert_storage();
});
}
pub fn xcm_payment_api_with_native_token_works<
Runtime,
RuntimeCall,
RuntimeOrigin,
Block,
WeightToFee,
>()
where
Runtime: XcmPaymentApiV2<Block>
+ pezframe_system::Config<RuntimeOrigin = RuntimeOrigin, AccountId = AccountId>
+ pezpallet_balances::Config<Balance = u128>
+ pezpallet_session::Config
+ pezpallet_xcm::Config
+ teyrchain_info::Config
+ pezpallet_collator_selection::Config
+ pezcumulus_pezpallet_teyrchain_system::Config
+ pezcumulus_pezpallet_xcmp_queue::Config
+ pezpallet_timestamp::Config,
ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
RuntimeOrigin: OriginTrait<AccountId = <Runtime as pezframe_system::Config>::AccountId>,
<<Runtime as pezframe_system::Config>::Lookup as StaticLookup>::Source:
From<<Runtime as pezframe_system::Config>::AccountId>,
Block: BlockT,
WeightToFee: WeightToFeeT,
{
use xcm::prelude::*;
ExtBuilder::<Runtime>::default().build().execute_with(|| {
let transfer_amount = 100u128;
let xcm_to_weigh = Xcm::<RuntimeCall>::builder_unsafe()
.withdraw_asset((Here, transfer_amount))
.buy_execution((Here, transfer_amount), Unlimited)
.deposit_asset(AllCounted(1), [1u8; 32])
.build();
let versioned_xcm_to_weigh = VersionedXcm::from(xcm_to_weigh.clone().into());
let lower_version_xcm_to_weigh =
versioned_xcm_to_weigh.clone().into_version(XCM_VERSION - 1).unwrap();
let xcm_weight = Runtime::query_xcm_weight(lower_version_xcm_to_weigh)
.expect("xcm weight must be computed");
let expected_weight_fee: u128 = WeightToFee::weight_to_fee(&xcm_weight).saturated_into();
let native_token: Location = Parent.into();
let native_token_versioned = VersionedAssetId::from(AssetId(native_token));
let lower_version_native_token =
native_token_versioned.clone().into_version(XCM_VERSION - 1).unwrap();
let execution_fees =
Runtime::query_weight_to_asset_fee(xcm_weight, lower_version_native_token)
.expect("weight must be converted to native fee");
assert_eq!(execution_fees, expected_weight_fee);
let xcm_weight =
Runtime::query_xcm_weight(versioned_xcm_to_weigh).expect("xcm weight must be computed");
let expected_weight_fee: u128 = WeightToFee::weight_to_fee(&xcm_weight).saturated_into();
let execution_fees = Runtime::query_weight_to_asset_fee(xcm_weight, native_token_versioned)
.expect("weight must be converted to native fee");
assert_eq!(execution_fees, expected_weight_fee);
let non_existent_token: Location = Here.into();
let non_existent_token_versioned = VersionedAssetId::from(AssetId(non_existent_token));
let execution_fees =
Runtime::query_weight_to_asset_fee(xcm_weight, non_existent_token_versioned);
assert_eq!(execution_fees, Err(XcmPaymentApiError::AssetNotFound));
});
}
pub fn can_governance_authorize_upgrade<Runtime, RuntimeOrigin>(
governance_origin: GovernanceOrigin<RuntimeOrigin>,
) -> Result<(), Either<DispatchError, InstructionError>>
where
Runtime: BasicTeyrchainRuntime
+ pezframe_system::Config<RuntimeOrigin = RuntimeOrigin, AccountId = AccountId>,
{
ExtBuilder::<Runtime>::default().build().execute_with(|| {
assert!(pezframe_system::Pezpallet::<Runtime>::authorized_upgrade().is_none());
let code_hash = Runtime::Hash::default();
let authorize_upgrade_call: <Runtime as pezframe_system::Config>::RuntimeCall =
pezframe_system::Call::<Runtime>::authorize_upgrade { code_hash }.into();
RuntimeHelper::<Runtime>::execute_as_governance_call(
authorize_upgrade_call,
governance_origin,
)?;
match pezframe_system::Pezpallet::<Runtime>::authorized_upgrade() {
None => Err(Either::Left(pezframe_system::Error::<Runtime>::NothingAuthorized.into())),
Some(_) => Ok(()),
}
})
}