1234567891011121314151617#![cfg_attr(not(feature = "std"), no_std)]1819pub use pallet::*;2021#[cfg(feature = "runtime-benchmarks")]22pub mod benchmarking;2324pub mod weights;2526#[frame_support::pallet]27pub mod pallet {2829 use frame_support::{dispatch::*, pallet_prelude::*};30 use frame_support::traits::{QueryPreimage, StorePreimage, EnsureOrigin};31 use frame_system::pallet_prelude::*;32 use sp_core::H256;3334 use crate::weights::WeightInfo;3536 #[pallet::config]37 pub trait Config: frame_system::Config {38 39 type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;4041 42 type RuntimeCall: Parameter43 + Dispatchable<RuntimeOrigin = Self::RuntimeOrigin, PostInfo = PostDispatchInfo>44 + GetDispatchInfo45 + From<frame_system::Call<Self>>;4647 48 type Preimages: QueryPreimage + StorePreimage;4950 51 type ManagerOrigin: EnsureOrigin<<Self as frame_system::Config>::RuntimeOrigin>;5253 54 type PreimageOrigin: EnsureOrigin<<Self as frame_system::Config>::RuntimeOrigin>;5556 57 type WeightInfo: WeightInfo;58 }5960 #[pallet::event]61 #[pallet::generate_deposit(pub(super) fn deposit_event)]62 pub enum Event<T: Config> {63 MaintenanceEnabled,64 MaintenanceDisabled,65 }6667 #[pallet::pallet]68 pub struct Pallet<T>(_);6970 #[pallet::storage]71 #[pallet::getter(fn is_enabled)]72 pub type Enabled<T> = StorageValue<_, bool, ValueQuery>;7374 #[pallet::error]75 pub enum Error<T> {}7677 #[pallet::call]78 impl<T: Config> Pallet<T> {79 #[pallet::call_index(0)]80 #[pallet::weight(<T as Config>::WeightInfo::enable())]81 pub fn enable(origin: OriginFor<T>) -> DispatchResult {82 T::ManagerOrigin::ensure_origin(origin)?;8384 <Enabled<T>>::set(true);8586 Self::deposit_event(Event::MaintenanceEnabled);8788 Ok(())89 }9091 #[pallet::call_index(1)]92 #[pallet::weight(<T as Config>::WeightInfo::disable())]93 pub fn disable(origin: OriginFor<T>) -> DispatchResult {94 T::ManagerOrigin::ensure_origin(origin)?;9596 <Enabled<T>>::set(false);9798 Self::deposit_event(Event::MaintenanceDisabled);99100 Ok(())101 }102103 104 105 106 107 #[pallet::call_index(2)]108 #[pallet::weight(<T as Config>::WeightInfo::execute_preimage() + *weight_bound)]109 pub fn execute_preimage(110 origin: OriginFor<T>,111 hash: H256,112 weight_bound: Weight,113 ) -> DispatchResultWithPostInfo {114 use codec::Decode;115116 T::PreimageOrigin::ensure_origin(origin.clone())?;117118 let data = T::Preimages::fetch(&hash, None)?;119 weight_bound.set_proof_size(120 weight_bound121 .proof_size()122 .checked_sub(123 data.len()124 .try_into()125 .map_err(|_| DispatchError::Corruption)?,126 )127 .ok_or(DispatchError::Exhausted)?,128 );129130 let call = <T as Config>::RuntimeCall::decode(&mut &data[..])131 .map_err(|_| DispatchError::Corruption)?;132133 ensure!(134 call.get_dispatch_info().weight.all_lte(weight_bound),135 DispatchError::Exhausted136 );137138 match call.dispatch(origin) {139 Ok(_) => Ok(Pays::No.into()),140 Err(error_and_info) => Err(DispatchErrorWithPostInfo {141 post_info: Pays::No.into(),142 error: error_and_info.error,143 }),144 }145 }146 }147}