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 pallet_prelude::{BlockNumberFor, HeaderFor};
105#[cfg(feature = "std")]
106use serde::Serialize;
107use sp_io::hashing::blake2_256;
108#[cfg(feature = "runtime-benchmarks")]
109use sp_runtime::traits::TrailingZeroInput;
110use sp_runtime::{
111 generic,
112 traits::{
113 self, AtLeast32Bit, BadOrigin, BlockNumberProvider, Bounded, CheckEqual, Dispatchable,
114 Hash, Header, Lookup, LookupError, MaybeDisplay, MaybeSerializeDeserialize, Member, One,
115 Saturating, SimpleBitOps, StaticLookup, Zero,
116 },
117 transaction_validity::{
118 InvalidTransaction, TransactionLongevity, TransactionSource, TransactionValidity,
119 ValidTransaction,
120 },
121 DispatchError, RuntimeDebug,
122};
123use sp_version::RuntimeVersion;
124
125use codec::{Decode, DecodeWithMemTracking, Encode, EncodeLike, FullCodec, MaxEncodedLen};
126#[cfg(feature = "std")]
127use frame_support::traits::BuildGenesisConfig;
128use frame_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 pallet_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 scale_info::TypeInfo;
146use sp_core::storage::well_known_keys;
147use sp_runtime::{
148 traits::{DispatchInfoOf, PostDispatchInfoOf},
149 transaction_validity::TransactionValidityError,
150};
151use sp_weights::{RuntimeDbWeight, Weight};
152
153#[cfg(any(feature = "std", test))]
154use sp_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 check_genesis::CheckGenesis, check_mortality::CheckMortality,
173 check_non_zero_sender::CheckNonZeroSender, check_nonce::CheckNonce,
174 check_spec_version::CheckSpecVersion, check_tx_version::CheckTxVersion,
175 check_weight::CheckWeight, weight_reclaim::WeightReclaim,
176 weights::SubstrateWeight as SubstrateExtensionsWeight, WeightInfo as ExtensionsWeightInfo,
177};
178pub use extensions::check_mortality::CheckMortality as CheckEra;
180pub use frame_support::dispatch::RawOrigin;
181use frame_support::traits::{PostInherents, PostTransactions, PreInherents};
182use sp_core::storage::StateVersion;
183pub use weights::WeightInfo;
184
185const LOG_TARGET: &str = "runtime::system";
186
187pub fn extrinsics_root<H: Hash, E: codec::Encode>(
192 extrinsics: &[E],
193 state_version: StateVersion,
194) -> H::Output {
195 extrinsics_data_root::<H>(extrinsics.iter().map(codec::Encode::encode).collect(), state_version)
196}
197
198pub fn extrinsics_data_root<H: Hash>(xts: Vec<Vec<u8>>, state_version: StateVersion) -> H::Output {
203 H::ordered_trie_root(xts, state_version)
204}
205
206pub type ConsumedWeight = PerDispatchClass<Weight>;
208
209pub use pallet::*;
210
211pub trait SetCode<T: Config> {
213 fn set_code(code: Vec<u8>) -> DispatchResult;
215}
216
217impl<T: Config> SetCode<T> for () {
218 fn set_code(code: Vec<u8>) -> DispatchResult {
219 <Pallet<T>>::update_code_in_storage(&code);
220 Ok(())
221 }
222}
223
224pub trait ConsumerLimits {
226 fn max_consumers() -> RefCount;
228 fn max_overflow() -> RefCount;
234}
235
236impl<const Z: u32> ConsumerLimits for ConstU32<Z> {
237 fn max_consumers() -> RefCount {
238 Z
239 }
240 fn max_overflow() -> RefCount {
241 Z
242 }
243}
244
245impl<MaxNormal: Get<u32>, MaxOverflow: Get<u32>> ConsumerLimits for (MaxNormal, MaxOverflow) {
246 fn max_consumers() -> RefCount {
247 MaxNormal::get()
248 }
249 fn max_overflow() -> RefCount {
250 MaxOverflow::get()
251 }
252}
253
254#[derive(Decode, Encode, Default, PartialEq, Eq, MaxEncodedLen, TypeInfo)]
257#[scale_info(skip_type_params(T))]
258pub struct CodeUpgradeAuthorization<T>
259where
260 T: Config,
261{
262 code_hash: T::Hash,
264 check_version: bool,
266}
267
268#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
269impl<T> CodeUpgradeAuthorization<T>
270where
271 T: Config,
272{
273 pub fn code_hash(&self) -> &T::Hash {
274 &self.code_hash
275 }
276}
277
278#[derive(
282 Clone,
283 Copy,
284 Eq,
285 PartialEq,
286 Default,
287 RuntimeDebug,
288 Encode,
289 Decode,
290 DecodeWithMemTracking,
291 TypeInfo,
292)]
293pub struct DispatchEventInfo {
294 pub weight: Weight,
296 pub class: DispatchClass,
298 pub pays_fee: Pays,
300}
301
302#[frame_support::pallet]
303pub mod pallet {
304 use crate::{self as frame_system, pallet_prelude::*, *};
305 use codec::HasCompact;
306 use frame_support::pallet_prelude::*;
307
308 pub mod config_preludes {
310 use super::{inject_runtime_type, DefaultConfig};
311 use frame_support::{derive_impl, traits::Get};
312
313 pub struct TestBlockHashCount<C: Get<u32>>(core::marker::PhantomData<C>);
319 impl<I: From<u32>, C: Get<u32>> Get<I> for TestBlockHashCount<C> {
320 fn get() -> I {
321 C::get().into()
322 }
323 }
324
325 pub struct TestDefaultConfig;
332
333 #[frame_support::register_default_impl(TestDefaultConfig)]
334 impl DefaultConfig for TestDefaultConfig {
335 type Nonce = u32;
336 type Hash = sp_core::hash::H256;
337 type Hashing = sp_runtime::traits::BlakeTwo256;
338 type AccountId = u64;
339 type Lookup = sp_runtime::traits::IdentityLookup<Self::AccountId>;
340 type MaxConsumers = frame_support::traits::ConstU32<16>;
341 type AccountData = ();
342 type OnNewAccount = ();
343 type OnKilledAccount = ();
344 type SystemWeightInfo = ();
345 type ExtensionsWeightInfo = ();
346 type SS58Prefix = ();
347 type Version = ();
348 type BlockWeights = ();
349 type BlockLength = ();
350 type DbWeight = ();
351 #[inject_runtime_type]
352 type RuntimeEvent = ();
353 #[inject_runtime_type]
354 type RuntimeOrigin = ();
355 #[inject_runtime_type]
356 type RuntimeCall = ();
357 #[inject_runtime_type]
358 type PalletInfo = ();
359 #[inject_runtime_type]
360 type RuntimeTask = ();
361 type BaseCallFilter = frame_support::traits::Everything;
362 type BlockHashCount = TestBlockHashCount<frame_support::traits::ConstU32<10>>;
363 type OnSetCode = ();
364 type SingleBlockMigrations = ();
365 type MultiBlockMigrator = ();
366 type PreInherents = ();
367 type PostInherents = ();
368 type PostTransactions = ();
369 }
370
371 pub struct SolochainDefaultConfig;
385
386 #[frame_support::register_default_impl(SolochainDefaultConfig)]
387 impl DefaultConfig for SolochainDefaultConfig {
388 type Nonce = u32;
390
391 type Hash = sp_core::hash::H256;
393
394 type Hashing = sp_runtime::traits::BlakeTwo256;
396
397 type AccountId = sp_runtime::AccountId32;
399
400 type Lookup = sp_runtime::traits::AccountIdLookup<Self::AccountId, ()>;
402
403 type MaxConsumers = frame_support::traits::ConstU32<128>;
405
406 type AccountData = ();
408
409 type OnNewAccount = ();
411
412 type OnKilledAccount = ();
414
415 type SystemWeightInfo = ();
417
418 type ExtensionsWeightInfo = ();
420
421 type SS58Prefix = ();
423
424 type Version = ();
426
427 type BlockWeights = ();
429
430 type BlockLength = ();
432
433 type DbWeight = ();
435
436 #[inject_runtime_type]
438 type RuntimeEvent = ();
439
440 #[inject_runtime_type]
442 type RuntimeOrigin = ();
443
444 #[inject_runtime_type]
447 type RuntimeCall = ();
448
449 #[inject_runtime_type]
451 type RuntimeTask = ();
452
453 #[inject_runtime_type]
455 type PalletInfo = ();
456
457 type BaseCallFilter = frame_support::traits::Everything;
459
460 type BlockHashCount = TestBlockHashCount<frame_support::traits::ConstU32<256>>;
463
464 type OnSetCode = ();
466 type SingleBlockMigrations = ();
467 type MultiBlockMigrator = ();
468 type PreInherents = ();
469 type PostInherents = ();
470 type PostTransactions = ();
471 }
472
473 pub struct RelayChainDefaultConfig;
475
476 #[derive_impl(SolochainDefaultConfig as DefaultConfig, no_aggregated_types)]
478 #[frame_support::register_default_impl(RelayChainDefaultConfig)]
479 impl DefaultConfig for RelayChainDefaultConfig {}
480
481 pub struct ParaChainDefaultConfig;
483
484 #[derive_impl(SolochainDefaultConfig as DefaultConfig, no_aggregated_types)]
486 #[frame_support::register_default_impl(ParaChainDefaultConfig)]
487 impl DefaultConfig for ParaChainDefaultConfig {}
488 }
489
490 #[pallet::config(with_default)]
492 #[pallet::disable_frame_system_supertrait_check]
493 pub trait Config: 'static + Eq + Clone {
494 #[pallet::no_default_bounds]
496 type RuntimeEvent: Parameter
497 + Member
498 + From<Event<Self>>
499 + Debug
500 + IsType<<Self as frame_system::Config>::RuntimeEvent>;
501
502 #[pallet::no_default_bounds]
513 type BaseCallFilter: Contains<Self::RuntimeCall>;
514
515 #[pallet::constant]
517 type BlockWeights: Get<limits::BlockWeights>;
518
519 #[pallet::constant]
521 type BlockLength: Get<limits::BlockLength>;
522
523 #[pallet::no_default_bounds]
525 type RuntimeOrigin: Into<Result<RawOrigin<Self::AccountId>, Self::RuntimeOrigin>>
526 + From<RawOrigin<Self::AccountId>>
527 + Clone
528 + OriginTrait<Call = Self::RuntimeCall, AccountId = Self::AccountId>;
529
530 #[docify::export(system_runtime_call)]
531 #[pallet::no_default_bounds]
533 type RuntimeCall: Parameter
534 + Dispatchable<RuntimeOrigin = Self::RuntimeOrigin>
535 + Debug
536 + GetDispatchInfo
537 + From<Call<Self>>;
538
539 #[pallet::no_default_bounds]
541 type RuntimeTask: Task;
542
543 type Nonce: Parameter
545 + HasCompact<Type: DecodeWithMemTracking>
546 + Member
547 + MaybeSerializeDeserialize
548 + Debug
549 + Default
550 + MaybeDisplay
551 + AtLeast32Bit
552 + Copy
553 + MaxEncodedLen;
554
555 type Hash: Parameter
557 + Member
558 + MaybeSerializeDeserialize
559 + Debug
560 + MaybeDisplay
561 + SimpleBitOps
562 + Ord
563 + Default
564 + Copy
565 + CheckEqual
566 + core::hash::Hash
567 + AsRef<[u8]>
568 + AsMut<[u8]>
569 + MaxEncodedLen;
570
571 type Hashing: Hash<Output = Self::Hash> + TypeInfo;
573
574 type AccountId: Parameter
576 + Member
577 + MaybeSerializeDeserialize
578 + Debug
579 + MaybeDisplay
580 + Ord
581 + MaxEncodedLen;
582
583 type Lookup: StaticLookup<Target = Self::AccountId>;
590
591 #[pallet::no_default]
594 type Block: Parameter + Member + traits::Block<Hash = Self::Hash>;
595
596 #[pallet::constant]
598 #[pallet::no_default_bounds]
599 type BlockHashCount: Get<BlockNumberFor<Self>>;
600
601 #[pallet::constant]
603 type DbWeight: Get<RuntimeDbWeight>;
604
605 #[pallet::constant]
607 type Version: Get<RuntimeVersion>;
608
609 #[pallet::no_default_bounds]
616 type PalletInfo: PalletInfo;
617
618 type AccountData: Member + FullCodec + Clone + Default + TypeInfo + MaxEncodedLen;
621
622 type OnNewAccount: OnNewAccount<Self::AccountId>;
624
625 type OnKilledAccount: OnKilledAccount<Self::AccountId>;
629
630 type SystemWeightInfo: WeightInfo;
632
633 type ExtensionsWeightInfo: extensions::WeightInfo;
635
636 #[pallet::constant]
642 type SS58Prefix: Get<u16>;
643
644 #[pallet::no_default_bounds]
652 type OnSetCode: SetCode<Self>;
653
654 type MaxConsumers: ConsumerLimits;
656
657 type SingleBlockMigrations: OnRuntimeUpgrade;
664
665 type MultiBlockMigrator: MultiStepMigrator;
670
671 type PreInherents: PreInherents;
675
676 type PostInherents: PostInherents;
680
681 type PostTransactions: PostTransactions;
685 }
686
687 #[pallet::pallet]
688 pub struct Pallet<T>(_);
689
690 #[pallet::hooks]
691 impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
692 #[cfg(feature = "std")]
693 fn integrity_test() {
694 T::BlockWeights::get().validate().expect("The weights are invalid.");
695 }
696 }
697
698 #[pallet::call]
699 impl<T: Config> Pallet<T> {
700 #[pallet::call_index(0)]
704 #[pallet::weight(T::SystemWeightInfo::remark(remark.len() as u32))]
705 pub fn remark(_origin: OriginFor<T>, remark: Vec<u8>) -> DispatchResultWithPostInfo {
706 let _ = remark; Ok(().into())
708 }
709
710 #[pallet::call_index(1)]
712 #[pallet::weight((T::SystemWeightInfo::set_heap_pages(), DispatchClass::Operational))]
713 pub fn set_heap_pages(origin: OriginFor<T>, pages: u64) -> DispatchResultWithPostInfo {
714 ensure_root(origin)?;
715 storage::unhashed::put_raw(well_known_keys::HEAP_PAGES, &pages.encode());
716 Self::deposit_log(generic::DigestItem::RuntimeEnvironmentUpdated);
717 Ok(().into())
718 }
719
720 #[pallet::call_index(2)]
722 #[pallet::weight((T::SystemWeightInfo::set_code(), DispatchClass::Operational))]
723 pub fn set_code(origin: OriginFor<T>, code: Vec<u8>) -> DispatchResultWithPostInfo {
724 ensure_root(origin)?;
725 Self::can_set_code(&code, true).into_result()?;
726 T::OnSetCode::set_code(code)?;
727 Ok(Some(T::BlockWeights::get().max_block).into())
729 }
730
731 #[pallet::call_index(3)]
736 #[pallet::weight((T::SystemWeightInfo::set_code(), DispatchClass::Operational))]
737 pub fn set_code_without_checks(
738 origin: OriginFor<T>,
739 code: Vec<u8>,
740 ) -> DispatchResultWithPostInfo {
741 ensure_root(origin)?;
742 Self::can_set_code(&code, false).into_result()?;
743 T::OnSetCode::set_code(code)?;
744 Ok(Some(T::BlockWeights::get().max_block).into())
745 }
746
747 #[pallet::call_index(4)]
749 #[pallet::weight((
750 T::SystemWeightInfo::set_storage(items.len() as u32),
751 DispatchClass::Operational,
752 ))]
753 pub fn set_storage(
754 origin: OriginFor<T>,
755 items: Vec<KeyValue>,
756 ) -> DispatchResultWithPostInfo {
757 ensure_root(origin)?;
758 for i in &items {
759 storage::unhashed::put_raw(&i.0, &i.1);
760 }
761 Ok(().into())
762 }
763
764 #[pallet::call_index(5)]
766 #[pallet::weight((
767 T::SystemWeightInfo::kill_storage(keys.len() as u32),
768 DispatchClass::Operational,
769 ))]
770 pub fn kill_storage(origin: OriginFor<T>, keys: Vec<Key>) -> DispatchResultWithPostInfo {
771 ensure_root(origin)?;
772 for key in &keys {
773 storage::unhashed::kill(key);
774 }
775 Ok(().into())
776 }
777
778 #[pallet::call_index(6)]
783 #[pallet::weight((
784 T::SystemWeightInfo::kill_prefix(subkeys.saturating_add(1)),
785 DispatchClass::Operational,
786 ))]
787 pub fn kill_prefix(
788 origin: OriginFor<T>,
789 prefix: Key,
790 subkeys: u32,
791 ) -> DispatchResultWithPostInfo {
792 ensure_root(origin)?;
793 let _ = storage::unhashed::clear_prefix(&prefix, Some(subkeys), None);
794 Ok(().into())
795 }
796
797 #[pallet::call_index(7)]
799 #[pallet::weight(T::SystemWeightInfo::remark_with_event(remark.len() as u32))]
800 pub fn remark_with_event(
801 origin: OriginFor<T>,
802 remark: Vec<u8>,
803 ) -> DispatchResultWithPostInfo {
804 let who = ensure_signed(origin)?;
805 let hash = T::Hashing::hash(&remark[..]);
806 Self::deposit_event(Event::Remarked { sender: who, hash });
807 Ok(().into())
808 }
809
810 #[cfg(feature = "experimental")]
811 #[pallet::call_index(8)]
812 #[pallet::weight(task.weight())]
813 pub fn do_task(_origin: OriginFor<T>, task: T::RuntimeTask) -> DispatchResultWithPostInfo {
814 if !task.is_valid() {
815 return Err(Error::<T>::InvalidTask.into())
816 }
817
818 Self::deposit_event(Event::TaskStarted { task: task.clone() });
819 if let Err(err) = task.run() {
820 Self::deposit_event(Event::TaskFailed { task, err });
821 return Err(Error::<T>::FailedTask.into())
822 }
823
824 Self::deposit_event(Event::TaskCompleted { task });
826
827 Ok(().into())
829 }
830
831 #[pallet::call_index(9)]
836 #[pallet::weight((T::SystemWeightInfo::authorize_upgrade(), DispatchClass::Operational))]
837 pub fn authorize_upgrade(origin: OriginFor<T>, code_hash: T::Hash) -> DispatchResult {
838 ensure_root(origin)?;
839 Self::do_authorize_upgrade(code_hash, true);
840 Ok(())
841 }
842
843 #[pallet::call_index(10)]
852 #[pallet::weight((T::SystemWeightInfo::authorize_upgrade(), DispatchClass::Operational))]
853 pub fn authorize_upgrade_without_checks(
854 origin: OriginFor<T>,
855 code_hash: T::Hash,
856 ) -> DispatchResult {
857 ensure_root(origin)?;
858 Self::do_authorize_upgrade(code_hash, false);
859 Ok(())
860 }
861
862 #[pallet::call_index(11)]
872 #[pallet::weight((T::SystemWeightInfo::apply_authorized_upgrade(), DispatchClass::Operational))]
873 pub fn apply_authorized_upgrade(
874 _: OriginFor<T>,
875 code: Vec<u8>,
876 ) -> DispatchResultWithPostInfo {
877 let res = Self::validate_code_is_authorized(&code)?;
878 AuthorizedUpgrade::<T>::kill();
879
880 match Self::can_set_code(&code, res.check_version) {
881 CanSetCodeResult::Ok => {},
882 CanSetCodeResult::MultiBlockMigrationsOngoing =>
883 return Err(Error::<T>::MultiBlockMigrationsOngoing.into()),
884 CanSetCodeResult::InvalidVersion(error) => {
885 Self::deposit_event(Event::RejectedInvalidAuthorizedUpgrade {
887 code_hash: res.code_hash,
888 error: error.into(),
889 });
890
891 return Ok(Pays::No.into())
893 },
894 };
895 T::OnSetCode::set_code(code)?;
896
897 Ok(PostDispatchInfo {
898 actual_weight: Some(T::BlockWeights::get().max_block),
900 pays_fee: Pays::No,
902 })
903 }
904 }
905
906 #[pallet::event]
908 pub enum Event<T: Config> {
909 ExtrinsicSuccess { dispatch_info: DispatchEventInfo },
911 ExtrinsicFailed { dispatch_error: DispatchError, dispatch_info: DispatchEventInfo },
913 CodeUpdated,
915 NewAccount { account: T::AccountId },
917 KilledAccount { account: T::AccountId },
919 Remarked { sender: T::AccountId, hash: T::Hash },
921 #[cfg(feature = "experimental")]
922 TaskStarted { task: T::RuntimeTask },
924 #[cfg(feature = "experimental")]
925 TaskCompleted { task: T::RuntimeTask },
927 #[cfg(feature = "experimental")]
928 TaskFailed { task: T::RuntimeTask, err: DispatchError },
930 UpgradeAuthorized { code_hash: T::Hash, check_version: bool },
932 RejectedInvalidAuthorizedUpgrade { code_hash: T::Hash, error: DispatchError },
934 }
935
936 #[pallet::error]
938 pub enum Error<T> {
939 InvalidSpecName,
942 SpecVersionNeedsToIncrease,
945 FailedToExtractRuntimeVersion,
949 NonDefaultComposite,
951 NonZeroRefCount,
953 CallFiltered,
955 MultiBlockMigrationsOngoing,
957 #[cfg(feature = "experimental")]
958 InvalidTask,
960 #[cfg(feature = "experimental")]
961 FailedTask,
963 NothingAuthorized,
965 Unauthorized,
967 }
968
969 #[pallet::origin]
971 pub type Origin<T> = RawOrigin<<T as Config>::AccountId>;
972
973 #[pallet::storage]
975 #[pallet::getter(fn account)]
976 pub type Account<T: Config> = StorageMap<
977 _,
978 Blake2_128Concat,
979 T::AccountId,
980 AccountInfo<T::Nonce, T::AccountData>,
981 ValueQuery,
982 >;
983
984 #[pallet::storage]
986 pub(super) type ExtrinsicCount<T: Config> = StorageValue<_, u32>;
987
988 #[pallet::storage]
990 pub type InherentsApplied<T: Config> = StorageValue<_, bool, ValueQuery>;
991
992 #[pallet::storage]
994 #[pallet::whitelist_storage]
995 #[pallet::getter(fn block_weight)]
996 pub type BlockWeight<T: Config> = StorageValue<_, ConsumedWeight, ValueQuery>;
997
998 #[pallet::storage]
1000 #[pallet::whitelist_storage]
1001 pub type AllExtrinsicsLen<T: Config> = StorageValue<_, u32>;
1002
1003 #[pallet::storage]
1005 #[pallet::getter(fn block_hash)]
1006 pub type BlockHash<T: Config> =
1007 StorageMap<_, Twox64Concat, BlockNumberFor<T>, T::Hash, ValueQuery>;
1008
1009 #[pallet::storage]
1011 #[pallet::getter(fn extrinsic_data)]
1012 #[pallet::unbounded]
1013 pub(super) type ExtrinsicData<T: Config> =
1014 StorageMap<_, Twox64Concat, u32, Vec<u8>, ValueQuery>;
1015
1016 #[pallet::storage]
1018 #[pallet::whitelist_storage]
1019 #[pallet::getter(fn block_number)]
1020 pub(super) type Number<T: Config> = StorageValue<_, BlockNumberFor<T>, ValueQuery>;
1021
1022 #[pallet::storage]
1024 #[pallet::getter(fn parent_hash)]
1025 pub(super) type ParentHash<T: Config> = StorageValue<_, T::Hash, ValueQuery>;
1026
1027 #[pallet::storage]
1029 #[pallet::whitelist_storage]
1030 #[pallet::unbounded]
1031 #[pallet::getter(fn digest)]
1032 pub(super) type Digest<T: Config> = StorageValue<_, generic::Digest, ValueQuery>;
1033
1034 #[pallet::storage]
1042 #[pallet::whitelist_storage]
1043 #[pallet::disable_try_decode_storage]
1044 #[pallet::unbounded]
1045 pub(super) type Events<T: Config> =
1046 StorageValue<_, Vec<Box<EventRecord<T::RuntimeEvent, T::Hash>>>, ValueQuery>;
1047
1048 #[pallet::storage]
1050 #[pallet::whitelist_storage]
1051 #[pallet::getter(fn event_count)]
1052 pub(super) type EventCount<T: Config> = StorageValue<_, EventIndex, ValueQuery>;
1053
1054 #[pallet::storage]
1065 #[pallet::unbounded]
1066 #[pallet::getter(fn event_topics)]
1067 pub(super) type EventTopics<T: Config> =
1068 StorageMap<_, Blake2_128Concat, T::Hash, Vec<(BlockNumberFor<T>, EventIndex)>, ValueQuery>;
1069
1070 #[pallet::storage]
1072 #[pallet::unbounded]
1073 pub type LastRuntimeUpgrade<T: Config> = StorageValue<_, LastRuntimeUpgradeInfo>;
1074
1075 #[pallet::storage]
1077 pub(super) type UpgradedToU32RefCount<T: Config> = StorageValue<_, bool, ValueQuery>;
1078
1079 #[pallet::storage]
1082 pub(super) type UpgradedToTripleRefCount<T: Config> = StorageValue<_, bool, ValueQuery>;
1083
1084 #[pallet::storage]
1086 #[pallet::whitelist_storage]
1087 pub(super) type ExecutionPhase<T: Config> = StorageValue<_, Phase>;
1088
1089 #[pallet::storage]
1091 #[pallet::getter(fn authorized_upgrade)]
1092 pub(super) type AuthorizedUpgrade<T: Config> =
1093 StorageValue<_, CodeUpgradeAuthorization<T>, OptionQuery>;
1094
1095 #[pallet::storage]
1103 #[pallet::whitelist_storage]
1104 pub type ExtrinsicWeightReclaimed<T: Config> = StorageValue<_, Weight, ValueQuery>;
1105
1106 #[derive(frame_support::DefaultNoBound)]
1107 #[pallet::genesis_config]
1108 pub struct GenesisConfig<T: Config> {
1109 #[serde(skip)]
1110 pub _config: core::marker::PhantomData<T>,
1111 }
1112
1113 #[pallet::genesis_build]
1114 impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
1115 fn build(&self) {
1116 <BlockHash<T>>::insert::<_, T::Hash>(BlockNumberFor::<T>::zero(), hash69());
1117 <ParentHash<T>>::put::<T::Hash>(hash69());
1118 <LastRuntimeUpgrade<T>>::put(LastRuntimeUpgradeInfo::from(T::Version::get()));
1119 <UpgradedToU32RefCount<T>>::put(true);
1120 <UpgradedToTripleRefCount<T>>::put(true);
1121
1122 sp_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode());
1123 }
1124 }
1125
1126 #[pallet::validate_unsigned]
1127 impl<T: Config> sp_runtime::traits::ValidateUnsigned for Pallet<T> {
1128 type Call = Call<T>;
1129 fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity {
1130 if let Call::apply_authorized_upgrade { ref code } = call {
1131 if let Ok(res) = Self::validate_code_is_authorized(&code[..]) {
1132 if Self::can_set_code(&code, false).is_ok() {
1133 return Ok(ValidTransaction {
1134 priority: u64::max_value(),
1135 requires: Vec::new(),
1136 provides: vec![res.code_hash.encode()],
1137 longevity: TransactionLongevity::max_value(),
1138 propagate: true,
1139 })
1140 }
1141 }
1142 }
1143
1144 #[cfg(feature = "experimental")]
1145 if let Call::do_task { ref task } = call {
1146 if task.is_valid() {
1147 return Ok(ValidTransaction {
1148 priority: u64::max_value(),
1149 requires: Vec::new(),
1150 provides: vec![T::Hashing::hash_of(&task.encode()).as_ref().to_vec()],
1151 longevity: TransactionLongevity::max_value(),
1152 propagate: true,
1153 })
1154 }
1155 }
1156
1157 Err(InvalidTransaction::Call.into())
1158 }
1159 }
1160}
1161
1162pub type Key = Vec<u8>;
1163pub type KeyValue = (Vec<u8>, Vec<u8>);
1164
1165#[derive(Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen)]
1167#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone))]
1168pub enum Phase {
1169 ApplyExtrinsic(u32),
1171 Finalization,
1173 Initialization,
1175}
1176
1177impl Default for Phase {
1178 fn default() -> Self {
1179 Self::Initialization
1180 }
1181}
1182
1183#[derive(Encode, Decode, RuntimeDebug, TypeInfo)]
1185#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone))]
1186pub struct EventRecord<E: Parameter + Member, T> {
1187 pub phase: Phase,
1189 pub event: E,
1191 pub topics: Vec<T>,
1193}
1194
1195fn hash69<T: AsMut<[u8]> + Default>() -> T {
1198 let mut h = T::default();
1199 h.as_mut().iter_mut().for_each(|byte| *byte = 69);
1200 h
1201}
1202
1203type EventIndex = u32;
1208
1209pub type RefCount = u32;
1211
1212#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)]
1214pub struct AccountInfo<Nonce, AccountData> {
1215 pub nonce: Nonce,
1217 pub consumers: RefCount,
1220 pub providers: RefCount,
1223 pub sufficients: RefCount,
1226 pub data: AccountData,
1229}
1230
1231#[derive(RuntimeDebug, Encode, Decode, TypeInfo)]
1234#[cfg_attr(feature = "std", derive(PartialEq))]
1235pub struct LastRuntimeUpgradeInfo {
1236 pub spec_version: codec::Compact<u32>,
1237 pub spec_name: Cow<'static, str>,
1238}
1239
1240impl LastRuntimeUpgradeInfo {
1241 pub fn was_upgraded(&self, current: &RuntimeVersion) -> bool {
1245 current.spec_version > self.spec_version.0 || current.spec_name != self.spec_name
1246 }
1247}
1248
1249impl From<RuntimeVersion> for LastRuntimeUpgradeInfo {
1250 fn from(version: RuntimeVersion) -> Self {
1251 Self { spec_version: version.spec_version.into(), spec_name: version.spec_name }
1252 }
1253}
1254
1255pub struct EnsureRoot<AccountId>(core::marker::PhantomData<AccountId>);
1257impl<O: OriginTrait, AccountId> EnsureOrigin<O> for EnsureRoot<AccountId> {
1258 type Success = ();
1259 fn try_origin(o: O) -> Result<Self::Success, O> {
1260 match o.as_system_ref() {
1261 Some(RawOrigin::Root) => Ok(()),
1262 _ => Err(o),
1263 }
1264 }
1265
1266 #[cfg(feature = "runtime-benchmarks")]
1267 fn try_successful_origin() -> Result<O, ()> {
1268 Ok(O::root())
1269 }
1270}
1271
1272impl_ensure_origin_with_arg_ignoring_arg! {
1273 impl< { O: .., AccountId: Decode, T } >
1274 EnsureOriginWithArg<O, T> for EnsureRoot<AccountId>
1275 {}
1276}
1277
1278pub struct EnsureRootWithSuccess<AccountId, Success>(
1280 core::marker::PhantomData<(AccountId, Success)>,
1281);
1282impl<O: OriginTrait, AccountId, Success: TypedGet> EnsureOrigin<O>
1283 for EnsureRootWithSuccess<AccountId, Success>
1284{
1285 type Success = Success::Type;
1286 fn try_origin(o: O) -> Result<Self::Success, O> {
1287 match o.as_system_ref() {
1288 Some(RawOrigin::Root) => Ok(Success::get()),
1289 _ => Err(o),
1290 }
1291 }
1292
1293 #[cfg(feature = "runtime-benchmarks")]
1294 fn try_successful_origin() -> Result<O, ()> {
1295 Ok(O::root())
1296 }
1297}
1298
1299impl_ensure_origin_with_arg_ignoring_arg! {
1300 impl< { O: .., AccountId: Decode, Success: TypedGet, T } >
1301 EnsureOriginWithArg<O, T> for EnsureRootWithSuccess<AccountId, Success>
1302 {}
1303}
1304
1305pub struct EnsureWithSuccess<Ensure, AccountId, Success>(
1307 core::marker::PhantomData<(Ensure, AccountId, Success)>,
1308);
1309
1310impl<O: OriginTrait, Ensure: EnsureOrigin<O>, AccountId, Success: TypedGet> EnsureOrigin<O>
1311 for EnsureWithSuccess<Ensure, AccountId, Success>
1312{
1313 type Success = Success::Type;
1314
1315 fn try_origin(o: O) -> Result<Self::Success, O> {
1316 Ensure::try_origin(o).map(|_| Success::get())
1317 }
1318
1319 #[cfg(feature = "runtime-benchmarks")]
1320 fn try_successful_origin() -> Result<O, ()> {
1321 Ensure::try_successful_origin()
1322 }
1323}
1324
1325pub struct EnsureSigned<AccountId>(core::marker::PhantomData<AccountId>);
1327impl<O: OriginTrait<AccountId = AccountId>, AccountId: Decode + Clone> EnsureOrigin<O>
1328 for EnsureSigned<AccountId>
1329{
1330 type Success = AccountId;
1331 fn try_origin(o: O) -> Result<Self::Success, O> {
1332 match o.as_system_ref() {
1333 Some(RawOrigin::Signed(who)) => Ok(who.clone()),
1334 _ => Err(o),
1335 }
1336 }
1337
1338 #[cfg(feature = "runtime-benchmarks")]
1339 fn try_successful_origin() -> Result<O, ()> {
1340 let zero_account_id =
1341 AccountId::decode(&mut TrailingZeroInput::zeroes()).map_err(|_| ())?;
1342 Ok(O::signed(zero_account_id))
1343 }
1344}
1345
1346impl_ensure_origin_with_arg_ignoring_arg! {
1347 impl< { O: OriginTrait<AccountId = AccountId>, AccountId: Decode + Clone, T } >
1348 EnsureOriginWithArg<O, T> for EnsureSigned<AccountId>
1349 {}
1350}
1351
1352pub struct EnsureSignedBy<Who, AccountId>(core::marker::PhantomData<(Who, AccountId)>);
1354impl<
1355 O: OriginTrait<AccountId = AccountId>,
1356 Who: SortedMembers<AccountId>,
1357 AccountId: PartialEq + Clone + Ord + Decode,
1358 > EnsureOrigin<O> for EnsureSignedBy<Who, AccountId>
1359{
1360 type Success = AccountId;
1361 fn try_origin(o: O) -> Result<Self::Success, O> {
1362 match o.as_system_ref() {
1363 Some(RawOrigin::Signed(ref who)) if Who::contains(who) => Ok(who.clone()),
1364 _ => Err(o),
1365 }
1366 }
1367
1368 #[cfg(feature = "runtime-benchmarks")]
1369 fn try_successful_origin() -> Result<O, ()> {
1370 let first_member = match Who::sorted_members().first() {
1371 Some(account) => account.clone(),
1372 None => AccountId::decode(&mut TrailingZeroInput::zeroes()).map_err(|_| ())?,
1373 };
1374 Ok(O::signed(first_member))
1375 }
1376}
1377
1378impl_ensure_origin_with_arg_ignoring_arg! {
1379 impl< { O: OriginTrait<AccountId = AccountId>, Who: SortedMembers<AccountId>, AccountId: PartialEq + Clone + Ord + Decode, T } >
1380 EnsureOriginWithArg<O, T> for EnsureSignedBy<Who, AccountId>
1381 {}
1382}
1383
1384pub struct EnsureNone<AccountId>(core::marker::PhantomData<AccountId>);
1386impl<O: OriginTrait<AccountId = AccountId>, AccountId> EnsureOrigin<O> for EnsureNone<AccountId> {
1387 type Success = ();
1388 fn try_origin(o: O) -> Result<Self::Success, O> {
1389 match o.as_system_ref() {
1390 Some(RawOrigin::None) => Ok(()),
1391 _ => Err(o),
1392 }
1393 }
1394
1395 #[cfg(feature = "runtime-benchmarks")]
1396 fn try_successful_origin() -> Result<O, ()> {
1397 Ok(O::none())
1398 }
1399}
1400
1401impl_ensure_origin_with_arg_ignoring_arg! {
1402 impl< { O: OriginTrait<AccountId = AccountId>, AccountId, T } >
1403 EnsureOriginWithArg<O, T> for EnsureNone<AccountId>
1404 {}
1405}
1406
1407pub struct EnsureNever<Success>(core::marker::PhantomData<Success>);
1409impl<O, Success> EnsureOrigin<O> for EnsureNever<Success> {
1410 type Success = Success;
1411 fn try_origin(o: O) -> Result<Self::Success, O> {
1412 Err(o)
1413 }
1414
1415 #[cfg(feature = "runtime-benchmarks")]
1416 fn try_successful_origin() -> Result<O, ()> {
1417 Err(())
1418 }
1419}
1420
1421impl_ensure_origin_with_arg_ignoring_arg! {
1422 impl< { O, Success, T } >
1423 EnsureOriginWithArg<O, T> for EnsureNever<Success>
1424 {}
1425}
1426
1427#[docify::export]
1428pub fn ensure_signed<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<AccountId, BadOrigin>
1431where
1432 OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1433{
1434 match o.into() {
1435 Ok(RawOrigin::Signed(t)) => Ok(t),
1436 _ => Err(BadOrigin),
1437 }
1438}
1439
1440pub fn ensure_signed_or_root<OuterOrigin, AccountId>(
1444 o: OuterOrigin,
1445) -> Result<Option<AccountId>, BadOrigin>
1446where
1447 OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1448{
1449 match o.into() {
1450 Ok(RawOrigin::Root) => Ok(None),
1451 Ok(RawOrigin::Signed(t)) => Ok(Some(t)),
1452 _ => Err(BadOrigin),
1453 }
1454}
1455
1456pub fn ensure_root<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), BadOrigin>
1458where
1459 OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1460{
1461 match o.into() {
1462 Ok(RawOrigin::Root) => Ok(()),
1463 _ => Err(BadOrigin),
1464 }
1465}
1466
1467pub fn ensure_none<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), BadOrigin>
1469where
1470 OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1471{
1472 match o.into() {
1473 Ok(RawOrigin::None) => Ok(()),
1474 _ => Err(BadOrigin),
1475 }
1476}
1477
1478#[derive(RuntimeDebug)]
1480pub enum RefStatus {
1481 Referenced,
1482 Unreferenced,
1483}
1484
1485#[derive(Eq, PartialEq, RuntimeDebug)]
1487pub enum IncRefStatus {
1488 Created,
1490 Existed,
1492}
1493
1494#[derive(Eq, PartialEq, RuntimeDebug)]
1496pub enum DecRefStatus {
1497 Reaped,
1499 Exists,
1501}
1502
1503pub enum CanSetCodeResult<T: Config> {
1505 Ok,
1507 MultiBlockMigrationsOngoing,
1509 InvalidVersion(Error<T>),
1511}
1512
1513impl<T: Config> CanSetCodeResult<T> {
1514 pub fn into_result(self) -> Result<(), DispatchError> {
1516 match self {
1517 Self::Ok => Ok(()),
1518 Self::MultiBlockMigrationsOngoing =>
1519 Err(Error::<T>::MultiBlockMigrationsOngoing.into()),
1520 Self::InvalidVersion(err) => Err(err.into()),
1521 }
1522 }
1523
1524 pub fn is_ok(&self) -> bool {
1526 matches!(self, Self::Ok)
1527 }
1528}
1529
1530impl<T: Config> Pallet<T> {
1531 #[doc = docify::embed!("src/tests.rs", last_runtime_upgrade_spec_version_usage)]
1545 pub fn last_runtime_upgrade_spec_version() -> u32 {
1546 LastRuntimeUpgrade::<T>::get().map_or(0, |l| l.spec_version.0)
1547 }
1548
1549 pub fn account_exists(who: &T::AccountId) -> bool {
1551 Account::<T>::contains_key(who)
1552 }
1553
1554 pub fn update_code_in_storage(code: &[u8]) {
1560 storage::unhashed::put_raw(well_known_keys::CODE, code);
1561 Self::deposit_log(generic::DigestItem::RuntimeEnvironmentUpdated);
1562 Self::deposit_event(Event::CodeUpdated);
1563 }
1564
1565 pub fn inherents_applied() -> bool {
1567 InherentsApplied::<T>::get()
1568 }
1569
1570 pub fn note_inherents_applied() {
1575 InherentsApplied::<T>::put(true);
1576 }
1577
1578 #[deprecated = "Use `inc_consumers` instead"]
1580 pub fn inc_ref(who: &T::AccountId) {
1581 let _ = Self::inc_consumers(who);
1582 }
1583
1584 #[deprecated = "Use `dec_consumers` instead"]
1587 pub fn dec_ref(who: &T::AccountId) {
1588 let _ = Self::dec_consumers(who);
1589 }
1590
1591 #[deprecated = "Use `consumers` instead"]
1593 pub fn refs(who: &T::AccountId) -> RefCount {
1594 Self::consumers(who)
1595 }
1596
1597 #[deprecated = "Use `!is_provider_required` instead"]
1599 pub fn allow_death(who: &T::AccountId) -> bool {
1600 !Self::is_provider_required(who)
1601 }
1602
1603 pub fn inc_providers(who: &T::AccountId) -> IncRefStatus {
1605 Account::<T>::mutate(who, |a| {
1606 if a.providers == 0 && a.sufficients == 0 {
1607 a.providers = 1;
1609 Self::on_created_account(who.clone(), a);
1610 IncRefStatus::Created
1611 } else {
1612 a.providers = a.providers.saturating_add(1);
1613 IncRefStatus::Existed
1614 }
1615 })
1616 }
1617
1618 pub fn dec_providers(who: &T::AccountId) -> Result<DecRefStatus, DispatchError> {
1622 Account::<T>::try_mutate_exists(who, |maybe_account| {
1623 if let Some(mut account) = maybe_account.take() {
1624 if account.providers == 0 {
1625 log::error!(
1627 target: LOG_TARGET,
1628 "Logic error: Unexpected underflow in reducing provider",
1629 );
1630 account.providers = 1;
1631 }
1632 match (account.providers, account.consumers, account.sufficients) {
1633 (1, 0, 0) => {
1634 Pallet::<T>::on_killed_account(who.clone());
1637 Ok(DecRefStatus::Reaped)
1638 },
1639 (1, c, _) if c > 0 => {
1640 Err(DispatchError::ConsumerRemaining)
1642 },
1643 (x, _, _) => {
1644 account.providers = x - 1;
1647 *maybe_account = Some(account);
1648 Ok(DecRefStatus::Exists)
1649 },
1650 }
1651 } else {
1652 log::error!(
1653 target: LOG_TARGET,
1654 "Logic error: Account already dead when reducing provider",
1655 );
1656 Ok(DecRefStatus::Reaped)
1657 }
1658 })
1659 }
1660
1661 pub fn inc_sufficients(who: &T::AccountId) -> IncRefStatus {
1663 Account::<T>::mutate(who, |a| {
1664 if a.providers + a.sufficients == 0 {
1665 a.sufficients = 1;
1667 Self::on_created_account(who.clone(), a);
1668 IncRefStatus::Created
1669 } else {
1670 a.sufficients = a.sufficients.saturating_add(1);
1671 IncRefStatus::Existed
1672 }
1673 })
1674 }
1675
1676 pub fn dec_sufficients(who: &T::AccountId) -> DecRefStatus {
1680 Account::<T>::mutate_exists(who, |maybe_account| {
1681 if let Some(mut account) = maybe_account.take() {
1682 if account.sufficients == 0 {
1683 log::error!(
1685 target: LOG_TARGET,
1686 "Logic error: Unexpected underflow in reducing sufficients",
1687 );
1688 }
1689 match (account.sufficients, account.providers) {
1690 (0, 0) | (1, 0) => {
1691 Pallet::<T>::on_killed_account(who.clone());
1692 DecRefStatus::Reaped
1693 },
1694 (x, _) => {
1695 account.sufficients = x.saturating_sub(1);
1696 *maybe_account = Some(account);
1697 DecRefStatus::Exists
1698 },
1699 }
1700 } else {
1701 log::error!(
1702 target: LOG_TARGET,
1703 "Logic error: Account already dead when reducing provider",
1704 );
1705 DecRefStatus::Reaped
1706 }
1707 })
1708 }
1709
1710 pub fn providers(who: &T::AccountId) -> RefCount {
1712 Account::<T>::get(who).providers
1713 }
1714
1715 pub fn sufficients(who: &T::AccountId) -> RefCount {
1717 Account::<T>::get(who).sufficients
1718 }
1719
1720 pub fn reference_count(who: &T::AccountId) -> RefCount {
1722 let a = Account::<T>::get(who);
1723 a.providers + a.sufficients
1724 }
1725
1726 pub fn inc_consumers(who: &T::AccountId) -> Result<(), DispatchError> {
1731 Account::<T>::try_mutate(who, |a| {
1732 if a.providers > 0 {
1733 if a.consumers < T::MaxConsumers::max_consumers() {
1734 a.consumers = a.consumers.saturating_add(1);
1735 Ok(())
1736 } else {
1737 Err(DispatchError::TooManyConsumers)
1738 }
1739 } else {
1740 Err(DispatchError::NoProviders)
1741 }
1742 })
1743 }
1744
1745 pub fn inc_consumers_without_limit(who: &T::AccountId) -> Result<(), DispatchError> {
1749 Account::<T>::try_mutate(who, |a| {
1750 if a.providers > 0 {
1751 a.consumers = a.consumers.saturating_add(1);
1752 Ok(())
1753 } else {
1754 Err(DispatchError::NoProviders)
1755 }
1756 })
1757 }
1758
1759 pub fn dec_consumers(who: &T::AccountId) {
1762 Account::<T>::mutate(who, |a| {
1763 if a.consumers > 0 {
1764 a.consumers -= 1;
1765 } else {
1766 log::error!(
1767 target: LOG_TARGET,
1768 "Logic error: Unexpected underflow in reducing consumer",
1769 );
1770 }
1771 })
1772 }
1773
1774 pub fn consumers(who: &T::AccountId) -> RefCount {
1776 Account::<T>::get(who).consumers
1777 }
1778
1779 pub fn is_provider_required(who: &T::AccountId) -> bool {
1781 Account::<T>::get(who).consumers != 0
1782 }
1783
1784 pub fn can_dec_provider(who: &T::AccountId) -> bool {
1786 let a = Account::<T>::get(who);
1787 a.consumers == 0 || a.providers > 1
1788 }
1789
1790 pub fn can_accrue_consumers(who: &T::AccountId, amount: u32) -> bool {
1793 let a = Account::<T>::get(who);
1794 match a.consumers.checked_add(amount) {
1795 Some(c) => a.providers > 0 && c <= T::MaxConsumers::max_consumers(),
1796 None => false,
1797 }
1798 }
1799
1800 pub fn can_inc_consumer(who: &T::AccountId) -> bool {
1803 Self::can_accrue_consumers(who, 1)
1804 }
1805
1806 pub fn deposit_event(event: impl Into<T::RuntimeEvent>) {
1810 Self::deposit_event_indexed(&[], event.into());
1811 }
1812
1813 pub fn deposit_event_indexed(topics: &[T::Hash], event: T::RuntimeEvent) {
1821 let block_number = Self::block_number();
1822
1823 if block_number.is_zero() {
1825 return
1826 }
1827
1828 let phase = ExecutionPhase::<T>::get().unwrap_or_default();
1829 let event = EventRecord { phase, event, topics: topics.to_vec() };
1830
1831 let event_idx = {
1833 let old_event_count = EventCount::<T>::get();
1834 let new_event_count = match old_event_count.checked_add(1) {
1835 None => return,
1838 Some(nc) => nc,
1839 };
1840 EventCount::<T>::put(new_event_count);
1841 old_event_count
1842 };
1843
1844 Events::<T>::append(event);
1845
1846 for topic in topics {
1847 <EventTopics<T>>::append(topic, &(block_number, event_idx));
1848 }
1849 }
1850
1851 pub fn extrinsic_index() -> Option<u32> {
1853 storage::unhashed::get(well_known_keys::EXTRINSIC_INDEX)
1854 }
1855
1856 pub fn extrinsic_count() -> u32 {
1858 ExtrinsicCount::<T>::get().unwrap_or_default()
1859 }
1860
1861 pub fn all_extrinsics_len() -> u32 {
1862 AllExtrinsicsLen::<T>::get().unwrap_or_default()
1863 }
1864
1865 pub fn register_extra_weight_unchecked(weight: Weight, class: DispatchClass) {
1881 BlockWeight::<T>::mutate(|current_weight| {
1882 current_weight.accrue(weight, class);
1883 });
1884 }
1885
1886 pub fn initialize(number: &BlockNumberFor<T>, parent_hash: &T::Hash, digest: &generic::Digest) {
1888 ExecutionPhase::<T>::put(Phase::Initialization);
1890 storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &0u32);
1891 let entropy = (b"frame_system::initialize", parent_hash).using_encoded(blake2_256);
1892 storage::unhashed::put_raw(well_known_keys::INTRABLOCK_ENTROPY, &entropy[..]);
1893 <Number<T>>::put(number);
1894 <Digest<T>>::put(digest);
1895 <ParentHash<T>>::put(parent_hash);
1896 <BlockHash<T>>::insert(*number - One::one(), parent_hash);
1897 <InherentsApplied<T>>::kill();
1898
1899 BlockWeight::<T>::kill();
1901 }
1902
1903 pub fn finalize() -> HeaderFor<T> {
1906 log::debug!(
1907 target: LOG_TARGET,
1908 "[{:?}] {} extrinsics, length: {} (normal {}%, op: {}%, mandatory {}%) / normal weight:\
1909 {} ({}%) op weight {} ({}%) / mandatory weight {} ({}%)",
1910 Self::block_number(),
1911 Self::extrinsic_count(),
1912 Self::all_extrinsics_len(),
1913 sp_runtime::Percent::from_rational(
1914 Self::all_extrinsics_len(),
1915 *T::BlockLength::get().max.get(DispatchClass::Normal)
1916 ).deconstruct(),
1917 sp_runtime::Percent::from_rational(
1918 Self::all_extrinsics_len(),
1919 *T::BlockLength::get().max.get(DispatchClass::Operational)
1920 ).deconstruct(),
1921 sp_runtime::Percent::from_rational(
1922 Self::all_extrinsics_len(),
1923 *T::BlockLength::get().max.get(DispatchClass::Mandatory)
1924 ).deconstruct(),
1925 Self::block_weight().get(DispatchClass::Normal),
1926 sp_runtime::Percent::from_rational(
1927 Self::block_weight().get(DispatchClass::Normal).ref_time(),
1928 T::BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap_or(Bounded::max_value()).ref_time()
1929 ).deconstruct(),
1930 Self::block_weight().get(DispatchClass::Operational),
1931 sp_runtime::Percent::from_rational(
1932 Self::block_weight().get(DispatchClass::Operational).ref_time(),
1933 T::BlockWeights::get().get(DispatchClass::Operational).max_total.unwrap_or(Bounded::max_value()).ref_time()
1934 ).deconstruct(),
1935 Self::block_weight().get(DispatchClass::Mandatory),
1936 sp_runtime::Percent::from_rational(
1937 Self::block_weight().get(DispatchClass::Mandatory).ref_time(),
1938 T::BlockWeights::get().get(DispatchClass::Mandatory).max_total.unwrap_or(Bounded::max_value()).ref_time()
1939 ).deconstruct(),
1940 );
1941 ExecutionPhase::<T>::kill();
1942 AllExtrinsicsLen::<T>::kill();
1943 storage::unhashed::kill(well_known_keys::INTRABLOCK_ENTROPY);
1944 InherentsApplied::<T>::kill();
1945
1946 let number = <Number<T>>::get();
1957 let parent_hash = <ParentHash<T>>::get();
1958 let digest = <Digest<T>>::get();
1959
1960 let extrinsics = (0..ExtrinsicCount::<T>::take().unwrap_or_default())
1961 .map(ExtrinsicData::<T>::take)
1962 .collect();
1963 let extrinsics_root_state_version = T::Version::get().extrinsics_root_state_version();
1964 let extrinsics_root =
1965 extrinsics_data_root::<T::Hashing>(extrinsics, extrinsics_root_state_version);
1966
1967 let block_hash_count = T::BlockHashCount::get();
1969 let to_remove = number.saturating_sub(block_hash_count).saturating_sub(One::one());
1970
1971 if !to_remove.is_zero() {
1973 <BlockHash<T>>::remove(to_remove);
1974 }
1975
1976 let version = T::Version::get().state_version();
1977 let storage_root = T::Hash::decode(&mut &sp_io::storage::root(version)[..])
1978 .expect("Node is configured to use the same hash; qed");
1979
1980 HeaderFor::<T>::new(number, extrinsics_root, storage_root, parent_hash, digest)
1981 }
1982
1983 pub fn deposit_log(item: generic::DigestItem) {
1985 <Digest<T>>::append(item);
1986 }
1987
1988 #[cfg(any(feature = "std", test))]
1990 pub fn externalities() -> TestExternalities {
1991 TestExternalities::new(sp_core::storage::Storage {
1992 top: [
1993 (<BlockHash<T>>::hashed_key_for(BlockNumberFor::<T>::zero()), [69u8; 32].encode()),
1994 (<Number<T>>::hashed_key().to_vec(), BlockNumberFor::<T>::one().encode()),
1995 (<ParentHash<T>>::hashed_key().to_vec(), [69u8; 32].encode()),
1996 ]
1997 .into_iter()
1998 .collect(),
1999 children_default: Default::default(),
2000 })
2001 }
2002
2003 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2011 pub fn events() -> Vec<EventRecord<T::RuntimeEvent, T::Hash>> {
2012 Self::read_events_no_consensus().map(|e| *e).collect()
2014 }
2015
2016 pub fn event_no_consensus(index: usize) -> Option<T::RuntimeEvent> {
2021 Self::read_events_no_consensus().nth(index).map(|e| e.event.clone())
2022 }
2023
2024 pub fn read_events_no_consensus(
2029 ) -> impl Iterator<Item = Box<EventRecord<T::RuntimeEvent, T::Hash>>> {
2030 Events::<T>::stream_iter()
2031 }
2032
2033 pub fn read_events_for_pallet<E>() -> Vec<E>
2038 where
2039 T::RuntimeEvent: TryInto<E>,
2040 {
2041 Events::<T>::get()
2042 .into_iter()
2043 .map(|er| er.event)
2044 .filter_map(|e| e.try_into().ok())
2045 .collect::<_>()
2046 }
2047
2048 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2057 pub fn run_to_block_with<AllPalletsWithSystem>(
2058 n: BlockNumberFor<T>,
2059 mut hooks: RunToBlockHooks<T>,
2060 ) where
2061 AllPalletsWithSystem: frame_support::traits::OnInitialize<BlockNumberFor<T>>
2062 + frame_support::traits::OnFinalize<BlockNumberFor<T>>,
2063 {
2064 let mut bn = Self::block_number();
2065
2066 while bn < n {
2067 if !bn.is_zero() {
2069 (hooks.before_finalize)(bn);
2070 AllPalletsWithSystem::on_finalize(bn);
2071 (hooks.after_finalize)(bn);
2072 }
2073
2074 bn += One::one();
2075
2076 Self::set_block_number(bn);
2077 (hooks.before_initialize)(bn);
2078 AllPalletsWithSystem::on_initialize(bn);
2079 (hooks.after_initialize)(bn);
2080 }
2081 }
2082
2083 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2085 pub fn run_to_block<AllPalletsWithSystem>(n: BlockNumberFor<T>)
2086 where
2087 AllPalletsWithSystem: frame_support::traits::OnInitialize<BlockNumberFor<T>>
2088 + frame_support::traits::OnFinalize<BlockNumberFor<T>>,
2089 {
2090 Self::run_to_block_with::<AllPalletsWithSystem>(n, Default::default());
2091 }
2092
2093 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2096 pub fn set_block_number(n: BlockNumberFor<T>) {
2097 <Number<T>>::put(n);
2098 }
2099
2100 #[cfg(any(feature = "std", test))]
2102 pub fn set_extrinsic_index(extrinsic_index: u32) {
2103 storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &extrinsic_index)
2104 }
2105
2106 #[cfg(any(feature = "std", test))]
2109 pub fn set_parent_hash(n: T::Hash) {
2110 <ParentHash<T>>::put(n);
2111 }
2112
2113 #[cfg(any(feature = "std", test))]
2115 pub fn set_block_consumed_resources(weight: Weight, len: usize) {
2116 BlockWeight::<T>::mutate(|current_weight| {
2117 current_weight.set(weight, DispatchClass::Normal)
2118 });
2119 AllExtrinsicsLen::<T>::put(len as u32);
2120 }
2121
2122 pub fn reset_events() {
2127 <Events<T>>::kill();
2128 EventCount::<T>::kill();
2129 let _ = <EventTopics<T>>::clear(u32::max_value(), None);
2130 }
2131
2132 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2136 #[track_caller]
2137 pub fn assert_has_event(event: T::RuntimeEvent) {
2138 let warn = if Self::block_number().is_zero() {
2139 "WARNING: block number is zero, and events are not registered at block number zero.\n"
2140 } else {
2141 ""
2142 };
2143
2144 let events = Self::events();
2145 assert!(
2146 events.iter().any(|record| record.event == event),
2147 "{warn}expected event {event:?} not found in events {events:?}",
2148 );
2149 }
2150
2151 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2155 #[track_caller]
2156 pub fn assert_last_event(event: T::RuntimeEvent) {
2157 let warn = if Self::block_number().is_zero() {
2158 "WARNING: block number is zero, and events are not registered at block number zero.\n"
2159 } else {
2160 ""
2161 };
2162
2163 let last_event = Self::events()
2164 .last()
2165 .expect(&alloc::format!("{warn}events expected"))
2166 .event
2167 .clone();
2168 assert_eq!(
2169 last_event, event,
2170 "{warn}expected event {event:?} is not equal to the last event {last_event:?}",
2171 );
2172 }
2173
2174 pub fn runtime_version() -> RuntimeVersion {
2176 T::Version::get()
2177 }
2178
2179 pub fn account_nonce(who: impl EncodeLike<T::AccountId>) -> T::Nonce {
2181 Account::<T>::get(who).nonce
2182 }
2183
2184 pub fn inc_account_nonce(who: impl EncodeLike<T::AccountId>) {
2186 Account::<T>::mutate(who, |a| a.nonce += T::Nonce::one());
2187 }
2188
2189 pub fn note_extrinsic(encoded_xt: Vec<u8>) {
2194 ExtrinsicData::<T>::insert(Self::extrinsic_index().unwrap_or_default(), encoded_xt);
2195 }
2196
2197 pub fn note_applied_extrinsic(r: &DispatchResultWithPostInfo, info: DispatchInfo) {
2203 let weight = extract_actual_weight(r, &info)
2204 .saturating_add(T::BlockWeights::get().get(info.class).base_extrinsic);
2205 let class = info.class;
2206 let pays_fee = extract_actual_pays_fee(r, &info);
2207 let dispatch_event_info = DispatchEventInfo { weight, class, pays_fee };
2208
2209 Self::deposit_event(match r {
2210 Ok(_) => Event::ExtrinsicSuccess { dispatch_info: dispatch_event_info },
2211 Err(err) => {
2212 log::trace!(
2213 target: LOG_TARGET,
2214 "Extrinsic failed at block({:?}): {:?}",
2215 Self::block_number(),
2216 err,
2217 );
2218 Event::ExtrinsicFailed {
2219 dispatch_error: err.error,
2220 dispatch_info: dispatch_event_info,
2221 }
2222 },
2223 });
2224
2225 log::trace!(
2226 target: LOG_TARGET,
2227 "Used block weight: {:?}",
2228 BlockWeight::<T>::get(),
2229 );
2230
2231 log::trace!(
2232 target: LOG_TARGET,
2233 "Used block length: {:?}",
2234 Pallet::<T>::all_extrinsics_len(),
2235 );
2236
2237 let next_extrinsic_index = Self::extrinsic_index().unwrap_or_default() + 1u32;
2238
2239 storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &next_extrinsic_index);
2240 ExecutionPhase::<T>::put(Phase::ApplyExtrinsic(next_extrinsic_index));
2241 ExtrinsicWeightReclaimed::<T>::kill();
2242 }
2243
2244 pub fn note_finished_extrinsics() {
2247 let extrinsic_index: u32 =
2248 storage::unhashed::take(well_known_keys::EXTRINSIC_INDEX).unwrap_or_default();
2249 ExtrinsicCount::<T>::put(extrinsic_index);
2250 ExecutionPhase::<T>::put(Phase::Finalization);
2251 }
2252
2253 pub fn note_finished_initialize() {
2256 ExecutionPhase::<T>::put(Phase::ApplyExtrinsic(0))
2257 }
2258
2259 pub fn on_created_account(who: T::AccountId, _a: &mut AccountInfo<T::Nonce, T::AccountData>) {
2261 T::OnNewAccount::on_new_account(&who);
2262 Self::deposit_event(Event::NewAccount { account: who });
2263 }
2264
2265 fn on_killed_account(who: T::AccountId) {
2267 T::OnKilledAccount::on_killed_account(&who);
2268 Self::deposit_event(Event::KilledAccount { account: who });
2269 }
2270
2271 pub fn can_set_code(code: &[u8], check_version: bool) -> CanSetCodeResult<T> {
2275 if T::MultiBlockMigrator::ongoing() {
2276 return CanSetCodeResult::MultiBlockMigrationsOngoing
2277 }
2278
2279 if check_version {
2280 let current_version = T::Version::get();
2281 let Some(new_version) = sp_io::misc::runtime_version(code)
2282 .and_then(|v| RuntimeVersion::decode(&mut &v[..]).ok())
2283 else {
2284 return CanSetCodeResult::InvalidVersion(Error::<T>::FailedToExtractRuntimeVersion)
2285 };
2286
2287 cfg_if::cfg_if! {
2288 if #[cfg(all(feature = "runtime-benchmarks", not(test)))] {
2289 core::hint::black_box((new_version, current_version));
2291 } else {
2292 if new_version.spec_name != current_version.spec_name {
2293 return CanSetCodeResult::InvalidVersion( Error::<T>::InvalidSpecName)
2294 }
2295
2296 if new_version.spec_version <= current_version.spec_version {
2297 return CanSetCodeResult::InvalidVersion(Error::<T>::SpecVersionNeedsToIncrease)
2298 }
2299 }
2300 }
2301 }
2302
2303 CanSetCodeResult::Ok
2304 }
2305
2306 pub fn do_authorize_upgrade(code_hash: T::Hash, check_version: bool) {
2308 AuthorizedUpgrade::<T>::put(CodeUpgradeAuthorization { code_hash, check_version });
2309 Self::deposit_event(Event::UpgradeAuthorized { code_hash, check_version });
2310 }
2311
2312 fn validate_code_is_authorized(
2316 code: &[u8],
2317 ) -> Result<CodeUpgradeAuthorization<T>, DispatchError> {
2318 let authorization = AuthorizedUpgrade::<T>::get().ok_or(Error::<T>::NothingAuthorized)?;
2319 let actual_hash = T::Hashing::hash(code);
2320 ensure!(actual_hash == authorization.code_hash, Error::<T>::Unauthorized);
2321 Ok(authorization)
2322 }
2323
2324 pub fn reclaim_weight(
2329 info: &DispatchInfoOf<T::RuntimeCall>,
2330 post_info: &PostDispatchInfoOf<T::RuntimeCall>,
2331 ) -> Result<(), TransactionValidityError>
2332 where
2333 T::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
2334 {
2335 let already_reclaimed = crate::ExtrinsicWeightReclaimed::<T>::get();
2336 let unspent = post_info.calc_unspent(info);
2337 let accurate_reclaim = already_reclaimed.max(unspent);
2338 let to_reclaim_more = accurate_reclaim.saturating_sub(already_reclaimed);
2340 if to_reclaim_more != Weight::zero() {
2341 crate::BlockWeight::<T>::mutate(|current_weight| {
2342 current_weight.reduce(to_reclaim_more, info.class);
2343 });
2344 crate::ExtrinsicWeightReclaimed::<T>::put(accurate_reclaim);
2345 }
2346
2347 Ok(())
2348 }
2349}
2350
2351pub fn unique(entropy: impl Encode) -> [u8; 32] {
2354 let mut last = [0u8; 32];
2355 sp_io::storage::read(well_known_keys::INTRABLOCK_ENTROPY, &mut last[..], 0);
2356 let next = (b"frame_system::unique", entropy, last).using_encoded(blake2_256);
2357 sp_io::storage::set(well_known_keys::INTRABLOCK_ENTROPY, &next);
2358 next
2359}
2360
2361pub struct Provider<T>(PhantomData<T>);
2363impl<T: Config> HandleLifetime<T::AccountId> for Provider<T> {
2364 fn created(t: &T::AccountId) -> Result<(), DispatchError> {
2365 Pallet::<T>::inc_providers(t);
2366 Ok(())
2367 }
2368 fn killed(t: &T::AccountId) -> Result<(), DispatchError> {
2369 Pallet::<T>::dec_providers(t).map(|_| ())
2370 }
2371}
2372
2373pub struct SelfSufficient<T>(PhantomData<T>);
2375impl<T: Config> HandleLifetime<T::AccountId> for SelfSufficient<T> {
2376 fn created(t: &T::AccountId) -> Result<(), DispatchError> {
2377 Pallet::<T>::inc_sufficients(t);
2378 Ok(())
2379 }
2380 fn killed(t: &T::AccountId) -> Result<(), DispatchError> {
2381 Pallet::<T>::dec_sufficients(t);
2382 Ok(())
2383 }
2384}
2385
2386pub struct Consumer<T>(PhantomData<T>);
2388impl<T: Config> HandleLifetime<T::AccountId> for Consumer<T> {
2389 fn created(t: &T::AccountId) -> Result<(), DispatchError> {
2390 Pallet::<T>::inc_consumers(t)
2391 }
2392 fn killed(t: &T::AccountId) -> Result<(), DispatchError> {
2393 Pallet::<T>::dec_consumers(t);
2394 Ok(())
2395 }
2396}
2397
2398impl<T: Config> BlockNumberProvider for Pallet<T> {
2399 type BlockNumber = BlockNumberFor<T>;
2400
2401 fn current_block_number() -> Self::BlockNumber {
2402 Pallet::<T>::block_number()
2403 }
2404
2405 #[cfg(feature = "runtime-benchmarks")]
2406 fn set_block_number(n: BlockNumberFor<T>) {
2407 Self::set_block_number(n)
2408 }
2409}
2410
2411impl<T: Config> StoredMap<T::AccountId, T::AccountData> for Pallet<T> {
2417 fn get(k: &T::AccountId) -> T::AccountData {
2418 Account::<T>::get(k).data
2419 }
2420
2421 fn try_mutate_exists<R, E: From<DispatchError>>(
2422 k: &T::AccountId,
2423 f: impl FnOnce(&mut Option<T::AccountData>) -> Result<R, E>,
2424 ) -> Result<R, E> {
2425 let account = Account::<T>::get(k);
2426 let is_default = account.data == T::AccountData::default();
2427 let mut some_data = if is_default { None } else { Some(account.data) };
2428 let result = f(&mut some_data)?;
2429 if Self::providers(k) > 0 || Self::sufficients(k) > 0 {
2430 Account::<T>::mutate(k, |a| a.data = some_data.unwrap_or_default());
2431 } else {
2432 Account::<T>::remove(k)
2433 }
2434 Ok(result)
2435 }
2436}
2437
2438pub fn split_inner<T, R, S>(
2440 option: Option<T>,
2441 splitter: impl FnOnce(T) -> (R, S),
2442) -> (Option<R>, Option<S>) {
2443 match option {
2444 Some(inner) => {
2445 let (r, s) = splitter(inner);
2446 (Some(r), Some(s))
2447 },
2448 None => (None, None),
2449 }
2450}
2451
2452pub struct ChainContext<T>(PhantomData<T>);
2453impl<T> Default for ChainContext<T> {
2454 fn default() -> Self {
2455 ChainContext(PhantomData)
2456 }
2457}
2458
2459impl<T: Config> Lookup for ChainContext<T> {
2460 type Source = <T::Lookup as StaticLookup>::Source;
2461 type Target = <T::Lookup as StaticLookup>::Target;
2462
2463 fn lookup(&self, s: Self::Source) -> Result<Self::Target, LookupError> {
2464 <T::Lookup as StaticLookup>::lookup(s)
2465 }
2466}
2467
2468#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2470pub struct RunToBlockHooks<'a, T>
2471where
2472 T: 'a + Config,
2473{
2474 before_initialize: Box<dyn 'a + FnMut(BlockNumberFor<T>)>,
2475 after_initialize: Box<dyn 'a + FnMut(BlockNumberFor<T>)>,
2476 before_finalize: Box<dyn 'a + FnMut(BlockNumberFor<T>)>,
2477 after_finalize: Box<dyn 'a + FnMut(BlockNumberFor<T>)>,
2478}
2479
2480#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2481impl<'a, T> RunToBlockHooks<'a, T>
2482where
2483 T: 'a + Config,
2484{
2485 pub fn before_initialize<F>(mut self, f: F) -> Self
2487 where
2488 F: 'a + FnMut(BlockNumberFor<T>),
2489 {
2490 self.before_initialize = Box::new(f);
2491 self
2492 }
2493 pub fn after_initialize<F>(mut self, f: F) -> Self
2495 where
2496 F: 'a + FnMut(BlockNumberFor<T>),
2497 {
2498 self.after_initialize = Box::new(f);
2499 self
2500 }
2501 pub fn before_finalize<F>(mut self, f: F) -> Self
2503 where
2504 F: 'a + FnMut(BlockNumberFor<T>),
2505 {
2506 self.before_finalize = Box::new(f);
2507 self
2508 }
2509 pub fn after_finalize<F>(mut self, f: F) -> Self
2511 where
2512 F: 'a + FnMut(BlockNumberFor<T>),
2513 {
2514 self.after_finalize = Box::new(f);
2515 self
2516 }
2517}
2518
2519#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2520impl<'a, T> Default for RunToBlockHooks<'a, T>
2521where
2522 T: Config,
2523{
2524 fn default() -> Self {
2525 Self {
2526 before_initialize: Box::new(|_| {}),
2527 after_initialize: Box::new(|_| {}),
2528 before_finalize: Box::new(|_| {}),
2529 after_finalize: Box::new(|_| {}),
2530 }
2531 }
2532}
2533
2534pub mod pallet_prelude {
2536 pub use crate::{ensure_none, ensure_root, ensure_signed, ensure_signed_or_root};
2537
2538 pub type OriginFor<T> = <T as crate::Config>::RuntimeOrigin;
2540
2541 pub type HeaderFor<T> =
2543 <<T as crate::Config>::Block as sp_runtime::traits::HeaderProvider>::HeaderT;
2544
2545 pub type BlockNumberFor<T> = <HeaderFor<T> as sp_runtime::traits::Header>::Number;
2547
2548 pub type ExtrinsicFor<T> =
2550 <<T as crate::Config>::Block as sp_runtime::traits::Block>::Extrinsic;
2551
2552 pub type RuntimeCallFor<T> = <T as crate::Config>::RuntimeCall;
2554}