1#![cfg_attr(not(feature = "std"), no_std)]
99
100extern crate alloc;
101
102use alloc::{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};
123#[cfg(any(feature = "std", test))]
124use sp_std::map;
125use sp_version::RuntimeVersion;
126
127use codec::{Decode, Encode, EncodeLike, FullCodec, MaxEncodedLen};
128#[cfg(feature = "std")]
129use frame_support::traits::BuildGenesisConfig;
130use frame_support::{
131 dispatch::{
132 extract_actual_pays_fee, extract_actual_weight, DispatchClass, DispatchInfo,
133 DispatchResult, DispatchResultWithPostInfo, PerDispatchClass, 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_weights::{RuntimeDbWeight, Weight};
149
150#[cfg(any(feature = "std", test))]
151use sp_io::TestExternalities;
152
153pub mod limits;
154#[cfg(test)]
155pub(crate) mod mock;
156
157pub mod offchain;
158
159mod extensions;
160#[cfg(feature = "std")]
161pub mod mocking;
162#[cfg(test)]
163mod tests;
164pub mod weights;
165
166pub mod migrations;
167
168pub use extensions::{
169 check_genesis::CheckGenesis, check_mortality::CheckMortality,
170 check_non_zero_sender::CheckNonZeroSender, check_nonce::CheckNonce,
171 check_spec_version::CheckSpecVersion, check_tx_version::CheckTxVersion,
172 check_weight::CheckWeight,
173};
174pub use extensions::check_mortality::CheckMortality as CheckEra;
176pub use frame_support::dispatch::RawOrigin;
177use frame_support::traits::{PostInherents, PostTransactions, PreInherents};
178use sp_core::storage::StateVersion;
179pub use weights::WeightInfo;
180
181const LOG_TARGET: &str = "runtime::system";
182
183pub fn extrinsics_root<H: Hash, E: codec::Encode>(
188 extrinsics: &[E],
189 state_version: StateVersion,
190) -> H::Output {
191 extrinsics_data_root::<H>(extrinsics.iter().map(codec::Encode::encode).collect(), state_version)
192}
193
194pub fn extrinsics_data_root<H: Hash>(xts: Vec<Vec<u8>>, state_version: StateVersion) -> H::Output {
199 H::ordered_trie_root(xts, state_version)
200}
201
202pub type ConsumedWeight = PerDispatchClass<Weight>;
204
205pub use pallet::*;
206
207pub trait SetCode<T: Config> {
209 fn set_code(code: Vec<u8>) -> DispatchResult;
211}
212
213impl<T: Config> SetCode<T> for () {
214 fn set_code(code: Vec<u8>) -> DispatchResult {
215 <Pallet<T>>::update_code_in_storage(&code);
216 Ok(())
217 }
218}
219
220pub trait ConsumerLimits {
222 fn max_consumers() -> RefCount;
224 fn max_overflow() -> RefCount;
230}
231
232impl<const Z: u32> ConsumerLimits for ConstU32<Z> {
233 fn max_consumers() -> RefCount {
234 Z
235 }
236 fn max_overflow() -> RefCount {
237 Z
238 }
239}
240
241impl<MaxNormal: Get<u32>, MaxOverflow: Get<u32>> ConsumerLimits for (MaxNormal, MaxOverflow) {
242 fn max_consumers() -> RefCount {
243 MaxNormal::get()
244 }
245 fn max_overflow() -> RefCount {
246 MaxOverflow::get()
247 }
248}
249
250#[derive(Decode, Encode, Default, PartialEq, Eq, MaxEncodedLen, TypeInfo)]
253#[scale_info(skip_type_params(T))]
254pub struct CodeUpgradeAuthorization<T>
255where
256 T: Config,
257{
258 code_hash: T::Hash,
260 check_version: bool,
262}
263
264#[frame_support::pallet]
265pub mod pallet {
266 use crate::{self as frame_system, pallet_prelude::*, *};
267 use frame_support::pallet_prelude::*;
268
269 pub mod config_preludes {
271 use super::{inject_runtime_type, DefaultConfig};
272 use frame_support::{derive_impl, traits::Get};
273
274 pub struct TestBlockHashCount<C: Get<u32>>(core::marker::PhantomData<C>);
280 impl<I: From<u32>, C: Get<u32>> Get<I> for TestBlockHashCount<C> {
281 fn get() -> I {
282 C::get().into()
283 }
284 }
285
286 pub struct TestDefaultConfig;
293
294 #[frame_support::register_default_impl(TestDefaultConfig)]
295 impl DefaultConfig for TestDefaultConfig {
296 type Nonce = u32;
297 type Hash = sp_core::hash::H256;
298 type Hashing = sp_runtime::traits::BlakeTwo256;
299 type AccountId = u64;
300 type Lookup = sp_runtime::traits::IdentityLookup<u64>;
301 type MaxConsumers = frame_support::traits::ConstU32<16>;
302 type AccountData = ();
303 type OnNewAccount = ();
304 type OnKilledAccount = ();
305 type SystemWeightInfo = ();
306 type SS58Prefix = ();
307 type Version = ();
308 type BlockWeights = ();
309 type BlockLength = ();
310 type DbWeight = ();
311 #[inject_runtime_type]
312 type RuntimeEvent = ();
313 #[inject_runtime_type]
314 type RuntimeOrigin = ();
315 #[inject_runtime_type]
316 type RuntimeCall = ();
317 #[inject_runtime_type]
318 type PalletInfo = ();
319 #[inject_runtime_type]
320 type RuntimeTask = ();
321 type BaseCallFilter = frame_support::traits::Everything;
322 type BlockHashCount = TestBlockHashCount<frame_support::traits::ConstU32<10>>;
323 type OnSetCode = ();
324 type SingleBlockMigrations = ();
325 type MultiBlockMigrator = ();
326 type PreInherents = ();
327 type PostInherents = ();
328 type PostTransactions = ();
329 }
330
331 pub struct SolochainDefaultConfig;
345
346 #[frame_support::register_default_impl(SolochainDefaultConfig)]
347 impl DefaultConfig for SolochainDefaultConfig {
348 type Nonce = u32;
350
351 type Hash = sp_core::hash::H256;
353
354 type Hashing = sp_runtime::traits::BlakeTwo256;
356
357 type AccountId = sp_runtime::AccountId32;
359
360 type Lookup = sp_runtime::traits::AccountIdLookup<Self::AccountId, ()>;
362
363 type MaxConsumers = frame_support::traits::ConstU32<128>;
365
366 type AccountData = crate::AccountInfo<Self::Nonce, ()>;
368
369 type OnNewAccount = ();
371
372 type OnKilledAccount = ();
374
375 type SystemWeightInfo = ();
377
378 type SS58Prefix = ();
380
381 type Version = ();
383
384 type BlockWeights = ();
386
387 type BlockLength = ();
389
390 type DbWeight = ();
392
393 #[inject_runtime_type]
395 type RuntimeEvent = ();
396
397 #[inject_runtime_type]
399 type RuntimeOrigin = ();
400
401 #[inject_runtime_type]
404 type RuntimeCall = ();
405
406 #[inject_runtime_type]
408 type RuntimeTask = ();
409
410 #[inject_runtime_type]
412 type PalletInfo = ();
413
414 type BaseCallFilter = frame_support::traits::Everything;
416
417 type BlockHashCount = TestBlockHashCount<frame_support::traits::ConstU32<256>>;
420
421 type OnSetCode = ();
423 type SingleBlockMigrations = ();
424 type MultiBlockMigrator = ();
425 type PreInherents = ();
426 type PostInherents = ();
427 type PostTransactions = ();
428 }
429
430 pub struct RelayChainDefaultConfig;
432
433 #[derive_impl(SolochainDefaultConfig as DefaultConfig, no_aggregated_types)]
435 #[frame_support::register_default_impl(RelayChainDefaultConfig)]
436 impl DefaultConfig for RelayChainDefaultConfig {}
437
438 pub struct ParaChainDefaultConfig;
440
441 #[derive_impl(SolochainDefaultConfig as DefaultConfig, no_aggregated_types)]
443 #[frame_support::register_default_impl(ParaChainDefaultConfig)]
444 impl DefaultConfig for ParaChainDefaultConfig {}
445 }
446
447 #[pallet::config(with_default)]
449 #[pallet::disable_frame_system_supertrait_check]
450 pub trait Config: 'static + Eq + Clone {
451 #[pallet::no_default_bounds]
453 type RuntimeEvent: Parameter
454 + Member
455 + From<Event<Self>>
456 + Debug
457 + IsType<<Self as frame_system::Config>::RuntimeEvent>;
458
459 #[pallet::no_default_bounds]
470 type BaseCallFilter: Contains<Self::RuntimeCall>;
471
472 #[pallet::constant]
474 type BlockWeights: Get<limits::BlockWeights>;
475
476 #[pallet::constant]
478 type BlockLength: Get<limits::BlockLength>;
479
480 #[pallet::no_default_bounds]
482 type RuntimeOrigin: Into<Result<RawOrigin<Self::AccountId>, Self::RuntimeOrigin>>
483 + From<RawOrigin<Self::AccountId>>
484 + Clone
485 + OriginTrait<Call = Self::RuntimeCall, AccountId = Self::AccountId>;
486
487 #[docify::export(system_runtime_call)]
488 #[pallet::no_default_bounds]
490 type RuntimeCall: Parameter
491 + Dispatchable<RuntimeOrigin = Self::RuntimeOrigin>
492 + Debug
493 + From<Call<Self>>;
494
495 #[pallet::no_default_bounds]
497 type RuntimeTask: Task;
498
499 type Nonce: Parameter
501 + Member
502 + MaybeSerializeDeserialize
503 + Debug
504 + Default
505 + MaybeDisplay
506 + AtLeast32Bit
507 + Copy
508 + MaxEncodedLen;
509
510 type Hash: Parameter
512 + Member
513 + MaybeSerializeDeserialize
514 + Debug
515 + MaybeDisplay
516 + SimpleBitOps
517 + Ord
518 + Default
519 + Copy
520 + CheckEqual
521 + core::hash::Hash
522 + AsRef<[u8]>
523 + AsMut<[u8]>
524 + MaxEncodedLen;
525
526 type Hashing: Hash<Output = Self::Hash> + TypeInfo;
528
529 type AccountId: Parameter
531 + Member
532 + MaybeSerializeDeserialize
533 + Debug
534 + MaybeDisplay
535 + Ord
536 + MaxEncodedLen;
537
538 type Lookup: StaticLookup<Target = Self::AccountId>;
545
546 #[pallet::no_default]
549 type Block: Parameter + Member + traits::Block<Hash = Self::Hash>;
550
551 #[pallet::constant]
553 #[pallet::no_default_bounds]
554 type BlockHashCount: Get<BlockNumberFor<Self>>;
555
556 #[pallet::constant]
558 type DbWeight: Get<RuntimeDbWeight>;
559
560 #[pallet::constant]
562 type Version: Get<RuntimeVersion>;
563
564 #[pallet::no_default_bounds]
571 type PalletInfo: PalletInfo;
572
573 type AccountData: Member + FullCodec + Clone + Default + TypeInfo + MaxEncodedLen;
576
577 type OnNewAccount: OnNewAccount<Self::AccountId>;
579
580 type OnKilledAccount: OnKilledAccount<Self::AccountId>;
584
585 type SystemWeightInfo: WeightInfo;
586
587 #[pallet::constant]
593 type SS58Prefix: Get<u16>;
594
595 #[pallet::no_default_bounds]
603 type OnSetCode: SetCode<Self>;
604
605 type MaxConsumers: ConsumerLimits;
607
608 type SingleBlockMigrations: OnRuntimeUpgrade;
615
616 type MultiBlockMigrator: MultiStepMigrator;
621
622 type PreInherents: PreInherents;
626
627 type PostInherents: PostInherents;
631
632 type PostTransactions: PostTransactions;
636 }
637
638 #[pallet::pallet]
639 pub struct Pallet<T>(_);
640
641 #[pallet::hooks]
642 impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
643 #[cfg(feature = "std")]
644 fn integrity_test() {
645 T::BlockWeights::get().validate().expect("The weights are invalid.");
646 }
647 }
648
649 #[pallet::call]
650 impl<T: Config> Pallet<T> {
651 #[pallet::call_index(0)]
655 #[pallet::weight(T::SystemWeightInfo::remark(remark.len() as u32))]
656 pub fn remark(_origin: OriginFor<T>, remark: Vec<u8>) -> DispatchResultWithPostInfo {
657 let _ = remark; Ok(().into())
659 }
660
661 #[pallet::call_index(1)]
663 #[pallet::weight((T::SystemWeightInfo::set_heap_pages(), DispatchClass::Operational))]
664 pub fn set_heap_pages(origin: OriginFor<T>, pages: u64) -> DispatchResultWithPostInfo {
665 ensure_root(origin)?;
666 storage::unhashed::put_raw(well_known_keys::HEAP_PAGES, &pages.encode());
667 Self::deposit_log(generic::DigestItem::RuntimeEnvironmentUpdated);
668 Ok(().into())
669 }
670
671 #[pallet::call_index(2)]
673 #[pallet::weight((T::SystemWeightInfo::set_code(), DispatchClass::Operational))]
674 pub fn set_code(origin: OriginFor<T>, code: Vec<u8>) -> DispatchResultWithPostInfo {
675 ensure_root(origin)?;
676 Self::can_set_code(&code)?;
677 T::OnSetCode::set_code(code)?;
678 Ok(Some(T::BlockWeights::get().max_block).into())
680 }
681
682 #[pallet::call_index(3)]
687 #[pallet::weight((T::SystemWeightInfo::set_code(), DispatchClass::Operational))]
688 pub fn set_code_without_checks(
689 origin: OriginFor<T>,
690 code: Vec<u8>,
691 ) -> DispatchResultWithPostInfo {
692 ensure_root(origin)?;
693 T::OnSetCode::set_code(code)?;
694 Ok(Some(T::BlockWeights::get().max_block).into())
695 }
696
697 #[pallet::call_index(4)]
699 #[pallet::weight((
700 T::SystemWeightInfo::set_storage(items.len() as u32),
701 DispatchClass::Operational,
702 ))]
703 pub fn set_storage(
704 origin: OriginFor<T>,
705 items: Vec<KeyValue>,
706 ) -> DispatchResultWithPostInfo {
707 ensure_root(origin)?;
708 for i in &items {
709 storage::unhashed::put_raw(&i.0, &i.1);
710 }
711 Ok(().into())
712 }
713
714 #[pallet::call_index(5)]
716 #[pallet::weight((
717 T::SystemWeightInfo::kill_storage(keys.len() as u32),
718 DispatchClass::Operational,
719 ))]
720 pub fn kill_storage(origin: OriginFor<T>, keys: Vec<Key>) -> DispatchResultWithPostInfo {
721 ensure_root(origin)?;
722 for key in &keys {
723 storage::unhashed::kill(key);
724 }
725 Ok(().into())
726 }
727
728 #[pallet::call_index(6)]
733 #[pallet::weight((
734 T::SystemWeightInfo::kill_prefix(subkeys.saturating_add(1)),
735 DispatchClass::Operational,
736 ))]
737 pub fn kill_prefix(
738 origin: OriginFor<T>,
739 prefix: Key,
740 subkeys: u32,
741 ) -> DispatchResultWithPostInfo {
742 ensure_root(origin)?;
743 let _ = storage::unhashed::clear_prefix(&prefix, Some(subkeys), None);
744 Ok(().into())
745 }
746
747 #[pallet::call_index(7)]
749 #[pallet::weight(T::SystemWeightInfo::remark_with_event(remark.len() as u32))]
750 pub fn remark_with_event(
751 origin: OriginFor<T>,
752 remark: Vec<u8>,
753 ) -> DispatchResultWithPostInfo {
754 let who = ensure_signed(origin)?;
755 let hash = T::Hashing::hash(&remark[..]);
756 Self::deposit_event(Event::Remarked { sender: who, hash });
757 Ok(().into())
758 }
759
760 #[cfg(feature = "experimental")]
761 #[pallet::call_index(8)]
762 #[pallet::weight(task.weight())]
763 pub fn do_task(_origin: OriginFor<T>, task: T::RuntimeTask) -> DispatchResultWithPostInfo {
764 if !task.is_valid() {
765 return Err(Error::<T>::InvalidTask.into())
766 }
767
768 Self::deposit_event(Event::TaskStarted { task: task.clone() });
769 if let Err(err) = task.run() {
770 Self::deposit_event(Event::TaskFailed { task, err });
771 return Err(Error::<T>::FailedTask.into())
772 }
773
774 Self::deposit_event(Event::TaskCompleted { task });
776
777 Ok(().into())
779 }
780
781 #[pallet::call_index(9)]
786 #[pallet::weight((T::SystemWeightInfo::authorize_upgrade(), DispatchClass::Operational))]
787 pub fn authorize_upgrade(origin: OriginFor<T>, code_hash: T::Hash) -> DispatchResult {
788 ensure_root(origin)?;
789 Self::do_authorize_upgrade(code_hash, true);
790 Ok(())
791 }
792
793 #[pallet::call_index(10)]
802 #[pallet::weight((T::SystemWeightInfo::authorize_upgrade(), DispatchClass::Operational))]
803 pub fn authorize_upgrade_without_checks(
804 origin: OriginFor<T>,
805 code_hash: T::Hash,
806 ) -> DispatchResult {
807 ensure_root(origin)?;
808 Self::do_authorize_upgrade(code_hash, false);
809 Ok(())
810 }
811
812 #[pallet::call_index(11)]
822 #[pallet::weight((T::SystemWeightInfo::apply_authorized_upgrade(), DispatchClass::Operational))]
823 pub fn apply_authorized_upgrade(
824 _: OriginFor<T>,
825 code: Vec<u8>,
826 ) -> DispatchResultWithPostInfo {
827 let post = Self::do_apply_authorize_upgrade(code)?;
828 Ok(post)
829 }
830 }
831
832 #[pallet::event]
834 pub enum Event<T: Config> {
835 ExtrinsicSuccess { dispatch_info: DispatchInfo },
837 ExtrinsicFailed { dispatch_error: DispatchError, dispatch_info: DispatchInfo },
839 CodeUpdated,
841 NewAccount { account: T::AccountId },
843 KilledAccount { account: T::AccountId },
845 Remarked { sender: T::AccountId, hash: T::Hash },
847 #[cfg(feature = "experimental")]
848 TaskStarted { task: T::RuntimeTask },
850 #[cfg(feature = "experimental")]
851 TaskCompleted { task: T::RuntimeTask },
853 #[cfg(feature = "experimental")]
854 TaskFailed { task: T::RuntimeTask, err: DispatchError },
856 UpgradeAuthorized { code_hash: T::Hash, check_version: bool },
858 }
859
860 #[pallet::error]
862 pub enum Error<T> {
863 InvalidSpecName,
866 SpecVersionNeedsToIncrease,
869 FailedToExtractRuntimeVersion,
873 NonDefaultComposite,
875 NonZeroRefCount,
877 CallFiltered,
879 MultiBlockMigrationsOngoing,
881 #[cfg(feature = "experimental")]
882 InvalidTask,
884 #[cfg(feature = "experimental")]
885 FailedTask,
887 NothingAuthorized,
889 Unauthorized,
891 }
892
893 #[pallet::origin]
895 pub type Origin<T> = RawOrigin<<T as Config>::AccountId>;
896
897 #[pallet::storage]
899 #[pallet::getter(fn account)]
900 pub type Account<T: Config> = StorageMap<
901 _,
902 Blake2_128Concat,
903 T::AccountId,
904 AccountInfo<T::Nonce, T::AccountData>,
905 ValueQuery,
906 >;
907
908 #[pallet::storage]
910 pub(super) type ExtrinsicCount<T: Config> = StorageValue<_, u32>;
911
912 #[pallet::storage]
914 pub type InherentsApplied<T: Config> = StorageValue<_, bool, ValueQuery>;
915
916 #[pallet::storage]
918 #[pallet::whitelist_storage]
919 #[pallet::getter(fn block_weight)]
920 pub type BlockWeight<T: Config> = StorageValue<_, ConsumedWeight, ValueQuery>;
921
922 #[pallet::storage]
924 pub type AllExtrinsicsLen<T: Config> = StorageValue<_, u32>;
925
926 #[pallet::storage]
928 #[pallet::getter(fn block_hash)]
929 pub type BlockHash<T: Config> =
930 StorageMap<_, Twox64Concat, BlockNumberFor<T>, T::Hash, ValueQuery>;
931
932 #[pallet::storage]
934 #[pallet::getter(fn extrinsic_data)]
935 #[pallet::unbounded]
936 pub(super) type ExtrinsicData<T: Config> =
937 StorageMap<_, Twox64Concat, u32, Vec<u8>, ValueQuery>;
938
939 #[pallet::storage]
941 #[pallet::whitelist_storage]
942 #[pallet::getter(fn block_number)]
943 pub(super) type Number<T: Config> = StorageValue<_, BlockNumberFor<T>, ValueQuery>;
944
945 #[pallet::storage]
947 #[pallet::getter(fn parent_hash)]
948 pub(super) type ParentHash<T: Config> = StorageValue<_, T::Hash, ValueQuery>;
949
950 #[pallet::storage]
952 #[pallet::unbounded]
953 #[pallet::getter(fn digest)]
954 pub(super) type Digest<T: Config> = StorageValue<_, generic::Digest, ValueQuery>;
955
956 #[pallet::storage]
964 #[pallet::whitelist_storage]
965 #[pallet::disable_try_decode_storage]
966 #[pallet::unbounded]
967 pub(super) type Events<T: Config> =
968 StorageValue<_, Vec<Box<EventRecord<T::RuntimeEvent, T::Hash>>>, ValueQuery>;
969
970 #[pallet::storage]
972 #[pallet::whitelist_storage]
973 #[pallet::getter(fn event_count)]
974 pub(super) type EventCount<T: Config> = StorageValue<_, EventIndex, ValueQuery>;
975
976 #[pallet::storage]
987 #[pallet::unbounded]
988 #[pallet::getter(fn event_topics)]
989 pub(super) type EventTopics<T: Config> =
990 StorageMap<_, Blake2_128Concat, T::Hash, Vec<(BlockNumberFor<T>, EventIndex)>, ValueQuery>;
991
992 #[pallet::storage]
994 #[pallet::unbounded]
995 pub type LastRuntimeUpgrade<T: Config> = StorageValue<_, LastRuntimeUpgradeInfo>;
996
997 #[pallet::storage]
999 pub(super) type UpgradedToU32RefCount<T: Config> = StorageValue<_, bool, ValueQuery>;
1000
1001 #[pallet::storage]
1004 pub(super) type UpgradedToTripleRefCount<T: Config> = StorageValue<_, bool, ValueQuery>;
1005
1006 #[pallet::storage]
1008 #[pallet::whitelist_storage]
1009 pub(super) type ExecutionPhase<T: Config> = StorageValue<_, Phase>;
1010
1011 #[pallet::storage]
1013 #[pallet::getter(fn authorized_upgrade)]
1014 pub(super) type AuthorizedUpgrade<T: Config> =
1015 StorageValue<_, CodeUpgradeAuthorization<T>, OptionQuery>;
1016
1017 #[derive(frame_support::DefaultNoBound)]
1018 #[pallet::genesis_config]
1019 pub struct GenesisConfig<T: Config> {
1020 #[serde(skip)]
1021 pub _config: core::marker::PhantomData<T>,
1022 }
1023
1024 #[pallet::genesis_build]
1025 impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
1026 fn build(&self) {
1027 <BlockHash<T>>::insert::<_, T::Hash>(BlockNumberFor::<T>::zero(), hash69());
1028 <ParentHash<T>>::put::<T::Hash>(hash69());
1029 <LastRuntimeUpgrade<T>>::put(LastRuntimeUpgradeInfo::from(T::Version::get()));
1030 <UpgradedToU32RefCount<T>>::put(true);
1031 <UpgradedToTripleRefCount<T>>::put(true);
1032
1033 sp_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode());
1034 }
1035 }
1036
1037 #[pallet::validate_unsigned]
1038 impl<T: Config> sp_runtime::traits::ValidateUnsigned for Pallet<T> {
1039 type Call = Call<T>;
1040 fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity {
1041 if let Call::apply_authorized_upgrade { ref code } = call {
1042 if let Ok(hash) = Self::validate_authorized_upgrade(&code[..]) {
1043 return Ok(ValidTransaction {
1044 priority: 100,
1045 requires: Vec::new(),
1046 provides: vec![hash.as_ref().to_vec()],
1047 longevity: TransactionLongevity::max_value(),
1048 propagate: true,
1049 })
1050 }
1051 }
1052 #[cfg(feature = "experimental")]
1053 if let Call::do_task { ref task } = call {
1054 if task.is_valid() {
1055 return Ok(ValidTransaction {
1056 priority: u64::max_value(),
1057 requires: Vec::new(),
1058 provides: vec![T::Hashing::hash_of(&task.encode()).as_ref().to_vec()],
1059 longevity: TransactionLongevity::max_value(),
1060 propagate: true,
1061 })
1062 }
1063 }
1064 Err(InvalidTransaction::Call.into())
1065 }
1066 }
1067}
1068
1069pub type Key = Vec<u8>;
1070pub type KeyValue = (Vec<u8>, Vec<u8>);
1071
1072#[derive(Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen)]
1074#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone))]
1075pub enum Phase {
1076 ApplyExtrinsic(u32),
1078 Finalization,
1080 Initialization,
1082}
1083
1084impl Default for Phase {
1085 fn default() -> Self {
1086 Self::Initialization
1087 }
1088}
1089
1090#[derive(Encode, Decode, RuntimeDebug, TypeInfo)]
1092#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone))]
1093pub struct EventRecord<E: Parameter + Member, T> {
1094 pub phase: Phase,
1096 pub event: E,
1098 pub topics: Vec<T>,
1100}
1101
1102fn hash69<T: AsMut<[u8]> + Default>() -> T {
1105 let mut h = T::default();
1106 h.as_mut().iter_mut().for_each(|byte| *byte = 69);
1107 h
1108}
1109
1110type EventIndex = u32;
1115
1116pub type RefCount = u32;
1118
1119#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)]
1121pub struct AccountInfo<Nonce, AccountData> {
1122 pub nonce: Nonce,
1124 pub consumers: RefCount,
1127 pub providers: RefCount,
1130 pub sufficients: RefCount,
1133 pub data: AccountData,
1136}
1137
1138#[derive(sp_runtime::RuntimeDebug, Encode, Decode, TypeInfo)]
1141#[cfg_attr(feature = "std", derive(PartialEq))]
1142pub struct LastRuntimeUpgradeInfo {
1143 pub spec_version: codec::Compact<u32>,
1144 pub spec_name: sp_runtime::RuntimeString,
1145}
1146
1147impl LastRuntimeUpgradeInfo {
1148 pub fn was_upgraded(&self, current: &sp_version::RuntimeVersion) -> bool {
1152 current.spec_version > self.spec_version.0 || current.spec_name != self.spec_name
1153 }
1154}
1155
1156impl From<sp_version::RuntimeVersion> for LastRuntimeUpgradeInfo {
1157 fn from(version: sp_version::RuntimeVersion) -> Self {
1158 Self { spec_version: version.spec_version.into(), spec_name: version.spec_name }
1159 }
1160}
1161
1162pub struct EnsureRoot<AccountId>(core::marker::PhantomData<AccountId>);
1164impl<O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>, AccountId>
1165 EnsureOrigin<O> for EnsureRoot<AccountId>
1166{
1167 type Success = ();
1168 fn try_origin(o: O) -> Result<Self::Success, O> {
1169 o.into().and_then(|o| match o {
1170 RawOrigin::Root => Ok(()),
1171 r => Err(O::from(r)),
1172 })
1173 }
1174
1175 #[cfg(feature = "runtime-benchmarks")]
1176 fn try_successful_origin() -> Result<O, ()> {
1177 Ok(O::from(RawOrigin::Root))
1178 }
1179}
1180
1181impl_ensure_origin_with_arg_ignoring_arg! {
1182 impl< { O: .., AccountId: Decode, T } >
1183 EnsureOriginWithArg<O, T> for EnsureRoot<AccountId>
1184 {}
1185}
1186
1187pub struct EnsureRootWithSuccess<AccountId, Success>(
1189 core::marker::PhantomData<(AccountId, Success)>,
1190);
1191impl<
1192 O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
1193 AccountId,
1194 Success: TypedGet,
1195 > EnsureOrigin<O> for EnsureRootWithSuccess<AccountId, Success>
1196{
1197 type Success = Success::Type;
1198 fn try_origin(o: O) -> Result<Self::Success, O> {
1199 o.into().and_then(|o| match o {
1200 RawOrigin::Root => Ok(Success::get()),
1201 r => Err(O::from(r)),
1202 })
1203 }
1204
1205 #[cfg(feature = "runtime-benchmarks")]
1206 fn try_successful_origin() -> Result<O, ()> {
1207 Ok(O::from(RawOrigin::Root))
1208 }
1209}
1210
1211impl_ensure_origin_with_arg_ignoring_arg! {
1212 impl< { O: .., AccountId: Decode, Success: TypedGet, T } >
1213 EnsureOriginWithArg<O, T> for EnsureRootWithSuccess<AccountId, Success>
1214 {}
1215}
1216
1217pub struct EnsureWithSuccess<Ensure, AccountId, Success>(
1219 core::marker::PhantomData<(Ensure, AccountId, Success)>,
1220);
1221
1222impl<
1223 O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
1224 Ensure: EnsureOrigin<O>,
1225 AccountId,
1226 Success: TypedGet,
1227 > EnsureOrigin<O> for EnsureWithSuccess<Ensure, AccountId, Success>
1228{
1229 type Success = Success::Type;
1230
1231 fn try_origin(o: O) -> Result<Self::Success, O> {
1232 Ensure::try_origin(o).map(|_| Success::get())
1233 }
1234
1235 #[cfg(feature = "runtime-benchmarks")]
1236 fn try_successful_origin() -> Result<O, ()> {
1237 Ensure::try_successful_origin()
1238 }
1239}
1240
1241pub struct EnsureSigned<AccountId>(core::marker::PhantomData<AccountId>);
1243impl<O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>, AccountId: Decode>
1244 EnsureOrigin<O> for EnsureSigned<AccountId>
1245{
1246 type Success = AccountId;
1247 fn try_origin(o: O) -> Result<Self::Success, O> {
1248 o.into().and_then(|o| match o {
1249 RawOrigin::Signed(who) => Ok(who),
1250 r => Err(O::from(r)),
1251 })
1252 }
1253
1254 #[cfg(feature = "runtime-benchmarks")]
1255 fn try_successful_origin() -> Result<O, ()> {
1256 let zero_account_id =
1257 AccountId::decode(&mut TrailingZeroInput::zeroes()).map_err(|_| ())?;
1258 Ok(O::from(RawOrigin::Signed(zero_account_id)))
1259 }
1260}
1261
1262impl_ensure_origin_with_arg_ignoring_arg! {
1263 impl< { O: .., AccountId: Decode, T } >
1264 EnsureOriginWithArg<O, T> for EnsureSigned<AccountId>
1265 {}
1266}
1267
1268pub struct EnsureSignedBy<Who, AccountId>(core::marker::PhantomData<(Who, AccountId)>);
1270impl<
1271 O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
1272 Who: SortedMembers<AccountId>,
1273 AccountId: PartialEq + Clone + Ord + Decode,
1274 > EnsureOrigin<O> for EnsureSignedBy<Who, AccountId>
1275{
1276 type Success = AccountId;
1277 fn try_origin(o: O) -> Result<Self::Success, O> {
1278 o.into().and_then(|o| match o {
1279 RawOrigin::Signed(ref who) if Who::contains(who) => Ok(who.clone()),
1280 r => Err(O::from(r)),
1281 })
1282 }
1283
1284 #[cfg(feature = "runtime-benchmarks")]
1285 fn try_successful_origin() -> Result<O, ()> {
1286 let first_member = match Who::sorted_members().first() {
1287 Some(account) => account.clone(),
1288 None => AccountId::decode(&mut TrailingZeroInput::zeroes()).map_err(|_| ())?,
1289 };
1290 Ok(O::from(RawOrigin::Signed(first_member)))
1291 }
1292}
1293
1294impl_ensure_origin_with_arg_ignoring_arg! {
1295 impl< { O: .., Who: SortedMembers<AccountId>, AccountId: PartialEq + Clone + Ord + Decode, T } >
1296 EnsureOriginWithArg<O, T> for EnsureSignedBy<Who, AccountId>
1297 {}
1298}
1299
1300pub struct EnsureNone<AccountId>(core::marker::PhantomData<AccountId>);
1302impl<O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>, AccountId>
1303 EnsureOrigin<O> for EnsureNone<AccountId>
1304{
1305 type Success = ();
1306 fn try_origin(o: O) -> Result<Self::Success, O> {
1307 o.into().and_then(|o| match o {
1308 RawOrigin::None => Ok(()),
1309 r => Err(O::from(r)),
1310 })
1311 }
1312
1313 #[cfg(feature = "runtime-benchmarks")]
1314 fn try_successful_origin() -> Result<O, ()> {
1315 Ok(O::from(RawOrigin::None))
1316 }
1317}
1318
1319impl_ensure_origin_with_arg_ignoring_arg! {
1320 impl< { O: .., AccountId, T } >
1321 EnsureOriginWithArg<O, T> for EnsureNone<AccountId>
1322 {}
1323}
1324
1325pub struct EnsureNever<Success>(core::marker::PhantomData<Success>);
1327impl<O, Success> EnsureOrigin<O> for EnsureNever<Success> {
1328 type Success = Success;
1329 fn try_origin(o: O) -> Result<Self::Success, O> {
1330 Err(o)
1331 }
1332
1333 #[cfg(feature = "runtime-benchmarks")]
1334 fn try_successful_origin() -> Result<O, ()> {
1335 Err(())
1336 }
1337}
1338
1339impl_ensure_origin_with_arg_ignoring_arg! {
1340 impl< { O, Success, T } >
1341 EnsureOriginWithArg<O, T> for EnsureNever<Success>
1342 {}
1343}
1344
1345#[docify::export]
1346pub fn ensure_signed<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<AccountId, BadOrigin>
1349where
1350 OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1351{
1352 match o.into() {
1353 Ok(RawOrigin::Signed(t)) => Ok(t),
1354 _ => Err(BadOrigin),
1355 }
1356}
1357
1358pub fn ensure_signed_or_root<OuterOrigin, AccountId>(
1362 o: OuterOrigin,
1363) -> Result<Option<AccountId>, BadOrigin>
1364where
1365 OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1366{
1367 match o.into() {
1368 Ok(RawOrigin::Root) => Ok(None),
1369 Ok(RawOrigin::Signed(t)) => Ok(Some(t)),
1370 _ => Err(BadOrigin),
1371 }
1372}
1373
1374pub fn ensure_root<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), BadOrigin>
1376where
1377 OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1378{
1379 match o.into() {
1380 Ok(RawOrigin::Root) => Ok(()),
1381 _ => Err(BadOrigin),
1382 }
1383}
1384
1385pub fn ensure_none<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), BadOrigin>
1387where
1388 OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1389{
1390 match o.into() {
1391 Ok(RawOrigin::None) => Ok(()),
1392 _ => Err(BadOrigin),
1393 }
1394}
1395
1396#[derive(RuntimeDebug)]
1398pub enum RefStatus {
1399 Referenced,
1400 Unreferenced,
1401}
1402
1403#[derive(Eq, PartialEq, RuntimeDebug)]
1405pub enum IncRefStatus {
1406 Created,
1408 Existed,
1410}
1411
1412#[derive(Eq, PartialEq, RuntimeDebug)]
1414pub enum DecRefStatus {
1415 Reaped,
1417 Exists,
1419}
1420
1421impl<T: Config> Pallet<T> {
1422 #[doc = docify::embed!("src/tests.rs", last_runtime_upgrade_spec_version_usage)]
1436 pub fn last_runtime_upgrade_spec_version() -> u32 {
1437 LastRuntimeUpgrade::<T>::get().map_or(0, |l| l.spec_version.0)
1438 }
1439
1440 pub fn account_exists(who: &T::AccountId) -> bool {
1442 Account::<T>::contains_key(who)
1443 }
1444
1445 pub fn update_code_in_storage(code: &[u8]) {
1451 storage::unhashed::put_raw(well_known_keys::CODE, code);
1452 Self::deposit_log(generic::DigestItem::RuntimeEnvironmentUpdated);
1453 Self::deposit_event(Event::CodeUpdated);
1454 }
1455
1456 pub fn inherents_applied() -> bool {
1458 InherentsApplied::<T>::get()
1459 }
1460
1461 pub fn note_inherents_applied() {
1466 InherentsApplied::<T>::put(true);
1467 }
1468
1469 #[deprecated = "Use `inc_consumers` instead"]
1471 pub fn inc_ref(who: &T::AccountId) {
1472 let _ = Self::inc_consumers(who);
1473 }
1474
1475 #[deprecated = "Use `dec_consumers` instead"]
1478 pub fn dec_ref(who: &T::AccountId) {
1479 let _ = Self::dec_consumers(who);
1480 }
1481
1482 #[deprecated = "Use `consumers` instead"]
1484 pub fn refs(who: &T::AccountId) -> RefCount {
1485 Self::consumers(who)
1486 }
1487
1488 #[deprecated = "Use `!is_provider_required` instead"]
1490 pub fn allow_death(who: &T::AccountId) -> bool {
1491 !Self::is_provider_required(who)
1492 }
1493
1494 pub fn inc_providers(who: &T::AccountId) -> IncRefStatus {
1496 Account::<T>::mutate(who, |a| {
1497 if a.providers == 0 && a.sufficients == 0 {
1498 a.providers = 1;
1500 Self::on_created_account(who.clone(), a);
1501 IncRefStatus::Created
1502 } else {
1503 a.providers = a.providers.saturating_add(1);
1504 IncRefStatus::Existed
1505 }
1506 })
1507 }
1508
1509 pub fn dec_providers(who: &T::AccountId) -> Result<DecRefStatus, DispatchError> {
1513 Account::<T>::try_mutate_exists(who, |maybe_account| {
1514 if let Some(mut account) = maybe_account.take() {
1515 if account.providers == 0 {
1516 log::error!(
1518 target: LOG_TARGET,
1519 "Logic error: Unexpected underflow in reducing provider",
1520 );
1521 account.providers = 1;
1522 }
1523 match (account.providers, account.consumers, account.sufficients) {
1524 (1, 0, 0) => {
1525 Pallet::<T>::on_killed_account(who.clone());
1528 Ok(DecRefStatus::Reaped)
1529 },
1530 (1, c, _) if c > 0 => {
1531 Err(DispatchError::ConsumerRemaining)
1533 },
1534 (x, _, _) => {
1535 account.providers = x - 1;
1538 *maybe_account = Some(account);
1539 Ok(DecRefStatus::Exists)
1540 },
1541 }
1542 } else {
1543 log::error!(
1544 target: LOG_TARGET,
1545 "Logic error: Account already dead when reducing provider",
1546 );
1547 Ok(DecRefStatus::Reaped)
1548 }
1549 })
1550 }
1551
1552 pub fn inc_sufficients(who: &T::AccountId) -> IncRefStatus {
1554 Account::<T>::mutate(who, |a| {
1555 if a.providers + a.sufficients == 0 {
1556 a.sufficients = 1;
1558 Self::on_created_account(who.clone(), a);
1559 IncRefStatus::Created
1560 } else {
1561 a.sufficients = a.sufficients.saturating_add(1);
1562 IncRefStatus::Existed
1563 }
1564 })
1565 }
1566
1567 pub fn dec_sufficients(who: &T::AccountId) -> DecRefStatus {
1571 Account::<T>::mutate_exists(who, |maybe_account| {
1572 if let Some(mut account) = maybe_account.take() {
1573 if account.sufficients == 0 {
1574 log::error!(
1576 target: LOG_TARGET,
1577 "Logic error: Unexpected underflow in reducing sufficients",
1578 );
1579 }
1580 match (account.sufficients, account.providers) {
1581 (0, 0) | (1, 0) => {
1582 Pallet::<T>::on_killed_account(who.clone());
1583 DecRefStatus::Reaped
1584 },
1585 (x, _) => {
1586 account.sufficients = x - 1;
1587 *maybe_account = Some(account);
1588 DecRefStatus::Exists
1589 },
1590 }
1591 } else {
1592 log::error!(
1593 target: LOG_TARGET,
1594 "Logic error: Account already dead when reducing provider",
1595 );
1596 DecRefStatus::Reaped
1597 }
1598 })
1599 }
1600
1601 pub fn providers(who: &T::AccountId) -> RefCount {
1603 Account::<T>::get(who).providers
1604 }
1605
1606 pub fn sufficients(who: &T::AccountId) -> RefCount {
1608 Account::<T>::get(who).sufficients
1609 }
1610
1611 pub fn reference_count(who: &T::AccountId) -> RefCount {
1613 let a = Account::<T>::get(who);
1614 a.providers + a.sufficients
1615 }
1616
1617 pub fn inc_consumers(who: &T::AccountId) -> Result<(), DispatchError> {
1622 Account::<T>::try_mutate(who, |a| {
1623 if a.providers > 0 {
1624 if a.consumers < T::MaxConsumers::max_consumers() {
1625 a.consumers = a.consumers.saturating_add(1);
1626 Ok(())
1627 } else {
1628 Err(DispatchError::TooManyConsumers)
1629 }
1630 } else {
1631 Err(DispatchError::NoProviders)
1632 }
1633 })
1634 }
1635
1636 pub fn inc_consumers_without_limit(who: &T::AccountId) -> Result<(), DispatchError> {
1640 Account::<T>::try_mutate(who, |a| {
1641 if a.providers > 0 {
1642 a.consumers = a.consumers.saturating_add(1);
1643 Ok(())
1644 } else {
1645 Err(DispatchError::NoProviders)
1646 }
1647 })
1648 }
1649
1650 pub fn dec_consumers(who: &T::AccountId) {
1653 Account::<T>::mutate(who, |a| {
1654 if a.consumers > 0 {
1655 a.consumers -= 1;
1656 } else {
1657 log::error!(
1658 target: LOG_TARGET,
1659 "Logic error: Unexpected underflow in reducing consumer",
1660 );
1661 }
1662 })
1663 }
1664
1665 pub fn consumers(who: &T::AccountId) -> RefCount {
1667 Account::<T>::get(who).consumers
1668 }
1669
1670 pub fn is_provider_required(who: &T::AccountId) -> bool {
1672 Account::<T>::get(who).consumers != 0
1673 }
1674
1675 pub fn can_dec_provider(who: &T::AccountId) -> bool {
1677 let a = Account::<T>::get(who);
1678 a.consumers == 0 || a.providers > 1
1679 }
1680
1681 pub fn can_accrue_consumers(who: &T::AccountId, amount: u32) -> bool {
1684 let a = Account::<T>::get(who);
1685 match a.consumers.checked_add(amount) {
1686 Some(c) => a.providers > 0 && c <= T::MaxConsumers::max_consumers(),
1687 None => false,
1688 }
1689 }
1690
1691 pub fn can_inc_consumer(who: &T::AccountId) -> bool {
1694 Self::can_accrue_consumers(who, 1)
1695 }
1696
1697 pub fn deposit_event(event: impl Into<T::RuntimeEvent>) {
1701 Self::deposit_event_indexed(&[], event.into());
1702 }
1703
1704 pub fn deposit_event_indexed(topics: &[T::Hash], event: T::RuntimeEvent) {
1712 let block_number = Self::block_number();
1713
1714 if block_number.is_zero() {
1716 return
1717 }
1718
1719 let phase = ExecutionPhase::<T>::get().unwrap_or_default();
1720 let event = EventRecord { phase, event, topics: topics.to_vec() };
1721
1722 let event_idx = {
1724 let old_event_count = EventCount::<T>::get();
1725 let new_event_count = match old_event_count.checked_add(1) {
1726 None => return,
1729 Some(nc) => nc,
1730 };
1731 EventCount::<T>::put(new_event_count);
1732 old_event_count
1733 };
1734
1735 Events::<T>::append(event);
1736
1737 for topic in topics {
1738 <EventTopics<T>>::append(topic, &(block_number, event_idx));
1739 }
1740 }
1741
1742 pub fn extrinsic_index() -> Option<u32> {
1744 storage::unhashed::get(well_known_keys::EXTRINSIC_INDEX)
1745 }
1746
1747 pub fn extrinsic_count() -> u32 {
1749 ExtrinsicCount::<T>::get().unwrap_or_default()
1750 }
1751
1752 pub fn all_extrinsics_len() -> u32 {
1753 AllExtrinsicsLen::<T>::get().unwrap_or_default()
1754 }
1755
1756 pub fn register_extra_weight_unchecked(weight: Weight, class: DispatchClass) {
1772 BlockWeight::<T>::mutate(|current_weight| {
1773 current_weight.accrue(weight, class);
1774 });
1775 }
1776
1777 pub fn initialize(number: &BlockNumberFor<T>, parent_hash: &T::Hash, digest: &generic::Digest) {
1779 ExecutionPhase::<T>::put(Phase::Initialization);
1781 storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &0u32);
1782 let entropy = (b"frame_system::initialize", parent_hash).using_encoded(blake2_256);
1783 storage::unhashed::put_raw(well_known_keys::INTRABLOCK_ENTROPY, &entropy[..]);
1784 <Number<T>>::put(number);
1785 <Digest<T>>::put(digest);
1786 <ParentHash<T>>::put(parent_hash);
1787 <BlockHash<T>>::insert(*number - One::one(), parent_hash);
1788 <InherentsApplied<T>>::kill();
1789
1790 BlockWeight::<T>::kill();
1792 }
1793
1794 pub fn finalize() -> HeaderFor<T> {
1797 log::debug!(
1798 target: LOG_TARGET,
1799 "[{:?}] {} extrinsics, length: {} (normal {}%, op: {}%, mandatory {}%) / normal weight:\
1800 {} ({}%) op weight {} ({}%) / mandatory weight {} ({}%)",
1801 Self::block_number(),
1802 Self::extrinsic_count(),
1803 Self::all_extrinsics_len(),
1804 sp_runtime::Percent::from_rational(
1805 Self::all_extrinsics_len(),
1806 *T::BlockLength::get().max.get(DispatchClass::Normal)
1807 ).deconstruct(),
1808 sp_runtime::Percent::from_rational(
1809 Self::all_extrinsics_len(),
1810 *T::BlockLength::get().max.get(DispatchClass::Operational)
1811 ).deconstruct(),
1812 sp_runtime::Percent::from_rational(
1813 Self::all_extrinsics_len(),
1814 *T::BlockLength::get().max.get(DispatchClass::Mandatory)
1815 ).deconstruct(),
1816 Self::block_weight().get(DispatchClass::Normal),
1817 sp_runtime::Percent::from_rational(
1818 Self::block_weight().get(DispatchClass::Normal).ref_time(),
1819 T::BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap_or(Bounded::max_value()).ref_time()
1820 ).deconstruct(),
1821 Self::block_weight().get(DispatchClass::Operational),
1822 sp_runtime::Percent::from_rational(
1823 Self::block_weight().get(DispatchClass::Operational).ref_time(),
1824 T::BlockWeights::get().get(DispatchClass::Operational).max_total.unwrap_or(Bounded::max_value()).ref_time()
1825 ).deconstruct(),
1826 Self::block_weight().get(DispatchClass::Mandatory),
1827 sp_runtime::Percent::from_rational(
1828 Self::block_weight().get(DispatchClass::Mandatory).ref_time(),
1829 T::BlockWeights::get().get(DispatchClass::Mandatory).max_total.unwrap_or(Bounded::max_value()).ref_time()
1830 ).deconstruct(),
1831 );
1832 ExecutionPhase::<T>::kill();
1833 AllExtrinsicsLen::<T>::kill();
1834 storage::unhashed::kill(well_known_keys::INTRABLOCK_ENTROPY);
1835 InherentsApplied::<T>::kill();
1836
1837 let number = <Number<T>>::get();
1848 let parent_hash = <ParentHash<T>>::get();
1849 let digest = <Digest<T>>::get();
1850
1851 let extrinsics = (0..ExtrinsicCount::<T>::take().unwrap_or_default())
1852 .map(ExtrinsicData::<T>::take)
1853 .collect();
1854 let extrinsics_root_state_version = T::Version::get().extrinsics_root_state_version();
1855 let extrinsics_root =
1856 extrinsics_data_root::<T::Hashing>(extrinsics, extrinsics_root_state_version);
1857
1858 let block_hash_count = T::BlockHashCount::get();
1860 let to_remove = number.saturating_sub(block_hash_count).saturating_sub(One::one());
1861
1862 if !to_remove.is_zero() {
1864 <BlockHash<T>>::remove(to_remove);
1865 }
1866
1867 let version = T::Version::get().state_version();
1868 let storage_root = T::Hash::decode(&mut &sp_io::storage::root(version)[..])
1869 .expect("Node is configured to use the same hash; qed");
1870
1871 HeaderFor::<T>::new(number, extrinsics_root, storage_root, parent_hash, digest)
1872 }
1873
1874 pub fn deposit_log(item: generic::DigestItem) {
1876 <Digest<T>>::append(item);
1877 }
1878
1879 #[cfg(any(feature = "std", test))]
1881 pub fn externalities() -> TestExternalities {
1882 TestExternalities::new(sp_core::storage::Storage {
1883 top: map![
1884 <BlockHash<T>>::hashed_key_for(BlockNumberFor::<T>::zero()) => [69u8; 32].encode(),
1885 <Number<T>>::hashed_key().to_vec() => BlockNumberFor::<T>::one().encode(),
1886 <ParentHash<T>>::hashed_key().to_vec() => [69u8; 32].encode()
1887 ],
1888 children_default: map![],
1889 })
1890 }
1891
1892 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
1900 pub fn events() -> Vec<EventRecord<T::RuntimeEvent, T::Hash>> {
1901 Self::read_events_no_consensus().map(|e| *e).collect()
1903 }
1904
1905 pub fn event_no_consensus(index: usize) -> Option<T::RuntimeEvent> {
1910 Self::read_events_no_consensus().nth(index).map(|e| e.event.clone())
1911 }
1912
1913 pub fn read_events_no_consensus(
1918 ) -> impl Iterator<Item = Box<EventRecord<T::RuntimeEvent, T::Hash>>> {
1919 Events::<T>::stream_iter()
1920 }
1921
1922 pub fn read_events_for_pallet<E>() -> Vec<E>
1927 where
1928 T::RuntimeEvent: TryInto<E>,
1929 {
1930 Events::<T>::get()
1931 .into_iter()
1932 .map(|er| er.event)
1933 .filter_map(|e| e.try_into().ok())
1934 .collect::<_>()
1935 }
1936
1937 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
1940 pub fn set_block_number(n: BlockNumberFor<T>) {
1941 <Number<T>>::put(n);
1942 }
1943
1944 #[cfg(any(feature = "std", test))]
1946 pub fn set_extrinsic_index(extrinsic_index: u32) {
1947 storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &extrinsic_index)
1948 }
1949
1950 #[cfg(any(feature = "std", test))]
1953 pub fn set_parent_hash(n: T::Hash) {
1954 <ParentHash<T>>::put(n);
1955 }
1956
1957 #[cfg(any(feature = "std", test))]
1959 pub fn set_block_consumed_resources(weight: Weight, len: usize) {
1960 BlockWeight::<T>::mutate(|current_weight| {
1961 current_weight.set(weight, DispatchClass::Normal)
1962 });
1963 AllExtrinsicsLen::<T>::put(len as u32);
1964 }
1965
1966 pub fn reset_events() {
1971 <Events<T>>::kill();
1972 EventCount::<T>::kill();
1973 let _ = <EventTopics<T>>::clear(u32::max_value(), None);
1974 }
1975
1976 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
1980 pub fn assert_has_event(event: T::RuntimeEvent) {
1981 let events = Self::events();
1982 assert!(
1983 events.iter().any(|record| record.event == event),
1984 "expected event {event:?} not found in events {events:?}",
1985 );
1986 }
1987
1988 #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
1992 pub fn assert_last_event(event: T::RuntimeEvent) {
1993 let last_event = Self::events().last().expect("events expected").event.clone();
1994 assert_eq!(
1995 last_event, event,
1996 "expected event {event:?} is not equal to the last event {last_event:?}",
1997 );
1998 }
1999
2000 pub fn runtime_version() -> RuntimeVersion {
2002 T::Version::get()
2003 }
2004
2005 pub fn account_nonce(who: impl EncodeLike<T::AccountId>) -> T::Nonce {
2007 Account::<T>::get(who).nonce
2008 }
2009
2010 pub fn inc_account_nonce(who: impl EncodeLike<T::AccountId>) {
2012 Account::<T>::mutate(who, |a| a.nonce += T::Nonce::one());
2013 }
2014
2015 pub fn note_extrinsic(encoded_xt: Vec<u8>) {
2020 ExtrinsicData::<T>::insert(Self::extrinsic_index().unwrap_or_default(), encoded_xt);
2021 }
2022
2023 pub fn note_applied_extrinsic(r: &DispatchResultWithPostInfo, mut info: DispatchInfo) {
2029 info.weight = extract_actual_weight(r, &info)
2030 .saturating_add(T::BlockWeights::get().get(info.class).base_extrinsic);
2031 info.pays_fee = extract_actual_pays_fee(r, &info);
2032
2033 Self::deposit_event(match r {
2034 Ok(_) => Event::ExtrinsicSuccess { dispatch_info: info },
2035 Err(err) => {
2036 log::trace!(
2037 target: LOG_TARGET,
2038 "Extrinsic failed at block({:?}): {:?}",
2039 Self::block_number(),
2040 err,
2041 );
2042 Event::ExtrinsicFailed { dispatch_error: err.error, dispatch_info: info }
2043 },
2044 });
2045
2046 let next_extrinsic_index = Self::extrinsic_index().unwrap_or_default() + 1u32;
2047
2048 storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &next_extrinsic_index);
2049 ExecutionPhase::<T>::put(Phase::ApplyExtrinsic(next_extrinsic_index));
2050 }
2051
2052 pub fn note_finished_extrinsics() {
2055 let extrinsic_index: u32 =
2056 storage::unhashed::take(well_known_keys::EXTRINSIC_INDEX).unwrap_or_default();
2057 ExtrinsicCount::<T>::put(extrinsic_index);
2058 ExecutionPhase::<T>::put(Phase::Finalization);
2059 }
2060
2061 pub fn note_finished_initialize() {
2064 ExecutionPhase::<T>::put(Phase::ApplyExtrinsic(0))
2065 }
2066
2067 pub fn on_created_account(who: T::AccountId, _a: &mut AccountInfo<T::Nonce, T::AccountData>) {
2069 T::OnNewAccount::on_new_account(&who);
2070 Self::deposit_event(Event::NewAccount { account: who });
2071 }
2072
2073 fn on_killed_account(who: T::AccountId) {
2075 T::OnKilledAccount::on_killed_account(&who);
2076 Self::deposit_event(Event::KilledAccount { account: who });
2077 }
2078
2079 pub fn can_set_code(code: &[u8]) -> Result<(), sp_runtime::DispatchError> {
2085 if T::MultiBlockMigrator::ongoing() {
2086 return Err(Error::<T>::MultiBlockMigrationsOngoing.into())
2087 }
2088
2089 let current_version = T::Version::get();
2090 let new_version = sp_io::misc::runtime_version(code)
2091 .and_then(|v| RuntimeVersion::decode(&mut &v[..]).ok())
2092 .ok_or(Error::<T>::FailedToExtractRuntimeVersion)?;
2093
2094 cfg_if::cfg_if! {
2095 if #[cfg(all(feature = "runtime-benchmarks", not(test)))] {
2096 core::hint::black_box((new_version, current_version));
2098 Ok(())
2099 } else {
2100 if new_version.spec_name != current_version.spec_name {
2101 return Err(Error::<T>::InvalidSpecName.into())
2102 }
2103
2104 if new_version.spec_version <= current_version.spec_version {
2105 return Err(Error::<T>::SpecVersionNeedsToIncrease.into())
2106 }
2107
2108 Ok(())
2109 }
2110 }
2111 }
2112
2113 pub fn do_authorize_upgrade(code_hash: T::Hash, check_version: bool) {
2116 AuthorizedUpgrade::<T>::put(CodeUpgradeAuthorization { code_hash, check_version });
2117 Self::deposit_event(Event::UpgradeAuthorized { code_hash, check_version });
2118 }
2119
2120 pub fn do_apply_authorize_upgrade(code: Vec<u8>) -> Result<PostDispatchInfo, DispatchError> {
2124 Self::validate_authorized_upgrade(&code[..])?;
2125 T::OnSetCode::set_code(code)?;
2126 AuthorizedUpgrade::<T>::kill();
2127 let post = PostDispatchInfo {
2128 actual_weight: Some(T::BlockWeights::get().max_block),
2130 pays_fee: Pays::No,
2132 };
2133 Ok(post)
2134 }
2135
2136 pub fn validate_authorized_upgrade(code: &[u8]) -> Result<T::Hash, DispatchError> {
2139 let authorization = AuthorizedUpgrade::<T>::get().ok_or(Error::<T>::NothingAuthorized)?;
2140 let actual_hash = T::Hashing::hash(code);
2141 ensure!(actual_hash == authorization.code_hash, Error::<T>::Unauthorized);
2142 if authorization.check_version {
2143 Self::can_set_code(code)?
2144 }
2145 Ok(actual_hash)
2146 }
2147}
2148
2149pub fn unique(entropy: impl Encode) -> [u8; 32] {
2152 let mut last = [0u8; 32];
2153 sp_io::storage::read(well_known_keys::INTRABLOCK_ENTROPY, &mut last[..], 0);
2154 let next = (b"frame_system::unique", entropy, last).using_encoded(blake2_256);
2155 sp_io::storage::set(well_known_keys::INTRABLOCK_ENTROPY, &next);
2156 next
2157}
2158
2159pub struct Provider<T>(PhantomData<T>);
2161impl<T: Config> HandleLifetime<T::AccountId> for Provider<T> {
2162 fn created(t: &T::AccountId) -> Result<(), DispatchError> {
2163 Pallet::<T>::inc_providers(t);
2164 Ok(())
2165 }
2166 fn killed(t: &T::AccountId) -> Result<(), DispatchError> {
2167 Pallet::<T>::dec_providers(t).map(|_| ())
2168 }
2169}
2170
2171pub struct SelfSufficient<T>(PhantomData<T>);
2173impl<T: Config> HandleLifetime<T::AccountId> for SelfSufficient<T> {
2174 fn created(t: &T::AccountId) -> Result<(), DispatchError> {
2175 Pallet::<T>::inc_sufficients(t);
2176 Ok(())
2177 }
2178 fn killed(t: &T::AccountId) -> Result<(), DispatchError> {
2179 Pallet::<T>::dec_sufficients(t);
2180 Ok(())
2181 }
2182}
2183
2184pub struct Consumer<T>(PhantomData<T>);
2186impl<T: Config> HandleLifetime<T::AccountId> for Consumer<T> {
2187 fn created(t: &T::AccountId) -> Result<(), DispatchError> {
2188 Pallet::<T>::inc_consumers(t)
2189 }
2190 fn killed(t: &T::AccountId) -> Result<(), DispatchError> {
2191 Pallet::<T>::dec_consumers(t);
2192 Ok(())
2193 }
2194}
2195
2196impl<T: Config> BlockNumberProvider for Pallet<T> {
2197 type BlockNumber = BlockNumberFor<T>;
2198
2199 fn current_block_number() -> Self::BlockNumber {
2200 Pallet::<T>::block_number()
2201 }
2202
2203 #[cfg(feature = "runtime-benchmarks")]
2204 fn set_block_number(n: BlockNumberFor<T>) {
2205 Self::set_block_number(n)
2206 }
2207}
2208
2209impl<T: Config> StoredMap<T::AccountId, T::AccountData> for Pallet<T> {
2215 fn get(k: &T::AccountId) -> T::AccountData {
2216 Account::<T>::get(k).data
2217 }
2218
2219 fn try_mutate_exists<R, E: From<DispatchError>>(
2220 k: &T::AccountId,
2221 f: impl FnOnce(&mut Option<T::AccountData>) -> Result<R, E>,
2222 ) -> Result<R, E> {
2223 let account = Account::<T>::get(k);
2224 let is_default = account.data == T::AccountData::default();
2225 let mut some_data = if is_default { None } else { Some(account.data) };
2226 let result = f(&mut some_data)?;
2227 if Self::providers(k) > 0 || Self::sufficients(k) > 0 {
2228 Account::<T>::mutate(k, |a| a.data = some_data.unwrap_or_default());
2229 } else {
2230 Account::<T>::remove(k)
2231 }
2232 Ok(result)
2233 }
2234}
2235
2236pub fn split_inner<T, R, S>(
2238 option: Option<T>,
2239 splitter: impl FnOnce(T) -> (R, S),
2240) -> (Option<R>, Option<S>) {
2241 match option {
2242 Some(inner) => {
2243 let (r, s) = splitter(inner);
2244 (Some(r), Some(s))
2245 },
2246 None => (None, None),
2247 }
2248}
2249
2250pub struct ChainContext<T>(PhantomData<T>);
2251impl<T> Default for ChainContext<T> {
2252 fn default() -> Self {
2253 ChainContext(PhantomData)
2254 }
2255}
2256
2257impl<T: Config> Lookup for ChainContext<T> {
2258 type Source = <T::Lookup as StaticLookup>::Source;
2259 type Target = <T::Lookup as StaticLookup>::Target;
2260
2261 fn lookup(&self, s: Self::Source) -> Result<Self::Target, LookupError> {
2262 <T::Lookup as StaticLookup>::lookup(s)
2263 }
2264}
2265
2266pub mod pallet_prelude {
2268 pub use crate::{ensure_none, ensure_root, ensure_signed, ensure_signed_or_root};
2269
2270 pub type OriginFor<T> = <T as crate::Config>::RuntimeOrigin;
2272
2273 pub type HeaderFor<T> =
2275 <<T as crate::Config>::Block as sp_runtime::traits::HeaderProvider>::HeaderT;
2276
2277 pub type BlockNumberFor<T> = <HeaderFor<T> as sp_runtime::traits::Header>::Number;
2279
2280 pub type ExtrinsicFor<T> =
2282 <<T as crate::Config>::Block as sp_runtime::traits::Block>::Extrinsic;
2283
2284 pub type RuntimeCallFor<T> = <T as crate::Config>::RuntimeCall;
2286}