Skip to main content

topsoil_core/system/
mod.rs

1// This file is part of Soil.
2
3// Copyright (C) Soil contributors.
4// Copyright (C) Parity Technologies (UK) Ltd.
5// SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later WITH Classpath-exception-2.0
6
7//! # System Pallet
8//!
9//! The System pallet provides low-level access to core types and cross-cutting utilities. It acts
10//! as the base layer for other pallets to interact with the Substrate framework components.
11//!
12//! - [`Config`]
13//!
14//! ## Overview
15//!
16//! The System pallet defines the core data types used in a Substrate runtime. It also provides
17//! several utility functions (see [`Pallet`]) for other FRAME pallets.
18//!
19//! In addition, it manages the storage items for extrinsic data, indices, event records, and digest
20//! items, among other things that support the execution of the current block.
21//!
22//! It also handles low-level tasks like depositing logs, basic set up and take down of temporary
23//! storage entries, and access to previous block hashes.
24//!
25//! ## Interface
26//!
27//! ### Dispatchable Functions
28//!
29//! The System pallet provides dispatchable functions that, with the exception of `remark`, manage
30//! low-level or privileged functionality of a Substrate-based runtime.
31//!
32//! - `remark`: Make some on-chain remark.
33//! - `set_heap_pages`: Set the number of pages in the WebAssembly environment's heap.
34//! - `set_code`: Set the new runtime code.
35//! - `set_code_without_checks`: Set the new runtime code without any checks.
36//! - `set_storage`: Set some items of storage.
37//! - `kill_storage`: Kill some items from storage.
38//! - `kill_prefix`: Kill all storage items with a key that starts with the given prefix.
39//! - `remark_with_event`: Make some on-chain remark and emit an event.
40//! - `do_task`: Do some specified task.
41//! - `authorize_upgrade`: Authorize new runtime code.
42//! - `authorize_upgrade_without_checks`: Authorize new runtime code and an upgrade sans
43//!   verification.
44//! - `apply_authorized_upgrade`: Provide new, already-authorized runtime code.
45//!
46//! #### A Note on Upgrades
47//!
48//! The pallet provides two primary means of upgrading the runtime, a single-phase means using
49//! `set_code` and a two-phase means using `authorize_upgrade` followed by
50//! `apply_authorized_upgrade`. The first will directly attempt to apply the provided `code`
51//! (application may have to be scheduled, depending on the context and implementation of the
52//! `OnSetCode` trait).
53//!
54//! The `authorize_upgrade` route allows the authorization of a runtime's code hash. Once
55//! authorized, anyone may upload the correct runtime to apply the code. This pattern is useful when
56//! providing the runtime ahead of time may be unwieldy, for example when a large preimage (the
57//! code) would need to be stored on-chain or sent over a message transport protocol such as a
58//! bridge.
59//!
60//! The `*_without_checks` variants do not perform any version checks, so using them runs the risk
61//! of applying a downgrade or entirely other chain specification. They will still validate that the
62//! `code` meets the authorized hash.
63//!
64//! ### Public Functions
65//!
66//! See the [`Pallet`] struct for details of publicly available functions.
67//!
68//! ### Signed Extensions
69//!
70//! The System pallet defines the following extensions:
71//!
72//!   - [`CheckWeight`]: Checks the weight and length of the block and ensure that it does not
73//!     exceed the limits.
74//!   - [`CheckNonce`]: Checks the nonce of the transaction. Contains a single payload of type
75//!     `T::Nonce`.
76//!   - [`CheckEra`]: Checks the era of the transaction. Contains a single payload of type `Era`.
77//!   - [`CheckGenesis`]: Checks the provided genesis hash of the transaction. Must be a part of the
78//!     signed payload of the transaction.
79//!   - [`CheckSpecVersion`]: Checks that the runtime version is the same as the one used to sign
80//!     the transaction.
81//!   - [`CheckTxVersion`]: Checks that the transaction version is the same as the one used to sign
82//!     the transaction.
83//!
84//! Look up the runtime aggregator file (e.g. `node/runtime`) to see the full list of signed
85//! extensions included in a chain.
86
87use alloc::{borrow::Cow, boxed::Box, vec, vec::Vec};
88use core::{fmt::Debug, marker::PhantomData};
89use pallet_prelude::{BlockNumberFor, HeaderFor};
90#[cfg(feature = "std")]
91use serde::Serialize;
92use subsoil::io::hashing::blake2_256;
93#[cfg(feature = "runtime-benchmarks")]
94use subsoil::runtime::traits::TrailingZeroInput;
95use subsoil::runtime::{
96	generic,
97	traits::{
98		self, AsTransactionAuthorizedOrigin, AtLeast32Bit, BadOrigin, BlockNumberProvider, Bounded,
99		CheckEqual, Dispatchable, Hash, Header, Lookup, LookupError, MaybeDisplay,
100		MaybeSerializeDeserialize, Member, One, Saturating, SimpleBitOps, StaticLookup, Zero,
101	},
102	transaction_validity::{
103		InvalidTransaction, TransactionLongevity, TransactionSource, TransactionValidity,
104		ValidTransaction,
105	},
106	DispatchError,
107};
108use subsoil::version::RuntimeVersion;
109
110use codec::{Decode, DecodeWithMemTracking, Encode, EncodeLike, FullCodec, MaxEncodedLen};
111use scale_info::TypeInfo;
112use subsoil::core::storage::well_known_keys;
113use subsoil::runtime::{
114	traits::{DispatchInfoOf, PostDispatchInfoOf},
115	transaction_validity::TransactionValidityError,
116};
117use subsoil::weights::{RuntimeDbWeight, Weight, WeightMeter};
118#[cfg(feature = "std")]
119use topsoil_core::traits::BuildGenesisConfig;
120use topsoil_core::{
121	dispatch::{
122		extract_actual_pays_fee, extract_actual_weight, DispatchClass, DispatchInfo,
123		DispatchResult, DispatchResultWithPostInfo, GetDispatchInfo, PerDispatchClass,
124		PostDispatchInfo,
125	},
126	ensure, impl_ensure_origin_with_arg_ignoring_arg,
127	migrations::MultiStepMigrator,
128	pallet_prelude::Pays,
129	storage::{self, StorageStreamIter},
130	traits::{
131		ConstU32, Contains, EnsureOrigin, EnsureOriginWithArg, Get, HandleLifetime,
132		OnKilledAccount, OnNewAccount, OnRuntimeUpgrade, OriginTrait, PalletInfo, SortedMembers,
133		StoredMap, TypedGet,
134	},
135	Parameter,
136};
137
138#[cfg(any(feature = "std", test))]
139use subsoil::io::TestExternalities;
140
141pub mod limits;
142#[cfg(test)]
143pub(crate) mod mock;
144
145pub mod offchain;
146
147mod extensions;
148#[cfg(feature = "std")]
149pub mod mocking;
150#[cfg(test)]
151mod tests;
152pub mod weights;
153
154pub mod migrations;
155
156pub use extensions::{
157	authorize_call::AuthorizeCall,
158	check_genesis::CheckGenesis,
159	check_mortality::CheckMortality,
160	check_non_zero_sender::CheckNonZeroSender,
161	check_nonce::{CheckNonce, ValidNonceInfo},
162	check_spec_version::CheckSpecVersion,
163	check_tx_version::CheckTxVersion,
164	check_weight::CheckWeight,
165	weight_reclaim::WeightReclaim,
166	weights::SubstrateWeight as SubstrateExtensionsWeight,
167	WeightInfo as ExtensionsWeightInfo,
168};
169// Backward compatible re-export.
170pub use extensions::check_mortality::CheckMortality as CheckEra;
171use subsoil::core::storage::StateVersion;
172pub use topsoil_core::dispatch::RawOrigin;
173use topsoil_core::traits::{Authorize, PostInherents, PostTransactions, PreInherents};
174pub use weights::WeightInfo;
175
176const LOG_TARGET: &str = "runtime::system";
177
178/// Compute the trie root of a list of extrinsics.
179///
180/// The merkle proof is using the same trie as runtime state with
181/// `state_version` 0 or 1.
182pub fn extrinsics_root<H: Hash, E: codec::Encode>(
183	extrinsics: &[E],
184	state_version: StateVersion,
185) -> H::Output {
186	extrinsics_data_root::<H>(extrinsics.iter().map(codec::Encode::encode).collect(), state_version)
187}
188
189/// Compute the trie root of a list of extrinsics.
190///
191/// The merkle proof is using the same trie as runtime state with
192/// `state_version` 0 or 1.
193pub fn extrinsics_data_root<H: Hash>(xts: Vec<Vec<u8>>, state_version: StateVersion) -> H::Output {
194	H::ordered_trie_root(xts, state_version)
195}
196
197/// An object to track the currently used extrinsic weight in a block.
198pub type ConsumedWeight = PerDispatchClass<Weight>;
199
200pub use pallet::*;
201
202/// Do something when we should be setting the code.
203pub trait SetCode<T: Config> {
204	/// Set the code to the given blob.
205	fn set_code(code: Vec<u8>) -> DispatchResult;
206}
207
208impl<T: Config> SetCode<T> for () {
209	fn set_code(code: Vec<u8>) -> DispatchResult {
210		<Pallet<T>>::update_code_in_storage(&code);
211		Ok(())
212	}
213}
214
215/// Numeric limits over the ability to add a consumer ref using `inc_consumers`.
216pub trait ConsumerLimits {
217	/// The number of consumers over which `inc_consumers` will cease to work.
218	fn max_consumers() -> RefCount;
219	/// The maximum number of additional consumers expected to be over be added at once using
220	/// `inc_consumers_without_limit`.
221	///
222	/// Note: This is not enforced and it's up to the chain's author to ensure this reflects the
223	/// actual situation.
224	fn max_overflow() -> RefCount;
225}
226
227impl<const Z: u32> ConsumerLimits for ConstU32<Z> {
228	fn max_consumers() -> RefCount {
229		Z
230	}
231	fn max_overflow() -> RefCount {
232		Z
233	}
234}
235
236impl<MaxNormal: Get<u32>, MaxOverflow: Get<u32>> ConsumerLimits for (MaxNormal, MaxOverflow) {
237	fn max_consumers() -> RefCount {
238		MaxNormal::get()
239	}
240	fn max_overflow() -> RefCount {
241		MaxOverflow::get()
242	}
243}
244
245/// Information needed when a new runtime binary is submitted and needs to be authorized before
246/// replacing the current runtime.
247#[derive(Decode, Encode, Default, PartialEq, Eq, MaxEncodedLen, TypeInfo)]
248#[scale_info(skip_type_params(T))]
249pub struct CodeUpgradeAuthorization<T>
250where
251	T: Config,
252{
253	/// Hash of the new runtime binary.
254	code_hash: T::Hash,
255	/// Whether or not to carry out version checks.
256	check_version: bool,
257}
258
259#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
260impl<T> CodeUpgradeAuthorization<T>
261where
262	T: Config,
263{
264	pub fn code_hash(&self) -> &T::Hash {
265		&self.code_hash
266	}
267}
268
269/// Information about the dispatch of a call, to be displayed in the
270/// [`ExtrinsicSuccess`](Event::ExtrinsicSuccess) and [`ExtrinsicFailed`](Event::ExtrinsicFailed)
271/// events.
272#[derive(
273	Clone, Copy, Eq, PartialEq, Default, Debug, Encode, Decode, DecodeWithMemTracking, TypeInfo,
274)]
275pub struct DispatchEventInfo {
276	/// Weight of this transaction.
277	pub weight: Weight,
278	/// Class of this transaction.
279	pub class: DispatchClass,
280	/// Does this transaction pay fees.
281	pub pays_fee: Pays,
282}
283
284#[topsoil_core::pallet]
285pub mod pallet {
286	use crate::system::{self as topsoil_system, pallet_prelude::*, *};
287	use codec::HasCompact;
288	use topsoil_core::pallet_prelude::*;
289
290	/// Default implementations of [`DefaultConfig`], which can be used to implement [`Config`].
291	pub mod config_preludes {
292		use super::{inject_runtime_type, DefaultConfig};
293		use topsoil_core::{derive_impl, traits::Get};
294
295		/// A predefined adapter that covers `BlockNumberFor<T>` for `Config::Block::BlockNumber` of
296		/// the types `u32`, `u64`, and `u128`.
297		///
298		/// NOTE: Avoids overriding `BlockHashCount` when using `mocking::{MockBlock, MockBlockU32,
299		/// MockBlockU128}`.
300		pub struct TestBlockHashCount<C: Get<u32>>(core::marker::PhantomData<C>);
301		impl<I: From<u32>, C: Get<u32>> Get<I> for TestBlockHashCount<C> {
302			fn get() -> I {
303				C::get().into()
304			}
305		}
306
307		/// Provides a viable default config that can be used with
308		/// [`derive_impl`](`topsoil_core::derive_impl`) to derive a testing pallet config
309		/// based on this one.
310		///
311		/// See `Test` in the `default-config` example pallet's `test.rs` for an example of
312		/// a downstream user of this particular `TestDefaultConfig`
313		pub struct TestDefaultConfig;
314
315		#[topsoil_core::register_default_impl(TestDefaultConfig)]
316		impl DefaultConfig for TestDefaultConfig {
317			type Nonce = u32;
318			type Hash = subsoil::core::hash::H256;
319			type Hashing = subsoil::runtime::traits::BlakeTwo256;
320			type AccountId = u64;
321			type Lookup = subsoil::runtime::traits::IdentityLookup<Self::AccountId>;
322			type MaxConsumers = topsoil_core::traits::ConstU32<16>;
323			type AccountData = ();
324			type OnNewAccount = ();
325			type OnKilledAccount = ();
326			type SystemWeightInfo = ();
327			type ExtensionsWeightInfo = ();
328			type SS58Prefix = ();
329			type Version = ();
330			type BlockWeights = ();
331			type BlockLength = ();
332			type DbWeight = ();
333			#[inject_runtime_type]
334			type RuntimeEvent = ();
335			#[inject_runtime_type]
336			type RuntimeOrigin = ();
337			#[inject_runtime_type]
338			type RuntimeCall = ();
339			#[inject_runtime_type]
340			type PalletInfo = ();
341			#[inject_runtime_type]
342			type RuntimeTask = ();
343			type BaseCallFilter = topsoil_core::traits::Everything;
344			type BlockHashCount = TestBlockHashCount<topsoil_core::traits::ConstU32<10>>;
345			type OnSetCode = ();
346			type SingleBlockMigrations = ();
347			type MultiBlockMigrator = ();
348			type PreInherents = ();
349			type PostInherents = ();
350			type PostTransactions = ();
351		}
352
353		/// Default configurations of this pallet in a solochain environment.
354		///
355		/// ## Considerations:
356		///
357		/// By default, this type makes the following choices:
358		///
359		/// * Use a normal 32 byte account id, with a [`DefaultConfig::Lookup`] that implies no
360		///   'account-indexing' pallet is being used.
361		/// * Given that we don't know anything about the existence of a currency system in scope,
362		///   an [`DefaultConfig::AccountData`] is chosen that has no addition data. Overwrite this
363		///   if you use `plant-balances` or similar.
364		/// * Make sure to overwrite [`DefaultConfig::Version`].
365		/// * 2s block time, and a default 5mb block size is used.
366		pub struct SolochainDefaultConfig;
367
368		#[topsoil_core::register_default_impl(SolochainDefaultConfig)]
369		impl DefaultConfig for SolochainDefaultConfig {
370			/// The default type for storing how many extrinsics an account has signed.
371			type Nonce = u32;
372
373			/// The default type for hashing blocks and tries.
374			type Hash = subsoil::core::hash::H256;
375
376			/// The default hashing algorithm used.
377			type Hashing = subsoil::runtime::traits::BlakeTwo256;
378
379			/// The default identifier used to distinguish between accounts.
380			type AccountId = subsoil::runtime::AccountId32;
381
382			/// The lookup mechanism to get account ID from whatever is passed in dispatchers.
383			type Lookup = subsoil::runtime::traits::AccountIdLookup<Self::AccountId, ()>;
384
385			/// The maximum number of consumers allowed on a single account. Using 128 as default.
386			type MaxConsumers = topsoil_core::traits::ConstU32<128>;
387
388			/// The default data to be stored in an account.
389			type AccountData = ();
390
391			/// What to do if a new account is created.
392			type OnNewAccount = ();
393
394			/// What to do if an account is fully reaped from the system.
395			type OnKilledAccount = ();
396
397			/// Weight information for the extrinsics of this pallet.
398			type SystemWeightInfo = ();
399
400			/// Weight information for the extensions of this pallet.
401			type ExtensionsWeightInfo = ();
402
403			/// This is used as an identifier of the chain.
404			type SS58Prefix = ();
405
406			/// Version of the runtime.
407			type Version = ();
408
409			/// Block & extrinsics weights: base values and limits.
410			type BlockWeights = ();
411
412			/// The maximum length of a block (in bytes).
413			type BlockLength = ();
414
415			/// The weight of database operations that the runtime can invoke.
416			type DbWeight = ();
417
418			/// The ubiquitous event type injected by `construct_runtime!`.
419			#[inject_runtime_type]
420			type RuntimeEvent = ();
421
422			/// The ubiquitous origin type injected by `construct_runtime!`.
423			#[inject_runtime_type]
424			type RuntimeOrigin = ();
425
426			/// The aggregated dispatch type available for extrinsics, injected by
427			/// `construct_runtime!`.
428			#[inject_runtime_type]
429			type RuntimeCall = ();
430
431			/// The aggregated Task type, injected by `construct_runtime!`.
432			#[inject_runtime_type]
433			type RuntimeTask = ();
434
435			/// Converts a module to the index of the module, injected by `construct_runtime!`.
436			#[inject_runtime_type]
437			type PalletInfo = ();
438
439			/// The basic call filter to use in dispatchable. Supports everything as the default.
440			type BaseCallFilter = topsoil_core::traits::Everything;
441
442			/// Maximum number of block number to block hash mappings to keep (oldest pruned first).
443			/// Using 256 as default.
444			type BlockHashCount = TestBlockHashCount<topsoil_core::traits::ConstU32<256>>;
445
446			/// The set code logic, just the default since we're not a parachain.
447			type OnSetCode = ();
448			type SingleBlockMigrations = ();
449			type MultiBlockMigrator = ();
450			type PreInherents = ();
451			type PostInherents = ();
452			type PostTransactions = ();
453		}
454
455		/// Default configurations of this pallet in a relay-chain environment.
456		pub struct RelayChainDefaultConfig;
457
458		/// It currently uses the same configuration as `SolochainDefaultConfig`.
459		#[derive_impl(SolochainDefaultConfig as DefaultConfig, no_aggregated_types)]
460		#[topsoil_core::register_default_impl(RelayChainDefaultConfig)]
461		impl DefaultConfig for RelayChainDefaultConfig {}
462
463		/// Default configurations of this pallet in a parachain environment.
464		pub struct ParaChainDefaultConfig;
465
466		/// It currently uses the same configuration as `SolochainDefaultConfig`.
467		#[derive_impl(SolochainDefaultConfig as DefaultConfig, no_aggregated_types)]
468		#[topsoil_core::register_default_impl(ParaChainDefaultConfig)]
469		impl DefaultConfig for ParaChainDefaultConfig {}
470	}
471
472	/// System configuration trait. Implemented by runtime.
473	#[pallet::config(with_default, frame_system_config)]
474	#[pallet::disable_frame_system_supertrait_check]
475	pub trait Config: 'static + Eq + Clone {
476		/// The aggregated event type of the runtime.
477		#[pallet::no_default_bounds]
478		type RuntimeEvent: Parameter
479			+ Member
480			+ From<Event<Self>>
481			+ Debug
482			+ IsType<<Self as topsoil_system::Config>::RuntimeEvent>;
483
484		/// The basic call filter to use in Origin. All origins are built with this filter as base,
485		/// except Root.
486		///
487		/// This works as a filter for each incoming call. The call needs to pass this filter in
488		/// order to dispatch. Otherwise it will be rejected with `CallFiltered`. This can be
489		/// bypassed via `dispatch_bypass_filter` which should only be accessible by root. The
490		/// filter can be composed of sub-filters by nesting for example
491		/// [`topsoil_core::traits::InsideBoth`], [`topsoil_core::traits::TheseExcept`] or
492		/// [`topsoil_core::traits::EverythingBut`] et al. The default would be
493		/// [`topsoil_core::traits::Everything`].
494		#[pallet::no_default_bounds]
495		type BaseCallFilter: Contains<Self::RuntimeCall>;
496
497		/// Block & extrinsics weights: base values and limits.
498		#[pallet::constant]
499		type BlockWeights: Get<limits::BlockWeights>;
500
501		/// The maximum length of a block (in bytes).
502		#[pallet::constant]
503		type BlockLength: Get<limits::BlockLength>;
504
505		/// The `RuntimeOrigin` type used by dispatchable calls.
506		#[pallet::no_default_bounds]
507		type RuntimeOrigin: Into<Result<RawOrigin<Self::AccountId>, Self::RuntimeOrigin>>
508			+ From<RawOrigin<Self::AccountId>>
509			+ Clone
510			+ OriginTrait<Call = Self::RuntimeCall, AccountId = Self::AccountId>
511			+ AsTransactionAuthorizedOrigin;
512
513		#[docify::export(system_runtime_call)]
514		/// The aggregated `RuntimeCall` type.
515		#[pallet::no_default_bounds]
516		type RuntimeCall: Parameter
517			+ Dispatchable<RuntimeOrigin = Self::RuntimeOrigin>
518			+ Debug
519			+ GetDispatchInfo
520			+ From<Call<Self>>
521			+ Authorize;
522
523		/// The aggregated `RuntimeTask` type.
524		#[pallet::no_default_bounds]
525		type RuntimeTask: Task;
526
527		/// This stores the number of previous transactions associated with a sender account.
528		type Nonce: Parameter
529			+ HasCompact<Type: DecodeWithMemTracking>
530			+ Member
531			+ MaybeSerializeDeserialize
532			+ Debug
533			+ Default
534			+ MaybeDisplay
535			+ AtLeast32Bit
536			+ Copy
537			+ MaxEncodedLen;
538
539		/// The output of the `Hashing` function.
540		type Hash: Parameter
541			+ Member
542			+ MaybeSerializeDeserialize
543			+ Debug
544			+ MaybeDisplay
545			+ SimpleBitOps
546			+ Ord
547			+ Default
548			+ Copy
549			+ CheckEqual
550			+ core::hash::Hash
551			+ AsRef<[u8]>
552			+ AsMut<[u8]>
553			+ MaxEncodedLen;
554
555		/// The hashing system (algorithm) being used in the runtime (e.g. Blake2).
556		type Hashing: Hash<Output = Self::Hash> + TypeInfo;
557
558		/// The user account identifier type for the runtime.
559		type AccountId: Parameter
560			+ Member
561			+ MaybeSerializeDeserialize
562			+ Debug
563			+ MaybeDisplay
564			+ Ord
565			+ MaxEncodedLen;
566
567		/// Converting trait to take a source type and convert to `AccountId`.
568		///
569		/// Used to define the type and conversion mechanism for referencing accounts in
570		/// transactions. It's perfectly reasonable for this to be an identity conversion (with the
571		/// source type being `AccountId`), but other pallets (e.g. Indices pallet) may provide more
572		/// functional/efficient alternatives.
573		type Lookup: StaticLookup<Target = Self::AccountId>;
574
575		/// The Block type used by the runtime. This is used by `construct_runtime` to retrieve the
576		/// extrinsics or other block specific data as needed.
577		#[pallet::no_default]
578		type Block: Parameter + Member + traits::Block<Hash = Self::Hash>;
579
580		/// Maximum number of block number to block hash mappings to keep (oldest pruned first).
581		#[pallet::constant]
582		#[pallet::no_default_bounds]
583		type BlockHashCount: Get<BlockNumberFor<Self>>;
584
585		/// The weight of runtime database operations the runtime can invoke.
586		#[pallet::constant]
587		type DbWeight: Get<RuntimeDbWeight>;
588
589		/// Get the chain's in-code version.
590		#[pallet::constant]
591		type Version: Get<RuntimeVersion>;
592
593		/// Provides information about the pallet setup in the runtime.
594		///
595		/// Expects the `PalletInfo` type that is being generated by `construct_runtime!` in the
596		/// runtime.
597		///
598		/// For tests it is okay to use `()` as type, however it will provide "useless" data.
599		#[pallet::no_default_bounds]
600		type PalletInfo: PalletInfo;
601
602		/// Data to be associated with an account (other than nonce/transaction counter, which this
603		/// pallet does regardless).
604		type AccountData: Member + FullCodec + Clone + Default + TypeInfo + MaxEncodedLen;
605
606		/// Handler for when a new account has just been created.
607		type OnNewAccount: OnNewAccount<Self::AccountId>;
608
609		/// A function that is invoked when an account has been determined to be dead.
610		///
611		/// All resources should be cleaned up associated with the given account.
612		type OnKilledAccount: OnKilledAccount<Self::AccountId>;
613
614		/// Weight information for the extrinsics of this pallet.
615		type SystemWeightInfo: WeightInfo;
616
617		/// Weight information for the transaction extensions of this pallet.
618		type ExtensionsWeightInfo: extensions::WeightInfo;
619
620		/// The designated SS58 prefix of this chain.
621		///
622		/// This replaces the "ss58Format" property declared in the chain spec. Reason is
623		/// that the runtime should know about the prefix in order to make use of it as
624		/// an identifier of the chain.
625		#[pallet::constant]
626		type SS58Prefix: Get<u16>;
627
628		/// What to do if the runtime wants to change the code to something new.
629		///
630		/// The default (`()`) implementation is responsible for setting the correct storage
631		/// entry and emitting corresponding event and log item. (see
632		/// [`Pallet::update_code_in_storage`]).
633		/// It's unlikely that this needs to be customized, unless you are writing a parachain using
634		/// `Cumulus`, where the actual code change is deferred.
635		#[pallet::no_default_bounds]
636		type OnSetCode: SetCode<Self>;
637
638		/// The maximum number of consumers allowed on a single account.
639		type MaxConsumers: ConsumerLimits;
640
641		/// All migrations that should run in the next runtime upgrade.
642		///
643		/// These used to be formerly configured in `Executive`. Parachains need to ensure that
644		/// running all these migrations in one block will not overflow the weight limit of a block.
645		/// The migrations are run *before* the pallet `on_runtime_upgrade` hooks, just like the
646		/// `OnRuntimeUpgrade` migrations.
647		type SingleBlockMigrations: OnRuntimeUpgrade;
648
649		/// The migrator that is used to run Multi-Block-Migrations.
650		///
651		/// Can be set to an implementation of the `MultiStepMigrator` interface.
652		/// The diagram in `topsoil_executive::block_flowchart` explains when it runs.
653		type MultiBlockMigrator: MultiStepMigrator;
654
655		/// A callback that executes in *every block* directly before all inherents were applied.
656		///
657		/// See `topsoil_executive::block_flowchart` for a in-depth explanation when it runs.
658		type PreInherents: PreInherents;
659
660		/// A callback that executes in *every block* directly after all inherents were applied.
661		///
662		/// See `topsoil_executive::block_flowchart` for a in-depth explanation when it runs.
663		type PostInherents: PostInherents;
664
665		/// A callback that executes in *every block* directly after all transactions were applied.
666		///
667		/// See `topsoil_executive::block_flowchart` for a in-depth explanation when it runs.
668		type PostTransactions: PostTransactions;
669	}
670
671	#[pallet::pallet]
672	pub struct Pallet<T>(_);
673
674	#[pallet::hooks]
675	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
676		#[cfg(feature = "std")]
677		fn integrity_test() {
678			T::BlockWeights::get().validate().expect("The weights are invalid.");
679		}
680	}
681
682	#[pallet::call(weight = <T as Config>::SystemWeightInfo)]
683	impl<T: Config> Pallet<T> {
684		/// Make some on-chain remark.
685		///
686		/// Can be executed by every `origin`.
687		#[pallet::call_index(0)]
688		#[pallet::weight(T::SystemWeightInfo::remark(remark.len() as u32))]
689		pub fn remark(_origin: OriginFor<T>, remark: Vec<u8>) -> DispatchResultWithPostInfo {
690			let _ = remark; // No need to check the weight witness.
691			Ok(().into())
692		}
693
694		/// Set the number of pages in the WebAssembly environment's heap.
695		#[pallet::call_index(1)]
696		#[pallet::weight((T::SystemWeightInfo::set_heap_pages(), DispatchClass::Operational))]
697		pub fn set_heap_pages(origin: OriginFor<T>, pages: u64) -> DispatchResultWithPostInfo {
698			ensure_root(origin)?;
699			storage::unhashed::put_raw(well_known_keys::HEAP_PAGES, &pages.encode());
700			Self::deposit_log(generic::DigestItem::RuntimeEnvironmentUpdated);
701			Ok(().into())
702		}
703
704		/// Set the new runtime code.
705		#[pallet::call_index(2)]
706		#[pallet::weight((T::SystemWeightInfo::set_code(), DispatchClass::Operational))]
707		pub fn set_code(origin: OriginFor<T>, code: Vec<u8>) -> DispatchResultWithPostInfo {
708			ensure_root(origin)?;
709			Self::can_set_code(&code, true).into_result()?;
710			T::OnSetCode::set_code(code)?;
711			// consume the rest of the block to prevent further transactions
712			Ok(Some(T::BlockWeights::get().max_block).into())
713		}
714
715		/// Set the new runtime code without doing any checks of the given `code`.
716		///
717		/// Note that runtime upgrades will not run if this is called with a not-increasing spec
718		/// version!
719		#[pallet::call_index(3)]
720		#[pallet::weight((T::SystemWeightInfo::set_code(), DispatchClass::Operational))]
721		pub fn set_code_without_checks(
722			origin: OriginFor<T>,
723			code: Vec<u8>,
724		) -> DispatchResultWithPostInfo {
725			ensure_root(origin)?;
726			Self::can_set_code(&code, false).into_result()?;
727			T::OnSetCode::set_code(code)?;
728			Ok(Some(T::BlockWeights::get().max_block).into())
729		}
730
731		/// Set some items of storage.
732		#[pallet::call_index(4)]
733		#[pallet::weight((
734			T::SystemWeightInfo::set_storage(items.len() as u32),
735			DispatchClass::Operational,
736		))]
737		pub fn set_storage(
738			origin: OriginFor<T>,
739			items: Vec<KeyValue>,
740		) -> DispatchResultWithPostInfo {
741			ensure_root(origin)?;
742			for i in &items {
743				storage::unhashed::put_raw(&i.0, &i.1);
744			}
745			Ok(().into())
746		}
747
748		/// Kill some items from storage.
749		#[pallet::call_index(5)]
750		#[pallet::weight((
751			T::SystemWeightInfo::kill_storage(keys.len() as u32),
752			DispatchClass::Operational,
753		))]
754		pub fn kill_storage(origin: OriginFor<T>, keys: Vec<Key>) -> DispatchResultWithPostInfo {
755			ensure_root(origin)?;
756			for key in &keys {
757				storage::unhashed::kill(key);
758			}
759			Ok(().into())
760		}
761
762		/// Kill all storage items with a key that starts with the given prefix.
763		///
764		/// **NOTE:** We rely on the Root origin to provide us the number of subkeys under
765		/// the prefix we are removing to accurately calculate the weight of this function.
766		#[pallet::call_index(6)]
767		#[pallet::weight((
768			T::SystemWeightInfo::kill_prefix(subkeys.saturating_add(1)),
769			DispatchClass::Operational,
770		))]
771		pub fn kill_prefix(
772			origin: OriginFor<T>,
773			prefix: Key,
774			subkeys: u32,
775		) -> DispatchResultWithPostInfo {
776			ensure_root(origin)?;
777			let _ = storage::unhashed::clear_prefix(&prefix, Some(subkeys), None);
778			Ok(().into())
779		}
780
781		/// Make some on-chain remark and emit event.
782		#[pallet::call_index(7)]
783		#[pallet::weight(T::SystemWeightInfo::remark_with_event(remark.len() as u32))]
784		pub fn remark_with_event(
785			origin: OriginFor<T>,
786			remark: Vec<u8>,
787		) -> DispatchResultWithPostInfo {
788			let who = ensure_signed(origin)?;
789			let hash = T::Hashing::hash(&remark[..]);
790			Self::deposit_event(Event::Remarked { sender: who, hash });
791			Ok(().into())
792		}
793
794		#[cfg(feature = "experimental")]
795		#[pallet::call_index(8)]
796		#[pallet::weight(task.weight())]
797		pub fn do_task(_origin: OriginFor<T>, task: T::RuntimeTask) -> DispatchResultWithPostInfo {
798			if !task.is_valid() {
799				return Err(Error::<T>::InvalidTask.into());
800			}
801
802			Self::deposit_event(Event::TaskStarted { task: task.clone() });
803			if let Err(err) = task.run() {
804				Self::deposit_event(Event::TaskFailed { task, err });
805				return Err(Error::<T>::FailedTask.into());
806			}
807
808			// Emit a success event, if your design includes events for this pallet.
809			Self::deposit_event(Event::TaskCompleted { task });
810
811			// Return success.
812			Ok(().into())
813		}
814
815		/// Authorize an upgrade to a given `code_hash` for the runtime. The runtime can be supplied
816		/// later.
817		///
818		/// This call requires Root origin.
819		#[pallet::call_index(9)]
820		#[pallet::weight((T::SystemWeightInfo::authorize_upgrade(), DispatchClass::Operational))]
821		pub fn authorize_upgrade(origin: OriginFor<T>, code_hash: T::Hash) -> DispatchResult {
822			ensure_root(origin)?;
823			Self::do_authorize_upgrade(code_hash, true);
824			Ok(())
825		}
826
827		/// Authorize an upgrade to a given `code_hash` for the runtime. The runtime can be supplied
828		/// later.
829		///
830		/// WARNING: This authorizes an upgrade that will take place without any safety checks, for
831		/// example that the spec name remains the same and that the version number increases. Not
832		/// recommended for normal use. Use `authorize_upgrade` instead.
833		///
834		/// This call requires Root origin.
835		#[pallet::call_index(10)]
836		#[pallet::weight((T::SystemWeightInfo::authorize_upgrade(), DispatchClass::Operational))]
837		pub fn authorize_upgrade_without_checks(
838			origin: OriginFor<T>,
839			code_hash: T::Hash,
840		) -> DispatchResult {
841			ensure_root(origin)?;
842			Self::do_authorize_upgrade(code_hash, false);
843			Ok(())
844		}
845
846		/// Provide the preimage (runtime binary) `code` for an upgrade that has been authorized.
847		///
848		/// If the authorization required a version check, this call will ensure the spec name
849		/// remains unchanged and that the spec version has increased.
850		///
851		/// Depending on the runtime's `OnSetCode` configuration, this function may directly apply
852		/// the new `code` in the same block or attempt to schedule the upgrade.
853		///
854		/// All origins are allowed.
855		#[pallet::call_index(11)]
856		#[pallet::weight((T::SystemWeightInfo::apply_authorized_upgrade(), DispatchClass::Operational))]
857		pub fn apply_authorized_upgrade(
858			_: OriginFor<T>,
859			code: Vec<u8>,
860		) -> DispatchResultWithPostInfo {
861			let res = Self::validate_code_is_authorized(&code)?;
862			AuthorizedUpgrade::<T>::kill();
863
864			match Self::can_set_code(&code, res.check_version) {
865				CanSetCodeResult::Ok => {},
866				CanSetCodeResult::MultiBlockMigrationsOngoing => {
867					return Err(Error::<T>::MultiBlockMigrationsOngoing.into())
868				},
869				CanSetCodeResult::InvalidVersion(error) => {
870					// The upgrade is invalid and there is no benefit in trying to apply this again.
871					Self::deposit_event(Event::RejectedInvalidAuthorizedUpgrade {
872						code_hash: res.code_hash,
873						error: error.into(),
874					});
875
876					// Not the fault of the caller of call.
877					return Ok(Pays::No.into());
878				},
879			};
880			T::OnSetCode::set_code(code)?;
881
882			Ok(PostDispatchInfo {
883				// consume the rest of the block to prevent further transactions
884				actual_weight: Some(T::BlockWeights::get().max_block),
885				// no fee for valid upgrade
886				pays_fee: Pays::No,
887			})
888		}
889	}
890
891	/// Event for the System pallet.
892	#[pallet::event]
893	pub enum Event<T: Config> {
894		/// An extrinsic completed successfully.
895		ExtrinsicSuccess { dispatch_info: DispatchEventInfo },
896		/// An extrinsic failed.
897		ExtrinsicFailed { dispatch_error: DispatchError, dispatch_info: DispatchEventInfo },
898		/// `:code` was updated.
899		CodeUpdated,
900		/// A new account was created.
901		NewAccount { account: T::AccountId },
902		/// An account was reaped.
903		KilledAccount { account: T::AccountId },
904		/// On on-chain remark happened.
905		Remarked { sender: T::AccountId, hash: T::Hash },
906		#[cfg(feature = "experimental")]
907		/// A [`Task`] has started executing
908		TaskStarted { task: T::RuntimeTask },
909		#[cfg(feature = "experimental")]
910		/// A [`Task`] has finished executing.
911		TaskCompleted { task: T::RuntimeTask },
912		#[cfg(feature = "experimental")]
913		/// A [`Task`] failed during execution.
914		TaskFailed { task: T::RuntimeTask, err: DispatchError },
915		/// An upgrade was authorized.
916		UpgradeAuthorized { code_hash: T::Hash, check_version: bool },
917		/// An invalid authorized upgrade was rejected while trying to apply it.
918		RejectedInvalidAuthorizedUpgrade { code_hash: T::Hash, error: DispatchError },
919	}
920
921	/// Error for the System pallet
922	#[pallet::error]
923	pub enum Error<T> {
924		/// The name of specification does not match between the current runtime
925		/// and the new runtime.
926		InvalidSpecName,
927		/// The specification version is not allowed to decrease between the current runtime
928		/// and the new runtime.
929		SpecVersionNeedsToIncrease,
930		/// Failed to extract the runtime version from the new runtime.
931		///
932		/// Either calling `Core_version` or decoding `RuntimeVersion` failed.
933		FailedToExtractRuntimeVersion,
934		/// Suicide called when the account has non-default composite data.
935		NonDefaultComposite,
936		/// There is a non-zero reference count preventing the account from being purged.
937		NonZeroRefCount,
938		/// The origin filter prevent the call to be dispatched.
939		CallFiltered,
940		/// A multi-block migration is ongoing and prevents the current code from being replaced.
941		MultiBlockMigrationsOngoing,
942		#[cfg(feature = "experimental")]
943		/// The specified [`Task`] is not valid.
944		InvalidTask,
945		#[cfg(feature = "experimental")]
946		/// The specified [`Task`] failed during execution.
947		FailedTask,
948		/// No upgrade authorized.
949		NothingAuthorized,
950		/// The submitted code is not authorized.
951		Unauthorized,
952	}
953
954	/// Exposed trait-generic origin type.
955	#[pallet::origin]
956	pub type Origin<T> = RawOrigin<<T as Config>::AccountId>;
957
958	/// The full account information for a particular account ID.
959	#[pallet::storage]
960	#[pallet::getter(fn account)]
961	pub type Account<T: Config> = StorageMap<
962		_,
963		Blake2_128Concat,
964		T::AccountId,
965		AccountInfo<T::Nonce, T::AccountData>,
966		ValueQuery,
967	>;
968
969	/// Total extrinsics count for the current block.
970	#[pallet::storage]
971	#[pallet::whitelist_storage]
972	pub(super) type ExtrinsicCount<T: Config> = StorageValue<_, u32>;
973
974	/// Whether all inherents have been applied.
975	#[pallet::storage]
976	#[pallet::whitelist_storage]
977	pub type InherentsApplied<T: Config> = StorageValue<_, bool, ValueQuery>;
978
979	/// The current weight for the block.
980	#[pallet::storage]
981	#[pallet::whitelist_storage]
982	#[pallet::getter(fn block_weight)]
983	pub type BlockWeight<T: Config> = StorageValue<_, ConsumedWeight, ValueQuery>;
984
985	/// Total size (in bytes) of the current block.
986	///
987	/// Tracks the size of the header and all extrinsics.
988	#[pallet::storage]
989	#[pallet::whitelist_storage]
990	pub type BlockSize<T: Config> = StorageValue<_, u32>;
991
992	/// Map of block numbers to block hashes.
993	#[pallet::storage]
994	#[pallet::getter(fn block_hash)]
995	pub type BlockHash<T: Config> =
996		StorageMap<_, Twox64Concat, BlockNumberFor<T>, T::Hash, ValueQuery>;
997
998	/// Extrinsics data for the current block (maps an extrinsic's index to its data).
999	#[pallet::storage]
1000	#[pallet::getter(fn extrinsic_data)]
1001	#[pallet::unbounded]
1002	pub(super) type ExtrinsicData<T: Config> =
1003		StorageMap<_, Twox64Concat, u32, Vec<u8>, ValueQuery>;
1004
1005	/// The current block number being processed. Set by `execute_block`.
1006	#[pallet::storage]
1007	#[pallet::whitelist_storage]
1008	#[pallet::getter(fn block_number)]
1009	pub(super) type Number<T: Config> = StorageValue<_, BlockNumberFor<T>, ValueQuery>;
1010
1011	/// Hash of the previous block.
1012	#[pallet::storage]
1013	#[pallet::getter(fn parent_hash)]
1014	pub(super) type ParentHash<T: Config> = StorageValue<_, T::Hash, ValueQuery>;
1015
1016	/// Digest of the current block, also part of the block header.
1017	#[pallet::storage]
1018	#[pallet::whitelist_storage]
1019	#[pallet::unbounded]
1020	#[pallet::getter(fn digest)]
1021	pub(super) type Digest<T: Config> = StorageValue<_, generic::Digest, ValueQuery>;
1022
1023	/// Events deposited for the current block.
1024	///
1025	/// NOTE: The item is unbound and should therefore never be read on chain.
1026	/// It could otherwise inflate the PoV size of a block.
1027	///
1028	/// Events have a large in-memory size. Box the events to not go out-of-memory
1029	/// just in case someone still reads them from within the runtime.
1030	#[pallet::storage]
1031	#[pallet::whitelist_storage]
1032	#[pallet::disable_try_decode_storage]
1033	#[pallet::unbounded]
1034	pub(super) type Events<T: Config> =
1035		StorageValue<_, Vec<Box<EventRecord<T::RuntimeEvent, T::Hash>>>, ValueQuery>;
1036
1037	/// The number of events in the `Events<T>` list.
1038	#[pallet::storage]
1039	#[pallet::whitelist_storage]
1040	#[pallet::getter(fn event_count)]
1041	pub(super) type EventCount<T: Config> = StorageValue<_, EventIndex, ValueQuery>;
1042
1043	/// Mapping between a topic (represented by T::Hash) and a vector of indexes
1044	/// of events in the `<Events<T>>` list.
1045	///
1046	/// All topic vectors have deterministic storage locations depending on the topic. This
1047	/// allows light-clients to leverage the changes trie storage tracking mechanism and
1048	/// in case of changes fetch the list of events of interest.
1049	///
1050	/// The value has the type `(BlockNumberFor<T>, EventIndex)` because if we used only just
1051	/// the `EventIndex` then in case if the topic has the same contents on the next block
1052	/// no notification will be triggered thus the event might be lost.
1053	#[pallet::storage]
1054	#[pallet::unbounded]
1055	#[pallet::getter(fn event_topics)]
1056	pub(super) type EventTopics<T: Config> =
1057		StorageMap<_, Blake2_128Concat, T::Hash, Vec<(BlockNumberFor<T>, EventIndex)>, ValueQuery>;
1058
1059	/// Stores the `spec_version` and `spec_name` of when the last runtime upgrade happened.
1060	#[pallet::storage]
1061	#[pallet::unbounded]
1062	pub type LastRuntimeUpgrade<T: Config> = StorageValue<_, LastRuntimeUpgradeInfo>;
1063
1064	/// True if we have upgraded so that `type RefCount` is `u32`. False (default) if not.
1065	#[pallet::storage]
1066	pub(super) type UpgradedToU32RefCount<T: Config> = StorageValue<_, bool, ValueQuery>;
1067
1068	/// True if we have upgraded so that AccountInfo contains three types of `RefCount`. False
1069	/// (default) if not.
1070	#[pallet::storage]
1071	pub(super) type UpgradedToTripleRefCount<T: Config> = StorageValue<_, bool, ValueQuery>;
1072
1073	/// The execution phase of the block.
1074	#[pallet::storage]
1075	#[pallet::whitelist_storage]
1076	pub(super) type ExecutionPhase<T: Config> = StorageValue<_, Phase>;
1077
1078	/// `Some` if a code upgrade has been authorized.
1079	#[pallet::storage]
1080	#[pallet::getter(fn authorized_upgrade)]
1081	pub(super) type AuthorizedUpgrade<T: Config> =
1082		StorageValue<_, CodeUpgradeAuthorization<T>, OptionQuery>;
1083
1084	/// The weight reclaimed for the extrinsic.
1085	///
1086	/// This information is available until the end of the extrinsic execution.
1087	/// More precisely this information is removed in `note_applied_extrinsic`.
1088	///
1089	/// Logic doing some post dispatch weight reduction must update this storage to avoid duplicate
1090	/// reduction.
1091	#[pallet::storage]
1092	#[pallet::whitelist_storage]
1093	pub type ExtrinsicWeightReclaimed<T: Config> = StorageValue<_, Weight, ValueQuery>;
1094
1095	#[derive(topsoil_core::DefaultNoBound)]
1096	#[pallet::genesis_config]
1097	pub struct GenesisConfig<T: Config> {
1098		#[serde(skip)]
1099		pub _config: core::marker::PhantomData<T>,
1100	}
1101
1102	#[pallet::genesis_build]
1103	impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
1104		fn build(&self) {
1105			<BlockHash<T>>::insert::<_, T::Hash>(BlockNumberFor::<T>::zero(), hash69());
1106			<ParentHash<T>>::put::<T::Hash>(hash69());
1107			<LastRuntimeUpgrade<T>>::put(LastRuntimeUpgradeInfo::from(T::Version::get()));
1108			<UpgradedToU32RefCount<T>>::put(true);
1109			<UpgradedToTripleRefCount<T>>::put(true);
1110
1111			subsoil::io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode());
1112		}
1113	}
1114
1115	#[pallet::validate_unsigned]
1116	impl<T: Config> subsoil::runtime::traits::ValidateUnsigned for Pallet<T> {
1117		type Call = Call<T>;
1118		fn validate_unsigned(source: TransactionSource, call: &Self::Call) -> TransactionValidity {
1119			if let Call::apply_authorized_upgrade { ref code } = call {
1120				if let Ok(res) = Self::validate_code_is_authorized(&code[..]) {
1121					if Self::can_set_code(&code, false).is_ok() {
1122						return Ok(ValidTransaction {
1123							priority: u64::max_value(),
1124							requires: Vec::new(),
1125							provides: vec![res.code_hash.encode()],
1126							longevity: TransactionLongevity::max_value(),
1127							propagate: true,
1128						});
1129					}
1130				}
1131			}
1132
1133			#[cfg(feature = "experimental")]
1134			if let Call::do_task { ref task } = call {
1135				// If valid, the tasks provides the tag: hash of task.
1136				// But it is allowed to have many task for a single process, e.g. a task that takes
1137				// a limit on the number of item to migrate is valid from 1 to the limit while
1138				// actually advancing a single migration process.
1139				// In the transaction pool, transaction are identified by their provides tag.
1140				// So in order to protect the transaction pool against spam, we only accept tasks
1141				// from local source.
1142				if source == TransactionSource::InBlock || source == TransactionSource::Local {
1143					if task.is_valid() {
1144						return Ok(ValidTransaction {
1145							priority: u64::max_value(),
1146							requires: Vec::new(),
1147							provides: vec![T::Hashing::hash_of(&task.encode()).as_ref().to_vec()],
1148							longevity: TransactionLongevity::max_value(),
1149							propagate: false,
1150						});
1151					}
1152				}
1153			}
1154
1155			#[cfg(not(feature = "experimental"))]
1156			let _ = source;
1157
1158			Err(InvalidTransaction::Call.into())
1159		}
1160	}
1161}
1162
1163pub type Key = Vec<u8>;
1164pub type KeyValue = (Vec<u8>, Vec<u8>);
1165
1166/// A phase of a block's execution.
1167#[derive(Encode, Decode, Debug, TypeInfo, MaxEncodedLen)]
1168#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone))]
1169pub enum Phase {
1170	/// Applying an extrinsic.
1171	ApplyExtrinsic(u32),
1172	/// Finalizing the block.
1173	Finalization,
1174	/// Initializing the block.
1175	Initialization,
1176}
1177
1178impl Default for Phase {
1179	fn default() -> Self {
1180		Self::Initialization
1181	}
1182}
1183
1184/// Record of an event happening.
1185#[derive(Encode, Decode, Debug, TypeInfo)]
1186#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone))]
1187pub struct EventRecord<E: Parameter + Member, T> {
1188	/// The phase of the block it happened in.
1189	pub phase: Phase,
1190	/// The event itself.
1191	pub event: E,
1192	/// The list of the topics this event has.
1193	pub topics: Vec<T>,
1194}
1195
1196// Create a Hash with 69 for each byte,
1197// only used to build genesis config.
1198fn hash69<T: AsMut<[u8]> + Default>() -> T {
1199	let mut h = T::default();
1200	h.as_mut().iter_mut().for_each(|byte| *byte = 69);
1201	h
1202}
1203
1204/// This type alias represents an index of an event.
1205///
1206/// We use `u32` here because this index is used as index for `Events<T>`
1207/// which can't contain more than `u32::MAX` items.
1208type EventIndex = u32;
1209
1210/// Type used to encode the number of references an account has.
1211pub type RefCount = u32;
1212
1213/// Information of an account.
1214#[derive(Clone, Eq, PartialEq, Default, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)]
1215pub struct AccountInfo<Nonce, AccountData> {
1216	/// The number of transactions this account has sent.
1217	pub nonce: Nonce,
1218	/// The number of other modules that currently depend on this account's existence. The account
1219	/// cannot be reaped until this is zero.
1220	pub consumers: RefCount,
1221	/// The number of other modules that allow this account to exist. The account may not be reaped
1222	/// until this and `sufficients` are both zero.
1223	pub providers: RefCount,
1224	/// The number of modules that allow this account to exist for their own purposes only. The
1225	/// account may not be reaped until this and `providers` are both zero.
1226	pub sufficients: RefCount,
1227	/// The additional data that belongs to this account. Used to store the balance(s) in a lot of
1228	/// chains.
1229	pub data: AccountData,
1230}
1231
1232/// Stores the `spec_version` and `spec_name` of when the last runtime upgrade
1233/// happened.
1234#[derive(Debug, Encode, Decode, TypeInfo)]
1235#[cfg_attr(feature = "std", derive(PartialEq))]
1236pub struct LastRuntimeUpgradeInfo {
1237	pub spec_version: codec::Compact<u32>,
1238	pub spec_name: Cow<'static, str>,
1239}
1240
1241impl LastRuntimeUpgradeInfo {
1242	/// Returns if the runtime was upgraded in comparison of `self` and `current`.
1243	///
1244	/// Checks if either the `spec_version` increased or the `spec_name` changed.
1245	pub fn was_upgraded(&self, current: &RuntimeVersion) -> bool {
1246		current.spec_version > self.spec_version.0 || current.spec_name != self.spec_name
1247	}
1248}
1249
1250impl From<RuntimeVersion> for LastRuntimeUpgradeInfo {
1251	fn from(version: RuntimeVersion) -> Self {
1252		Self { spec_version: version.spec_version.into(), spec_name: version.spec_name }
1253	}
1254}
1255
1256/// Ensure the origin is Root.
1257pub struct EnsureRoot<AccountId>(core::marker::PhantomData<AccountId>);
1258impl<O: OriginTrait, AccountId> EnsureOrigin<O> for EnsureRoot<AccountId> {
1259	type Success = ();
1260	fn try_origin(o: O) -> Result<Self::Success, O> {
1261		match o.as_system_ref() {
1262			Some(RawOrigin::Root) => Ok(()),
1263			_ => Err(o),
1264		}
1265	}
1266
1267	#[cfg(feature = "runtime-benchmarks")]
1268	fn try_successful_origin() -> Result<O, ()> {
1269		Ok(O::root())
1270	}
1271}
1272
1273impl_ensure_origin_with_arg_ignoring_arg! {
1274	impl< { O: .., AccountId: Decode, T } >
1275		EnsureOriginWithArg<O, T> for EnsureRoot<AccountId>
1276	{}
1277}
1278
1279/// Ensure the origin is Root and return the provided `Success` value.
1280pub struct EnsureRootWithSuccess<AccountId, Success>(
1281	core::marker::PhantomData<(AccountId, Success)>,
1282);
1283impl<O: OriginTrait, AccountId, Success: TypedGet> EnsureOrigin<O>
1284	for EnsureRootWithSuccess<AccountId, Success>
1285{
1286	type Success = Success::Type;
1287	fn try_origin(o: O) -> Result<Self::Success, O> {
1288		match o.as_system_ref() {
1289			Some(RawOrigin::Root) => Ok(Success::get()),
1290			_ => Err(o),
1291		}
1292	}
1293
1294	#[cfg(feature = "runtime-benchmarks")]
1295	fn try_successful_origin() -> Result<O, ()> {
1296		Ok(O::root())
1297	}
1298}
1299
1300impl_ensure_origin_with_arg_ignoring_arg! {
1301	impl< { O: .., AccountId: Decode, Success: TypedGet, T } >
1302		EnsureOriginWithArg<O, T> for EnsureRootWithSuccess<AccountId, Success>
1303	{}
1304}
1305
1306/// Ensure the origin is provided `Ensure` origin and return the provided `Success` value.
1307pub struct EnsureWithSuccess<Ensure, AccountId, Success>(
1308	core::marker::PhantomData<(Ensure, AccountId, Success)>,
1309);
1310
1311impl<O: OriginTrait, Ensure: EnsureOrigin<O>, AccountId, Success: TypedGet> EnsureOrigin<O>
1312	for EnsureWithSuccess<Ensure, AccountId, Success>
1313{
1314	type Success = Success::Type;
1315
1316	fn try_origin(o: O) -> Result<Self::Success, O> {
1317		Ensure::try_origin(o).map(|_| Success::get())
1318	}
1319
1320	#[cfg(feature = "runtime-benchmarks")]
1321	fn try_successful_origin() -> Result<O, ()> {
1322		Ensure::try_successful_origin()
1323	}
1324}
1325
1326/// Ensure the origin is any `Signed` origin.
1327pub struct EnsureSigned<AccountId>(core::marker::PhantomData<AccountId>);
1328impl<O: OriginTrait<AccountId = AccountId>, AccountId: Decode + Clone> EnsureOrigin<O>
1329	for EnsureSigned<AccountId>
1330{
1331	type Success = AccountId;
1332	fn try_origin(o: O) -> Result<Self::Success, O> {
1333		match o.as_system_ref() {
1334			Some(RawOrigin::Signed(who)) => Ok(who.clone()),
1335			_ => Err(o),
1336		}
1337	}
1338
1339	#[cfg(feature = "runtime-benchmarks")]
1340	fn try_successful_origin() -> Result<O, ()> {
1341		let zero_account_id =
1342			AccountId::decode(&mut TrailingZeroInput::zeroes()).map_err(|_| ())?;
1343		Ok(O::signed(zero_account_id))
1344	}
1345}
1346
1347impl_ensure_origin_with_arg_ignoring_arg! {
1348	impl< { O: OriginTrait<AccountId = AccountId>, AccountId: Decode + Clone, T } >
1349		EnsureOriginWithArg<O, T> for EnsureSigned<AccountId>
1350	{}
1351}
1352
1353/// Ensure the origin is `Signed` origin from the given `AccountId`.
1354pub struct EnsureSignedBy<Who, AccountId>(core::marker::PhantomData<(Who, AccountId)>);
1355impl<
1356		O: OriginTrait<AccountId = AccountId>,
1357		Who: SortedMembers<AccountId>,
1358		AccountId: PartialEq + Clone + Ord + Decode,
1359	> EnsureOrigin<O> for EnsureSignedBy<Who, AccountId>
1360{
1361	type Success = AccountId;
1362	fn try_origin(o: O) -> Result<Self::Success, O> {
1363		match o.as_system_ref() {
1364			Some(RawOrigin::Signed(ref who)) if Who::contains(who) => Ok(who.clone()),
1365			_ => Err(o),
1366		}
1367	}
1368
1369	#[cfg(feature = "runtime-benchmarks")]
1370	fn try_successful_origin() -> Result<O, ()> {
1371		let first_member = match Who::sorted_members().first() {
1372			Some(account) => account.clone(),
1373			None => AccountId::decode(&mut TrailingZeroInput::zeroes()).map_err(|_| ())?,
1374		};
1375		Ok(O::signed(first_member))
1376	}
1377}
1378
1379impl_ensure_origin_with_arg_ignoring_arg! {
1380	impl< { O: OriginTrait<AccountId = AccountId>, Who: SortedMembers<AccountId>, AccountId: PartialEq + Clone + Ord + Decode, T } >
1381		EnsureOriginWithArg<O, T> for EnsureSignedBy<Who, AccountId>
1382	{}
1383}
1384
1385/// Ensure the origin is `None`. i.e. unsigned transaction.
1386pub struct EnsureNone<AccountId>(core::marker::PhantomData<AccountId>);
1387impl<O: OriginTrait<AccountId = AccountId>, AccountId> EnsureOrigin<O> for EnsureNone<AccountId> {
1388	type Success = ();
1389	fn try_origin(o: O) -> Result<Self::Success, O> {
1390		match o.as_system_ref() {
1391			Some(RawOrigin::None) => Ok(()),
1392			_ => Err(o),
1393		}
1394	}
1395
1396	#[cfg(feature = "runtime-benchmarks")]
1397	fn try_successful_origin() -> Result<O, ()> {
1398		Ok(O::none())
1399	}
1400}
1401
1402impl_ensure_origin_with_arg_ignoring_arg! {
1403	impl< { O: OriginTrait<AccountId = AccountId>, AccountId, T } >
1404		EnsureOriginWithArg<O, T> for EnsureNone<AccountId>
1405	{}
1406}
1407
1408/// Always fail.
1409pub struct EnsureNever<Success>(core::marker::PhantomData<Success>);
1410impl<O, Success> EnsureOrigin<O> for EnsureNever<Success> {
1411	type Success = Success;
1412	fn try_origin(o: O) -> Result<Self::Success, O> {
1413		Err(o)
1414	}
1415
1416	#[cfg(feature = "runtime-benchmarks")]
1417	fn try_successful_origin() -> Result<O, ()> {
1418		Err(())
1419	}
1420}
1421
1422impl_ensure_origin_with_arg_ignoring_arg! {
1423	impl< { O, Success, T } >
1424		EnsureOriginWithArg<O, T> for EnsureNever<Success>
1425	{}
1426}
1427
1428#[docify::export]
1429/// Ensure that the origin `o` represents a signed extrinsic (i.e. transaction).
1430/// Returns `Ok` with the account that signed the extrinsic or an `Err` otherwise.
1431pub fn ensure_signed<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<AccountId, BadOrigin>
1432where
1433	OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1434{
1435	match o.into() {
1436		Ok(RawOrigin::Signed(t)) => Ok(t),
1437		_ => Err(BadOrigin),
1438	}
1439}
1440
1441/// Ensure that the origin `o` represents either a signed extrinsic (i.e. transaction) or the root.
1442/// Returns `Ok` with the account that signed the extrinsic, `None` if it was root,  or an `Err`
1443/// otherwise.
1444pub fn ensure_signed_or_root<OuterOrigin, AccountId>(
1445	o: OuterOrigin,
1446) -> Result<Option<AccountId>, BadOrigin>
1447where
1448	OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1449{
1450	match o.into() {
1451		Ok(RawOrigin::Root) => Ok(None),
1452		Ok(RawOrigin::Signed(t)) => Ok(Some(t)),
1453		_ => Err(BadOrigin),
1454	}
1455}
1456
1457/// Ensure that the origin `o` represents the root. Returns `Ok` or an `Err` otherwise.
1458pub fn ensure_root<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), BadOrigin>
1459where
1460	OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1461{
1462	match o.into() {
1463		Ok(RawOrigin::Root) => Ok(()),
1464		_ => Err(BadOrigin),
1465	}
1466}
1467
1468/// Ensure that the origin `o` represents an unsigned extrinsic. Returns `Ok` or an `Err` otherwise.
1469pub fn ensure_none<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), BadOrigin>
1470where
1471	OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1472{
1473	match o.into() {
1474		Ok(RawOrigin::None) => Ok(()),
1475		_ => Err(BadOrigin),
1476	}
1477}
1478
1479/// Ensure that the origin `o` represents an extrinsic with authorized call. Returns `Ok` or an
1480/// `Err` otherwise.
1481pub fn ensure_authorized<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), BadOrigin>
1482where
1483	OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
1484{
1485	match o.into() {
1486		Ok(RawOrigin::Authorized) => Ok(()),
1487		_ => Err(BadOrigin),
1488	}
1489}
1490
1491/// Reference status; can be either referenced or unreferenced.
1492#[derive(Debug)]
1493pub enum RefStatus {
1494	Referenced,
1495	Unreferenced,
1496}
1497
1498/// Some resultant status relevant to incrementing a provider/self-sufficient reference.
1499#[derive(Eq, PartialEq, Debug)]
1500pub enum IncRefStatus {
1501	/// Account was created.
1502	Created,
1503	/// Account already existed.
1504	Existed,
1505}
1506
1507/// Some resultant status relevant to decrementing a provider/self-sufficient reference.
1508#[derive(Eq, PartialEq, Debug)]
1509pub enum DecRefStatus {
1510	/// Account was destroyed.
1511	Reaped,
1512	/// Account still exists.
1513	Exists,
1514}
1515
1516/// Result of [`Pallet::can_set_code`].
1517pub enum CanSetCodeResult<T: Config> {
1518	/// Everything is fine.
1519	Ok,
1520	/// Multi-block migrations are on-going.
1521	MultiBlockMigrationsOngoing,
1522	/// The runtime version is invalid or could not be fetched.
1523	InvalidVersion(Error<T>),
1524}
1525
1526impl<T: Config> CanSetCodeResult<T> {
1527	/// Convert `Self` into a result.
1528	pub fn into_result(self) -> Result<(), DispatchError> {
1529		match self {
1530			Self::Ok => Ok(()),
1531			Self::MultiBlockMigrationsOngoing => {
1532				Err(Error::<T>::MultiBlockMigrationsOngoing.into())
1533			},
1534			Self::InvalidVersion(err) => Err(err.into()),
1535		}
1536	}
1537
1538	/// Is this `Ok`?
1539	pub fn is_ok(&self) -> bool {
1540		matches!(self, Self::Ok)
1541	}
1542}
1543
1544impl<T: Config> Pallet<T> {
1545	/// Returns the `spec_version` of the last runtime upgrade.
1546	///
1547	/// This function is useful for writing guarded runtime migrations in the runtime. A runtime
1548	/// migration can use the `spec_version` to ensure that it isn't applied twice. This works
1549	/// similar as the storage version for pallets.
1550	///
1551	/// This functions returns the `spec_version` of the last runtime upgrade while executing the
1552	/// runtime migrations
1553	/// [`on_runtime_upgrade`](topsoil_core::traits::OnRuntimeUpgrade::on_runtime_upgrade)
1554	/// function. After all migrations are executed, this will return the `spec_version` of the
1555	/// current runtime until there is another runtime upgrade.
1556	///
1557	/// Example:
1558	#[doc = docify::embed!("src/system/tests.rs", last_runtime_upgrade_spec_version_usage)]
1559	pub fn last_runtime_upgrade_spec_version() -> u32 {
1560		LastRuntimeUpgrade::<T>::get().map_or(0, |l| l.spec_version.0)
1561	}
1562
1563	/// Returns true if the given account exists.
1564	pub fn account_exists(who: &T::AccountId) -> bool {
1565		Account::<T>::contains_key(who)
1566	}
1567
1568	/// Write code to the storage and emit related events and digest items.
1569	///
1570	/// Note this function almost never should be used directly. It is exposed
1571	/// for `OnSetCode` implementations that defer actual code being written to
1572	/// the storage (for instance in case of parachains).
1573	pub fn update_code_in_storage(code: &[u8]) {
1574		storage::unhashed::put_raw(well_known_keys::CODE, code);
1575		Self::deposit_log(generic::DigestItem::RuntimeEnvironmentUpdated);
1576		Self::deposit_event(Event::CodeUpdated);
1577	}
1578
1579	/// Whether all inherents have been applied.
1580	pub fn inherents_applied() -> bool {
1581		InherentsApplied::<T>::get()
1582	}
1583
1584	/// Note that all inherents have been applied.
1585	///
1586	/// Should be called immediately after all inherents have been applied. Must be called at least
1587	/// once per block.
1588	pub fn note_inherents_applied() {
1589		InherentsApplied::<T>::put(true);
1590	}
1591
1592	/// Increment the reference counter on an account.
1593	#[deprecated = "Use `inc_consumers` instead"]
1594	pub fn inc_ref(who: &T::AccountId) {
1595		let _ = Self::inc_consumers(who);
1596	}
1597
1598	/// Decrement the reference counter on an account. This *MUST* only be done once for every time
1599	/// you called `inc_consumers` on `who`.
1600	#[deprecated = "Use `dec_consumers` instead"]
1601	pub fn dec_ref(who: &T::AccountId) {
1602		let _ = Self::dec_consumers(who);
1603	}
1604
1605	/// The number of outstanding references for the account `who`.
1606	#[deprecated = "Use `consumers` instead"]
1607	pub fn refs(who: &T::AccountId) -> RefCount {
1608		Self::consumers(who)
1609	}
1610
1611	/// True if the account has no outstanding references.
1612	#[deprecated = "Use `!is_provider_required` instead"]
1613	pub fn allow_death(who: &T::AccountId) -> bool {
1614		!Self::is_provider_required(who)
1615	}
1616
1617	/// Increment the provider reference counter on an account.
1618	pub fn inc_providers(who: &T::AccountId) -> IncRefStatus {
1619		Account::<T>::mutate(who, |a| {
1620			if a.providers == 0 && a.sufficients == 0 {
1621				// Account is being created.
1622				a.providers = 1;
1623				Self::on_created_account(who.clone(), a);
1624				IncRefStatus::Created
1625			} else {
1626				a.providers = a.providers.saturating_add(1);
1627				IncRefStatus::Existed
1628			}
1629		})
1630	}
1631
1632	/// Decrement the provider reference counter on an account.
1633	///
1634	/// This *MUST* only be done once for every time you called `inc_providers` on `who`.
1635	pub fn dec_providers(who: &T::AccountId) -> Result<DecRefStatus, DispatchError> {
1636		Account::<T>::try_mutate_exists(who, |maybe_account| {
1637			if let Some(mut account) = maybe_account.take() {
1638				if account.providers == 0 {
1639					// Logic error - cannot decrement beyond zero.
1640					log::error!(
1641						target: LOG_TARGET,
1642						"Logic error: Unexpected underflow in reducing provider",
1643					);
1644					account.providers = 1;
1645				}
1646				match (account.providers, account.consumers, account.sufficients) {
1647					(1, 0, 0) => {
1648						// No providers left (and no consumers) and no sufficients. Account dead.
1649
1650						Pallet::<T>::on_killed_account(who.clone());
1651						Ok(DecRefStatus::Reaped)
1652					},
1653					(1, c, _) if c > 0 => {
1654						// Cannot remove last provider if there are consumers.
1655						Err(DispatchError::ConsumerRemaining)
1656					},
1657					(x, _, _) => {
1658						// Account will continue to exist as there is either > 1 provider or
1659						// > 0 sufficients.
1660						account.providers = x - 1;
1661						*maybe_account = Some(account);
1662						Ok(DecRefStatus::Exists)
1663					},
1664				}
1665			} else {
1666				log::error!(
1667					target: LOG_TARGET,
1668					"Logic error: Account already dead when reducing provider",
1669				);
1670				Ok(DecRefStatus::Reaped)
1671			}
1672		})
1673	}
1674
1675	/// Increment the self-sufficient reference counter on an account.
1676	pub fn inc_sufficients(who: &T::AccountId) -> IncRefStatus {
1677		Account::<T>::mutate(who, |a| {
1678			if a.providers + a.sufficients == 0 {
1679				// Account is being created.
1680				a.sufficients = 1;
1681				Self::on_created_account(who.clone(), a);
1682				IncRefStatus::Created
1683			} else {
1684				a.sufficients = a.sufficients.saturating_add(1);
1685				IncRefStatus::Existed
1686			}
1687		})
1688	}
1689
1690	/// Decrement the sufficients reference counter on an account.
1691	///
1692	/// This *MUST* only be done once for every time you called `inc_sufficients` on `who`.
1693	pub fn dec_sufficients(who: &T::AccountId) -> DecRefStatus {
1694		Account::<T>::mutate_exists(who, |maybe_account| {
1695			if let Some(mut account) = maybe_account.take() {
1696				if account.sufficients == 0 {
1697					// Logic error - cannot decrement beyond zero.
1698					log::error!(
1699						target: LOG_TARGET,
1700						"Logic error: Unexpected underflow in reducing sufficients",
1701					);
1702				}
1703				match (account.sufficients, account.providers) {
1704					(0, 0) | (1, 0) => {
1705						Pallet::<T>::on_killed_account(who.clone());
1706						DecRefStatus::Reaped
1707					},
1708					(x, _) => {
1709						account.sufficients = x.saturating_sub(1);
1710						*maybe_account = Some(account);
1711						DecRefStatus::Exists
1712					},
1713				}
1714			} else {
1715				log::error!(
1716					target: LOG_TARGET,
1717					"Logic error: Account already dead when reducing provider",
1718				);
1719				DecRefStatus::Reaped
1720			}
1721		})
1722	}
1723
1724	/// The number of outstanding provider references for the account `who`.
1725	pub fn providers(who: &T::AccountId) -> RefCount {
1726		Account::<T>::get(who).providers
1727	}
1728
1729	/// The number of outstanding sufficient references for the account `who`.
1730	pub fn sufficients(who: &T::AccountId) -> RefCount {
1731		Account::<T>::get(who).sufficients
1732	}
1733
1734	/// The number of outstanding provider and sufficient references for the account `who`.
1735	pub fn reference_count(who: &T::AccountId) -> RefCount {
1736		let a = Account::<T>::get(who);
1737		a.providers + a.sufficients
1738	}
1739
1740	/// Increment the reference counter on an account.
1741	///
1742	/// The account `who`'s `providers` must be non-zero and the current number of consumers must
1743	/// be less than `MaxConsumers::max_consumers()` or this will return an error.
1744	pub fn inc_consumers(who: &T::AccountId) -> Result<(), DispatchError> {
1745		Account::<T>::try_mutate(who, |a| {
1746			if a.providers > 0 {
1747				if a.consumers < T::MaxConsumers::max_consumers() {
1748					a.consumers = a.consumers.saturating_add(1);
1749					Ok(())
1750				} else {
1751					Err(DispatchError::TooManyConsumers)
1752				}
1753			} else {
1754				Err(DispatchError::NoProviders)
1755			}
1756		})
1757	}
1758
1759	/// Increment the reference counter on an account, ignoring the `MaxConsumers` limits.
1760	///
1761	/// The account `who`'s `providers` must be non-zero or this will return an error.
1762	pub fn inc_consumers_without_limit(who: &T::AccountId) -> Result<(), DispatchError> {
1763		Account::<T>::try_mutate(who, |a| {
1764			if a.providers > 0 {
1765				a.consumers = a.consumers.saturating_add(1);
1766				Ok(())
1767			} else {
1768				Err(DispatchError::NoProviders)
1769			}
1770		})
1771	}
1772
1773	/// Decrement the reference counter on an account. This *MUST* only be done once for every time
1774	/// you called `inc_consumers` on `who`.
1775	pub fn dec_consumers(who: &T::AccountId) {
1776		Account::<T>::mutate(who, |a| {
1777			if a.consumers > 0 {
1778				a.consumers -= 1;
1779			} else {
1780				log::error!(
1781					target: LOG_TARGET,
1782					"Logic error: Unexpected underflow in reducing consumer",
1783				);
1784			}
1785		})
1786	}
1787
1788	/// The number of outstanding references for the account `who`.
1789	pub fn consumers(who: &T::AccountId) -> RefCount {
1790		Account::<T>::get(who).consumers
1791	}
1792
1793	/// True if the account has some outstanding consumer references.
1794	pub fn is_provider_required(who: &T::AccountId) -> bool {
1795		Account::<T>::get(who).consumers != 0
1796	}
1797
1798	/// True if the account has no outstanding consumer references or more than one provider.
1799	pub fn can_dec_provider(who: &T::AccountId) -> bool {
1800		let a = Account::<T>::get(who);
1801		a.consumers == 0 || a.providers > 1
1802	}
1803
1804	/// True if the account has at least one provider reference and adding `amount` consumer
1805	/// references would not take it above the the maximum.
1806	pub fn can_accrue_consumers(who: &T::AccountId, amount: u32) -> bool {
1807		let a = Account::<T>::get(who);
1808		match a.consumers.checked_add(amount) {
1809			Some(c) => a.providers > 0 && c <= T::MaxConsumers::max_consumers(),
1810			None => false,
1811		}
1812	}
1813
1814	/// True if the account has at least one provider reference and fewer consumer references than
1815	/// the maximum.
1816	pub fn can_inc_consumer(who: &T::AccountId) -> bool {
1817		Self::can_accrue_consumers(who, 1)
1818	}
1819
1820	/// Deposits an event into this block's event record.
1821	///
1822	/// NOTE: Events not registered at the genesis block and quietly omitted.
1823	pub fn deposit_event(event: impl Into<T::RuntimeEvent>) {
1824		Self::deposit_event_indexed(&[], event.into());
1825	}
1826
1827	/// Deposits an event into this block's event record adding this event
1828	/// to the corresponding topic indexes.
1829	///
1830	/// This will update storage entries that correspond to the specified topics.
1831	/// It is expected that light-clients could subscribe to this topics.
1832	///
1833	/// NOTE: Events not registered at the genesis block and quietly omitted.
1834	pub fn deposit_event_indexed(topics: &[T::Hash], event: T::RuntimeEvent) {
1835		let block_number = Self::block_number();
1836
1837		// Don't populate events on genesis.
1838		if block_number.is_zero() {
1839			return;
1840		}
1841
1842		let phase = ExecutionPhase::<T>::get().unwrap_or_default();
1843		let event = EventRecord { phase, event, topics: topics.to_vec() };
1844
1845		// Index of the event to be added.
1846		let event_idx = {
1847			let old_event_count = EventCount::<T>::get();
1848			let new_event_count = match old_event_count.checked_add(1) {
1849				// We've reached the maximum number of events at this block, just
1850				// don't do anything and leave the event_count unaltered.
1851				None => return,
1852				Some(nc) => nc,
1853			};
1854			EventCount::<T>::put(new_event_count);
1855			old_event_count
1856		};
1857
1858		Events::<T>::append(event);
1859
1860		for topic in topics {
1861			<EventTopics<T>>::append(topic, &(block_number, event_idx));
1862		}
1863	}
1864
1865	/// Gets the index of extrinsic that is currently executing.
1866	pub fn extrinsic_index() -> Option<u32> {
1867		storage::unhashed::get(well_known_keys::EXTRINSIC_INDEX)
1868	}
1869
1870	/// Gets extrinsics count.
1871	pub fn extrinsic_count() -> u32 {
1872		ExtrinsicCount::<T>::get().unwrap_or_default()
1873	}
1874
1875	/// Gets the total size (in bytes) of the current block.
1876	pub fn block_size() -> u32 {
1877		BlockSize::<T>::get().unwrap_or_default()
1878	}
1879
1880	/// Inform the system pallet of some additional weight that should be accounted for, in the
1881	/// current block.
1882	///
1883	/// NOTE: use with extra care; this function is made public only be used for certain pallets
1884	/// that need it. A runtime that does not have dynamic calls should never need this and should
1885	/// stick to static weights. A typical use case for this is inner calls or smart contract calls.
1886	/// Furthermore, it only makes sense to use this when it is presumably  _cheap_ to provide the
1887	/// argument `weight`; In other words, if this function is to be used to account for some
1888	/// unknown, user provided call's weight, it would only make sense to use it if you are sure you
1889	/// can rapidly compute the weight of the inner call.
1890	///
1891	/// Even more dangerous is to note that this function does NOT take any action, if the new sum
1892	/// of block weight is more than the block weight limit. This is what the _unchecked_.
1893	///
1894	/// Another potential use-case could be for the `on_initialize` and `on_finalize` hooks.
1895	pub fn register_extra_weight_unchecked(weight: Weight, class: DispatchClass) {
1896		BlockWeight::<T>::mutate(|current_weight| {
1897			current_weight.accrue(weight, class);
1898		});
1899	}
1900
1901	/// Start the execution of a particular block.
1902	///
1903	/// # Panics
1904	///
1905	/// Panics when the given `number` is not `Self::block_number() + 1`. If you are using this in
1906	/// tests, you can use [`Self::set_block_number`] to make the check succeed.
1907	pub fn initialize(number: &BlockNumberFor<T>, parent_hash: &T::Hash, digest: &generic::Digest) {
1908		let expected_block_number = Self::block_number() + One::one();
1909		assert_eq!(expected_block_number, *number, "Block number must be strictly increasing.");
1910
1911		// populate environment
1912		ExecutionPhase::<T>::put(Phase::Initialization);
1913		storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &0u32);
1914		Self::initialize_intra_block_entropy(parent_hash);
1915		<Number<T>>::put(number);
1916		<Digest<T>>::put(digest);
1917		<ParentHash<T>>::put(parent_hash);
1918		<BlockHash<T>>::insert(*number - One::one(), parent_hash);
1919
1920		// Remove previous block data from storage
1921		BlockWeight::<T>::kill();
1922
1923		// Account for digest size and empty header overhead in block length.
1924		// This ensures block limits consider the full block size, not just extrinsics.
1925		let digest_size = digest.encoded_size();
1926		let empty_header = <<T as Config>::Block as traits::Block>::Header::new(
1927			*number,
1928			Default::default(),
1929			Default::default(),
1930			*parent_hash,
1931			Default::default(),
1932		);
1933		let empty_header_size = empty_header.encoded_size();
1934		let overhead = digest_size.saturating_add(empty_header_size) as u32;
1935		BlockSize::<T>::put(overhead);
1936
1937		// Ensure inherent digests don't exceed the configured max header size
1938		let max_total_header = T::BlockLength::get().max_header_size();
1939		assert!(
1940			overhead <= max_total_header as u32,
1941			"Header size ({overhead}) exceeds max header size limit ({max_total_header})"
1942		);
1943	}
1944
1945	/// Initialize [`INTRABLOCK_ENTROPY`](well_known_keys::INTRABLOCK_ENTROPY).
1946	///
1947	/// Normally this is called internally [`initialize`](Self::initialize) at block initiation.
1948	pub fn initialize_intra_block_entropy(parent_hash: &T::Hash) {
1949		let entropy = (b"topsoil_system::initialize", parent_hash).using_encoded(blake2_256);
1950		storage::unhashed::put_raw(well_known_keys::INTRABLOCK_ENTROPY, &entropy[..]);
1951	}
1952
1953	/// Log the entire resouce usage report up until this point.
1954	///
1955	/// Uses `crate::LOG_TARGET`, level `debug` and prints the weight and block length usage.
1956	pub fn resource_usage_report() {
1957		log::debug!(
1958			target: LOG_TARGET,
1959			"[{:?}] {} extrinsics, block size: {} (normal {}%, op: {}%, mandatory {}%) / normal weight:\
1960			 {} (ref_time: {}%, proof_size: {}%) op weight {} (ref_time {}%, proof_size {}%) / \
1961			  mandatory weight {} (ref_time: {}%, proof_size: {}%)",
1962			Self::block_number(),
1963			Self::extrinsic_count(),
1964			Self::block_size(),
1965			subsoil::runtime::Percent::from_rational(
1966				Self::block_size(),
1967				*T::BlockLength::get().max.get(DispatchClass::Normal)
1968			).deconstruct(),
1969			subsoil::runtime::Percent::from_rational(
1970				Self::block_size(),
1971				*T::BlockLength::get().max.get(DispatchClass::Operational)
1972			).deconstruct(),
1973			subsoil::runtime::Percent::from_rational(
1974				Self::block_size(),
1975				*T::BlockLength::get().max.get(DispatchClass::Mandatory)
1976			).deconstruct(),
1977			Self::block_weight().get(DispatchClass::Normal),
1978			subsoil::runtime::Percent::from_rational(
1979				Self::block_weight().get(DispatchClass::Normal).ref_time(),
1980				T::BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap_or(Bounded::max_value()).ref_time()
1981			).deconstruct(),
1982			subsoil::runtime::Percent::from_rational(
1983				Self::block_weight().get(DispatchClass::Normal).proof_size(),
1984				T::BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap_or(Bounded::max_value()).proof_size()
1985			).deconstruct(),
1986			Self::block_weight().get(DispatchClass::Operational),
1987			subsoil::runtime::Percent::from_rational(
1988				Self::block_weight().get(DispatchClass::Operational).ref_time(),
1989				T::BlockWeights::get().get(DispatchClass::Operational).max_total.unwrap_or(Bounded::max_value()).ref_time()
1990			).deconstruct(),
1991			subsoil::runtime::Percent::from_rational(
1992				Self::block_weight().get(DispatchClass::Operational).proof_size(),
1993				T::BlockWeights::get().get(DispatchClass::Operational).max_total.unwrap_or(Bounded::max_value()).proof_size()
1994			).deconstruct(),
1995			Self::block_weight().get(DispatchClass::Mandatory),
1996			subsoil::runtime::Percent::from_rational(
1997				Self::block_weight().get(DispatchClass::Mandatory).ref_time(),
1998				T::BlockWeights::get().get(DispatchClass::Mandatory).max_total.unwrap_or(Bounded::max_value()).ref_time()
1999			).deconstruct(),
2000			subsoil::runtime::Percent::from_rational(
2001				Self::block_weight().get(DispatchClass::Mandatory).proof_size(),
2002				T::BlockWeights::get().get(DispatchClass::Mandatory).max_total.unwrap_or(Bounded::max_value()).proof_size()
2003			).deconstruct(),
2004		);
2005	}
2006
2007	/// Remove temporary "environment" entries in storage, compute the storage root and return the
2008	/// resulting header for this block.
2009	pub fn finalize() -> HeaderFor<T> {
2010		Self::resource_usage_report();
2011		ExecutionPhase::<T>::kill();
2012		BlockSize::<T>::kill();
2013		storage::unhashed::kill(well_known_keys::INTRABLOCK_ENTROPY);
2014		InherentsApplied::<T>::kill();
2015
2016		// The following fields
2017		//
2018		// - <Events<T>>
2019		// - <EventCount<T>>
2020		// - <EventTopics<T>>
2021		// - <Number<T>>
2022		// - <ParentHash<T>>
2023		// - <Digest<T>>
2024		//
2025		// stay to be inspected by the client and will be cleared by `Self::initialize`.
2026		let number = <Number<T>>::get();
2027		let parent_hash = <ParentHash<T>>::get();
2028		let digest = <Digest<T>>::get();
2029
2030		let extrinsics = (0..ExtrinsicCount::<T>::take().unwrap_or_default())
2031			.map(ExtrinsicData::<T>::take)
2032			.collect();
2033		let extrinsics_root_state_version = T::Version::get().extrinsics_root_state_version();
2034		let extrinsics_root =
2035			extrinsics_data_root::<T::Hashing>(extrinsics, extrinsics_root_state_version);
2036
2037		// move block hash pruning window by one block
2038		let block_hash_count = T::BlockHashCount::get();
2039		let to_remove = number.saturating_sub(block_hash_count).saturating_sub(One::one());
2040
2041		// keep genesis hash
2042		if !to_remove.is_zero() {
2043			<BlockHash<T>>::remove(to_remove);
2044		}
2045
2046		let version = T::Version::get().state_version();
2047		let storage_root = T::Hash::decode(&mut &subsoil::io::storage::root(version)[..])
2048			.expect("Node is configured to use the same hash; qed");
2049
2050		HeaderFor::<T>::new(number, extrinsics_root, storage_root, parent_hash, digest)
2051	}
2052
2053	/// Deposits a log (digest) in the block's header.
2054	///
2055	/// Digests should not be directly controllable by external users as they increase the size of
2056	/// the header.
2057	pub fn deposit_log(item: generic::DigestItem) {
2058		BlockSize::<T>::mutate(|len| {
2059			*len = Some(len.unwrap_or(0).saturating_add(item.encoded_size() as u32));
2060		});
2061		<Digest<T>>::append(item);
2062	}
2063
2064	/// Get the basic externalities for this pallet, useful for tests.
2065	#[cfg(any(feature = "std", test))]
2066	pub fn externalities() -> TestExternalities {
2067		TestExternalities::new(subsoil::core::storage::Storage {
2068			top: [
2069				(<BlockHash<T>>::hashed_key_for(BlockNumberFor::<T>::zero()), [69u8; 32].encode()),
2070				(<Number<T>>::hashed_key().to_vec(), BlockNumberFor::<T>::one().encode()),
2071				(<ParentHash<T>>::hashed_key().to_vec(), [69u8; 32].encode()),
2072			]
2073			.into_iter()
2074			.collect(),
2075			children_default: Default::default(),
2076		})
2077	}
2078
2079	/// Get the current events deposited by the runtime.
2080	///
2081	/// NOTE: This should only be used in tests. Reading events from the runtime can have a large
2082	/// impact on the PoV size of a block. Users should use alternative and well bounded storage
2083	/// items for any behavior like this.
2084	///
2085	/// NOTE: Events not registered at the genesis block and quietly omitted.
2086	#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2087	pub fn events() -> Vec<EventRecord<T::RuntimeEvent, T::Hash>> {
2088		// Dereferencing the events here is fine since we are not in the memory-restricted runtime.
2089		Self::read_events_no_consensus().map(|e| *e).collect()
2090	}
2091
2092	/// Get a single event at specified index.
2093	///
2094	/// Should only be called if you know what you are doing and outside of the runtime block
2095	/// execution else it can have a large impact on the PoV size of a block.
2096	pub fn event_no_consensus(index: usize) -> Option<T::RuntimeEvent> {
2097		Self::read_events_no_consensus().nth(index).map(|e| e.event.clone())
2098	}
2099
2100	/// Get the current events deposited by the runtime.
2101	///
2102	/// Should only be called if you know what you are doing and outside of the runtime block
2103	/// execution else it can have a large impact on the PoV size of a block.
2104	pub fn read_events_no_consensus(
2105	) -> impl Iterator<Item = Box<EventRecord<T::RuntimeEvent, T::Hash>>> {
2106		Events::<T>::stream_iter()
2107	}
2108
2109	/// Read and return the events of a specific pallet, as denoted by `E`.
2110	///
2111	/// This is useful for a pallet that wishes to read only the events it has deposited into
2112	/// `topsoil_system` using the standard `fn deposit_event`.
2113	pub fn read_events_for_pallet<E>() -> Vec<E>
2114	where
2115		T::RuntimeEvent: TryInto<E>,
2116	{
2117		Events::<T>::get()
2118			.into_iter()
2119			.map(|er| er.event)
2120			.filter_map(|e| e.try_into().ok())
2121			.collect::<_>()
2122	}
2123
2124	/// Simulate the execution of a block sequence up to a specified height, injecting the
2125	/// provided hooks at each block.
2126	///
2127	/// `on_finalize` is always called before `on_initialize` with the current block number.
2128	/// `on_initalize` is always called with the next block number.
2129	///
2130	/// These hooks allows custom logic to be executed at each block at specific location.
2131	/// For example, you might use one of them to set a timestamp for each block.
2132	#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2133	pub fn run_to_block_with<AllPalletsWithSystem>(
2134		n: BlockNumberFor<T>,
2135		mut hooks: RunToBlockHooks<T>,
2136	) where
2137		AllPalletsWithSystem: topsoil_core::traits::OnInitialize<BlockNumberFor<T>>
2138			+ topsoil_core::traits::OnFinalize<BlockNumberFor<T>>,
2139	{
2140		let mut bn = Self::block_number();
2141
2142		while bn < n {
2143			// Skip block 0.
2144			if !bn.is_zero() {
2145				(hooks.before_finalize)(bn);
2146				AllPalletsWithSystem::on_finalize(bn);
2147				(hooks.after_finalize)(bn);
2148			}
2149
2150			bn += One::one();
2151
2152			Self::set_block_number(bn);
2153			(hooks.before_initialize)(bn);
2154			AllPalletsWithSystem::on_initialize(bn);
2155			(hooks.after_initialize)(bn);
2156		}
2157	}
2158
2159	/// Simulate the execution of a block sequence up to a specified height.
2160	#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2161	pub fn run_to_block<AllPalletsWithSystem>(n: BlockNumberFor<T>)
2162	where
2163		AllPalletsWithSystem: topsoil_core::traits::OnInitialize<BlockNumberFor<T>>
2164			+ topsoil_core::traits::OnFinalize<BlockNumberFor<T>>,
2165	{
2166		Self::run_to_block_with::<AllPalletsWithSystem>(n, Default::default());
2167	}
2168
2169	/// Set the block number to something in particular. Can be used as an alternative to
2170	/// `initialize` for tests that don't need to bother with the other environment entries.
2171	#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2172	pub fn set_block_number(n: BlockNumberFor<T>) {
2173		<Number<T>>::put(n);
2174	}
2175
2176	/// Sets the index of extrinsic that is currently executing.
2177	#[cfg(any(feature = "std", test))]
2178	pub fn set_extrinsic_index(extrinsic_index: u32) {
2179		storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &extrinsic_index)
2180	}
2181
2182	/// Set the parent hash number to something in particular. Can be used as an alternative to
2183	/// `initialize` for tests that don't need to bother with the other environment entries.
2184	#[cfg(any(feature = "std", test))]
2185	pub fn set_parent_hash(n: T::Hash) {
2186		<ParentHash<T>>::put(n);
2187	}
2188
2189	/// Set the current block weight. This should only be used in some integration tests.
2190	#[cfg(any(feature = "std", test))]
2191	pub fn set_block_consumed_resources(weight: Weight, len: usize) {
2192		BlockWeight::<T>::mutate(|current_weight| {
2193			current_weight.set(weight, DispatchClass::Normal)
2194		});
2195		BlockSize::<T>::put(len as u32);
2196	}
2197
2198	/// Reset events.
2199	///
2200	/// This needs to be used in prior calling [`initialize`](Self::initialize) for each new block
2201	/// to clear events from previous block.
2202	pub fn reset_events() {
2203		<Events<T>>::kill();
2204		EventCount::<T>::kill();
2205		let _ = <EventTopics<T>>::clear(u32::max_value(), None);
2206	}
2207
2208	/// Assert the given `event` exists.
2209	///
2210	/// NOTE: Events not registered at the genesis block and quietly omitted.
2211	#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2212	#[track_caller]
2213	pub fn assert_has_event(event: T::RuntimeEvent) {
2214		let warn = if Self::block_number().is_zero() {
2215			"WARNING: block number is zero, and events are not registered at block number zero.\n"
2216		} else {
2217			""
2218		};
2219
2220		let events = Self::events();
2221		assert!(
2222			events.iter().any(|record| record.event == event),
2223			"{warn}expected event {event:?} not found in events {events:?}",
2224		);
2225	}
2226
2227	/// Assert the last event equal to the given `event`.
2228	///
2229	/// NOTE: Events not registered at the genesis block and quietly omitted.
2230	#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2231	#[track_caller]
2232	pub fn assert_last_event(event: T::RuntimeEvent) {
2233		let warn = if Self::block_number().is_zero() {
2234			"WARNING: block number is zero, and events are not registered at block number zero.\n"
2235		} else {
2236			""
2237		};
2238
2239		let last_event = Self::events()
2240			.last()
2241			.expect(&alloc::format!("{warn}events expected"))
2242			.event
2243			.clone();
2244		assert_eq!(
2245			last_event, event,
2246			"{warn}expected event {event:?} is not equal to the last event {last_event:?}",
2247		);
2248	}
2249
2250	/// Return the chain's current runtime version.
2251	pub fn runtime_version() -> RuntimeVersion {
2252		T::Version::get()
2253	}
2254
2255	/// Retrieve the account transaction counter from storage.
2256	pub fn account_nonce(who: impl EncodeLike<T::AccountId>) -> T::Nonce {
2257		Account::<T>::get(who).nonce
2258	}
2259
2260	/// Increment a particular account's nonce by 1.
2261	pub fn inc_account_nonce(who: impl EncodeLike<T::AccountId>) {
2262		Account::<T>::mutate(who, |a| a.nonce += T::Nonce::one());
2263	}
2264
2265	/// Note what the extrinsic data of the current extrinsic index is.
2266	///
2267	/// This is required to be called before applying an extrinsic. The data will used
2268	/// in [`Self::finalize`] to calculate the correct extrinsics root.
2269	pub fn note_extrinsic(encoded_xt: Vec<u8>) {
2270		ExtrinsicData::<T>::insert(Self::extrinsic_index().unwrap_or_default(), encoded_xt);
2271	}
2272
2273	/// To be called immediately after an extrinsic has been applied.
2274	///
2275	/// Emits an `ExtrinsicSuccess` or `ExtrinsicFailed` event depending on the outcome.
2276	/// The emitted event contains the post-dispatch corrected weight including
2277	/// the base-weight for its dispatch class.
2278	pub fn note_applied_extrinsic(r: &DispatchResultWithPostInfo, info: DispatchInfo) {
2279		let weight = extract_actual_weight(r, &info)
2280			.saturating_add(T::BlockWeights::get().get(info.class).base_extrinsic);
2281		let class = info.class;
2282		let pays_fee = extract_actual_pays_fee(r, &info);
2283		let dispatch_event_info = DispatchEventInfo { weight, class, pays_fee };
2284
2285		Self::deposit_event(match r {
2286			Ok(_) => Event::ExtrinsicSuccess { dispatch_info: dispatch_event_info },
2287			Err(err) => {
2288				log::trace!(
2289					target: LOG_TARGET,
2290					"Extrinsic failed at block({:?}): {:?}",
2291					Self::block_number(),
2292					err,
2293				);
2294				Event::ExtrinsicFailed {
2295					dispatch_error: err.error,
2296					dispatch_info: dispatch_event_info,
2297				}
2298			},
2299		});
2300
2301		log::trace!(
2302			target: LOG_TARGET,
2303			"Used block weight: {:?}",
2304			BlockWeight::<T>::get(),
2305		);
2306
2307		log::trace!(
2308			target: LOG_TARGET,
2309			"Used block length: {:?}",
2310			Pallet::<T>::block_size(),
2311		);
2312
2313		let next_extrinsic_index = Self::extrinsic_index().unwrap_or_default() + 1u32;
2314
2315		storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &next_extrinsic_index);
2316		ExecutionPhase::<T>::put(Phase::ApplyExtrinsic(next_extrinsic_index));
2317		ExtrinsicWeightReclaimed::<T>::kill();
2318	}
2319
2320	/// To be called immediately after `note_applied_extrinsic` of the last extrinsic of the block
2321	/// has been called.
2322	pub fn note_finished_extrinsics() {
2323		let extrinsic_index: u32 =
2324			storage::unhashed::take(well_known_keys::EXTRINSIC_INDEX).unwrap_or_default();
2325		ExtrinsicCount::<T>::put(extrinsic_index);
2326		ExecutionPhase::<T>::put(Phase::Finalization);
2327	}
2328
2329	/// To be called immediately after finishing the initialization of the block
2330	/// (e.g., called `on_initialize` for all pallets).
2331	pub fn note_finished_initialize() {
2332		ExecutionPhase::<T>::put(Phase::ApplyExtrinsic(0))
2333	}
2334
2335	/// An account is being created.
2336	pub fn on_created_account(who: T::AccountId, _a: &mut AccountInfo<T::Nonce, T::AccountData>) {
2337		T::OnNewAccount::on_new_account(&who);
2338		Self::deposit_event(Event::NewAccount { account: who });
2339	}
2340
2341	/// Do anything that needs to be done after an account has been killed.
2342	fn on_killed_account(who: T::AccountId) {
2343		T::OnKilledAccount::on_killed_account(&who);
2344		Self::deposit_event(Event::KilledAccount { account: who });
2345	}
2346
2347	/// Determine whether or not it is possible to update the code.
2348	///
2349	/// - `check_version`: Should the runtime version be checked?
2350	pub fn can_set_code(code: &[u8], check_version: bool) -> CanSetCodeResult<T> {
2351		if T::MultiBlockMigrator::ongoing() {
2352			return CanSetCodeResult::MultiBlockMigrationsOngoing;
2353		}
2354
2355		if check_version {
2356			let current_version = T::Version::get();
2357			let Some(new_version) = subsoil::io::misc::runtime_version(code)
2358				.and_then(|v| RuntimeVersion::decode(&mut &v[..]).ok())
2359			else {
2360				return CanSetCodeResult::InvalidVersion(Error::<T>::FailedToExtractRuntimeVersion);
2361			};
2362
2363			cfg_if::cfg_if! {
2364				if #[cfg(all(feature = "runtime-benchmarks", not(test)))] {
2365					// Let's ensure the compiler doesn't optimize our fetching of the runtime version away.
2366					core::hint::black_box((new_version, current_version));
2367				} else {
2368					if new_version.spec_name != current_version.spec_name {
2369						return CanSetCodeResult::InvalidVersion(Error::<T>::InvalidSpecName)
2370					}
2371
2372					if new_version.spec_version <= current_version.spec_version {
2373						return CanSetCodeResult::InvalidVersion(Error::<T>::SpecVersionNeedsToIncrease)
2374					}
2375				}
2376			}
2377		}
2378
2379		CanSetCodeResult::Ok
2380	}
2381
2382	/// Authorize the given `code_hash` as upgrade.
2383	pub fn do_authorize_upgrade(code_hash: T::Hash, check_version: bool) {
2384		AuthorizedUpgrade::<T>::put(CodeUpgradeAuthorization { code_hash, check_version });
2385		Self::deposit_event(Event::UpgradeAuthorized { code_hash, check_version });
2386	}
2387
2388	/// Check that provided `code` is authorized as an upgrade.
2389	///
2390	/// Returns the [`CodeUpgradeAuthorization`].
2391	fn validate_code_is_authorized(
2392		code: &[u8],
2393	) -> Result<CodeUpgradeAuthorization<T>, DispatchError> {
2394		let authorization = AuthorizedUpgrade::<T>::get().ok_or(Error::<T>::NothingAuthorized)?;
2395		let actual_hash = T::Hashing::hash(code);
2396		ensure!(actual_hash == authorization.code_hash, Error::<T>::Unauthorized);
2397		Ok(authorization)
2398	}
2399
2400	/// Reclaim the weight for the extrinsic given info and post info.
2401	///
2402	/// This function will check the already reclaimed weight, and reclaim more if the
2403	/// difference between pre dispatch and post dispatch weight is higher.
2404	pub fn reclaim_weight(
2405		info: &DispatchInfoOf<T::RuntimeCall>,
2406		post_info: &PostDispatchInfoOf<T::RuntimeCall>,
2407	) -> Result<(), TransactionValidityError>
2408	where
2409		T::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
2410	{
2411		let already_reclaimed = crate::system::ExtrinsicWeightReclaimed::<T>::get();
2412		let unspent = post_info.calc_unspent(info);
2413		let accurate_reclaim = already_reclaimed.max(unspent);
2414		// Saturation never happens, we took the maximum above.
2415		let to_reclaim_more = accurate_reclaim.saturating_sub(already_reclaimed);
2416		if to_reclaim_more != Weight::zero() {
2417			crate::system::BlockWeight::<T>::mutate(|current_weight| {
2418				current_weight.reduce(to_reclaim_more, info.class);
2419			});
2420			crate::system::ExtrinsicWeightReclaimed::<T>::put(accurate_reclaim);
2421		}
2422
2423		Ok(())
2424	}
2425
2426	/// Returns the remaining weight of the block.
2427	pub fn remaining_block_weight() -> WeightMeter {
2428		let limit = T::BlockWeights::get().max_block;
2429		let consumed = BlockWeight::<T>::get().total();
2430
2431		WeightMeter::with_consumed_and_limit(consumed, limit)
2432	}
2433}
2434
2435/// Returns a 32 byte datum which is guaranteed to be universally unique. `entropy` is provided
2436/// as a facility to reduce the potential for precalculating results.
2437pub fn unique(entropy: impl Encode) -> [u8; 32] {
2438	let mut last = [0u8; 32];
2439	subsoil::io::storage::read(well_known_keys::INTRABLOCK_ENTROPY, &mut last[..], 0);
2440	let next = (b"topsoil_system::unique", entropy, last).using_encoded(blake2_256);
2441	subsoil::io::storage::set(well_known_keys::INTRABLOCK_ENTROPY, &next);
2442	next
2443}
2444
2445/// Event handler which registers a provider when created.
2446pub struct Provider<T>(PhantomData<T>);
2447impl<T: Config> HandleLifetime<T::AccountId> for Provider<T> {
2448	fn created(t: &T::AccountId) -> Result<(), DispatchError> {
2449		Pallet::<T>::inc_providers(t);
2450		Ok(())
2451	}
2452	fn killed(t: &T::AccountId) -> Result<(), DispatchError> {
2453		Pallet::<T>::dec_providers(t).map(|_| ())
2454	}
2455}
2456
2457/// Event handler which registers a self-sufficient when created.
2458pub struct SelfSufficient<T>(PhantomData<T>);
2459impl<T: Config> HandleLifetime<T::AccountId> for SelfSufficient<T> {
2460	fn created(t: &T::AccountId) -> Result<(), DispatchError> {
2461		Pallet::<T>::inc_sufficients(t);
2462		Ok(())
2463	}
2464	fn killed(t: &T::AccountId) -> Result<(), DispatchError> {
2465		Pallet::<T>::dec_sufficients(t);
2466		Ok(())
2467	}
2468}
2469
2470/// Event handler which registers a consumer when created.
2471pub struct Consumer<T>(PhantomData<T>);
2472impl<T: Config> HandleLifetime<T::AccountId> for Consumer<T> {
2473	fn created(t: &T::AccountId) -> Result<(), DispatchError> {
2474		Pallet::<T>::inc_consumers(t)
2475	}
2476	fn killed(t: &T::AccountId) -> Result<(), DispatchError> {
2477		Pallet::<T>::dec_consumers(t);
2478		Ok(())
2479	}
2480}
2481
2482impl<T: Config> BlockNumberProvider for Pallet<T> {
2483	type BlockNumber = BlockNumberFor<T>;
2484
2485	fn current_block_number() -> Self::BlockNumber {
2486		Pallet::<T>::block_number()
2487	}
2488
2489	#[cfg(feature = "runtime-benchmarks")]
2490	fn set_block_number(n: BlockNumberFor<T>) {
2491		Self::set_block_number(n)
2492	}
2493}
2494
2495/// Implement StoredMap for a simple single-item, provide-when-not-default system. This works fine
2496/// for storing a single item which allows the account to continue existing as long as it's not
2497/// empty/default.
2498///
2499/// Anything more complex will need more sophisticated logic.
2500impl<T: Config> StoredMap<T::AccountId, T::AccountData> for Pallet<T> {
2501	fn get(k: &T::AccountId) -> T::AccountData {
2502		Account::<T>::get(k).data
2503	}
2504
2505	fn try_mutate_exists<R, E: From<DispatchError>>(
2506		k: &T::AccountId,
2507		f: impl FnOnce(&mut Option<T::AccountData>) -> Result<R, E>,
2508	) -> Result<R, E> {
2509		let account = Account::<T>::get(k);
2510		let is_default = account.data == T::AccountData::default();
2511		let mut some_data = if is_default { None } else { Some(account.data) };
2512		let result = f(&mut some_data)?;
2513		if Self::providers(k) > 0 || Self::sufficients(k) > 0 {
2514			Account::<T>::mutate(k, |a| a.data = some_data.unwrap_or_default());
2515		} else {
2516			Account::<T>::remove(k)
2517		}
2518		Ok(result)
2519	}
2520}
2521
2522/// Split an `option` into two constituent options, as defined by a `splitter` function.
2523pub fn split_inner<T, R, S>(
2524	option: Option<T>,
2525	splitter: impl FnOnce(T) -> (R, S),
2526) -> (Option<R>, Option<S>) {
2527	match option {
2528		Some(inner) => {
2529			let (r, s) = splitter(inner);
2530			(Some(r), Some(s))
2531		},
2532		None => (None, None),
2533	}
2534}
2535
2536pub struct ChainContext<T>(PhantomData<T>);
2537impl<T> Default for ChainContext<T> {
2538	fn default() -> Self {
2539		ChainContext(PhantomData)
2540	}
2541}
2542
2543impl<T: Config> Lookup for ChainContext<T> {
2544	type Source = <T::Lookup as StaticLookup>::Source;
2545	type Target = <T::Lookup as StaticLookup>::Target;
2546
2547	fn lookup(&self, s: Self::Source) -> Result<Self::Target, LookupError> {
2548		<T::Lookup as StaticLookup>::lookup(s)
2549	}
2550}
2551
2552/// Hooks for the [`Pallet::run_to_block_with`] function.
2553#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2554pub struct RunToBlockHooks<'a, T>
2555where
2556	T: 'a + Config,
2557{
2558	before_initialize: Box<dyn 'a + FnMut(BlockNumberFor<T>)>,
2559	after_initialize: Box<dyn 'a + FnMut(BlockNumberFor<T>)>,
2560	before_finalize: Box<dyn 'a + FnMut(BlockNumberFor<T>)>,
2561	after_finalize: Box<dyn 'a + FnMut(BlockNumberFor<T>)>,
2562}
2563
2564#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2565impl<'a, T> RunToBlockHooks<'a, T>
2566where
2567	T: 'a + Config,
2568{
2569	/// Set the hook function logic before the initialization of the block.
2570	pub fn before_initialize<F>(mut self, f: F) -> Self
2571	where
2572		F: 'a + FnMut(BlockNumberFor<T>),
2573	{
2574		self.before_initialize = Box::new(f);
2575		self
2576	}
2577	/// Set the hook function logic after the initialization of the block.
2578	pub fn after_initialize<F>(mut self, f: F) -> Self
2579	where
2580		F: 'a + FnMut(BlockNumberFor<T>),
2581	{
2582		self.after_initialize = Box::new(f);
2583		self
2584	}
2585	/// Set the hook function logic before the finalization of the block.
2586	pub fn before_finalize<F>(mut self, f: F) -> Self
2587	where
2588		F: 'a + FnMut(BlockNumberFor<T>),
2589	{
2590		self.before_finalize = Box::new(f);
2591		self
2592	}
2593	/// Set the hook function logic after the finalization of the block.
2594	pub fn after_finalize<F>(mut self, f: F) -> Self
2595	where
2596		F: 'a + FnMut(BlockNumberFor<T>),
2597	{
2598		self.after_finalize = Box::new(f);
2599		self
2600	}
2601}
2602
2603#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
2604impl<'a, T> Default for RunToBlockHooks<'a, T>
2605where
2606	T: Config,
2607{
2608	fn default() -> Self {
2609		Self {
2610			before_initialize: Box::new(|_| {}),
2611			after_initialize: Box::new(|_| {}),
2612			before_finalize: Box::new(|_| {}),
2613			after_finalize: Box::new(|_| {}),
2614		}
2615	}
2616}
2617
2618/// Prelude to be used alongside pallet macro, for ease of use.
2619pub mod pallet_prelude {
2620	pub use crate::system::{
2621		ensure_authorized, ensure_none, ensure_root, ensure_signed, ensure_signed_or_root,
2622	};
2623
2624	/// Type alias for the `Origin` associated type of system config.
2625	pub type OriginFor<T> = <T as crate::system::Config>::RuntimeOrigin;
2626
2627	/// Type alias for the `Header`.
2628	pub type HeaderFor<T> =
2629		<<T as crate::system::Config>::Block as subsoil::runtime::traits::HeaderProvider>::HeaderT;
2630
2631	/// Type alias for the `BlockNumber` associated type of system config.
2632	pub type BlockNumberFor<T> = <HeaderFor<T> as subsoil::runtime::traits::Header>::Number;
2633
2634	/// Type alias for the `Extrinsic` associated type of system config.
2635	pub type ExtrinsicFor<T> =
2636		<<T as crate::system::Config>::Block as subsoil::runtime::traits::Block>::Extrinsic;
2637
2638	/// Type alias for the `RuntimeCall` associated type of system config.
2639	pub type RuntimeCallFor<T> = <T as crate::system::Config>::RuntimeCall;
2640
2641	/// Type alias for the `AccountId` associated type of system config.
2642	pub type AccountIdFor<T> = <T as crate::system::Config>::AccountId;
2643}