1#![cfg_attr(not(feature = "std"), no_std)]
99
100extern crate alloc;
101
102use alloc::{borrow::Cow, boxed::Box, vec, vec::Vec};
103use core::{fmt::Debug, marker::PhantomData};
104use pezpallet_prelude::{BlockNumberFor, HeaderFor};
105use pezsp_io::hashing::blake2_256;
106#[cfg(feature = "runtime-benchmarks")]
107use pezsp_runtime::traits::TrailingZeroInput;
108use pezsp_runtime::{
109 generic,
110 traits::{
111 self, AsTransactionAuthorizedOrigin, AtLeast32Bit, BadOrigin, BlockNumberProvider, Bounded,
112 CheckEqual, Dispatchable, Hash, Header, Lookup, LookupError, MaybeDisplay,
113 MaybeSerializeDeserialize, Member, One, Saturating, SimpleBitOps, StaticLookup, Zero,
114 },
115 transaction_validity::{
116 InvalidTransaction, TransactionLongevity, TransactionSource, TransactionValidity,
117 ValidTransaction,
118 },
119 DispatchError, RuntimeDebug,
120};
121use pezsp_version::RuntimeVersion;
122#[cfg(feature = "std")]
123use serde::Serialize;
124
125use codec::{Decode, DecodeWithMemTracking, Encode, EncodeLike, FullCodec, MaxEncodedLen};
126#[cfg(feature = "std")]
127use pezframe_support::traits::BuildGenesisConfig;
128use pezframe_support::{
129 dispatch::{
130 extract_actual_pays_fee, extract_actual_weight, DispatchClass, DispatchInfo,
131 DispatchResult, DispatchResultWithPostInfo, GetDispatchInfo, PerDispatchClass,
132 PostDispatchInfo,
133 },
134 ensure, impl_ensure_origin_with_arg_ignoring_arg,
135 migrations::MultiStepMigrator,
136 pezpallet_prelude::Pays,
137 storage::{self, StorageStreamIter},
138 traits::{
139 ConstU32, Contains, EnsureOrigin, EnsureOriginWithArg, Get, HandleLifetime,
140 OnKilledAccount, OnNewAccount, OnRuntimeUpgrade, OriginTrait, PalletInfo, SortedMembers,
141 StoredMap, TypedGet,
142 },
143 Parameter,
144};
145use pezsp_core::storage::well_known_keys;
146use pezsp_runtime::{
147 traits::{DispatchInfoOf, PostDispatchInfoOf},
148 transaction_validity::TransactionValidityError,
149};
150use pezsp_weights::{RuntimeDbWeight, Weight, WeightMeter};
151use scale_info::TypeInfo;
152
153#[cfg(any(feature = "std", test))]
154use pezsp_io::TestExternalities;
155
156pub mod limits;
157#[cfg(test)]
158pub(crate) mod mock;
159
160pub mod offchain;
161
162mod extensions;
163#[cfg(feature = "std")]
164pub mod mocking;
165#[cfg(test)]
166mod tests;
167pub mod weights;
168
169pub mod migrations;
170
171pub use extensions::{
172 authorize_call::AuthorizeCall,
173 check_genesis::CheckGenesis,
174 check_mortality::CheckMortality,
175 check_non_zero_sender::CheckNonZeroSender,
176 check_nonce::{CheckNonce, ValidNonceInfo},
177 check_spec_version::CheckSpecVersion,
178 check_tx_version::CheckTxVersion,
179 check_weight::CheckWeight,
180 weight_reclaim::WeightReclaim,
181 weights::BizinikiwiWeight as BizinikiwiExtensionsWeight,
182 WeightInfo as ExtensionsWeightInfo,
183};
184pub use extensions::check_mortality::CheckMortality as CheckEra;
186pub use pezframe_support::dispatch::RawOrigin;
187use pezframe_support::traits::{Authorize, PostInherents, PostTransactions, PreInherents};
188use pezsp_core::storage::StateVersion;
189pub use weights::WeightInfo;
190
191const LOG_TARGET: &str = "runtime::system";
192
193pub fn extrinsics_root<H: Hash, E: codec::Encode>(
198 extrinsics: &[E],
199 state_version: StateVersion,
200) -> H::Output {
201 extrinsics_data_root::<H>(extrinsics.iter().map(codec::Encode::encode).collect(), state_version)
202}
203
204pub fn extrinsics_data_root<H: Hash>(xts: Vec<Vec<u8>>, state_version: StateVersion) -> H::Output {
209 H::ordered_trie_root(xts, state_version)
210}
211
212pub type ConsumedWeight = PerDispatchClass<Weight>;
214
215pub use pezpallet::*;
216
217pub trait SetCode<T: Config> {
219 fn set_code(code: Vec<u8>) -> DispatchResult;
221}
222
223impl<T: Config> SetCode<T> for () {
224 fn set_code(code: Vec<u8>) -> DispatchResult {
225 <Pezpallet<T>>::update_code_in_storage(&code);
226 Ok(())
227 }
228}
229
230pub trait ConsumerLimits {
232 fn max_consumers() -> RefCount;
234 fn max_overflow() -> RefCount;
240}
241
242impl<const Z: u32> ConsumerLimits for ConstU32<Z> {
243 fn max_consumers() -> RefCount {
244 Z
245 }
246 fn max_overflow() -> RefCount {
247 Z
248 }
249}
250
251impl<MaxNormal: Get<u32>, MaxOverflow: Get<u32>> ConsumerLimits for (MaxNormal, MaxOverflow) {
252 fn max_consumers() -> RefCount {
253 MaxNormal::get()
254 }
255 fn max_overflow() -> RefCount {
256 MaxOverflow::get()
257 }
258}
259
260#[derive(Decode, Encode, Default, PartialEq, Eq, MaxEncodedLen, TypeInfo)]
263#[scale_info(skip_type_params(T))]
264pub struct CodeUpgradeAuthorization<T>
265where
266 T: Config,
267{
268 code_hash: T::Hash,
270 check_version: bool,
272}
273
274#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
275impl<T> CodeUpgradeAuthorization<T>
276where
277 T: Config,
278{
279 pub fn code_hash(&self) -> &T::Hash {
280 &self.code_hash
281 }
282}
283
284#[derive(
288 Clone,
289 Copy,
290 Eq,
291 PartialEq,
292 Default,
293 RuntimeDebug,
294 Encode,
295 Decode,
296 DecodeWithMemTracking,
297 TypeInfo,
298)]
299pub struct DispatchEventInfo {
300 pub weight: Weight,
302 pub class: DispatchClass,
304 pub pays_fee: Pays,
306}
307
308#[pezframe_support::pezpallet]
309pub mod pezpallet {
310 use crate::{self as pezframe_system, pezpallet_prelude::*, *};
311 use codec::HasCompact;
312 use pezframe_support::pezpallet_prelude::*;
313
314 pub mod config_preludes {
316 use super::{inject_runtime_type, DefaultConfig};
317 use pezframe_support::{derive_impl, traits::Get};
318
319 pub struct TestBlockHashCount<C: Get<u32>>(core::marker::PhantomData<C>);
325 impl<I: From<u32>, C: Get<u32>> Get<I> for TestBlockHashCount<C> {
326 fn get() -> I {
327 C::get().into()
328 }
329 }
330
331 pub struct TestDefaultConfig;
338
339 #[pezframe_support::register_default_impl(TestDefaultConfig)]
340 impl DefaultConfig for TestDefaultConfig {
341 type Nonce = u32;
342 type Hash = pezsp_core::hash::H256;
343 type Hashing = pezsp_runtime::traits::BlakeTwo256;
344 type AccountId = u64;
345 type Lookup = pezsp_runtime::traits::IdentityLookup<Self::AccountId>;
346 type MaxConsumers = pezframe_support::traits::ConstU32<16>;
347 type AccountData = ();
348 type OnNewAccount = ();
349 type OnKilledAccount = ();
350 type SystemWeightInfo = ();
351 type ExtensionsWeightInfo = ();
352 type SS58Prefix = ();
353 type Version = ();
354 type BlockWeights = ();
355 type BlockLength = ();
356 type DbWeight = ();
357 #[inject_runtime_type]
358 type RuntimeEvent = ();
359 #[inject_runtime_type]
360 type RuntimeOrigin = ();
361 #[inject_runtime_type]
362 type RuntimeCall = ();
363 #[inject_runtime_type]
364 type PalletInfo = ();
365 #[inject_runtime_type]
366 type RuntimeTask = ();
367 type BaseCallFilter = pezframe_support::traits::Everything;
368 type BlockHashCount = TestBlockHashCount<pezframe_support::traits::ConstU32<10>>;
369 type OnSetCode = ();
370 type SingleBlockMigrations = ();
371 type MultiBlockMigrator = ();
372 type PreInherents = ();
373 type PostInherents = ();
374 type PostTransactions = ();
375 }
376
377 pub struct SolochainDefaultConfig;
391
392 #[pezframe_support::register_default_impl(SolochainDefaultConfig)]
393 impl DefaultConfig for SolochainDefaultConfig {
394 type Nonce = u32;
396
397 type Hash = pezsp_core::hash::H256;
399
400 type Hashing = pezsp_runtime::traits::BlakeTwo256;
402
403 type AccountId = pezsp_runtime::AccountId32;
405
406 type Lookup = pezsp_runtime::traits::AccountIdLookup<Self::AccountId, ()>;
408
409 type MaxConsumers = pezframe_support::traits::ConstU32<128>;
411
412 type AccountData = ();
414
415 type OnNewAccount = ();
417
418 type OnKilledAccount = ();
420
421 type SystemWeightInfo = ();
423
424 type ExtensionsWeightInfo = ();
426
427 type SS58Prefix = ();
429
430 type Version = ();
432
433 type BlockWeights = ();
435
436 type BlockLength = ();
438
439 type DbWeight = ();
441
442 #[inject_runtime_type]
444 type RuntimeEvent = ();
445
446 #[inject_runtime_type]
448 type RuntimeOrigin = ();
449
450 #[inject_runtime_type]
453 type RuntimeCall = ();
454
455 #[inject_runtime_type]
457 type RuntimeTask = ();
458
459 #[inject_runtime_type]
461 type PalletInfo = ();
462
463 type BaseCallFilter = pezframe_support::traits::Everything;
465
466 type BlockHashCount = TestBlockHashCount<pezframe_support::traits::ConstU32<256>>;
469
470 type OnSetCode = ();
472 type SingleBlockMigrations = ();
473 type MultiBlockMigrator = ();
474 type PreInherents = ();
475 type PostInherents = ();
476 type PostTransactions = ();
477 }
478
479 pub struct RelayChainDefaultConfig;
481
482 #[derive_impl(SolochainDefaultConfig as DefaultConfig, no_aggregated_types)]
484 #[pezframe_support::register_default_impl(RelayChainDefaultConfig)]
485 impl DefaultConfig for RelayChainDefaultConfig {}
486
487 pub struct TeyrchainDefaultConfig;
489
490 #[derive_impl(SolochainDefaultConfig as DefaultConfig, no_aggregated_types)]
492 #[pezframe_support::register_default_impl(TeyrchainDefaultConfig)]
493 impl DefaultConfig for TeyrchainDefaultConfig {}
494 }
495
496 #[pezpallet::config(with_default, pezframe_system_config)]
498 #[pezpallet::disable_pezframe_system_supertrait_check]
499 pub trait Config: 'static + Eq + Clone {
500 #[pezpallet::no_default_bounds]
502 type RuntimeEvent: Parameter
503 + Member
504 + From<Event<Self>>
505 + Debug
506 + IsType<<Self as pezframe_system::Config>::RuntimeEvent>;
507
508 #[pezpallet::no_default_bounds]
519 type BaseCallFilter: Contains<Self::RuntimeCall>;
520
521 #[pezpallet::constant]
523 type BlockWeights: Get<limits::BlockWeights>;
524
525 #[pezpallet::constant]
527 type BlockLength: Get<limits::BlockLength>;
528
529 #[pezpallet::no_default_bounds]
531 type RuntimeOrigin: Into<Result<RawOrigin<Self::AccountId>, Self::RuntimeOrigin>>
532 + From<RawOrigin<Self::AccountId>>
533 + Clone
534 + OriginTrait<Call = Self::RuntimeCall, AccountId = Self::AccountId>
535 + AsTransactionAuthorizedOrigin;
536
537 #[docify::export(system_runtime_call)]
538 #[pezpallet::no_default_bounds]
540 type RuntimeCall: Parameter
541 + Dispatchable<RuntimeOrigin = Self::RuntimeOrigin>
542 + Debug
543 + GetDispatchInfo
544 + From<Call<Self>>
545 + Authorize;
546
547 #[pezpallet::no_default_bounds]
549 type RuntimeTask: Task;
550
551 type Nonce: Parameter
553 + HasCompact<Type: DecodeWithMemTracking>
554 + Member
555 + MaybeSerializeDeserialize
556 + Debug
557 + Default
558 + MaybeDisplay
559 + AtLeast32Bit
560 + Copy
561 + MaxEncodedLen;
562
563 type Hash: Parameter
565 + Member
566 + MaybeSerializeDeserialize
567 + Debug
568 + MaybeDisplay
569 + SimpleBitOps
570 + Ord
571 + Default
572 + Copy
573 + CheckEqual
574 + core::hash::Hash
575 + AsRef<[u8]>
576 + AsMut<[u8]>
577 + MaxEncodedLen;
578
579 type Hashing: Hash<Output = Self::Hash> + TypeInfo;
581
582 type AccountId: Parameter
584 + Member
585 + MaybeSerializeDeserialize
586 + Debug
587 + MaybeDisplay
588 + Ord
589 + MaxEncodedLen;
590
591 type Lookup: StaticLookup<Target = Self::AccountId>;
598
599 #[pezpallet::no_default]
602 type Block: Parameter + Member + traits::Block<Hash = Self::Hash>;
603
604 #[pezpallet::constant]
606 #[pezpallet::no_default_bounds]
607 type BlockHashCount: Get<BlockNumberFor<Self>>;
608
609 #[pezpallet::constant]
611 type DbWeight: Get<RuntimeDbWeight>;
612
613 #[pezpallet::constant]
615 type Version: Get<RuntimeVersion>;
616
617 #[pezpallet::no_default_bounds]
624 type PalletInfo: PalletInfo;
625
626 type AccountData: Member + FullCodec + Clone + Default + TypeInfo + MaxEncodedLen;
629
630 type OnNewAccount: OnNewAccount<Self::AccountId>;
632
633 type OnKilledAccount: OnKilledAccount<Self::AccountId>;
637
638 type SystemWeightInfo: WeightInfo;
640
641 type ExtensionsWeightInfo: extensions::WeightInfo;
643
644 #[pezpallet::constant]
650 type SS58Prefix: Get<u16>;
651
652 #[pezpallet::no_default_bounds]
660 type OnSetCode: SetCode<Self>;
661
662 type MaxConsumers: ConsumerLimits;
664
665 type SingleBlockMigrations: OnRuntimeUpgrade;
672
673 type MultiBlockMigrator: MultiStepMigrator;
678
679 type PreInherents: PreInherents;
683
684 type PostInherents: PostInherents;
688
689 type PostTransactions: PostTransactions;
693 }
694
695 #[pezpallet::pezpallet]
696 pub struct Pezpallet<T>(_);
697
698 #[pezpallet::hooks]
699 impl<T: Config> Hooks<BlockNumberFor<T>> for Pezpallet<T> {
700 #[cfg(feature = "std")]
701 fn integrity_test() {
702 T::BlockWeights::get().validate().expect("The weights are invalid.");
703 }
704 }
705
706 #[pezpallet::call(weight = <T as Config>::SystemWeightInfo)]
707 impl<T: Config> Pezpallet<T> {
708 #[pezpallet::call_index(0)]
712 #[pezpallet::weight(T::SystemWeightInfo::remark(remark.len() as u32))]
713 pub fn remark(_origin: OriginFor<T>, remark: Vec<u8>) -> DispatchResultWithPostInfo {
714 let _ = remark; Ok(().into())
716 }
717
718 #[pezpallet::call_index(1)]
720 #[pezpallet::weight((T::SystemWeightInfo::set_heap_pages(), DispatchClass::Operational))]
721 pub fn set_heap_pages(origin: OriginFor<T>, pages: u64) -> DispatchResultWithPostInfo {
722 ensure_root(origin)?;
723 storage::unhashed::put_raw(well_known_keys::HEAP_PAGES, &pages.encode());
724 Self::deposit_log(generic::DigestItem::RuntimeEnvironmentUpdated);
725 Ok(().into())
726 }
727
728 #[pezpallet::call_index(2)]
730 #[pezpallet::weight((T::SystemWeightInfo::set_code(), DispatchClass::Operational))]
731 pub fn set_code(origin: OriginFor<T>, code: Vec<u8>) -> DispatchResultWithPostInfo {
732 ensure_root(origin)?;
733 Self::can_set_code(&code, true).into_result()?;
734 T::OnSetCode::set_code(code)?;
735 Ok(Some(T::BlockWeights::get().max_block).into())
737 }
738
739 #[pezpallet::call_index(3)]
744 #[pezpallet::weight((T::SystemWeightInfo::set_code(), DispatchClass::Operational))]
745 pub fn set_code_without_checks(
746 origin: OriginFor<T>,
747 code: Vec<u8>,
748 ) -> DispatchResultWithPostInfo {
749 ensure_root(origin)?;
750 Self::can_set_code(&code, false).into_result()?;
751 T::OnSetCode::set_code(code)?;
752 Ok(Some(T::BlockWeights::get().max_block).into())
753 }
754
755 #[pezpallet::call_index(4)]
757 #[pezpallet::weight((
758 T::SystemWeightInfo::set_storage(items.len() as u32),
759 DispatchClass::Operational,
760 ))]
761 pub fn set_storage(
762 origin: OriginFor<T>,
763 items: Vec<KeyValue>,
764 ) -> DispatchResultWithPostInfo {
765 ensure_root(origin)?;
766 for i in &items {
767 storage::unhashed::put_raw(&i.0, &i.1);
768 }
769 Ok(().into())
770 }
771
772 #[pezpallet::call_index(5)]
774 #[pezpallet::weight((
775 T::SystemWeightInfo::kill_storage(keys.len() as u32),
776 DispatchClass::Operational,
777 ))]
778 pub fn kill_storage(origin: OriginFor<T>, keys: Vec<Key>) -> DispatchResultWithPostInfo {
779 ensure_root(origin)?;
780 for key in &keys {
781 storage::unhashed::kill(key);
782 }
783 Ok(().into())
784 }
785
786 #[pezpallet::call_index(6)]
791 #[pezpallet::weight((
792 T::SystemWeightInfo::kill_prefix(pez_subkeys.saturating_add(1)),
793 DispatchClass::Operational,
794 ))]
795 pub fn kill_prefix(
796 origin: OriginFor<T>,
797 prefix: Key,
798 pez_subkeys: u32,
799 ) -> DispatchResultWithPostInfo {
800 ensure_root(origin)?;
801 let _ = storage::unhashed::clear_prefix(&prefix, Some(pez_subkeys), None);
802 Ok(().into())
803 }
804
805 #[pezpallet::call_index(7)]
807 #[pezpallet::weight(T::SystemWeightInfo::remark_with_event(remark.len() as u32))]
808 pub fn remark_with_event(
809 origin: OriginFor<T>,
810 remark: Vec<u8>,
811 ) -> DispatchResultWithPostInfo {
812 let who = ensure_signed(origin)?;
813 let hash = T::Hashing::hash(&remark[..]);
814 Self::deposit_event(Event::Remarked { sender: who, hash });
815 Ok(().into())
816 }
817
818 #[cfg(feature = "experimental")]
819 #[pezpallet::call_index(8)]
820 #[pezpallet::weight(task.weight())]
821 pub fn do_task(_origin: OriginFor<T>, task: T::RuntimeTask) -> DispatchResultWithPostInfo {
822 if !task.is_valid() {
823 return Err(Error::<T>::InvalidTask.into());
824 }
825
826 Self::deposit_event(Event::TaskStarted { task: task.clone() });
827 if let Err(err) = task.run() {
828 Self::deposit_event(Event::TaskFailed { task, err });
829 return Err(Error::<T>::FailedTask.into());
830 }
831
832 Self::deposit_event(Event::TaskCompleted { task });
834
835 Ok(().into())
837 }
838
839 #[pezpallet::call_index(9)]
844 #[pezpallet::weight((T::SystemWeightInfo::authorize_upgrade(), DispatchClass::Operational))]
845 pub fn authorize_upgrade(origin: OriginFor<T>, code_hash: T::Hash) -> DispatchResult {
846 ensure_root(origin)?;
847 Self::do_authorize_upgrade(code_hash, true);
848 Ok(())
849 }
850
851 #[pezpallet::call_index(10)]
860 #[pezpallet::weight((T::SystemWeightInfo::authorize_upgrade(), DispatchClass::Operational))]
861 pub fn authorize_upgrade_without_checks(
862 origin: OriginFor<T>,
863 code_hash: T::Hash,
864 ) -> DispatchResult {
865 ensure_root(origin)?;
866 Self::do_authorize_upgrade(code_hash, false);
867 Ok(())
868 }
869
870 #[pezpallet::call_index(11)]
880 #[pezpallet::weight((T::SystemWeightInfo::apply_authorized_upgrade(), DispatchClass::Operational))]
881 pub fn apply_authorized_upgrade(
882 _: OriginFor<T>,
883 code: Vec<u8>,
884 ) -> DispatchResultWithPostInfo {
885 let res = Self::validate_code_is_authorized(&code)?;
886 AuthorizedUpgrade::<T>::kill();
887
888 match Self::can_set_code(&code, res.check_version) {
889 CanSetCodeResult::Ok => {},
890 CanSetCodeResult::MultiBlockMigrationsOngoing => {
891 return Err(Error::<T>::MultiBlockMigrationsOngoing.into())
892 },
893 CanSetCodeResult::InvalidVersion(error) => {
894 Self::deposit_event(Event::RejectedInvalidAuthorizedUpgrade {
896 code_hash: res.code_hash,
897 error: error.into(),
898 });
899
900 return Ok(Pays::No.into());
902 },
903 };
904 T::OnSetCode::set_code(code)?;
905
906 Ok(PostDispatchInfo {
907 actual_weight: Some(T::BlockWeights::get().max_block),
909 pays_fee: Pays::No,
911 })
912 }
913 }
914
915 #[pezpallet::event]
917 pub enum Event<T: Config> {
918 ExtrinsicSuccess { dispatch_info: DispatchEventInfo },
920 ExtrinsicFailed { dispatch_error: DispatchError, dispatch_info: DispatchEventInfo },
922 CodeUpdated,
924 NewAccount { account: T::AccountId },
926 KilledAccount { account: T::AccountId },
928 Remarked { sender: T::AccountId, hash: T::Hash },
930 #[cfg(feature = "experimental")]
931 TaskStarted { task: T::RuntimeTask },
933 #[cfg(feature = "experimental")]
934 TaskCompleted { task: T::RuntimeTask },
936 #[cfg(feature = "experimental")]
937 TaskFailed { task: T::RuntimeTask, err: DispatchError },
939 UpgradeAuthorized { code_hash: T::Hash, check_version: bool },
941 RejectedInvalidAuthorizedUpgrade { code_hash: T::Hash, error: DispatchError },
943 }
944
945 #[pezpallet::error]
947 pub enum Error<T> {
948 InvalidSpecName,
951 SpecVersionNeedsToIncrease,
954 FailedToExtractRuntimeVersion,
958 NonDefaultComposite,
960 NonZeroRefCount,
962 CallFiltered,
964 MultiBlockMigrationsOngoing,
966 #[cfg(feature = "experimental")]
967 InvalidTask,
969 #[cfg(feature = "experimental")]
970 FailedTask,
972 NothingAuthorized,
974 Unauthorized,
976 }
977
978 #[pezpallet::origin]
980 pub type Origin<T> = RawOrigin<<T as Config>::AccountId>;
981
982 #[pezpallet::storage]
984 #[pezpallet::getter(fn account)]
985 pub type Account<T: Config> = StorageMap<
986 _,
987 Blake2_128Concat,
988 T::AccountId,
989 AccountInfo<T::Nonce, T::AccountData>,
990 ValueQuery,
991 >;
992
993 #[pezpallet::storage]
995 #[pezpallet::whitelist_storage]
996 pub(super) type ExtrinsicCount<T: Config> = StorageValue<_, u32>;
997
998 #[pezpallet::storage]
1000 #[pezpallet::whitelist_storage]
1001 pub type InherentsApplied<T: Config> = StorageValue<_, bool, ValueQuery>;
1002
1003 #[pezpallet::storage]
1005 #[pezpallet::whitelist_storage]
1006 #[pezpallet::getter(fn block_weight)]
1007 pub type BlockWeight<T: Config> = StorageValue<_, ConsumedWeight, ValueQuery>;
1008
1009 #[pezpallet::storage]
1011 #[pezpallet::whitelist_storage]
1012 pub type AllExtrinsicsLen<T: Config> = StorageValue<_, u32>;
1013
1014 #[pezpallet::storage]
1016 #[pezpallet::getter(fn block_hash)]
1017 pub type BlockHash<T: Config> =
1018 StorageMap<_, Twox64Concat, BlockNumberFor<T>, T::Hash, ValueQuery>;
1019
1020 #[pezpallet::storage]
1022 #[pezpallet::getter(fn extrinsic_data)]
1023 #[pezpallet::unbounded]
1024 pub(super) type ExtrinsicData<T: Config> =
1025 StorageMap<_, Twox64Concat, u32, Vec<u8>, ValueQuery>;
1026
1027 #[pezpallet::storage]
1029 #[pezpallet::whitelist_storage]
1030 #[pezpallet::getter(fn block_number)]
1031 pub(super) type Number<T: Config> = StorageValue<_, BlockNumberFor<T>, ValueQuery>;
1032
1033 #[pezpallet::storage]
1035 #[pezpallet::getter(fn parent_hash)]
1036 pub(super) type ParentHash<T: Config> = StorageValue<_, T::Hash, ValueQuery>;
1037
1038 #[pezpallet::storage]
1040 #[pezpallet::whitelist_storage]
1041 #[pezpallet::unbounded]
1042 #[pezpallet::getter(fn digest)]
1043 pub(super) type Digest<T: Config> = StorageValue<_, generic::Digest, ValueQuery>;
1044
1045 #[pezpallet::storage]
1053 #[pezpallet::whitelist_storage]
1054 #[pezpallet::disable_try_decode_storage]
1055 #[pezpallet::unbounded]
1056 pub(super) type Events<T: Config> =
1057 StorageValue<_, Vec<Box<EventRecord<T::RuntimeEvent, T::Hash>>>, ValueQuery>;
1058
1059 #[pezpallet::storage]
1061 #[pezpallet::whitelist_storage]
1062 #[pezpallet::getter(fn event_count)]
1063 pub(super) type EventCount<T: Config> = StorageValue<_, EventIndex, ValueQuery>;
1064
1065 #[pezpallet::storage]
1076 #[pezpallet::unbounded]
1077 #[pezpallet::getter(fn event_topics)]
1078 pub(super) type EventTopics<T: Config> =
1079 StorageMap<_, Blake2_128Concat, T::Hash, Vec<(BlockNumberFor<T>, EventIndex)>, ValueQuery>;
1080
1081 #[pezpallet::storage]
1083 #[pezpallet::unbounded]
1084 pub type LastRuntimeUpgrade<T: Config> = StorageValue<_, LastRuntimeUpgradeInfo>;
1085
1086 #[pezpallet::storage]
1088 pub(super) type UpgradedToU32RefCount<T: Config> = StorageValue<_, bool, ValueQuery>;
1089
1090 #[pezpallet::storage]
1093 pub(super) type UpgradedToTripleRefCount<T: Config> = StorageValue<_, bool, ValueQuery>;
1094
1095 #[pezpallet::storage]
1097 #[pezpallet::whitelist_storage]
1098 pub(super) type ExecutionPhase<T: Config> = StorageValue<_, Phase>;
1099
1100 #[pezpallet::storage]
1102 #[pezpallet::getter(fn authorized_upgrade)]
1103 pub(super) type AuthorizedUpgrade<T: Config> =
1104 StorageValue<_, CodeUpgradeAuthorization<T>, OptionQuery>;
1105
1106 #[pezpallet::storage]
1114 #[pezpallet::whitelist_storage]
1115 pub type ExtrinsicWeightReclaimed<T: Config> = StorageValue<_, Weight, ValueQuery>;
1116
1117 #[derive(pezframe_support::DefaultNoBound)]
1118 #[pezpallet::genesis_config]
1119 pub struct GenesisConfig<T: Config> {
1120 #[serde(skip)]
1121 pub _config: core::marker::PhantomData<T>,
1122 }
1123
1124 #[pezpallet::genesis_build]
1125 impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
1126 fn build(&self) {
1127 <BlockHash<T>>::insert::<_, T::Hash>(BlockNumberFor::<T>::zero(), hash69());
1128 <ParentHash<T>>::put::<T::Hash>(hash69());
1129 <LastRuntimeUpgrade<T>>::put(LastRuntimeUpgradeInfo::from(T::Version::get()));
1130 <UpgradedToU32RefCount<T>>::put(true);
1131 <UpgradedToTripleRefCount<T>>::put(true);
1132
1133 pezsp_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode());
1134 }
1135 }
1136
1137 #[pezpallet::validate_unsigned]
1138 impl<T: Config> pezsp_runtime::traits::ValidateUnsigned for Pezpallet<T> {
1139 type Call = Call<T>;
1140 fn validate_unsigned(source: TransactionSource, call: &Self::Call) -> TransactionValidity {
1141 if let Call::apply_authorized_upgrade { ref code } = call {
1142 if let Ok(res) = Self::validate_code_is_authorized(&code[..]) {
1143 if Self::can_set_code(&code, false).is_ok() {
1144 return Ok(ValidTransaction {
1145 priority: u64::max_value(),
1146 requires: Vec::new(),
1147 provides: vec![res.code_hash.encode()],
1148 longevity: TransactionLongevity::max_value(),
1149 propagate: true,
1150 });
1151 }
1152 }
1153 }
1154
1155 #[cfg(feature = "experimental")]
1156 if let Call::do_task { ref task } = call {
1157 if source == TransactionSource::InBlock || source == TransactionSource::Local {
1165 if task.is_valid() {
1166 return Ok(ValidTransaction {
1167 priority: u64::max_value(),
1168 requires: Vec::new(),
1169 provides: vec![T::Hashing::hash_of(&task.encode()).as_ref().to_vec()],
1170 longevity: TransactionLongevity::max_value(),
1171 propagate: false,
1172 });
1173 }
1174 }
1175 }
1176
1177 #[cfg(not(feature = "experimental"))]
1178 let _ = source;
1179
1180 Err(InvalidTransaction::Call.into())
1181 }
1182 }
1183}
1184
1185pub type Key = Vec<u8>;
1186pub type KeyValue = (Vec<u8>, Vec<u8>);
1187
1188#[derive(Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen)]
1190#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone))]
1191pub enum Phase {
1192 ApplyExtrinsic(u32),
1194 Finalization,
1196 Initialization,
1198}
1199
1200impl Default for Phase {
1201 fn default() -> Self {
1202 Self::Initialization
1203 }
1204}
1205
1206#[derive(Encode, Decode, RuntimeDebug, TypeInfo)]
1208#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone))]
1209pub struct EventRecord<E: Parameter + Member, T> {
1210 pub phase: Phase,
1212 pub event: E,
1214 pub topics: Vec<T>,
1216}
1217
1218fn hash69<T: AsMut<[u8]> + Default>() -> T {
1221 let mut h = T::default();
1222 h.as_mut().iter_mut().for_each(|byte| *byte = 69);
1223 h
1224}
1225
1226type EventIndex = u32;
1231
1232pub type RefCount = u32;
1234
1235#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)]
1237pub struct AccountInfo<Nonce, AccountData> {
1238 pub nonce: Nonce,
1240 pub consumers: RefCount,
1243 pub providers: RefCount,
1246 pub sufficients: RefCount,
1249 pub data: AccountData,
1252}
1253
1254#[derive(RuntimeDebug, Encode, Decode, TypeInfo)]
1257#[cfg_attr(feature = "std", derive(PartialEq))]
1258pub struct LastRuntimeUpgradeInfo {
1259 pub spec_version: codec::Compact<u32>,
1260 pub spec_name: Cow<'static, str>,
1261}
1262
1263impl LastRuntimeUpgradeInfo {
1264 pub fn was_upgraded(&self, current: &RuntimeVersion) -> bool {
1268 current.spec_version > self.spec_version.0 || current.spec_name != self.spec_name
1269 }
1270}
1271
1272impl From<RuntimeVersion> for LastRuntimeUpgradeInfo {
1273 fn from(version: RuntimeVersion) -> Self {
1274 Self { spec_version: version.spec_version.into(), spec_name: version.spec_name }
1275 }
1276}
1277
1278pub struct EnsureRoot<AccountId>(core::marker::PhantomData<AccountId>);
1280impl<O: OriginTrait, AccountId> EnsureOrigin<O> for EnsureRoot<AccountId> {
1281 type Success = ();
1282 fn try_origin(o: O) -> Result<Self::Success, O> {
1283 match o.as_system_ref() {
1284 Some(RawOrigin::Root) => Ok(()),
1285 _ => Err(o),
1286 }
1287 }
1288
1289 #[cfg(feature = "runtime-benchmarks")]
1290 fn try_successful_origin() -> Result<O, ()> {
1291 Ok(O::root())
1292 }
1293}
1294
1295impl_ensure_origin_with_arg_ignoring_arg! {
1296 impl< { O: .., AccountId: Decode, T } >
1297 EnsureOriginWithArg<O, T> for EnsureRoot<AccountId>
1298 {}
1299}
1300
1301pub struct EnsureRootWithSuccess<AccountId, Success>(
1303 core::marker::PhantomData<(AccountId, Success)>,
1304);
1305impl<O: OriginTrait, AccountId, Success: TypedGet> EnsureOrigin<O>
1306 for EnsureRootWithSuccess<AccountId, Success>
1307{
1308 type Success = Success::Type;
1309 fn try_origin(o: O) -> Result<Self::Success, O> {
1310 match o.as_system_ref() {
1311 Some(RawOrigin::Root) => Ok(Success::get()),
1312 _ => Err(o),
1313 }
1314 }
1315
1316 #[cfg(feature = "runtime-benchmarks")]
1317 fn try_successful_origin() -> Result<O, ()> {
1318 Ok(O::root())
1319 }
1320}
1321
1322impl_ensure_origin_with_arg_ignoring_arg! {
1323 impl< { O: .., AccountId: Decode, Success: TypedGet, T } >
1324 EnsureOriginWithArg<O, T> for EnsureRootWithSuccess<AccountId, Success>
1325 {}
1326}
1327
1328pub struct EnsureWithSuccess<Ensure, AccountId, Success>(
1330 core::marker::PhantomData<(Ensure, AccountId, Success)>,
1331);
1332
1333impl<O: OriginTrait, Ensure: EnsureOrigin<O>, AccountId, Success: TypedGet> EnsureOrigin<O>
1334 for EnsureWithSuccess<Ensure, AccountId, Success>
1335{
1336 type Success = Success::Type;
1337
1338 fn try_origin(o: O) -> Result<Self::Success, O> {
1339 Ensure::try_origin(o).map(|_| Success::get())
1340 }
1341
1342 #[cfg(feature = "runtime-benchmarks")]
1343 fn try_successful_origin() -> Result<O, ()> {
1344 Ensure::try_successful_origin()
1345 }
1346}
1347
1348pub struct EnsureSigned<AccountId>(core::marker::PhantomData<AccountId>);
1350impl<O: OriginTrait<AccountId = AccountId>, AccountId: Decode + Clone> EnsureOrigin<O>
1351 for EnsureSigned<AccountId>
1352{
1353 type Success = AccountId;
1354 fn try_origin(o: O) -> Result<Self::Success, O> {
1355 match o.as_system_ref() {
1356 Some(RawOrigin::Signed(who)) => Ok(who.clone()),
1357 _ => Err(o),
1358 }
1359 }
1360
1361 #[cfg(feature = "runtime-benchmarks")]
1362 fn try_successful_origin() -> Result<O, ()> {
1363 let zero_account_id =
1364 AccountId::decode(&mut TrailingZeroInput::zeroes()).map_err(|_| ())?;
1365 Ok(O::signed(zero_account_id))
1366 }
1367}
1368
1369impl_ensure_origin_with_arg_ignoring_arg! {
1370 impl< { O: OriginTrait<AccountId = AccountId>, AccountId: Decode + Clone, T } >
1371 EnsureOriginWithArg<O, T> for EnsureSigned<AccountId>
1372 {}
1373}
1374
1375pub struct EnsureSignedBy<Who, AccountId>(core::marker::PhantomData<(Who, AccountId)>);
1377impl<
1378 O: OriginTrait<AccountId = AccountId>,
1379 Who: SortedMembers<AccountId>,
1380 AccountId: PartialEq + Clone + Ord + Decode,
1381 > EnsureOrigin<O> for EnsureSignedBy<Who, AccountId>
1382{
1383 type Success = AccountId;
1384 fn try_origin(o: O) -> Result<Self::Success, O> {
1385 match o.as_system_ref() {
1386 Some(RawOrigin::Signed(ref who)) if Who::contains(who) => Ok(who.clone()),
1387 _ => Err(o),
1388 }
1389 }
1390
1391 #[cfg(feature = "runtime-benchmarks")]
1392 fn try_successful_origin() -> Result<O, ()> {
1393 let first_member = match Who::sorted_members().first() {
1394 Some(account) => account.clone(),
1395 None => AccountId::decode(&mut TrailingZeroInput::zeroes()).map_err(|_| ())?,
1396 };
1397 Ok(O::signed(first_member))
1398 }
1399}
1400
1401impl_ensure_origin_with_arg_ignoring_arg! {
1402 impl< { O: OriginTrait<AccountId = AccountId>, Who: SortedMembers<AccountId>, AccountId: PartialEq + Clone + Ord + Decode, T } >
1403 EnsureOriginWithArg<O, T> for EnsureSignedBy<Who, AccountId>
1404 {}
1405}
1406
1407pub struct EnsureNone<AccountId>(core::marker::PhantomData<AccountId>);
1409impl<O: OriginTrait<AccountId = AccountId>, AccountId> EnsureOrigin<O> for EnsureNone<AccountId> {
1410 type Success = ();
1411 fn try_origin(o: O) -> Result<Self::Success, O> {
1412 match o.as_system_ref() {
1413 Some(RawOrigin::None) => Ok(()),
1414 _ => Err(o),
1415 }
1416 }
1417
1418 #[cfg(feature = "runtime-benchmarks")]
1419 fn try_successful_origin() -> Result<O, ()> {
1420 Ok(O::none())
1421 }
1422}
1423
1424impl_ensure_origin_with_arg_ignoring_arg! {
1425 impl< { O: OriginTrait<AccountId = AccountId>, AccountId, T } >
1426 EnsureOriginWithArg<O, T> for EnsureNone<AccountId>
1427 {}
1428}
1429
1430pub struct EnsureNever<Success>(core::marker::PhantomData<Success>);
1432impl<O, Success> EnsureOrigin<O> for EnsureNever<Success> {
1433 type Success = Success;
1434 fn try_origin(o: O) -> Result<Self::Success, O> {
1435 Err(o)
1436 }
1437
1438 #[cfg(feature = "runtime-benchmarks")]
1439 fn try_successful_origin() -> Result<O, ()> {
1440 Err(())
1441 }
1442}
1443
1444impl_ensure_origin_with_arg_ignoring_arg! {
1445 impl< { O, Success, T } >
1446 EnsureOriginWithArg<O, T> for EnsureNever<Success>
1447 {}
1448}
1449
1450#[docify::export]
1451pub fn ensure_signed<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<AccountId, BadOrigin>
1454where
1455 OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1456{
1457 match o.into() {
1458 Ok(RawOrigin::Signed(t)) => Ok(t),
1459 _ => Err(BadOrigin),
1460 }
1461}
1462
1463pub fn ensure_signed_or_root<OuterOrigin, AccountId>(
1467 o: OuterOrigin,
1468) -> Result<Option<AccountId>, BadOrigin>
1469where
1470 OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1471{
1472 match o.into() {
1473 Ok(RawOrigin::Root) => Ok(None),
1474 Ok(RawOrigin::Signed(t)) => Ok(Some(t)),
1475 _ => Err(BadOrigin),
1476 }
1477}
1478
1479pub fn ensure_root<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), BadOrigin>
1481where
1482 OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1483{
1484 match o.into() {
1485 Ok(RawOrigin::Root) => Ok(()),
1486 _ => Err(BadOrigin),
1487 }
1488}
1489
1490pub fn ensure_none<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), BadOrigin>
1492where
1493 OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1494{
1495 match o.into() {
1496 Ok(RawOrigin::None) => Ok(()),
1497 _ => Err(BadOrigin),
1498 }
1499}
1500
1501pub fn ensure_authorized<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), BadOrigin>
1504where
1505 OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1506{
1507 match o.into() {
1508 Ok(RawOrigin::Authorized) => Ok(()),
1509 _ => Err(BadOrigin),
1510 }
1511}
1512
1513#[derive(RuntimeDebug)]
1515pub enum RefStatus {
1516 Referenced,
1517 Unreferenced,
1518}
1519
1520#[derive(Eq, PartialEq, RuntimeDebug)]
1522pub enum IncRefStatus {
1523 Created,
1525 Existed,
1527}
1528
1529#[derive(Eq, PartialEq, RuntimeDebug)]
1531pub enum DecRefStatus {
1532 Reaped,
1534 Exists,
1536}
1537
1538pub enum CanSetCodeResult<T: Config> {
1540 Ok,
1542 MultiBlockMigrationsOngoing,
1544 InvalidVersion(Error<T>),
1546}
1547
1548impl<T: Config> CanSetCodeResult<T> {
1549 pub fn into_result(self) -> Result<(), DispatchError> {
1551 match self {
1552 Self::Ok => Ok(()),
1553 Self::MultiBlockMigrationsOngoing => {
1554 Err(Error::<T>::MultiBlockMigrationsOngoing.into())
1555 },
1556 Self::InvalidVersion(err) => Err(err.into()),
1557 }
1558 }
1559
1560 pub fn is_ok(&self) -> bool {
1562 matches!(self, Self::Ok)
1563 }
1564}
1565
1566impl<T: Config> Pezpallet<T> {
1567 #[doc = docify::embed!("src/tests.rs", last_runtime_upgrade_spec_version_usage)]
1581 pub fn last_runtime_upgrade_spec_version() -> u32 {
1582 LastRuntimeUpgrade::<T>::get().map_or(0, |l| l.spec_version.0)
1583 }
1584
1585 pub fn account_exists(who: &T::AccountId) -> bool {
1587 Account::<T>::contains_key(who)
1588 }
1589
1590 pub fn update_code_in_storage(code: &[u8]) {
1596 storage::unhashed::put_raw(well_known_keys::CODE, code);
1597 Self::deposit_log(generic::DigestItem::RuntimeEnvironmentUpdated);
1598 Self::deposit_event(Event::CodeUpdated);
1599 }
1600
1601 pub fn inherents_applied() -> bool {
1603 InherentsApplied::<T>::get()
1604 }
1605
1606 pub fn note_inherents_applied() {
1611 InherentsApplied::<T>::put(true);
1612 }
1613
1614 #[deprecated = "Use `inc_consumers` instead"]
1616 pub fn inc_ref(who: &T::AccountId) {
1617 let _ = Self::inc_consumers(who);
1618 }
1619
1620 #[deprecated = "Use `dec_consumers` instead"]
1623 pub fn dec_ref(who: &T::AccountId) {
1624 let _ = Self::dec_consumers(who);
1625 }
1626
1627 #[deprecated = "Use `consumers` instead"]
1629 pub fn refs(who: &T::AccountId) -> RefCount {
1630 Self::consumers(who)
1631 }
1632
1633 #[deprecated = "Use `!is_provider_required` instead"]
1635 pub fn allow_death(who: &T::AccountId) -> bool {
1636 !Self::is_provider_required(who)
1637 }
1638
1639 pub fn inc_providers(who: &T::AccountId) -> IncRefStatus {
1641 Account::<T>::mutate(who, |a| {
1642 if a.providers == 0 && a.sufficients == 0 {
1643 a.providers = 1;
1645 Self::on_created_account(who.clone(), a);
1646 IncRefStatus::Created
1647 } else {
1648 a.providers = a.providers.saturating_add(1);
1649 IncRefStatus::Existed
1650 }
1651 })
1652 }
1653
1654 pub fn dec_providers(who: &T::AccountId) -> Result<DecRefStatus, DispatchError> {
1658 Account::<T>::try_mutate_exists(who, |maybe_account| {
1659 if let Some(mut account) = maybe_account.take() {
1660 if account.providers == 0 {
1661 log::error!(
1663 target: LOG_TARGET,
1664 "Logic error: Unexpected underflow in reducing provider",
1665 );
1666 account.providers = 1;
1667 }
1668 match (account.providers, account.consumers, account.sufficients) {
1669 (1, 0, 0) => {
1670 Pezpallet::<T>::on_killed_account(who.clone());
1673 Ok(DecRefStatus::Reaped)
1674 },
1675 (1, c, _) if c > 0 => {
1676 Err(DispatchError::ConsumerRemaining)
1678 },
1679 (x, _, _) => {
1680 account.providers = x - 1;
1683 *maybe_account = Some(account);
1684 Ok(DecRefStatus::Exists)
1685 },
1686 }
1687 } else {
1688 log::error!(
1689 target: LOG_TARGET,
1690 "Logic error: Account already dead when reducing provider",
1691 );
1692 Ok(DecRefStatus::Reaped)
1693 }
1694 })
1695 }
1696
1697 pub fn inc_sufficients(who: &T::AccountId) -> IncRefStatus {
1699 Account::<T>::mutate(who, |a| {
1700 if a.providers + a.sufficients == 0 {
1701 a.sufficients = 1;
1703 Self::on_created_account(who.clone(), a);
1704 IncRefStatus::Created
1705 } else {
1706 a.sufficients = a.sufficients.saturating_add(1);
1707 IncRefStatus::Existed
1708 }
1709 })
1710 }
1711
1712 pub fn dec_sufficients(who: &T::AccountId) -> DecRefStatus {
1716 Account::<T>::mutate_exists(who, |maybe_account| {
1717 if let Some(mut account) = maybe_account.take() {
1718 if account.sufficients == 0 {
1719 log::error!(
1721 target: LOG_TARGET,
1722 "Logic error: Unexpected underflow in reducing sufficients",
1723 );
1724 }
1725 match (account.sufficients, account.providers) {
1726 (0, 0) | (1, 0) => {
1727 Pezpallet::<T>::on_killed_account(who.clone());
1728 DecRefStatus::Reaped
1729 },
1730 (x, _) => {
1731 account.sufficients = x.saturating_sub(1);
1732 *maybe_account = Some(account);
1733 DecRefStatus::Exists
1734 },
1735 }
1736 } else {
1737 log::error!(
1738 target: LOG_TARGET,
1739 "Logic error: Account already dead when reducing provider",
1740 );
1741 DecRefStatus::Reaped
1742 }
1743 })
1744 }
1745
1746 pub fn providers(who: &T::AccountId) -> RefCount {
1748 Account::<T>::get(who).providers
1749 }
1750
1751 pub fn sufficients(who: &T::AccountId) -> RefCount {
1753 Account::<T>::get(who).sufficients
1754 }
1755
1756 pub fn reference_count(who: &T::AccountId) -> RefCount {
1758 let a = Account::<T>::get(who);
1759 a.providers + a.sufficients
1760 }
1761
1762 pub fn inc_consumers(who: &T::AccountId) -> Result<(), DispatchError> {
1767 Account::<T>::try_mutate(who, |a| {
1768 if a.providers > 0 {
1769 if a.consumers < T::MaxConsumers::max_consumers() {
1770 a.consumers = a.consumers.saturating_add(1);
1771 Ok(())
1772 } else {
1773 Err(DispatchError::TooManyConsumers)
1774 }
1775 } else {
1776 Err(DispatchError::NoProviders)
1777 }
1778 })
1779 }
1780
1781 pub fn inc_consumers_without_limit(who: &T::AccountId) -> Result<(), DispatchError> {
1785 Account::<T>::try_mutate(who, |a| {
1786 if a.providers > 0 {
1787 a.consumers = a.consumers.saturating_add(1);
1788 Ok(())
1789 } else {
1790 Err(DispatchError::NoProviders)
1791 }
1792 })
1793 }
1794
1795 pub fn dec_consumers(who: &T::AccountId) {
1798 Account::<T>::mutate(who, |a| {
1799 if a.consumers > 0 {
1800 a.consumers -= 1;
1801 } else {
1802 log::error!(
1803 target: LOG_TARGET,
1804 "Logic error: Unexpected underflow in reducing consumer",
1805 );
1806 }
1807 })
1808 }
1809
1810 pub fn consumers(who: &T::AccountId) -> RefCount {
1812 Account::<T>::get(who).consumers
1813 }
1814
1815 pub fn is_provider_required(who: &T::AccountId) -> bool {
1817 Account::<T>::get(who).consumers != 0
1818 }
1819
1820 pub fn can_dec_provider(who: &T::AccountId) -> bool {
1822 let a = Account::<T>::get(who);
1823 a.consumers == 0 || a.providers > 1
1824 }
1825
1826 pub fn can_accrue_consumers(who: &T::AccountId, amount: u32) -> bool {
1829 let a = Account::<T>::get(who);
1830 match a.consumers.checked_add(amount) {
1831 Some(c) => a.providers > 0 && c <= T::MaxConsumers::max_consumers(),
1832 None => false,
1833 }
1834 }
1835
1836 pub fn can_inc_consumer(who: &T::AccountId) -> bool {
1839 Self::can_accrue_consumers(who, 1)
1840 }
1841
1842 pub fn deposit_event(event: impl Into<T::RuntimeEvent>) {
1846 Self::deposit_event_indexed(&[], event.into());
1847 }
1848
1849 pub fn deposit_event_indexed(topics: &[T::Hash], event: T::RuntimeEvent) {
1857 let block_number = Self::block_number();
1858
1859 if block_number.is_zero() {
1861 return;
1862 }
1863
1864 let phase = ExecutionPhase::<T>::get().unwrap_or_default();
1865 let event = EventRecord { phase, event, topics: topics.to_vec() };
1866
1867 let event_idx = {
1869 let old_event_count = EventCount::<T>::get();
1870 let new_event_count = match old_event_count.checked_add(1) {
1871 None => return,
1874 Some(nc) => nc,
1875 };
1876 EventCount::<T>::put(new_event_count);
1877 old_event_count
1878 };
1879
1880 Events::<T>::append(event);
1881
1882 for topic in topics {
1883 <EventTopics<T>>::append(topic, &(block_number, event_idx));
1884 }
1885 }
1886
1887 pub fn extrinsic_index() -> Option<u32> {
1889 storage::unhashed::get(well_known_keys::EXTRINSIC_INDEX)
1890 }
1891
1892 pub fn extrinsic_count() -> u32 {
1894 ExtrinsicCount::<T>::get().unwrap_or_default()
1895 }
1896
1897 pub fn all_extrinsics_len() -> u32 {
1898 AllExtrinsicsLen::<T>::get().unwrap_or_default()
1899 }
1900
1901 pub fn register_extra_weight_unchecked(weight: Weight, class: DispatchClass) {
1917 BlockWeight::<T>::mutate(|current_weight| {
1918 current_weight.accrue(weight, class);
1919 });
1920 }
1921
1922 pub fn initialize(number: &BlockNumberFor<T>, parent_hash: &T::Hash, digest: &generic::Digest) {
1929 let expected_block_number = Self::block_number() + One::one();
1930 assert_eq!(expected_block_number, *number, "Block number must be strictly increasing.");
1931
1932 ExecutionPhase::<T>::put(Phase::Initialization);
1934 storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &0u32);
1935 Self::initialize_intra_block_entropy(parent_hash);
1936 <Number<T>>::put(number);
1937 <Digest<T>>::put(digest);
1938 <ParentHash<T>>::put(parent_hash);
1939 <BlockHash<T>>::insert(*number - One::one(), parent_hash);
1940
1941 BlockWeight::<T>::kill();
1943 }
1944
1945 pub fn initialize_intra_block_entropy(parent_hash: &T::Hash) {
1949 let entropy = (b"pezframe_system::initialize", parent_hash).using_encoded(blake2_256);
1950 storage::unhashed::put_raw(well_known_keys::INTRABLOCK_ENTROPY, &entropy[..]);
1951 }
1952
1953 pub fn resource_usage_report() {
1957 log::debug!(
1958 target: LOG_TARGET,
1959 "[{:?}] {} extrinsics, length: {} (normal {}%, op: {}%, mandatory {}%) / normal weight:\
1960 {} (ref_time: {}%, proof_size: {}%) op weight {} (ref_time {}%, proof_size {}%) / \
1961 mandatory weight {} (ref_time: {}%, proof_size: {}%)",
1962 Self::block_number(),
1963 Self::extrinsic_count(),
1964 Self::all_extrinsics_len(),
1965 pezsp_runtime::Percent::from_rational(
1966 Self::all_extrinsics_len(),
1967 *T::BlockLength::get().max.get(DispatchClass::Normal)
1968 ).deconstruct(),
1969 pezsp_runtime::Percent::from_rational(
1970 Self::all_extrinsics_len(),
1971 *T::BlockLength::get().max.get(DispatchClass::Operational)
1972 ).deconstruct(),
1973 pezsp_runtime::Percent::from_rational(
1974 Self::all_extrinsics_len(),
1975 *T::BlockLength::get().max.get(DispatchClass::Mandatory)
1976 ).deconstruct(),
1977 Self::block_weight().get(DispatchClass::Normal),
1978 pezsp_runtime::Percent::from_rational(
1979 Self::block_weight().get(DispatchClass::Normal).ref_time(),
1980 T::BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap_or(Bounded::max_value()).ref_time()
1981 ).deconstruct(),
1982 pezsp_runtime::Percent::from_rational(
1983 Self::block_weight().get(DispatchClass::Normal).proof_size(),
1984 T::BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap_or(Bounded::max_value()).proof_size()
1985 ).deconstruct(),
1986 Self::block_weight().get(DispatchClass::Operational),
1987 pezsp_runtime::Percent::from_rational(
1988 Self::block_weight().get(DispatchClass::Operational).ref_time(),
1989 T::BlockWeights::get().get(DispatchClass::Operational).max_total.unwrap_or(Bounded::max_value()).ref_time()
1990 ).deconstruct(),
1991 pezsp_runtime::Percent::from_rational(
1992 Self::block_weight().get(DispatchClass::Operational).proof_size(),
1993 T::BlockWeights::get().get(DispatchClass::Operational).max_total.unwrap_or(Bounded::max_value()).proof_size()
1994 ).deconstruct(),
1995 Self::block_weight().get(DispatchClass::Mandatory),
1996 pezsp_runtime::Percent::from_rational(
1997 Self::block_weight().get(DispatchClass::Mandatory).ref_time(),
1998 T::BlockWeights::get().get(DispatchClass::Mandatory).max_total.unwrap_or(Bounded::max_value()).ref_time()
1999 ).deconstruct(),
2000 pezsp_runtime::Percent::from_rational(
2001 Self::block_weight().get(DispatchClass::Mandatory).proof_size(),
2002 T::BlockWeights::get().get(DispatchClass::Mandatory).max_total.unwrap_or(Bounded::max_value()).proof_size()
2003 ).deconstruct(),
2004 );
2005 }
2006
2007 pub fn finalize() -> HeaderFor<T> {
2010 Self::resource_usage_report();
2011 ExecutionPhase::<T>::kill();
2012 AllExtrinsicsLen::<T>::kill();
2013 storage::unhashed::kill(well_known_keys::INTRABLOCK_ENTROPY);
2014 InherentsApplied::<T>::kill();
2015
2016 let number = <Number<T>>::get();
2027 let parent_hash = <ParentHash<T>>::get();
2028 let digest = <Digest<T>>::get();
2029
2030 let extrinsics = (0..ExtrinsicCount::<T>::take().unwrap_or_default())
2031 .map(ExtrinsicData::<T>::take)
2032 .collect();
2033 let extrinsics_root_state_version = T::Version::get().extrinsics_root_state_version();
2034 let extrinsics_root =
2035 extrinsics_data_root::<T::Hashing>(extrinsics, extrinsics_root_state_version);
2036
2037 let block_hash_count = T::BlockHashCount::get();
2039 let to_remove = number.saturating_sub(block_hash_count).saturating_sub(One::one());
2040
2041 if !to_remove.is_zero() {
2043 <BlockHash<T>>::remove(to_remove);
2044 }
2045
2046 let version = T::Version::get().state_version();
2047 let storage_root = T::Hash::decode(&mut &pezsp_io::storage::root(version)[..])
2048 .expect("Node is configured to use the same hash; qed");
2049
2050 HeaderFor::<T>::new(number, extrinsics_root, storage_root, parent_hash, digest)
2051 }
2052
2053 pub fn deposit_log(item: generic::DigestItem) {
2055 <Digest<T>>::append(item);
2056 }
2057
2058 #[cfg(any(feature = "std", test))]
2060 pub fn externalities() -> TestExternalities {
2061 TestExternalities::new(pezsp_core::storage::Storage {
2062 top: [
2063 (<BlockHash<T>>::hashed_key_for(BlockNumberFor::<T>::zero()), [69u8; 32].encode()),
2064 (<Number<T>>::hashed_key().to_vec(), BlockNumberFor::<T>::one().encode()),
2065 (<ParentHash<T>>::hashed_key().to_vec(), [69u8; 32].encode()),
2066 ]
2067 .into_iter()
2068 .collect(),
2069 children_default: Default::default(),
2070 })
2071 }
2072
2073 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2081 pub fn events() -> Vec<EventRecord<T::RuntimeEvent, T::Hash>> {
2082 Self::read_events_no_consensus().map(|e| *e).collect()
2084 }
2085
2086 pub fn event_no_consensus(index: usize) -> Option<T::RuntimeEvent> {
2091 Self::read_events_no_consensus().nth(index).map(|e| e.event.clone())
2092 }
2093
2094 pub fn read_events_no_consensus(
2099 ) -> impl Iterator<Item = Box<EventRecord<T::RuntimeEvent, T::Hash>>> {
2100 Events::<T>::stream_iter()
2101 }
2102
2103 pub fn read_events_for_pallet<E>() -> Vec<E>
2108 where
2109 T::RuntimeEvent: TryInto<E>,
2110 {
2111 Events::<T>::get()
2112 .into_iter()
2113 .map(|er| er.event)
2114 .filter_map(|e| e.try_into().ok())
2115 .collect::<_>()
2116 }
2117
2118 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2127 pub fn run_to_block_with<AllPalletsWithSystem>(
2128 n: BlockNumberFor<T>,
2129 mut hooks: RunToBlockHooks<T>,
2130 ) where
2131 AllPalletsWithSystem: pezframe_support::traits::OnInitialize<BlockNumberFor<T>>
2132 + pezframe_support::traits::OnFinalize<BlockNumberFor<T>>,
2133 {
2134 let mut bn = Self::block_number();
2135
2136 while bn < n {
2137 if !bn.is_zero() {
2139 (hooks.before_finalize)(bn);
2140 AllPalletsWithSystem::on_finalize(bn);
2141 (hooks.after_finalize)(bn);
2142 }
2143
2144 bn += One::one();
2145
2146 Self::set_block_number(bn);
2147 (hooks.before_initialize)(bn);
2148 AllPalletsWithSystem::on_initialize(bn);
2149 (hooks.after_initialize)(bn);
2150 }
2151 }
2152
2153 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2155 pub fn run_to_block<AllPalletsWithSystem>(n: BlockNumberFor<T>)
2156 where
2157 AllPalletsWithSystem: pezframe_support::traits::OnInitialize<BlockNumberFor<T>>
2158 + pezframe_support::traits::OnFinalize<BlockNumberFor<T>>,
2159 {
2160 Self::run_to_block_with::<AllPalletsWithSystem>(n, Default::default());
2161 }
2162
2163 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2166 pub fn set_block_number(n: BlockNumberFor<T>) {
2167 <Number<T>>::put(n);
2168 }
2169
2170 #[cfg(any(feature = "std", test))]
2172 pub fn set_extrinsic_index(extrinsic_index: u32) {
2173 storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &extrinsic_index)
2174 }
2175
2176 #[cfg(any(feature = "std", test))]
2179 pub fn set_parent_hash(n: T::Hash) {
2180 <ParentHash<T>>::put(n);
2181 }
2182
2183 #[cfg(any(feature = "std", test))]
2185 pub fn set_block_consumed_resources(weight: Weight, len: usize) {
2186 BlockWeight::<T>::mutate(|current_weight| {
2187 current_weight.set(weight, DispatchClass::Normal)
2188 });
2189 AllExtrinsicsLen::<T>::put(len as u32);
2190 }
2191
2192 pub fn reset_events() {
2197 <Events<T>>::kill();
2198 EventCount::<T>::kill();
2199 let _ = <EventTopics<T>>::clear(u32::max_value(), None);
2200 }
2201
2202 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2206 #[track_caller]
2207 pub fn assert_has_event(event: T::RuntimeEvent) {
2208 let warn = if Self::block_number().is_zero() {
2209 "WARNING: block number is zero, and events are not registered at block number zero.\n"
2210 } else {
2211 ""
2212 };
2213
2214 let events = Self::events();
2215 assert!(
2216 events.iter().any(|record| record.event == event),
2217 "{warn}expected event {event:?} not found in events {events:?}",
2218 );
2219 }
2220
2221 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2225 #[track_caller]
2226 pub fn assert_last_event(event: T::RuntimeEvent) {
2227 let warn = if Self::block_number().is_zero() {
2228 "WARNING: block number is zero, and events are not registered at block number zero.\n"
2229 } else {
2230 ""
2231 };
2232
2233 let last_event = Self::events()
2234 .last()
2235 .expect(&alloc::format!("{warn}events expected"))
2236 .event
2237 .clone();
2238 assert_eq!(
2239 last_event, event,
2240 "{warn}expected event {event:?} is not equal to the last event {last_event:?}",
2241 );
2242 }
2243
2244 pub fn runtime_version() -> RuntimeVersion {
2246 T::Version::get()
2247 }
2248
2249 pub fn account_nonce(who: impl EncodeLike<T::AccountId>) -> T::Nonce {
2251 Account::<T>::get(who).nonce
2252 }
2253
2254 pub fn inc_account_nonce(who: impl EncodeLike<T::AccountId>) {
2256 Account::<T>::mutate(who, |a| a.nonce += T::Nonce::one());
2257 }
2258
2259 pub fn note_extrinsic(encoded_xt: Vec<u8>) {
2264 ExtrinsicData::<T>::insert(Self::extrinsic_index().unwrap_or_default(), encoded_xt);
2265 }
2266
2267 pub fn note_applied_extrinsic(r: &DispatchResultWithPostInfo, info: DispatchInfo) {
2273 let weight = extract_actual_weight(r, &info)
2274 .saturating_add(T::BlockWeights::get().get(info.class).base_extrinsic);
2275 let class = info.class;
2276 let pays_fee = extract_actual_pays_fee(r, &info);
2277 let dispatch_event_info = DispatchEventInfo { weight, class, pays_fee };
2278
2279 Self::deposit_event(match r {
2280 Ok(_) => Event::ExtrinsicSuccess { dispatch_info: dispatch_event_info },
2281 Err(err) => {
2282 log::trace!(
2283 target: LOG_TARGET,
2284 "Extrinsic failed at block({:?}): {:?}",
2285 Self::block_number(),
2286 err,
2287 );
2288 Event::ExtrinsicFailed {
2289 dispatch_error: err.error,
2290 dispatch_info: dispatch_event_info,
2291 }
2292 },
2293 });
2294
2295 log::trace!(
2296 target: LOG_TARGET,
2297 "Used block weight: {:?}",
2298 BlockWeight::<T>::get(),
2299 );
2300
2301 log::trace!(
2302 target: LOG_TARGET,
2303 "Used block length: {:?}",
2304 Pezpallet::<T>::all_extrinsics_len(),
2305 );
2306
2307 let next_extrinsic_index = Self::extrinsic_index().unwrap_or_default() + 1u32;
2308
2309 storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &next_extrinsic_index);
2310 ExecutionPhase::<T>::put(Phase::ApplyExtrinsic(next_extrinsic_index));
2311 ExtrinsicWeightReclaimed::<T>::kill();
2312 }
2313
2314 pub fn note_finished_extrinsics() {
2317 let extrinsic_index: u32 =
2318 storage::unhashed::take(well_known_keys::EXTRINSIC_INDEX).unwrap_or_default();
2319 ExtrinsicCount::<T>::put(extrinsic_index);
2320 ExecutionPhase::<T>::put(Phase::Finalization);
2321 }
2322
2323 pub fn note_finished_initialize() {
2326 ExecutionPhase::<T>::put(Phase::ApplyExtrinsic(0))
2327 }
2328
2329 pub fn on_created_account(who: T::AccountId, _a: &mut AccountInfo<T::Nonce, T::AccountData>) {
2331 T::OnNewAccount::on_new_account(&who);
2332 Self::deposit_event(Event::NewAccount { account: who });
2333 }
2334
2335 fn on_killed_account(who: T::AccountId) {
2337 T::OnKilledAccount::on_killed_account(&who);
2338 Self::deposit_event(Event::KilledAccount { account: who });
2339 }
2340
2341 pub fn can_set_code(code: &[u8], check_version: bool) -> CanSetCodeResult<T> {
2345 if T::MultiBlockMigrator::ongoing() {
2346 return CanSetCodeResult::MultiBlockMigrationsOngoing;
2347 }
2348
2349 if check_version {
2350 let current_version = T::Version::get();
2351 let Some(new_version) = pezsp_io::misc::runtime_version(code)
2352 .and_then(|v| RuntimeVersion::decode(&mut &v[..]).ok())
2353 else {
2354 return CanSetCodeResult::InvalidVersion(Error::<T>::FailedToExtractRuntimeVersion);
2355 };
2356
2357 cfg_if::cfg_if! {
2358 if #[cfg(all(feature = "runtime-benchmarks", not(test)))] {
2359 core::hint::black_box((new_version, current_version));
2361 } else {
2362 if new_version.spec_name != current_version.spec_name {
2363 return CanSetCodeResult::InvalidVersion(Error::<T>::InvalidSpecName)
2364 }
2365
2366 if new_version.spec_version <= current_version.spec_version {
2367 return CanSetCodeResult::InvalidVersion(Error::<T>::SpecVersionNeedsToIncrease)
2368 }
2369 }
2370 }
2371 }
2372
2373 CanSetCodeResult::Ok
2374 }
2375
2376 pub fn do_authorize_upgrade(code_hash: T::Hash, check_version: bool) {
2378 AuthorizedUpgrade::<T>::put(CodeUpgradeAuthorization { code_hash, check_version });
2379 Self::deposit_event(Event::UpgradeAuthorized { code_hash, check_version });
2380 }
2381
2382 fn validate_code_is_authorized(
2386 code: &[u8],
2387 ) -> Result<CodeUpgradeAuthorization<T>, DispatchError> {
2388 let authorization = AuthorizedUpgrade::<T>::get().ok_or(Error::<T>::NothingAuthorized)?;
2389 let actual_hash = T::Hashing::hash(code);
2390 ensure!(actual_hash == authorization.code_hash, Error::<T>::Unauthorized);
2391 Ok(authorization)
2392 }
2393
2394 pub fn reclaim_weight(
2399 info: &DispatchInfoOf<T::RuntimeCall>,
2400 post_info: &PostDispatchInfoOf<T::RuntimeCall>,
2401 ) -> Result<(), TransactionValidityError>
2402 where
2403 T::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
2404 {
2405 let already_reclaimed = crate::ExtrinsicWeightReclaimed::<T>::get();
2406 let unspent = post_info.calc_unspent(info);
2407 let accurate_reclaim = already_reclaimed.max(unspent);
2408 let to_reclaim_more = accurate_reclaim.saturating_sub(already_reclaimed);
2410 if to_reclaim_more != Weight::zero() {
2411 crate::BlockWeight::<T>::mutate(|current_weight| {
2412 current_weight.reduce(to_reclaim_more, info.class);
2413 });
2414 crate::ExtrinsicWeightReclaimed::<T>::put(accurate_reclaim);
2415 }
2416
2417 Ok(())
2418 }
2419
2420 pub fn remaining_block_weight() -> WeightMeter {
2422 let limit = T::BlockWeights::get().max_block;
2423 let consumed = BlockWeight::<T>::get().total();
2424
2425 WeightMeter::with_consumed_and_limit(consumed, limit)
2426 }
2427}
2428
2429pub fn unique(entropy: impl Encode) -> [u8; 32] {
2432 let mut last = [0u8; 32];
2433 pezsp_io::storage::read(well_known_keys::INTRABLOCK_ENTROPY, &mut last[..], 0);
2434 let next = (b"pezframe_system::unique", entropy, last).using_encoded(blake2_256);
2435 pezsp_io::storage::set(well_known_keys::INTRABLOCK_ENTROPY, &next);
2436 next
2437}
2438
2439pub struct Provider<T>(PhantomData<T>);
2441impl<T: Config> HandleLifetime<T::AccountId> for Provider<T> {
2442 fn created(t: &T::AccountId) -> Result<(), DispatchError> {
2443 Pezpallet::<T>::inc_providers(t);
2444 Ok(())
2445 }
2446 fn killed(t: &T::AccountId) -> Result<(), DispatchError> {
2447 Pezpallet::<T>::dec_providers(t).map(|_| ())
2448 }
2449}
2450
2451pub struct SelfSufficient<T>(PhantomData<T>);
2453impl<T: Config> HandleLifetime<T::AccountId> for SelfSufficient<T> {
2454 fn created(t: &T::AccountId) -> Result<(), DispatchError> {
2455 Pezpallet::<T>::inc_sufficients(t);
2456 Ok(())
2457 }
2458 fn killed(t: &T::AccountId) -> Result<(), DispatchError> {
2459 Pezpallet::<T>::dec_sufficients(t);
2460 Ok(())
2461 }
2462}
2463
2464pub struct Consumer<T>(PhantomData<T>);
2466impl<T: Config> HandleLifetime<T::AccountId> for Consumer<T> {
2467 fn created(t: &T::AccountId) -> Result<(), DispatchError> {
2468 Pezpallet::<T>::inc_consumers(t)
2469 }
2470 fn killed(t: &T::AccountId) -> Result<(), DispatchError> {
2471 Pezpallet::<T>::dec_consumers(t);
2472 Ok(())
2473 }
2474}
2475
2476impl<T: Config> BlockNumberProvider for Pezpallet<T> {
2477 type BlockNumber = BlockNumberFor<T>;
2478
2479 fn current_block_number() -> Self::BlockNumber {
2480 Pezpallet::<T>::block_number()
2481 }
2482
2483 #[cfg(feature = "runtime-benchmarks")]
2484 fn set_block_number(n: BlockNumberFor<T>) {
2485 Self::set_block_number(n)
2486 }
2487}
2488
2489impl<T: Config> StoredMap<T::AccountId, T::AccountData> for Pezpallet<T> {
2495 fn get(k: &T::AccountId) -> T::AccountData {
2496 Account::<T>::get(k).data
2497 }
2498
2499 fn try_mutate_exists<R, E: From<DispatchError>>(
2500 k: &T::AccountId,
2501 f: impl FnOnce(&mut Option<T::AccountData>) -> Result<R, E>,
2502 ) -> Result<R, E> {
2503 let account = Account::<T>::get(k);
2504 let is_default = account.data == T::AccountData::default();
2505 let mut some_data = if is_default { None } else { Some(account.data) };
2506 let result = f(&mut some_data)?;
2507 if Self::providers(k) > 0 || Self::sufficients(k) > 0 {
2508 Account::<T>::mutate(k, |a| a.data = some_data.unwrap_or_default());
2509 } else {
2510 Account::<T>::remove(k)
2511 }
2512 Ok(result)
2513 }
2514}
2515
2516pub fn split_inner<T, R, S>(
2518 option: Option<T>,
2519 splitter: impl FnOnce(T) -> (R, S),
2520) -> (Option<R>, Option<S>) {
2521 match option {
2522 Some(inner) => {
2523 let (r, s) = splitter(inner);
2524 (Some(r), Some(s))
2525 },
2526 None => (None, None),
2527 }
2528}
2529
2530pub struct ChainContext<T>(PhantomData<T>);
2531impl<T> Default for ChainContext<T> {
2532 fn default() -> Self {
2533 ChainContext(PhantomData)
2534 }
2535}
2536
2537impl<T: Config> Lookup for ChainContext<T> {
2538 type Source = <T::Lookup as StaticLookup>::Source;
2539 type Target = <T::Lookup as StaticLookup>::Target;
2540
2541 fn lookup(&self, s: Self::Source) -> Result<Self::Target, LookupError> {
2542 <T::Lookup as StaticLookup>::lookup(s)
2543 }
2544}
2545
2546#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2548pub struct RunToBlockHooks<'a, T>
2549where
2550 T: 'a + Config,
2551{
2552 before_initialize: Box<dyn 'a + FnMut(BlockNumberFor<T>)>,
2553 after_initialize: Box<dyn 'a + FnMut(BlockNumberFor<T>)>,
2554 before_finalize: Box<dyn 'a + FnMut(BlockNumberFor<T>)>,
2555 after_finalize: Box<dyn 'a + FnMut(BlockNumberFor<T>)>,
2556}
2557
2558#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2559impl<'a, T> RunToBlockHooks<'a, T>
2560where
2561 T: 'a + Config,
2562{
2563 pub fn before_initialize<F>(mut self, f: F) -> Self
2565 where
2566 F: 'a + FnMut(BlockNumberFor<T>),
2567 {
2568 self.before_initialize = Box::new(f);
2569 self
2570 }
2571 pub fn after_initialize<F>(mut self, f: F) -> Self
2573 where
2574 F: 'a + FnMut(BlockNumberFor<T>),
2575 {
2576 self.after_initialize = Box::new(f);
2577 self
2578 }
2579 pub fn before_finalize<F>(mut self, f: F) -> Self
2581 where
2582 F: 'a + FnMut(BlockNumberFor<T>),
2583 {
2584 self.before_finalize = Box::new(f);
2585 self
2586 }
2587 pub fn after_finalize<F>(mut self, f: F) -> Self
2589 where
2590 F: 'a + FnMut(BlockNumberFor<T>),
2591 {
2592 self.after_finalize = Box::new(f);
2593 self
2594 }
2595}
2596
2597#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2598impl<'a, T> Default for RunToBlockHooks<'a, T>
2599where
2600 T: Config,
2601{
2602 fn default() -> Self {
2603 Self {
2604 before_initialize: Box::new(|_| {}),
2605 after_initialize: Box::new(|_| {}),
2606 before_finalize: Box::new(|_| {}),
2607 after_finalize: Box::new(|_| {}),
2608 }
2609 }
2610}
2611
2612pub mod pezpallet_prelude {
2614 pub use crate::{
2615 ensure_authorized, ensure_none, ensure_root, ensure_signed, ensure_signed_or_root,
2616 };
2617
2618 pub type OriginFor<T> = <T as crate::Config>::RuntimeOrigin;
2620
2621 pub type HeaderFor<T> =
2623 <<T as crate::Config>::Block as pezsp_runtime::traits::HeaderProvider>::HeaderT;
2624
2625 pub type BlockNumberFor<T> = <HeaderFor<T> as pezsp_runtime::traits::Header>::Number;
2627
2628 pub type ExtrinsicFor<T> =
2630 <<T as crate::Config>::Block as pezsp_runtime::traits::Block>::Extrinsic;
2631
2632 pub type RuntimeCallFor<T> = <T as crate::Config>::RuntimeCall;
2634
2635 pub type AccountIdFor<T> = <T as crate::Config>::AccountId;
2637}