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, AsTransactionAuthorizedOrigin, AtLeast32Bit, BadOrigin, BlockNumberProvider, Bounded,
114 CheckEqual, Dispatchable, Hash, Header, Lookup, LookupError, MaybeDisplay,
115 MaybeSerializeDeserialize, Member, One, Saturating, SimpleBitOps, StaticLookup, Zero,
116 },
117 transaction_validity::{
118 InvalidTransaction, TransactionLongevity, TransactionSource, TransactionValidity,
119 ValidTransaction,
120 },
121 DispatchError,
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 defensive,
130 dispatch::{
131 extract_actual_pays_fee, extract_actual_weight, DispatchClass, DispatchInfo,
132 DispatchResult, DispatchResultWithPostInfo, GetDispatchInfo, PerDispatchClass,
133 PostDispatchInfo,
134 },
135 ensure, impl_ensure_origin_with_arg_ignoring_arg,
136 migrations::MultiStepMigrator,
137 pallet_prelude::Pays,
138 storage::{self, StorageStreamIter},
139 traits::{
140 ConstU32, Contains, EnsureOrigin, EnsureOriginWithArg, Get, HandleLifetime,
141 OnKilledAccount, OnNewAccount, OnRuntimeUpgrade, OriginTrait, PalletInfo, SortedMembers,
142 StoredMap, TypedGet,
143 },
144 Parameter,
145};
146use scale_info::TypeInfo;
147use sp_core::storage::well_known_keys;
148use sp_runtime::{
149 traits::{DispatchInfoOf, PostDispatchInfoOf},
150 transaction_validity::TransactionValidityError,
151};
152use sp_weights::{RuntimeDbWeight, Weight, WeightMeter};
153
154#[cfg(any(feature = "std", test))]
155use sp_io::TestExternalities;
156
157pub mod limits;
158#[cfg(test)]
159pub(crate) mod mock;
160
161pub mod offchain;
162
163mod extensions;
164#[cfg(feature = "std")]
165pub mod mocking;
166#[cfg(test)]
167mod tests;
168pub mod weights;
169
170pub mod migrations;
171
172pub use extensions::{
173 authorize_call::AuthorizeCall,
174 check_genesis::CheckGenesis,
175 check_mortality::CheckMortality,
176 check_non_zero_sender::CheckNonZeroSender,
177 check_nonce::{CheckNonce, ValidNonceInfo},
178 check_spec_version::CheckSpecVersion,
179 check_tx_version::CheckTxVersion,
180 check_weight::{calculate_consumed_extrinsic_weight, CheckWeight},
181 weight_reclaim::WeightReclaim,
182 weights::SubstrateWeight as SubstrateExtensionsWeight,
183 WeightInfo as ExtensionsWeightInfo,
184};
185pub use extensions::check_mortality::CheckMortality as CheckEra;
187pub use frame_support::dispatch::RawOrigin;
188use frame_support::traits::{Authorize, PostInherents, PostTransactions, PreInherents};
189use sp_core::storage::StateVersion;
190pub use weights::WeightInfo;
191
192const LOG_TARGET: &str = "runtime::system";
193
194pub fn extrinsics_root<H: Hash, E: codec::Encode>(
199 extrinsics: &[E],
200 state_version: StateVersion,
201) -> H::Output {
202 extrinsics_data_root::<H>(extrinsics.iter().map(codec::Encode::encode).collect(), state_version)
203}
204
205pub fn extrinsics_data_root<H: Hash>(xts: Vec<Vec<u8>>, state_version: StateVersion) -> H::Output {
210 H::ordered_trie_root(xts, state_version)
211}
212
213pub type ConsumedWeight = PerDispatchClass<Weight>;
215
216pub use pallet::*;
217
218pub trait SetCode<T: Config> {
220 fn set_code(code: Vec<u8>) -> DispatchResult;
222}
223
224impl<T: Config> SetCode<T> for () {
225 fn set_code(code: Vec<u8>) -> DispatchResult {
226 <Pallet<T>>::update_code_in_storage(&code);
227 Ok(())
228 }
229}
230
231pub trait ConsumerLimits {
233 fn max_consumers() -> RefCount;
235 fn max_overflow() -> RefCount;
241}
242
243impl<const Z: u32> ConsumerLimits for ConstU32<Z> {
244 fn max_consumers() -> RefCount {
245 Z
246 }
247 fn max_overflow() -> RefCount {
248 Z
249 }
250}
251
252impl<MaxNormal: Get<u32>, MaxOverflow: Get<u32>> ConsumerLimits for (MaxNormal, MaxOverflow) {
253 fn max_consumers() -> RefCount {
254 MaxNormal::get()
255 }
256 fn max_overflow() -> RefCount {
257 MaxOverflow::get()
258 }
259}
260
261#[derive(Decode, Encode, Default, PartialEq, Eq, MaxEncodedLen, TypeInfo)]
264#[scale_info(skip_type_params(T))]
265pub struct CodeUpgradeAuthorization<T>
266where
267 T: Config,
268{
269 code_hash: T::Hash,
271 check_version: bool,
273}
274
275#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
276impl<T> CodeUpgradeAuthorization<T>
277where
278 T: Config,
279{
280 pub fn code_hash(&self) -> &T::Hash {
281 &self.code_hash
282 }
283}
284
285#[derive(
289 Clone, Copy, Eq, PartialEq, Default, Debug, Encode, Decode, DecodeWithMemTracking, TypeInfo,
290)]
291pub struct DispatchEventInfo {
292 pub weight: Weight,
294 pub class: DispatchClass,
296 pub pays_fee: Pays,
298}
299
300#[frame_support::pallet]
301pub mod pallet {
302 use crate::{self as frame_system, pallet_prelude::*, *};
303 use codec::HasCompact;
304 use frame_support::pallet_prelude::*;
305
306 pub mod config_preludes {
308 use super::{inject_runtime_type, DefaultConfig};
309 use frame_support::{derive_impl, traits::Get};
310
311 pub struct TestBlockHashCount<C: Get<u32>>(core::marker::PhantomData<C>);
317 impl<I: From<u32>, C: Get<u32>> Get<I> for TestBlockHashCount<C> {
318 fn get() -> I {
319 C::get().into()
320 }
321 }
322
323 pub struct TestDefaultConfig;
330
331 #[frame_support::register_default_impl(TestDefaultConfig)]
332 impl DefaultConfig for TestDefaultConfig {
333 type Nonce = u32;
334 type Hash = sp_core::hash::H256;
335 type Hashing = sp_runtime::traits::BlakeTwo256;
336 type AccountId = u64;
337 type Lookup = sp_runtime::traits::IdentityLookup<Self::AccountId>;
338 type MaxConsumers = frame_support::traits::ConstU32<16>;
339 type AccountData = ();
340 type OnNewAccount = ();
341 type OnKilledAccount = ();
342 type SystemWeightInfo = ();
343 type ExtensionsWeightInfo = ();
344 type SS58Prefix = ();
345 type Version = ();
346 type BlockWeights = ();
347 type BlockLength = ();
348 type DbWeight = ();
349 #[inject_runtime_type]
350 type RuntimeEvent = ();
351 #[inject_runtime_type]
352 type RuntimeOrigin = ();
353 #[inject_runtime_type]
354 type RuntimeCall = ();
355 #[inject_runtime_type]
356 type PalletInfo = ();
357 #[inject_runtime_type]
358 type RuntimeTask = ();
359 type BaseCallFilter = frame_support::traits::Everything;
360 type BlockHashCount = TestBlockHashCount<frame_support::traits::ConstU32<10>>;
361 type OnSetCode = ();
362 type SingleBlockMigrations = ();
363 type MultiBlockMigrator = ();
364 type PreInherents = ();
365 type PostInherents = ();
366 type PostTransactions = ();
367 }
368
369 pub struct SolochainDefaultConfig;
383
384 #[frame_support::register_default_impl(SolochainDefaultConfig)]
385 impl DefaultConfig for SolochainDefaultConfig {
386 type Nonce = u32;
388
389 type Hash = sp_core::hash::H256;
391
392 type Hashing = sp_runtime::traits::BlakeTwo256;
394
395 type AccountId = sp_runtime::AccountId32;
397
398 type Lookup = sp_runtime::traits::AccountIdLookup<Self::AccountId, ()>;
400
401 type MaxConsumers = frame_support::traits::ConstU32<128>;
403
404 type AccountData = ();
406
407 type OnNewAccount = ();
409
410 type OnKilledAccount = ();
412
413 type SystemWeightInfo = ();
415
416 type ExtensionsWeightInfo = ();
418
419 type SS58Prefix = ();
421
422 type Version = ();
424
425 type BlockWeights = ();
427
428 type BlockLength = ();
430
431 type DbWeight = ();
433
434 #[inject_runtime_type]
436 type RuntimeEvent = ();
437
438 #[inject_runtime_type]
440 type RuntimeOrigin = ();
441
442 #[inject_runtime_type]
445 type RuntimeCall = ();
446
447 #[inject_runtime_type]
449 type RuntimeTask = ();
450
451 #[inject_runtime_type]
453 type PalletInfo = ();
454
455 type BaseCallFilter = frame_support::traits::Everything;
457
458 type BlockHashCount = TestBlockHashCount<frame_support::traits::ConstU32<256>>;
461
462 type OnSetCode = ();
464 type SingleBlockMigrations = ();
465 type MultiBlockMigrator = ();
466 type PreInherents = ();
467 type PostInherents = ();
468 type PostTransactions = ();
469 }
470
471 pub struct RelayChainDefaultConfig;
473
474 #[derive_impl(SolochainDefaultConfig as DefaultConfig, no_aggregated_types)]
476 #[frame_support::register_default_impl(RelayChainDefaultConfig)]
477 impl DefaultConfig for RelayChainDefaultConfig {}
478
479 pub struct ParaChainDefaultConfig;
481
482 #[derive_impl(SolochainDefaultConfig as DefaultConfig, no_aggregated_types)]
484 #[frame_support::register_default_impl(ParaChainDefaultConfig)]
485 impl DefaultConfig for ParaChainDefaultConfig {}
486 }
487
488 #[pallet::config(with_default, frame_system_config)]
490 #[pallet::disable_frame_system_supertrait_check]
491 pub trait Config: 'static + Eq + Clone {
492 #[pallet::no_default_bounds]
494 type RuntimeEvent: Parameter
495 + Member
496 + From<Event<Self>>
497 + Debug
498 + IsType<<Self as frame_system::Config>::RuntimeEvent>;
499
500 #[pallet::no_default_bounds]
511 type BaseCallFilter: Contains<Self::RuntimeCall>;
512
513 #[pallet::constant]
515 type BlockWeights: Get<limits::BlockWeights>;
516
517 #[pallet::constant]
519 type BlockLength: Get<limits::BlockLength>;
520
521 #[pallet::no_default_bounds]
523 type RuntimeOrigin: Into<Result<RawOrigin<Self::AccountId>, Self::RuntimeOrigin>>
524 + From<RawOrigin<Self::AccountId>>
525 + Clone
526 + OriginTrait<Call = Self::RuntimeCall, AccountId = Self::AccountId>
527 + AsTransactionAuthorizedOrigin;
528
529 #[docify::export(system_runtime_call)]
530 #[pallet::no_default_bounds]
532 type RuntimeCall: Parameter
533 + Dispatchable<RuntimeOrigin = Self::RuntimeOrigin>
534 + Debug
535 + GetDispatchInfo
536 + From<Call<Self>>
537 + Authorize;
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(weight = <T as Config>::SystemWeightInfo)]
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 },
885 CanSetCodeResult::InvalidVersion(error) => {
886 Self::deposit_event(Event::RejectedInvalidAuthorizedUpgrade {
888 code_hash: res.code_hash,
889 error: error.into(),
890 });
891
892 return Ok(Pays::No.into());
894 },
895 };
896 T::OnSetCode::set_code(code)?;
897
898 Ok(PostDispatchInfo {
899 actual_weight: Some(T::BlockWeights::get().max_block),
901 pays_fee: Pays::No,
903 })
904 }
905 }
906
907 #[pallet::event]
909 pub enum Event<T: Config> {
910 ExtrinsicSuccess { dispatch_info: DispatchEventInfo },
912 ExtrinsicFailed { dispatch_error: DispatchError, dispatch_info: DispatchEventInfo },
914 CodeUpdated { hash: T::Hash },
916 NewAccount { account: T::AccountId },
918 KilledAccount { account: T::AccountId },
920 Remarked { sender: T::AccountId, hash: T::Hash },
922 #[cfg(feature = "experimental")]
923 TaskStarted { task: T::RuntimeTask },
925 #[cfg(feature = "experimental")]
926 TaskCompleted { task: T::RuntimeTask },
928 #[cfg(feature = "experimental")]
929 TaskFailed { task: T::RuntimeTask, err: DispatchError },
931 UpgradeAuthorized { code_hash: T::Hash, check_version: bool },
933 RejectedInvalidAuthorizedUpgrade { code_hash: T::Hash, error: DispatchError },
935 }
936
937 #[pallet::error]
939 pub enum Error<T> {
940 InvalidSpecName,
943 SpecVersionNeedsToIncrease,
946 FailedToExtractRuntimeVersion,
950 NonDefaultComposite,
952 NonZeroRefCount,
954 CallFiltered,
956 MultiBlockMigrationsOngoing,
958 #[cfg(feature = "experimental")]
959 InvalidTask,
961 #[cfg(feature = "experimental")]
962 FailedTask,
964 NothingAuthorized,
966 Unauthorized,
968 }
969
970 #[pallet::origin]
972 pub type Origin<T> = RawOrigin<<T as Config>::AccountId>;
973
974 #[pallet::storage]
976 #[pallet::getter(fn account)]
977 pub type Account<T: Config> = StorageMap<
978 _,
979 Blake2_128Concat,
980 T::AccountId,
981 AccountInfo<T::Nonce, T::AccountData>,
982 ValueQuery,
983 >;
984
985 #[pallet::storage]
987 #[pallet::whitelist_storage]
988 pub(super) type ExtrinsicCount<T: Config> = StorageValue<_, u32>;
989
990 #[pallet::storage]
992 #[pallet::whitelist_storage]
993 pub type InherentsApplied<T: Config> = StorageValue<_, bool, ValueQuery>;
994
995 #[pallet::storage]
997 #[pallet::whitelist_storage]
998 #[pallet::getter(fn block_weight)]
999 pub type BlockWeight<T: Config> = StorageValue<_, ConsumedWeight, ValueQuery>;
1000
1001 #[pallet::storage]
1005 #[pallet::whitelist_storage]
1006 pub type BlockSize<T: Config> = StorageValue<_, u32>;
1007
1008 #[pallet::storage]
1010 #[pallet::getter(fn block_hash)]
1011 pub type BlockHash<T: Config> =
1012 StorageMap<_, Twox64Concat, BlockNumberFor<T>, T::Hash, ValueQuery>;
1013
1014 #[pallet::storage]
1016 #[pallet::getter(fn extrinsic_data)]
1017 #[pallet::unbounded]
1018 pub(super) type ExtrinsicData<T: Config> =
1019 StorageMap<_, Twox64Concat, u32, Vec<u8>, ValueQuery>;
1020
1021 #[pallet::storage]
1023 #[pallet::whitelist_storage]
1024 #[pallet::getter(fn block_number)]
1025 pub(super) type Number<T: Config> = StorageValue<_, BlockNumberFor<T>, ValueQuery>;
1026
1027 #[pallet::storage]
1029 #[pallet::getter(fn parent_hash)]
1030 pub(super) type ParentHash<T: Config> = StorageValue<_, T::Hash, ValueQuery>;
1031
1032 #[pallet::storage]
1034 #[pallet::whitelist_storage]
1035 #[pallet::unbounded]
1036 #[pallet::getter(fn digest)]
1037 pub(super) type Digest<T: Config> = StorageValue<_, generic::Digest, ValueQuery>;
1038
1039 #[pallet::storage]
1047 #[pallet::whitelist_storage]
1048 #[pallet::disable_try_decode_storage]
1049 #[pallet::unbounded]
1050 pub(super) type Events<T: Config> =
1051 StorageValue<_, Vec<Box<EventRecord<T::RuntimeEvent, T::Hash>>>, ValueQuery>;
1052
1053 #[pallet::storage]
1055 #[pallet::whitelist_storage]
1056 #[pallet::getter(fn event_count)]
1057 pub(super) type EventCount<T: Config> = StorageValue<_, EventIndex, ValueQuery>;
1058
1059 #[pallet::storage]
1070 #[pallet::unbounded]
1071 #[pallet::getter(fn event_topics)]
1072 pub(super) type EventTopics<T: Config> =
1073 StorageMap<_, Blake2_128Concat, T::Hash, Vec<(BlockNumberFor<T>, EventIndex)>, ValueQuery>;
1074
1075 #[pallet::storage]
1077 #[pallet::unbounded]
1078 pub type LastRuntimeUpgrade<T: Config> = StorageValue<_, LastRuntimeUpgradeInfo>;
1079
1080 #[pallet::storage]
1082 pub(super) type BlocksTillUpgrade<T: Config> = StorageValue<_, u8>;
1083
1084 #[pallet::storage]
1086 pub(super) type UpgradedToU32RefCount<T: Config> = StorageValue<_, bool, ValueQuery>;
1087
1088 #[pallet::storage]
1091 pub(super) type UpgradedToTripleRefCount<T: Config> = StorageValue<_, bool, ValueQuery>;
1092
1093 #[pallet::storage]
1095 #[pallet::whitelist_storage]
1096 pub(super) type ExecutionPhase<T: Config> = StorageValue<_, Phase>;
1097
1098 #[pallet::storage]
1100 #[pallet::getter(fn authorized_upgrade)]
1101 pub(super) type AuthorizedUpgrade<T: Config> =
1102 StorageValue<_, CodeUpgradeAuthorization<T>, OptionQuery>;
1103
1104 #[pallet::storage]
1112 #[pallet::whitelist_storage]
1113 pub type ExtrinsicWeightReclaimed<T: Config> = StorageValue<_, Weight, ValueQuery>;
1114
1115 #[derive(frame_support::DefaultNoBound)]
1116 #[pallet::genesis_config]
1117 pub struct GenesisConfig<T: Config> {
1118 #[serde(skip)]
1119 pub _config: core::marker::PhantomData<T>,
1120 }
1121
1122 #[pallet::genesis_build]
1123 impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
1124 fn build(&self) {
1125 <BlockHash<T>>::insert::<_, T::Hash>(BlockNumberFor::<T>::zero(), hash69());
1126 <ParentHash<T>>::put::<T::Hash>(hash69());
1127 <LastRuntimeUpgrade<T>>::put(LastRuntimeUpgradeInfo::from(T::Version::get()));
1128 <UpgradedToU32RefCount<T>>::put(true);
1129 <UpgradedToTripleRefCount<T>>::put(true);
1130
1131 sp_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode());
1132 }
1133 }
1134
1135 #[allow(deprecated)]
1136 #[pallet::validate_unsigned]
1137 impl<T: Config> ValidateUnsigned for Pallet<T> {
1138 type Call = Call<T>;
1139 fn validate_unsigned(source: TransactionSource, call: &Self::Call) -> TransactionValidity {
1140 if let Call::apply_authorized_upgrade { ref code } = call {
1141 if let Ok(res) = Self::validate_code_is_authorized(&code[..]) {
1142 if Self::can_set_code(&code, false).is_ok() {
1143 return Ok(ValidTransaction {
1144 priority: u64::MAX,
1145 requires: Vec::new(),
1146 provides: vec![res.code_hash.encode()],
1147 longevity: TransactionLongevity::MAX,
1148 propagate: true,
1149 });
1150 }
1151 }
1152 }
1153
1154 #[cfg(feature = "experimental")]
1155 if let Call::do_task { ref task } = call {
1156 if source == TransactionSource::InBlock || source == TransactionSource::Local {
1164 if task.is_valid() {
1165 return Ok(ValidTransaction {
1166 priority: u64::MAX,
1167 requires: Vec::new(),
1168 provides: vec![T::Hashing::hash_of(&task.encode()).as_ref().to_vec()],
1169 longevity: TransactionLongevity::MAX,
1170 propagate: false,
1171 });
1172 }
1173 }
1174 }
1175
1176 #[cfg(not(feature = "experimental"))]
1177 let _ = source;
1178
1179 Err(InvalidTransaction::Call.into())
1180 }
1181 }
1182}
1183
1184pub type Key = Vec<u8>;
1185pub type KeyValue = (Vec<u8>, Vec<u8>);
1186
1187#[derive(Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
1189#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone))]
1190pub enum Phase {
1191 ApplyExtrinsic(u32),
1193 Finalization,
1195 Initialization,
1197}
1198
1199impl Default for Phase {
1200 fn default() -> Self {
1201 Self::Initialization
1202 }
1203}
1204
1205#[derive(Encode, Decode, Debug, TypeInfo)]
1207#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone))]
1208pub struct EventRecord<E: Parameter + Member, T> {
1209 pub phase: Phase,
1211 pub event: E,
1213 pub topics: Vec<T>,
1215}
1216
1217fn hash69<T: AsMut<[u8]> + Default>() -> T {
1220 let mut h = T::default();
1221 h.as_mut().iter_mut().for_each(|byte| *byte = 69);
1222 h
1223}
1224
1225type EventIndex = u32;
1230
1231pub type RefCount = u32;
1233
1234#[derive(Clone, Eq, PartialEq, Default, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)]
1236pub struct AccountInfo<Nonce, AccountData> {
1237 pub nonce: Nonce,
1239 pub consumers: RefCount,
1242 pub providers: RefCount,
1245 pub sufficients: RefCount,
1248 pub data: AccountData,
1251}
1252
1253#[derive(Debug, Encode, Decode, TypeInfo)]
1256#[cfg_attr(feature = "std", derive(PartialEq))]
1257pub struct LastRuntimeUpgradeInfo {
1258 pub spec_version: codec::Compact<u32>,
1259 pub spec_name: Cow<'static, str>,
1260}
1261
1262impl LastRuntimeUpgradeInfo {
1263 pub fn was_upgraded(&self, current: &RuntimeVersion) -> bool {
1267 current.spec_version > self.spec_version.0 || current.spec_name != self.spec_name
1268 }
1269}
1270
1271impl From<RuntimeVersion> for LastRuntimeUpgradeInfo {
1272 fn from(version: RuntimeVersion) -> Self {
1273 Self { spec_version: version.spec_version.into(), spec_name: version.spec_name }
1274 }
1275}
1276
1277pub struct EnsureRoot<AccountId>(core::marker::PhantomData<AccountId>);
1279impl<O: OriginTrait, AccountId> EnsureOrigin<O> for EnsureRoot<AccountId> {
1280 type Success = ();
1281 fn try_origin(o: O) -> Result<Self::Success, O> {
1282 match o.as_system_ref() {
1283 Some(RawOrigin::Root) => Ok(()),
1284 _ => Err(o),
1285 }
1286 }
1287
1288 #[cfg(feature = "runtime-benchmarks")]
1289 fn try_successful_origin() -> Result<O, ()> {
1290 Ok(O::root())
1291 }
1292}
1293
1294impl_ensure_origin_with_arg_ignoring_arg! {
1295 impl< { O: .., AccountId: Decode, T } >
1296 EnsureOriginWithArg<O, T> for EnsureRoot<AccountId>
1297 {}
1298}
1299
1300pub struct EnsureRootWithSuccess<AccountId, Success>(
1302 core::marker::PhantomData<(AccountId, Success)>,
1303);
1304impl<O: OriginTrait, AccountId, Success: TypedGet> EnsureOrigin<O>
1305 for EnsureRootWithSuccess<AccountId, Success>
1306{
1307 type Success = Success::Type;
1308 fn try_origin(o: O) -> Result<Self::Success, O> {
1309 match o.as_system_ref() {
1310 Some(RawOrigin::Root) => Ok(Success::get()),
1311 _ => Err(o),
1312 }
1313 }
1314
1315 #[cfg(feature = "runtime-benchmarks")]
1316 fn try_successful_origin() -> Result<O, ()> {
1317 Ok(O::root())
1318 }
1319}
1320
1321impl_ensure_origin_with_arg_ignoring_arg! {
1322 impl< { O: .., AccountId: Decode, Success: TypedGet, T } >
1323 EnsureOriginWithArg<O, T> for EnsureRootWithSuccess<AccountId, Success>
1324 {}
1325}
1326
1327pub struct EnsureWithSuccess<Ensure, AccountId, Success>(
1329 core::marker::PhantomData<(Ensure, AccountId, Success)>,
1330);
1331
1332impl<O: OriginTrait, Ensure: EnsureOrigin<O>, AccountId, Success: TypedGet> EnsureOrigin<O>
1333 for EnsureWithSuccess<Ensure, AccountId, Success>
1334{
1335 type Success = Success::Type;
1336
1337 fn try_origin(o: O) -> Result<Self::Success, O> {
1338 Ensure::try_origin(o).map(|_| Success::get())
1339 }
1340
1341 #[cfg(feature = "runtime-benchmarks")]
1342 fn try_successful_origin() -> Result<O, ()> {
1343 Ensure::try_successful_origin()
1344 }
1345}
1346
1347pub struct EnsureSigned<AccountId>(core::marker::PhantomData<AccountId>);
1349impl<O: OriginTrait<AccountId = AccountId>, AccountId: Decode + Clone> EnsureOrigin<O>
1350 for EnsureSigned<AccountId>
1351{
1352 type Success = AccountId;
1353 fn try_origin(o: O) -> Result<Self::Success, O> {
1354 match o.as_system_ref() {
1355 Some(RawOrigin::Signed(who)) => Ok(who.clone()),
1356 _ => Err(o),
1357 }
1358 }
1359
1360 #[cfg(feature = "runtime-benchmarks")]
1361 fn try_successful_origin() -> Result<O, ()> {
1362 let zero_account_id =
1363 AccountId::decode(&mut TrailingZeroInput::zeroes()).map_err(|_| ())?;
1364 Ok(O::signed(zero_account_id))
1365 }
1366}
1367
1368impl_ensure_origin_with_arg_ignoring_arg! {
1369 impl< { O: OriginTrait<AccountId = AccountId>, AccountId: Decode + Clone, T } >
1370 EnsureOriginWithArg<O, T> for EnsureSigned<AccountId>
1371 {}
1372}
1373
1374pub struct EnsureSignedBy<Who, AccountId>(core::marker::PhantomData<(Who, AccountId)>);
1376impl<
1377 O: OriginTrait<AccountId = AccountId>,
1378 Who: SortedMembers<AccountId>,
1379 AccountId: PartialEq + Clone + Ord + Decode,
1380 > EnsureOrigin<O> for EnsureSignedBy<Who, AccountId>
1381{
1382 type Success = AccountId;
1383 fn try_origin(o: O) -> Result<Self::Success, O> {
1384 match o.as_system_ref() {
1385 Some(RawOrigin::Signed(ref who)) if Who::contains(who) => Ok(who.clone()),
1386 _ => Err(o),
1387 }
1388 }
1389
1390 #[cfg(feature = "runtime-benchmarks")]
1391 fn try_successful_origin() -> Result<O, ()> {
1392 let first_member = match Who::sorted_members().first() {
1393 Some(account) => account.clone(),
1394 None => AccountId::decode(&mut TrailingZeroInput::zeroes()).map_err(|_| ())?,
1395 };
1396 Ok(O::signed(first_member))
1397 }
1398}
1399
1400impl_ensure_origin_with_arg_ignoring_arg! {
1401 impl< { O: OriginTrait<AccountId = AccountId>, Who: SortedMembers<AccountId>, AccountId: PartialEq + Clone + Ord + Decode, T } >
1402 EnsureOriginWithArg<O, T> for EnsureSignedBy<Who, AccountId>
1403 {}
1404}
1405
1406pub struct EnsureNone<AccountId>(core::marker::PhantomData<AccountId>);
1408impl<O: OriginTrait<AccountId = AccountId>, AccountId> EnsureOrigin<O> for EnsureNone<AccountId> {
1409 type Success = ();
1410 fn try_origin(o: O) -> Result<Self::Success, O> {
1411 match o.as_system_ref() {
1412 Some(RawOrigin::None) => Ok(()),
1413 _ => Err(o),
1414 }
1415 }
1416
1417 #[cfg(feature = "runtime-benchmarks")]
1418 fn try_successful_origin() -> Result<O, ()> {
1419 Ok(O::none())
1420 }
1421}
1422
1423impl_ensure_origin_with_arg_ignoring_arg! {
1424 impl< { O: OriginTrait<AccountId = AccountId>, AccountId, T } >
1425 EnsureOriginWithArg<O, T> for EnsureNone<AccountId>
1426 {}
1427}
1428
1429pub struct EnsureAuthorized<AccountId>(core::marker::PhantomData<AccountId>);
1431impl<O: OriginTrait<AccountId = AccountId>, AccountId> EnsureOrigin<O>
1432 for EnsureAuthorized<AccountId>
1433{
1434 type Success = ();
1435 fn try_origin(o: O) -> Result<Self::Success, O> {
1436 match o.as_system_ref() {
1437 Some(RawOrigin::Authorized) => Ok(()),
1438 _ => Err(o),
1439 }
1440 }
1441
1442 #[cfg(feature = "runtime-benchmarks")]
1443 fn try_successful_origin() -> Result<O, ()> {
1444 let mut o = O::none();
1445 o.set_caller(O::PalletsOrigin::from(RawOrigin::Authorized));
1446 Ok(o)
1447 }
1448}
1449
1450impl_ensure_origin_with_arg_ignoring_arg! {
1451 impl< { O: OriginTrait<AccountId = AccountId>, AccountId, T } >
1452 EnsureOriginWithArg<O, T> for EnsureAuthorized<AccountId>
1453 {}
1454}
1455
1456pub struct EnsureNever<Success>(core::marker::PhantomData<Success>);
1458impl<O, Success> EnsureOrigin<O> for EnsureNever<Success> {
1459 type Success = Success;
1460 fn try_origin(o: O) -> Result<Self::Success, O> {
1461 Err(o)
1462 }
1463
1464 #[cfg(feature = "runtime-benchmarks")]
1465 fn try_successful_origin() -> Result<O, ()> {
1466 Err(())
1467 }
1468}
1469
1470impl_ensure_origin_with_arg_ignoring_arg! {
1471 impl< { O, Success, T } >
1472 EnsureOriginWithArg<O, T> for EnsureNever<Success>
1473 {}
1474}
1475
1476#[docify::export]
1477pub fn ensure_signed<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<AccountId, BadOrigin>
1480where
1481 OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1482{
1483 match o.into() {
1484 Ok(RawOrigin::Signed(t)) => Ok(t),
1485 _ => Err(BadOrigin),
1486 }
1487}
1488
1489pub fn ensure_signed_or_root<OuterOrigin, AccountId>(
1493 o: OuterOrigin,
1494) -> Result<Option<AccountId>, BadOrigin>
1495where
1496 OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1497{
1498 match o.into() {
1499 Ok(RawOrigin::Root) => Ok(None),
1500 Ok(RawOrigin::Signed(t)) => Ok(Some(t)),
1501 _ => Err(BadOrigin),
1502 }
1503}
1504
1505pub fn ensure_root<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), BadOrigin>
1507where
1508 OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1509{
1510 match o.into() {
1511 Ok(RawOrigin::Root) => Ok(()),
1512 _ => Err(BadOrigin),
1513 }
1514}
1515
1516pub fn ensure_none<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), BadOrigin>
1518where
1519 OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1520{
1521 match o.into() {
1522 Ok(RawOrigin::None) => Ok(()),
1523 _ => Err(BadOrigin),
1524 }
1525}
1526
1527pub fn ensure_authorized<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), BadOrigin>
1530where
1531 OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1532{
1533 match o.into() {
1534 Ok(RawOrigin::Authorized) => Ok(()),
1535 _ => Err(BadOrigin),
1536 }
1537}
1538
1539#[derive(Debug)]
1541pub enum RefStatus {
1542 Referenced,
1543 Unreferenced,
1544}
1545
1546#[derive(Eq, PartialEq, Debug)]
1548pub enum IncRefStatus {
1549 Created,
1551 Existed,
1553}
1554
1555#[derive(Eq, PartialEq, Debug)]
1557pub enum DecRefStatus {
1558 Reaped,
1560 Exists,
1562}
1563
1564pub enum CanSetCodeResult<T: Config> {
1566 Ok,
1568 MultiBlockMigrationsOngoing,
1570 InvalidVersion(Error<T>),
1572}
1573
1574impl<T: Config> CanSetCodeResult<T> {
1575 pub fn into_result(self) -> Result<(), DispatchError> {
1577 match self {
1578 Self::Ok => Ok(()),
1579 Self::MultiBlockMigrationsOngoing => {
1580 Err(Error::<T>::MultiBlockMigrationsOngoing.into())
1581 },
1582 Self::InvalidVersion(err) => Err(err.into()),
1583 }
1584 }
1585
1586 pub fn is_ok(&self) -> bool {
1588 matches!(self, Self::Ok)
1589 }
1590}
1591
1592impl<T: Config> Pallet<T> {
1593 #[doc = docify::embed!("src/tests.rs", last_runtime_upgrade_spec_version_usage)]
1607 pub fn last_runtime_upgrade_spec_version() -> u32 {
1608 LastRuntimeUpgrade::<T>::get().map_or(0, |l| l.spec_version.0)
1609 }
1610
1611 pub fn account_exists(who: &T::AccountId) -> bool {
1613 Account::<T>::contains_key(who)
1614 }
1615
1616 pub fn update_code_in_storage(code: &[u8]) {
1623 match T::Version::get().system_version {
1624 0..=2 => {
1625 storage::unhashed::put_raw(well_known_keys::CODE, code);
1626 },
1627 _ => {
1628 BlocksTillUpgrade::<T>::put(2u8);
1629 storage::unhashed::put_raw(well_known_keys::PENDING_CODE, code);
1630 },
1631 }
1632 let hash = T::Hashing::hash(code);
1633
1634 Self::deposit_log(generic::DigestItem::RuntimeEnvironmentUpdated);
1635 Self::deposit_event(Event::CodeUpdated { hash });
1636 }
1637
1638 pub fn maybe_apply_pending_code_upgrade() {
1643 let Some(remaining) = BlocksTillUpgrade::<T>::get() else { return };
1644
1645 let remaining = remaining.saturating_sub(1);
1646
1647 if remaining > 0 {
1648 BlocksTillUpgrade::<T>::put(remaining);
1649 return;
1650 }
1651
1652 BlocksTillUpgrade::<T>::kill();
1653
1654 let Some(new_code) = storage::unhashed::get_raw(well_known_keys::PENDING_CODE) else {
1655 defensive!("BlocksTillUpgrade is set but no pending code found");
1657 return;
1658 };
1659
1660 storage::unhashed::put_raw(well_known_keys::CODE, &new_code);
1661 storage::unhashed::kill(well_known_keys::PENDING_CODE);
1662 }
1663
1664 pub fn inherents_applied() -> bool {
1666 InherentsApplied::<T>::get()
1667 }
1668
1669 pub fn note_inherents_applied() {
1674 InherentsApplied::<T>::put(true);
1675 }
1676
1677 #[deprecated = "Use `inc_consumers` instead"]
1679 pub fn inc_ref(who: &T::AccountId) {
1680 let _ = Self::inc_consumers(who);
1681 }
1682
1683 #[deprecated = "Use `dec_consumers` instead"]
1686 pub fn dec_ref(who: &T::AccountId) {
1687 let _ = Self::dec_consumers(who);
1688 }
1689
1690 #[deprecated = "Use `consumers` instead"]
1692 pub fn refs(who: &T::AccountId) -> RefCount {
1693 Self::consumers(who)
1694 }
1695
1696 #[deprecated = "Use `!is_provider_required` instead"]
1698 pub fn allow_death(who: &T::AccountId) -> bool {
1699 !Self::is_provider_required(who)
1700 }
1701
1702 pub fn inc_providers(who: &T::AccountId) -> IncRefStatus {
1704 Account::<T>::mutate(who, |a| {
1705 if a.providers == 0 && a.sufficients == 0 {
1706 a.providers = 1;
1708 Self::on_created_account(who.clone(), a);
1709 IncRefStatus::Created
1710 } else {
1711 a.providers = a.providers.saturating_add(1);
1712 IncRefStatus::Existed
1713 }
1714 })
1715 }
1716
1717 pub fn dec_providers(who: &T::AccountId) -> Result<DecRefStatus, DispatchError> {
1721 Account::<T>::try_mutate_exists(who, |maybe_account| {
1722 if let Some(mut account) = maybe_account.take() {
1723 if account.providers == 0 {
1724 log::error!(
1726 target: LOG_TARGET,
1727 "Logic error: Unexpected underflow in reducing provider",
1728 );
1729 account.providers = 1;
1730 }
1731 match (account.providers, account.consumers, account.sufficients) {
1732 (1, 0, 0) => {
1733 Pallet::<T>::on_killed_account(who.clone());
1736 Ok(DecRefStatus::Reaped)
1737 },
1738 (1, c, _) if c > 0 => {
1739 Err(DispatchError::ConsumerRemaining)
1741 },
1742 (x, _, _) => {
1743 account.providers = x - 1;
1746 *maybe_account = Some(account);
1747 Ok(DecRefStatus::Exists)
1748 },
1749 }
1750 } else {
1751 log::error!(
1752 target: LOG_TARGET,
1753 "Logic error: Account already dead when reducing provider",
1754 );
1755 Ok(DecRefStatus::Reaped)
1756 }
1757 })
1758 }
1759
1760 pub fn inc_sufficients(who: &T::AccountId) -> IncRefStatus {
1762 Account::<T>::mutate(who, |a| {
1763 if a.providers + a.sufficients == 0 {
1764 a.sufficients = 1;
1766 Self::on_created_account(who.clone(), a);
1767 IncRefStatus::Created
1768 } else {
1769 a.sufficients = a.sufficients.saturating_add(1);
1770 IncRefStatus::Existed
1771 }
1772 })
1773 }
1774
1775 pub fn dec_sufficients(who: &T::AccountId) -> DecRefStatus {
1779 Account::<T>::mutate_exists(who, |maybe_account| {
1780 if let Some(mut account) = maybe_account.take() {
1781 if account.sufficients == 0 {
1782 log::error!(
1784 target: LOG_TARGET,
1785 "Logic error: Unexpected underflow in reducing sufficients",
1786 );
1787 }
1788 match (account.sufficients, account.providers) {
1789 (0, 0) | (1, 0) => {
1790 Pallet::<T>::on_killed_account(who.clone());
1791 DecRefStatus::Reaped
1792 },
1793 (x, _) => {
1794 account.sufficients = x.saturating_sub(1);
1795 *maybe_account = Some(account);
1796 DecRefStatus::Exists
1797 },
1798 }
1799 } else {
1800 log::error!(
1801 target: LOG_TARGET,
1802 "Logic error: Account already dead when reducing provider",
1803 );
1804 DecRefStatus::Reaped
1805 }
1806 })
1807 }
1808
1809 pub fn providers(who: &T::AccountId) -> RefCount {
1811 Account::<T>::get(who).providers
1812 }
1813
1814 pub fn sufficients(who: &T::AccountId) -> RefCount {
1816 Account::<T>::get(who).sufficients
1817 }
1818
1819 pub fn reference_count(who: &T::AccountId) -> RefCount {
1821 let a = Account::<T>::get(who);
1822 a.providers + a.sufficients
1823 }
1824
1825 pub fn inc_consumers(who: &T::AccountId) -> Result<(), DispatchError> {
1830 Account::<T>::try_mutate(who, |a| {
1831 if a.providers > 0 {
1832 if a.consumers < T::MaxConsumers::max_consumers() {
1833 a.consumers = a.consumers.saturating_add(1);
1834 Ok(())
1835 } else {
1836 Err(DispatchError::TooManyConsumers)
1837 }
1838 } else {
1839 Err(DispatchError::NoProviders)
1840 }
1841 })
1842 }
1843
1844 pub fn inc_consumers_without_limit(who: &T::AccountId) -> Result<(), DispatchError> {
1848 Account::<T>::try_mutate(who, |a| {
1849 if a.providers > 0 {
1850 a.consumers = a.consumers.saturating_add(1);
1851 Ok(())
1852 } else {
1853 Err(DispatchError::NoProviders)
1854 }
1855 })
1856 }
1857
1858 pub fn dec_consumers(who: &T::AccountId) {
1861 Account::<T>::mutate(who, |a| {
1862 if a.consumers > 0 {
1863 a.consumers -= 1;
1864 } else {
1865 log::error!(
1866 target: LOG_TARGET,
1867 "Logic error: Unexpected underflow in reducing consumer",
1868 );
1869 }
1870 })
1871 }
1872
1873 pub fn consumers(who: &T::AccountId) -> RefCount {
1875 Account::<T>::get(who).consumers
1876 }
1877
1878 pub fn is_provider_required(who: &T::AccountId) -> bool {
1880 Account::<T>::get(who).consumers != 0
1881 }
1882
1883 pub fn can_dec_provider(who: &T::AccountId) -> bool {
1885 let a = Account::<T>::get(who);
1886 a.consumers == 0 || a.providers > 1
1887 }
1888
1889 pub fn can_accrue_consumers(who: &T::AccountId, amount: u32) -> bool {
1892 let a = Account::<T>::get(who);
1893 match a.consumers.checked_add(amount) {
1894 Some(c) => a.providers > 0 && c <= T::MaxConsumers::max_consumers(),
1895 None => false,
1896 }
1897 }
1898
1899 pub fn can_inc_consumer(who: &T::AccountId) -> bool {
1902 Self::can_accrue_consumers(who, 1)
1903 }
1904
1905 pub fn deposit_event(event: impl Into<T::RuntimeEvent>) {
1909 Self::deposit_event_indexed(&[], event.into());
1910 }
1911
1912 pub fn deposit_event_indexed(topics: &[T::Hash], event: T::RuntimeEvent) {
1920 let block_number = Self::block_number();
1921
1922 if block_number.is_zero() {
1924 return;
1925 }
1926
1927 let phase = ExecutionPhase::<T>::get().unwrap_or_default();
1928 let event = EventRecord { phase, event, topics: topics.to_vec() };
1929
1930 let event_idx = {
1932 let old_event_count = EventCount::<T>::get();
1933 let new_event_count = match old_event_count.checked_add(1) {
1934 None => return,
1937 Some(nc) => nc,
1938 };
1939 EventCount::<T>::put(new_event_count);
1940 old_event_count
1941 };
1942
1943 Events::<T>::append(event);
1944
1945 for topic in topics {
1946 <EventTopics<T>>::append(topic, &(block_number, event_idx));
1947 }
1948 }
1949
1950 pub fn extrinsic_index() -> Option<u32> {
1952 storage::unhashed::get(well_known_keys::EXTRINSIC_INDEX)
1953 }
1954
1955 pub fn extrinsic_count() -> u32 {
1957 ExtrinsicCount::<T>::get().unwrap_or_default()
1958 }
1959
1960 pub fn block_size() -> u32 {
1962 BlockSize::<T>::get().unwrap_or_default()
1963 }
1964
1965 pub fn execution_phase() -> Option<Phase> {
1967 ExecutionPhase::<T>::get()
1968 }
1969
1970 pub fn register_extra_weight_unchecked(weight: Weight, class: DispatchClass) {
1986 BlockWeight::<T>::mutate(|current_weight| {
1987 current_weight.accrue(weight, class);
1988 });
1989 }
1990
1991 pub fn initialize(number: &BlockNumberFor<T>, parent_hash: &T::Hash, digest: &generic::Digest) {
1998 let expected_block_number = Self::block_number() + One::one();
1999 assert_eq!(expected_block_number, *number, "Block number must be strictly increasing.");
2000
2001 ExecutionPhase::<T>::put(Phase::Initialization);
2003 storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &0u32);
2004 Self::initialize_intra_block_entropy(parent_hash);
2005 <Number<T>>::put(number);
2006 <Digest<T>>::put(digest);
2007 <ParentHash<T>>::put(parent_hash);
2008 <BlockHash<T>>::insert(*number - One::one(), parent_hash);
2009
2010 BlockWeight::<T>::kill();
2012
2013 let digest_size = digest.encoded_size();
2016 let empty_header = <<T as Config>::Block as traits::Block>::Header::new(
2017 *number,
2018 Default::default(),
2019 Default::default(),
2020 *parent_hash,
2021 Default::default(),
2022 );
2023 let empty_header_size = empty_header.encoded_size();
2024 let overhead = digest_size.saturating_add(empty_header_size) as u32;
2025 BlockSize::<T>::put(overhead);
2026
2027 let max_total_header = T::BlockLength::get().max_header_size();
2029 assert!(
2030 overhead <= max_total_header as u32,
2031 "Header size ({overhead}) exceeds max header size limit ({max_total_header})"
2032 );
2033 }
2034
2035 pub fn initialize_intra_block_entropy(parent_hash: &T::Hash) {
2039 let entropy = (b"frame_system::initialize", parent_hash).using_encoded(blake2_256);
2040 storage::unhashed::put_raw(well_known_keys::INTRABLOCK_ENTROPY, &entropy[..]);
2041 }
2042
2043 pub fn resource_usage_report() {
2047 log::debug!(
2048 target: LOG_TARGET,
2049 "[{:?}] {} extrinsics, block size: {} (normal {}%, op: {}%, mandatory {}%) / normal weight:\
2050 {} (ref_time: {}%, proof_size: {}%) op weight {} (ref_time {}%, proof_size {}%) / \
2051 mandatory weight {} (ref_time: {}%, proof_size: {}%)",
2052 Self::block_number(),
2053 Self::extrinsic_count(),
2054 Self::block_size(),
2055 sp_runtime::Percent::from_rational(
2056 Self::block_size(),
2057 *T::BlockLength::get().max.get(DispatchClass::Normal)
2058 ).deconstruct(),
2059 sp_runtime::Percent::from_rational(
2060 Self::block_size(),
2061 *T::BlockLength::get().max.get(DispatchClass::Operational)
2062 ).deconstruct(),
2063 sp_runtime::Percent::from_rational(
2064 Self::block_size(),
2065 *T::BlockLength::get().max.get(DispatchClass::Mandatory)
2066 ).deconstruct(),
2067 Self::block_weight().get(DispatchClass::Normal),
2068 sp_runtime::Percent::from_rational(
2069 Self::block_weight().get(DispatchClass::Normal).ref_time(),
2070 T::BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap_or(Bounded::max_value()).ref_time()
2071 ).deconstruct(),
2072 sp_runtime::Percent::from_rational(
2073 Self::block_weight().get(DispatchClass::Normal).proof_size(),
2074 T::BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap_or(Bounded::max_value()).proof_size()
2075 ).deconstruct(),
2076 Self::block_weight().get(DispatchClass::Operational),
2077 sp_runtime::Percent::from_rational(
2078 Self::block_weight().get(DispatchClass::Operational).ref_time(),
2079 T::BlockWeights::get().get(DispatchClass::Operational).max_total.unwrap_or(Bounded::max_value()).ref_time()
2080 ).deconstruct(),
2081 sp_runtime::Percent::from_rational(
2082 Self::block_weight().get(DispatchClass::Operational).proof_size(),
2083 T::BlockWeights::get().get(DispatchClass::Operational).max_total.unwrap_or(Bounded::max_value()).proof_size()
2084 ).deconstruct(),
2085 Self::block_weight().get(DispatchClass::Mandatory),
2086 sp_runtime::Percent::from_rational(
2087 Self::block_weight().get(DispatchClass::Mandatory).ref_time(),
2088 T::BlockWeights::get().get(DispatchClass::Mandatory).max_total.unwrap_or(Bounded::max_value()).ref_time()
2089 ).deconstruct(),
2090 sp_runtime::Percent::from_rational(
2091 Self::block_weight().get(DispatchClass::Mandatory).proof_size(),
2092 T::BlockWeights::get().get(DispatchClass::Mandatory).max_total.unwrap_or(Bounded::max_value()).proof_size()
2093 ).deconstruct(),
2094 );
2095 }
2096
2097 pub fn finalize() -> HeaderFor<T> {
2100 Self::resource_usage_report();
2101 ExecutionPhase::<T>::kill();
2102 BlockSize::<T>::kill();
2103 storage::unhashed::kill(well_known_keys::INTRABLOCK_ENTROPY);
2104 InherentsApplied::<T>::kill();
2105
2106 let number = <Number<T>>::get();
2117 let parent_hash = <ParentHash<T>>::get();
2118 let digest = <Digest<T>>::get();
2119
2120 let extrinsics = (0..ExtrinsicCount::<T>::take().unwrap_or_default())
2121 .map(ExtrinsicData::<T>::take)
2122 .collect();
2123 let extrinsics_root_state_version = T::Version::get().extrinsics_root_state_version();
2124 let extrinsics_root =
2125 extrinsics_data_root::<T::Hashing>(extrinsics, extrinsics_root_state_version);
2126
2127 let block_hash_count = T::BlockHashCount::get();
2129 let to_remove = number.saturating_sub(block_hash_count).saturating_sub(One::one());
2130
2131 if !to_remove.is_zero() {
2133 <BlockHash<T>>::remove(to_remove);
2134 }
2135
2136 let version = T::Version::get().state_version();
2137 let storage_root = T::Hash::decode(&mut &sp_io::storage::root(version)[..])
2138 .expect("Node is configured to use the same hash; qed");
2139
2140 HeaderFor::<T>::new(number, extrinsics_root, storage_root, parent_hash, digest)
2141 }
2142
2143 pub fn deposit_log(item: generic::DigestItem) {
2148 BlockSize::<T>::mutate(|len| {
2149 *len = Some(len.unwrap_or(0).saturating_add(item.encoded_size() as u32));
2150 });
2151 <Digest<T>>::append(item);
2152 }
2153
2154 #[cfg(any(feature = "std", test))]
2156 pub fn externalities() -> TestExternalities {
2157 TestExternalities::new(sp_core::storage::Storage {
2158 top: [
2159 (<BlockHash<T>>::hashed_key_for(BlockNumberFor::<T>::zero()), [69u8; 32].encode()),
2160 (<Number<T>>::hashed_key().to_vec(), BlockNumberFor::<T>::one().encode()),
2161 (<ParentHash<T>>::hashed_key().to_vec(), [69u8; 32].encode()),
2162 ]
2163 .into_iter()
2164 .collect(),
2165 children_default: Default::default(),
2166 })
2167 }
2168
2169 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2177 pub fn events() -> Vec<EventRecord<T::RuntimeEvent, T::Hash>> {
2178 Self::read_events_no_consensus().map(|e| *e).collect()
2180 }
2181
2182 pub fn event_no_consensus(index: usize) -> Option<T::RuntimeEvent> {
2187 Self::read_events_no_consensus().nth(index).map(|e| e.event.clone())
2188 }
2189
2190 pub fn read_events_no_consensus(
2195 ) -> impl Iterator<Item = Box<EventRecord<T::RuntimeEvent, T::Hash>>> {
2196 Events::<T>::stream_iter()
2197 }
2198
2199 pub fn read_events_for_pallet<E>() -> Vec<E>
2204 where
2205 T::RuntimeEvent: TryInto<E>,
2206 {
2207 Events::<T>::get()
2208 .into_iter()
2209 .map(|er| er.event)
2210 .filter_map(|e| e.try_into().ok())
2211 .collect::<_>()
2212 }
2213
2214 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2223 pub fn run_to_block_with<AllPalletsWithSystem>(
2224 n: BlockNumberFor<T>,
2225 mut hooks: RunToBlockHooks<T>,
2226 ) where
2227 AllPalletsWithSystem: frame_support::traits::OnInitialize<BlockNumberFor<T>>
2228 + frame_support::traits::OnFinalize<BlockNumberFor<T>>,
2229 {
2230 let mut bn = Self::block_number();
2231
2232 while bn < n {
2233 if !bn.is_zero() {
2235 (hooks.before_finalize)(bn);
2236 AllPalletsWithSystem::on_finalize(bn);
2237 (hooks.after_finalize)(bn);
2238 }
2239
2240 bn += One::one();
2241
2242 Self::set_block_number(bn);
2243 (hooks.before_initialize)(bn);
2244 AllPalletsWithSystem::on_initialize(bn);
2245 (hooks.after_initialize)(bn);
2246 }
2247 }
2248
2249 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2251 pub fn run_to_block<AllPalletsWithSystem>(n: BlockNumberFor<T>)
2252 where
2253 AllPalletsWithSystem: frame_support::traits::OnInitialize<BlockNumberFor<T>>
2254 + frame_support::traits::OnFinalize<BlockNumberFor<T>>,
2255 {
2256 Self::run_to_block_with::<AllPalletsWithSystem>(n, Default::default());
2257 }
2258
2259 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2262 pub fn set_block_number(n: BlockNumberFor<T>) {
2263 <Number<T>>::put(n);
2264 }
2265
2266 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2268 pub fn set_extrinsic_index(extrinsic_index: u32) {
2269 storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &extrinsic_index)
2270 }
2271
2272 #[cfg(any(feature = "std", test))]
2275 pub fn set_parent_hash(n: T::Hash) {
2276 <ParentHash<T>>::put(n);
2277 }
2278
2279 #[cfg(any(feature = "std", test))]
2281 pub fn set_block_consumed_resources(weight: Weight, len: usize) {
2282 BlockWeight::<T>::mutate(|current_weight| {
2283 current_weight.set(weight, DispatchClass::Normal)
2284 });
2285 BlockSize::<T>::put(len as u32);
2286 }
2287
2288 pub fn reset_events() {
2293 <Events<T>>::kill();
2294 EventCount::<T>::kill();
2295 let _ = <EventTopics<T>>::clear(u32::MAX, None);
2296 }
2297
2298 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2302 #[track_caller]
2303 pub fn assert_has_event(event: T::RuntimeEvent) {
2304 let warn = if Self::block_number().is_zero() {
2305 "WARNING: block number is zero, and events are not registered at block number zero.\n"
2306 } else {
2307 ""
2308 };
2309
2310 let events = Self::events();
2311 assert!(
2312 events.iter().any(|record| record.event == event),
2313 "{warn}expected event {event:?} not found in events {events:?}",
2314 );
2315 }
2316
2317 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2321 #[track_caller]
2322 pub fn assert_last_event(event: T::RuntimeEvent) {
2323 let warn = if Self::block_number().is_zero() {
2324 "WARNING: block number is zero, and events are not registered at block number zero.\n"
2325 } else {
2326 ""
2327 };
2328
2329 let last_event = Self::events()
2330 .last()
2331 .expect(&alloc::format!("{warn}events expected"))
2332 .event
2333 .clone();
2334 assert_eq!(
2335 last_event, event,
2336 "{warn}expected event {event:?} is not equal to the last event {last_event:?}",
2337 );
2338 }
2339
2340 pub fn runtime_version() -> RuntimeVersion {
2342 T::Version::get()
2343 }
2344
2345 pub fn account_nonce(who: impl EncodeLike<T::AccountId>) -> T::Nonce {
2347 Account::<T>::get(who).nonce
2348 }
2349
2350 pub fn inc_account_nonce(who: impl EncodeLike<T::AccountId>) {
2352 Account::<T>::mutate(who, |a| a.nonce += T::Nonce::one());
2353 }
2354
2355 pub fn note_extrinsic(encoded_xt: Vec<u8>) {
2360 ExtrinsicData::<T>::insert(Self::extrinsic_index().unwrap_or_default(), encoded_xt);
2361 }
2362
2363 pub fn note_applied_extrinsic(r: &DispatchResultWithPostInfo, info: DispatchInfo) {
2369 let weight = extract_actual_weight(r, &info)
2370 .saturating_add(T::BlockWeights::get().get(info.class).base_extrinsic);
2371 let class = info.class;
2372 let pays_fee = extract_actual_pays_fee(r, &info);
2373 let dispatch_event_info = DispatchEventInfo { weight, class, pays_fee };
2374
2375 Self::deposit_event(match r {
2376 Ok(_) => Event::ExtrinsicSuccess { dispatch_info: dispatch_event_info },
2377 Err(err) => {
2378 log::trace!(
2379 target: LOG_TARGET,
2380 "Extrinsic failed at block({:?}): {:?}",
2381 Self::block_number(),
2382 err,
2383 );
2384 Event::ExtrinsicFailed {
2385 dispatch_error: err.error,
2386 dispatch_info: dispatch_event_info,
2387 }
2388 },
2389 });
2390
2391 log::trace!(
2392 target: LOG_TARGET,
2393 "Used block weight: {:?}",
2394 BlockWeight::<T>::get(),
2395 );
2396
2397 log::trace!(
2398 target: LOG_TARGET,
2399 "Used block length: {:?}",
2400 Pallet::<T>::block_size(),
2401 );
2402
2403 let next_extrinsic_index = Self::extrinsic_index().unwrap_or_default() + 1u32;
2404
2405 storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &next_extrinsic_index);
2406 ExecutionPhase::<T>::put(Phase::ApplyExtrinsic(next_extrinsic_index));
2407 ExtrinsicWeightReclaimed::<T>::kill();
2408 }
2409
2410 pub fn note_finished_extrinsics() {
2413 let extrinsic_index: u32 =
2414 storage::unhashed::take(well_known_keys::EXTRINSIC_INDEX).unwrap_or_default();
2415 ExtrinsicCount::<T>::put(extrinsic_index);
2416 ExecutionPhase::<T>::put(Phase::Finalization);
2417 }
2418
2419 pub fn note_finished_initialize() {
2422 ExecutionPhase::<T>::put(Phase::ApplyExtrinsic(0))
2423 }
2424
2425 pub fn on_created_account(who: T::AccountId, _a: &mut AccountInfo<T::Nonce, T::AccountData>) {
2427 T::OnNewAccount::on_new_account(&who);
2428 Self::deposit_event(Event::NewAccount { account: who });
2429 }
2430
2431 fn on_killed_account(who: T::AccountId) {
2433 T::OnKilledAccount::on_killed_account(&who);
2434 Self::deposit_event(Event::KilledAccount { account: who });
2435 }
2436
2437 pub fn can_set_code(code: &[u8], check_version: bool) -> CanSetCodeResult<T> {
2441 if T::MultiBlockMigrator::ongoing() {
2442 return CanSetCodeResult::MultiBlockMigrationsOngoing;
2443 }
2444
2445 if check_version {
2446 let current_version = T::Version::get();
2447 let Some(new_version) = sp_io::misc::runtime_version(code)
2448 .and_then(|v| RuntimeVersion::decode(&mut &v[..]).ok())
2449 else {
2450 return CanSetCodeResult::InvalidVersion(Error::<T>::FailedToExtractRuntimeVersion);
2451 };
2452
2453 cfg_if::cfg_if! {
2454 if #[cfg(all(feature = "runtime-benchmarks", not(test)))] {
2455 core::hint::black_box((new_version, current_version));
2457 } else {
2458 if new_version.spec_name != current_version.spec_name {
2459 return CanSetCodeResult::InvalidVersion(Error::<T>::InvalidSpecName)
2460 }
2461
2462 if new_version.spec_version <= current_version.spec_version {
2463 return CanSetCodeResult::InvalidVersion(Error::<T>::SpecVersionNeedsToIncrease)
2464 }
2465 }
2466 }
2467 }
2468
2469 CanSetCodeResult::Ok
2470 }
2471
2472 pub fn do_authorize_upgrade(code_hash: T::Hash, check_version: bool) {
2474 AuthorizedUpgrade::<T>::put(CodeUpgradeAuthorization { code_hash, check_version });
2475 Self::deposit_event(Event::UpgradeAuthorized { code_hash, check_version });
2476 }
2477
2478 fn validate_code_is_authorized(
2482 code: &[u8],
2483 ) -> Result<CodeUpgradeAuthorization<T>, DispatchError> {
2484 let authorization = AuthorizedUpgrade::<T>::get().ok_or(Error::<T>::NothingAuthorized)?;
2485 let actual_hash = T::Hashing::hash(code);
2486 ensure!(actual_hash == authorization.code_hash, Error::<T>::Unauthorized);
2487 Ok(authorization)
2488 }
2489
2490 pub fn reclaim_weight(
2495 info: &DispatchInfoOf<T::RuntimeCall>,
2496 post_info: &PostDispatchInfoOf<T::RuntimeCall>,
2497 ) -> Result<(), TransactionValidityError>
2498 where
2499 T::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
2500 {
2501 let already_reclaimed = crate::ExtrinsicWeightReclaimed::<T>::get();
2502 let unspent = post_info.calc_unspent(info);
2503 let accurate_reclaim = already_reclaimed.max(unspent);
2504 let to_reclaim_more = accurate_reclaim.saturating_sub(already_reclaimed);
2506 if to_reclaim_more != Weight::zero() {
2507 crate::BlockWeight::<T>::mutate(|current_weight| {
2508 current_weight.reduce(to_reclaim_more, info.class);
2509 });
2510 crate::ExtrinsicWeightReclaimed::<T>::put(accurate_reclaim);
2511 }
2512
2513 Ok(())
2514 }
2515
2516 pub fn remaining_block_weight() -> WeightMeter {
2518 let limit = T::BlockWeights::get().max_block;
2519 let consumed = BlockWeight::<T>::get().total();
2520
2521 WeightMeter::with_consumed_and_limit(consumed, limit)
2522 }
2523}
2524
2525pub fn unique(entropy: impl Encode) -> [u8; 32] {
2528 let mut last = [0u8; 32];
2529 sp_io::storage::read(well_known_keys::INTRABLOCK_ENTROPY, &mut last[..], 0);
2530 let next = (b"frame_system::unique", entropy, last).using_encoded(blake2_256);
2531 sp_io::storage::set(well_known_keys::INTRABLOCK_ENTROPY, &next);
2532 next
2533}
2534
2535pub struct Provider<T>(PhantomData<T>);
2537impl<T: Config> HandleLifetime<T::AccountId> for Provider<T> {
2538 fn created(t: &T::AccountId) -> Result<(), DispatchError> {
2539 Pallet::<T>::inc_providers(t);
2540 Ok(())
2541 }
2542 fn killed(t: &T::AccountId) -> Result<(), DispatchError> {
2543 Pallet::<T>::dec_providers(t).map(|_| ())
2544 }
2545}
2546
2547pub struct SelfSufficient<T>(PhantomData<T>);
2549impl<T: Config> HandleLifetime<T::AccountId> for SelfSufficient<T> {
2550 fn created(t: &T::AccountId) -> Result<(), DispatchError> {
2551 Pallet::<T>::inc_sufficients(t);
2552 Ok(())
2553 }
2554 fn killed(t: &T::AccountId) -> Result<(), DispatchError> {
2555 Pallet::<T>::dec_sufficients(t);
2556 Ok(())
2557 }
2558}
2559
2560pub struct Consumer<T>(PhantomData<T>);
2562impl<T: Config> HandleLifetime<T::AccountId> for Consumer<T> {
2563 fn created(t: &T::AccountId) -> Result<(), DispatchError> {
2564 Pallet::<T>::inc_consumers(t)
2565 }
2566 fn killed(t: &T::AccountId) -> Result<(), DispatchError> {
2567 Pallet::<T>::dec_consumers(t);
2568 Ok(())
2569 }
2570}
2571
2572impl<T: Config> BlockNumberProvider for Pallet<T> {
2573 type BlockNumber = BlockNumberFor<T>;
2574
2575 fn current_block_number() -> Self::BlockNumber {
2576 Pallet::<T>::block_number()
2577 }
2578
2579 #[cfg(feature = "runtime-benchmarks")]
2580 fn set_block_number(n: BlockNumberFor<T>) {
2581 Self::set_block_number(n)
2582 }
2583}
2584
2585impl<T: Config> StoredMap<T::AccountId, T::AccountData> for Pallet<T> {
2591 fn get(k: &T::AccountId) -> T::AccountData {
2592 Account::<T>::get(k).data
2593 }
2594
2595 fn try_mutate_exists<R, E: From<DispatchError>>(
2596 k: &T::AccountId,
2597 f: impl FnOnce(&mut Option<T::AccountData>) -> Result<R, E>,
2598 ) -> Result<R, E> {
2599 let account = Account::<T>::get(k);
2600 let is_default = account.data == T::AccountData::default();
2601 let mut some_data = if is_default { None } else { Some(account.data) };
2602 let result = f(&mut some_data)?;
2603 if Self::providers(k) > 0 || Self::sufficients(k) > 0 {
2604 Account::<T>::mutate(k, |a| a.data = some_data.unwrap_or_default());
2605 } else {
2606 Account::<T>::remove(k)
2607 }
2608 Ok(result)
2609 }
2610}
2611
2612pub fn split_inner<T, R, S>(
2614 option: Option<T>,
2615 splitter: impl FnOnce(T) -> (R, S),
2616) -> (Option<R>, Option<S>) {
2617 match option {
2618 Some(inner) => {
2619 let (r, s) = splitter(inner);
2620 (Some(r), Some(s))
2621 },
2622 None => (None, None),
2623 }
2624}
2625
2626pub struct ChainContext<T>(PhantomData<T>);
2627impl<T> Default for ChainContext<T> {
2628 fn default() -> Self {
2629 ChainContext(PhantomData)
2630 }
2631}
2632
2633impl<T: Config> Lookup for ChainContext<T> {
2634 type Source = <T::Lookup as StaticLookup>::Source;
2635 type Target = <T::Lookup as StaticLookup>::Target;
2636
2637 fn lookup(&self, s: Self::Source) -> Result<Self::Target, LookupError> {
2638 <T::Lookup as StaticLookup>::lookup(s)
2639 }
2640}
2641
2642#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2644pub struct RunToBlockHooks<'a, T>
2645where
2646 T: 'a + Config,
2647{
2648 before_initialize: Box<dyn 'a + FnMut(BlockNumberFor<T>)>,
2649 after_initialize: Box<dyn 'a + FnMut(BlockNumberFor<T>)>,
2650 before_finalize: Box<dyn 'a + FnMut(BlockNumberFor<T>)>,
2651 after_finalize: Box<dyn 'a + FnMut(BlockNumberFor<T>)>,
2652}
2653
2654#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2655impl<'a, T> RunToBlockHooks<'a, T>
2656where
2657 T: 'a + Config,
2658{
2659 pub fn before_initialize<F>(mut self, f: F) -> Self
2661 where
2662 F: 'a + FnMut(BlockNumberFor<T>),
2663 {
2664 self.before_initialize = Box::new(f);
2665 self
2666 }
2667 pub fn after_initialize<F>(mut self, f: F) -> Self
2669 where
2670 F: 'a + FnMut(BlockNumberFor<T>),
2671 {
2672 self.after_initialize = Box::new(f);
2673 self
2674 }
2675 pub fn before_finalize<F>(mut self, f: F) -> Self
2677 where
2678 F: 'a + FnMut(BlockNumberFor<T>),
2679 {
2680 self.before_finalize = Box::new(f);
2681 self
2682 }
2683 pub fn after_finalize<F>(mut self, f: F) -> Self
2685 where
2686 F: 'a + FnMut(BlockNumberFor<T>),
2687 {
2688 self.after_finalize = Box::new(f);
2689 self
2690 }
2691}
2692
2693#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2694impl<'a, T> Default for RunToBlockHooks<'a, T>
2695where
2696 T: Config,
2697{
2698 fn default() -> Self {
2699 Self {
2700 before_initialize: Box::new(|_| {}),
2701 after_initialize: Box::new(|_| {}),
2702 before_finalize: Box::new(|_| {}),
2703 after_finalize: Box::new(|_| {}),
2704 }
2705 }
2706}
2707
2708pub mod pallet_prelude {
2710 pub use crate::{
2711 ensure_authorized, ensure_none, ensure_root, ensure_signed, ensure_signed_or_root,
2712 };
2713
2714 pub type OriginFor<T> = <T as crate::Config>::RuntimeOrigin;
2716
2717 pub type HeaderFor<T> =
2719 <<T as crate::Config>::Block as sp_runtime::traits::HeaderProvider>::HeaderT;
2720
2721 pub type BlockNumberFor<T> = <HeaderFor<T> as sp_runtime::traits::Header>::Number;
2723
2724 pub type ExtrinsicFor<T> =
2726 <<T as crate::Config>::Block as sp_runtime::traits::Block>::Extrinsic;
2727
2728 pub type RuntimeCallFor<T> = <T as crate::Config>::RuntimeCall;
2730
2731 pub type AccountIdFor<T> = <T as crate::Config>::AccountId;
2733}