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::{30 dispatch::*,31 pallet_prelude::*,32 traits::{EnsureOrigin, QueryPreimage, StorePreimage},33 };34 use frame_system::pallet_prelude::*;35 use sp_core::H256;36 use sp_runtime::traits::Dispatchable;3738 use crate::weights::WeightInfo;3940 #[pallet::config]41 pub trait Config: frame_system::Config {42 43 type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;4445 46 type RuntimeCall: Parameter47 + Dispatchable<RuntimeOrigin = Self::RuntimeOrigin, PostInfo = PostDispatchInfo>48 + GetDispatchInfo49 + From<frame_system::Call<Self>>;5051 52 type Preimages: QueryPreimage + StorePreimage;5354 55 type ManagerOrigin: EnsureOrigin<<Self as frame_system::Config>::RuntimeOrigin>;5657 58 type PreimageOrigin: EnsureOrigin<<Self as frame_system::Config>::RuntimeOrigin>;5960 61 type WeightInfo: WeightInfo;62 }6364 #[pallet::event]65 #[pallet::generate_deposit(pub(super) fn deposit_event)]66 pub enum Event<T: Config> {67 MaintenanceEnabled,68 MaintenanceDisabled,69 }7071 #[pallet::pallet]72 pub struct Pallet<T>(_);7374 #[pallet::storage]75 #[pallet::getter(fn is_enabled)]76 pub type Enabled<T> = StorageValue<_, bool, ValueQuery>;7778 #[pallet::error]79 pub enum Error<T> {}8081 #[pallet::call]82 impl<T: Config> Pallet<T> {83 #[pallet::call_index(0)]84 #[pallet::weight(<T as Config>::WeightInfo::enable())]85 pub fn enable(origin: OriginFor<T>) -> DispatchResult {86 T::ManagerOrigin::ensure_origin(origin)?;8788 <Enabled<T>>::set(true);8990 Self::deposit_event(Event::MaintenanceEnabled);9192 Ok(())93 }9495 #[pallet::call_index(1)]96 #[pallet::weight(<T as Config>::WeightInfo::disable())]97 pub fn disable(origin: OriginFor<T>) -> DispatchResult {98 T::ManagerOrigin::ensure_origin(origin)?;99100 <Enabled<T>>::set(false);101102 Self::deposit_event(Event::MaintenanceDisabled);103104 Ok(())105 }106107 108 109 110 111 #[pallet::call_index(2)]112 #[pallet::weight(<T as Config>::WeightInfo::execute_preimage() + *weight_bound)]113 pub fn execute_preimage(114 origin: OriginFor<T>,115 hash: H256,116 weight_bound: Weight,117 ) -> DispatchResultWithPostInfo {118 use parity_scale_codec::Decode;119120 T::PreimageOrigin::ensure_origin(origin.clone())?;121122 let data = T::Preimages::fetch(&hash, None)?;123 weight_bound.set_proof_size(124 weight_bound125 .proof_size()126 .checked_sub(127 data.len()128 .try_into()129 .map_err(|_| DispatchError::Corruption)?,130 )131 .ok_or(DispatchError::Exhausted)?,132 );133134 let call = <T as Config>::RuntimeCall::decode(&mut &data[..])135 .map_err(|_| DispatchError::Corruption)?;136137 ensure!(138 call.get_dispatch_info().weight.all_lte(weight_bound),139 DispatchError::Exhausted140 );141142 match call.dispatch(origin) {143 Ok(_) => Ok(Pays::No.into()),144 Err(error_and_info) => Err(DispatchErrorWithPostInfo {145 post_info: Pays::No.into(),146 error: error_and_info.error,147 }),148 }149 }150 }151}