1#![cfg_attr(not(feature = "std"), no_std)]
19
20#[cfg(doc)]
76#[cfg_attr(doc, aquamarine::aquamarine)]
77pub mod block_flowchart {}
104
105#[cfg(test)]
106mod tests;
107
108extern crate alloc;
109
110use codec::{Codec, Encode};
111use core::marker::PhantomData;
112use frame_support::{
113 defensive_assert,
114 dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, PostDispatchInfo},
115 migrations::MultiStepMigrator,
116 pallet_prelude::InvalidTransaction,
117 traits::{
118 BeforeAllRuntimeMigrations, ExecuteBlock, Get, IsInherent, OffchainWorker, OnFinalize,
119 OnIdle, OnInitialize, OnPoll, OnRuntimeUpgrade, PostInherents, PostTransactions,
120 PreInherents,
121 },
122 weights::{Weight, WeightMeter},
123 MAX_EXTRINSIC_DEPTH,
124};
125use frame_system::pallet_prelude::BlockNumberFor;
126use sp_runtime::{
127 generic::Digest,
128 traits::{
129 self, Applyable, CheckEqual, Checkable, Dispatchable, Header, LazyBlock, NumberFor, One,
130 Zero,
131 },
132 transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError},
133 ApplyExtrinsicResult, ExtrinsicInclusionMode,
134};
135
136#[allow(deprecated)]
137use sp_runtime::traits::ValidateUnsigned;
138
139#[cfg(feature = "try-runtime")]
140use ::{
141 frame_support::{
142 traits::{TryDecodeEntireStorage, TryDecodeEntireStorageError, TryState},
143 StorageNoopGuard,
144 },
145 frame_try_runtime::{TryStateSelect, UpgradeCheckSelect},
146 log,
147 sp_runtime::TryRuntimeError,
148};
149
150#[allow(dead_code)]
151const LOG_TARGET: &str = "runtime::executive";
152
153pub type CheckedOf<E, C> = <E as Checkable<C>>::Checked;
154pub type CallOf<E, C> = <CheckedOf<E, C> as Applyable>::Call;
155pub type OriginOf<E, C> = <CallOf<E, C> as Dispatchable>::RuntimeOrigin;
156
157#[cfg(feature = "try-runtime")]
159#[derive(Debug, Clone)]
160pub struct TryRuntimeUpgradeConfig {
161 pub checks: UpgradeCheckSelect,
163 pub try_state_select: TryStateSelect,
165}
166
167#[cfg(feature = "try-runtime")]
168impl TryRuntimeUpgradeConfig {
169 pub fn new(checks: UpgradeCheckSelect) -> Self {
171 Self { checks, try_state_select: TryStateSelect::All }
172 }
173
174 pub fn with_try_state_select(mut self, try_state_select: TryStateSelect) -> Self {
176 self.try_state_select = try_state_select;
177 self
178 }
179}
180
181#[derive(PartialEq)]
182pub enum ExecutiveError {
183 UnableToDecodeExtrinsic,
184 InvalidInherentPosition(usize),
185 OnlyInherentsAllowed,
186 ApplyExtrinsic(TransactionValidityError),
187 Custom(&'static str),
188}
189
190impl core::fmt::Debug for ExecutiveError {
191 fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
192 match self {
193 ExecutiveError::UnableToDecodeExtrinsic => {
194 write!(fmt, "The extrinsic could not be decoded correctly")
195 },
196 ExecutiveError::InvalidInherentPosition(i) => {
197 write!(fmt, "Invalid inherent position for extrinsic at index {}", i)
198 },
199 ExecutiveError::OnlyInherentsAllowed => {
200 write!(fmt, "Only inherents are allowed in this block")
201 },
202 ExecutiveError::ApplyExtrinsic(e) => write!(
203 fmt,
204 "ExecuteBlockError applying extrinsic: {}",
205 Into::<&'static str>::into(*e)
206 ),
207 ExecutiveError::Custom(err) => write!(fmt, "{err}"),
208 }
209 }
210}
211
212#[allow(deprecated)]
224pub struct Executive<
225 System,
226 Block,
227 Context,
228 UnsignedValidator,
229 AllPalletsWithSystem,
230 OnRuntimeUpgrade = (),
231>(
232 PhantomData<(
233 System,
234 Block,
235 Context,
236 UnsignedValidator,
237 AllPalletsWithSystem,
238 OnRuntimeUpgrade,
239 )>,
240);
241
242#[allow(deprecated)]
246impl<
247 System: frame_system::Config + IsInherent<Block::Extrinsic>,
248 Block: traits::Block<
249 Header = frame_system::pallet_prelude::HeaderFor<System>,
250 Hash = System::Hash,
251 >,
252 Context: Default,
253 UnsignedValidator,
254 AllPalletsWithSystem: OnRuntimeUpgrade
255 + BeforeAllRuntimeMigrations
256 + OnInitializeWithWeightRegistration<System>
257 + OnIdle<BlockNumberFor<System>>
258 + OnFinalize<BlockNumberFor<System>>
259 + OffchainWorker<BlockNumberFor<System>>
260 + OnPoll<BlockNumberFor<System>>,
261 COnRuntimeUpgrade: OnRuntimeUpgrade,
262 > ExecuteBlock<Block>
263 for Executive<System, Block, Context, UnsignedValidator, AllPalletsWithSystem, COnRuntimeUpgrade>
264where
265 Block::Extrinsic: Checkable<Context> + Codec,
266 CheckedOf<Block::Extrinsic, Context>: Applyable + GetDispatchInfo,
267 CallOf<Block::Extrinsic, Context>:
268 Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
269 OriginOf<Block::Extrinsic, Context>: From<Option<System::AccountId>>,
270 UnsignedValidator: ValidateUnsigned<Call = CallOf<Block::Extrinsic, Context>>,
271{
272 fn verify_and_remove_seal(_: &mut <Block as traits::Block>::LazyBlock) {
273 }
275
276 fn execute_verified_block(block: Block::LazyBlock) {
277 Executive::<
278 System,
279 Block,
280 Context,
281 UnsignedValidator,
282 AllPalletsWithSystem,
283 COnRuntimeUpgrade,
284 >::execute_block(block);
285 }
286}
287
288#[allow(deprecated)]
292#[cfg(feature = "try-runtime")]
293impl<
294 System: frame_system::Config + IsInherent<Block::Extrinsic>,
295 Block: traits::Block<
296 Header = frame_system::pallet_prelude::HeaderFor<System>,
297 Hash = System::Hash,
298 >,
299 Context: Default,
300 UnsignedValidator,
301 AllPalletsWithSystem: OnRuntimeUpgrade
302 + BeforeAllRuntimeMigrations
303 + OnInitializeWithWeightRegistration<System>
304 + OnIdle<BlockNumberFor<System>>
305 + OnFinalize<BlockNumberFor<System>>
306 + OffchainWorker<BlockNumberFor<System>>
307 + OnPoll<BlockNumberFor<System>>
308 + TryState<BlockNumberFor<System>>
309 + TryDecodeEntireStorage,
310 COnRuntimeUpgrade: OnRuntimeUpgrade,
311 > Executive<System, Block, Context, UnsignedValidator, AllPalletsWithSystem, COnRuntimeUpgrade>
312where
313 Block::Extrinsic: Checkable<Context> + Codec,
314 CheckedOf<Block::Extrinsic, Context>: Applyable + GetDispatchInfo,
315 CallOf<Block::Extrinsic, Context>:
316 Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
317 OriginOf<Block::Extrinsic, Context>: From<Option<System::AccountId>>,
318 UnsignedValidator: ValidateUnsigned<Call = CallOf<Block::Extrinsic, Context>>,
319{
320 pub fn try_execute_block(
329 block: Block::LazyBlock,
330 state_root_check: bool,
331 signature_check: bool,
332 select: frame_try_runtime::TryStateSelect,
333 ) -> Result<Weight, ExecutiveError> {
334 log::info!(
335 target: LOG_TARGET,
336 "try-runtime: executing block #{:?} / state root check: {:?} / signature check: {:?} / try-state-select: {:?}",
337 block.header().number(),
338 state_root_check,
339 signature_check,
340 select,
341 );
342
343 let mode = Self::initialize_block(block.header());
344 Self::initial_checks(block.header());
345
346 let signature_check = if signature_check {
348 Block::Extrinsic::check
349 } else {
350 Block::Extrinsic::unchecked_into_checked_i_know_what_i_am_doing
351 };
352 Self::apply_extrinsics(mode, block.extrinsics(), |uxt, is_inherent| {
353 Self::do_apply_extrinsic(uxt, is_inherent, signature_check)
354 })?;
355
356 if !<frame_system::Pallet<System>>::inherents_applied() {
358 Self::inherents_applied();
359 }
360
361 <frame_system::Pallet<System>>::note_finished_extrinsics();
363 <System as frame_system::Config>::PostTransactions::post_transactions();
364
365 let header = block.header();
366 Self::on_idle_hook(*header.number());
367 Self::on_finalize_hook(*header.number());
368
369 let _guard = frame_support::StorageNoopGuard::default();
371 <AllPalletsWithSystem as frame_support::traits::TryState<
372 BlockNumberFor<System>,
373 >>::try_state(*header.number(), select.clone())
374 .map_err(|e| {
375 log::error!(target: LOG_TARGET, "failure: {:?}", e);
376 ExecutiveError::Custom(e.into())
377 })?;
378 if select.any() {
379 let res = AllPalletsWithSystem::try_decode_entire_state();
380 Self::log_decode_result(res).map_err(|e| ExecutiveError::Custom(e.into()))?;
381 }
382 drop(_guard);
383
384 {
387 let new_header = <frame_system::Pallet<System>>::finalize();
388 let items_zip = header.digest().logs().iter().zip(new_header.digest().logs().iter());
389 for (header_item, computed_item) in items_zip {
390 header_item.check_equal(computed_item);
391 assert!(header_item == computed_item, "Digest item must match that calculated.");
392 }
393
394 if state_root_check {
395 let storage_root = new_header.state_root();
396 header.state_root().check_equal(storage_root);
397 assert!(
398 header.state_root() == storage_root,
399 "Storage root must match that calculated."
400 );
401 }
402
403 assert!(
404 header.extrinsics_root() == new_header.extrinsics_root(),
405 "Transaction trie root must be valid.",
406 );
407 }
408
409 log::info!(
410 target: LOG_TARGET,
411 "try-runtime: Block #{:?} successfully executed",
412 header.number(),
413 );
414
415 Ok(frame_system::Pallet::<System>::block_weight().total())
416 }
417
418 pub fn try_runtime_upgrade(checks: UpgradeCheckSelect) -> Result<Weight, TryRuntimeError> {
430 Self::try_runtime_upgrade_with_config(TryRuntimeUpgradeConfig::new(checks))
431 }
432
433 pub fn try_runtime_upgrade_with_config(
443 config: TryRuntimeUpgradeConfig,
444 ) -> Result<Weight, TryRuntimeError> {
445 let checks = config.checks;
446 let try_state_select = config.try_state_select;
447 let before_all_weight =
448 <AllPalletsWithSystem as BeforeAllRuntimeMigrations>::before_all_runtime_migrations();
449
450 let try_on_runtime_upgrade_weight =
451 <(
452 COnRuntimeUpgrade,
453 <System as frame_system::Config>::SingleBlockMigrations,
454 AllPalletsWithSystem,
457 ) as OnRuntimeUpgrade>::try_on_runtime_upgrade(checks.pre_and_post())?;
458
459 frame_system::LastRuntimeUpgrade::<System>::put(
460 frame_system::LastRuntimeUpgradeInfo::from(
461 <System::Version as frame_support::traits::Get<_>>::get(),
462 ),
463 );
464
465 let _guard = StorageNoopGuard::default();
467
468 if checks.any() {
470 let res = AllPalletsWithSystem::try_decode_entire_state();
471 Self::log_decode_result(res)?;
472 }
473
474 if checks.try_state() {
476 AllPalletsWithSystem::try_state(
477 frame_system::Pallet::<System>::block_number(),
478 try_state_select,
479 )?;
480 }
481
482 Ok(before_all_weight.saturating_add(try_on_runtime_upgrade_weight))
483 }
484
485 fn log_decode_result(
487 res: Result<usize, alloc::vec::Vec<TryDecodeEntireStorageError>>,
488 ) -> Result<(), TryRuntimeError> {
489 match res {
490 Ok(bytes) => {
491 log::info!(
492 target: LOG_TARGET,
493 "✅ Entire runtime state decodes without error. {} bytes total.",
494 bytes
495 );
496
497 Ok(())
498 },
499 Err(errors) => {
500 log::error!(
501 target: LOG_TARGET,
502 "`try_decode_entire_state` failed with {} errors",
503 errors.len(),
504 );
505
506 for (i, err) in errors.iter().enumerate() {
507 log::error!(target: LOG_TARGET, "- {i}. error: {err}");
509 log::debug!(target: LOG_TARGET, "- {i}. error: {err:?}");
510 }
511
512 Err("`try_decode_entire_state` failed".into())
513 },
514 }
515 }
516}
517
518pub trait OnInitializeWithWeightRegistration<T: frame_system::Config> {
525 fn on_initialize_with_weight_registration(_n: BlockNumberFor<T>) -> Weight;
527}
528
529frame_support::impl_for_tuples_attr! {
530 #[tuple_types_custom_trait_bound(OnInitialize<frame_system::pallet_prelude::BlockNumberFor<T>>)]
531 impl<T: frame_system::Config> OnInitializeWithWeightRegistration<T> for Tuple {
532 fn on_initialize_with_weight_registration(n: BlockNumberFor<T>) -> Weight {
533 let mut weight = Weight::zero();
534 for_tuples!( #(
535 let individual_weight = Tuple::on_initialize(n);
536
537 <frame_system::Pallet<T>>::register_extra_weight_unchecked(
538 individual_weight,
539 DispatchClass::Mandatory,
540 );
541
542 weight = weight.saturating_add(individual_weight);
543 )* );
544
545 weight
546 }
547 }
548}
549
550#[allow(deprecated)]
554impl<
555 System: frame_system::Config + IsInherent<Block::Extrinsic>,
556 Block: traits::Block<
557 Header = frame_system::pallet_prelude::HeaderFor<System>,
558 Hash = System::Hash,
559 >,
560 Context: Default,
561 UnsignedValidator,
562 AllPalletsWithSystem: OnRuntimeUpgrade
563 + BeforeAllRuntimeMigrations
564 + OnInitializeWithWeightRegistration<System>
565 + OnIdle<BlockNumberFor<System>>
566 + OnFinalize<BlockNumberFor<System>>
567 + OffchainWorker<BlockNumberFor<System>>
568 + OnPoll<BlockNumberFor<System>>,
569 COnRuntimeUpgrade: OnRuntimeUpgrade,
570 > Executive<System, Block, Context, UnsignedValidator, AllPalletsWithSystem, COnRuntimeUpgrade>
571where
572 Block::Extrinsic: Checkable<Context> + Codec,
573 CheckedOf<Block::Extrinsic, Context>: Applyable + GetDispatchInfo,
574 CallOf<Block::Extrinsic, Context>:
575 Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
576 OriginOf<Block::Extrinsic, Context>: From<Option<System::AccountId>>,
577 UnsignedValidator: ValidateUnsigned<Call = CallOf<Block::Extrinsic, Context>>,
578{
579 pub fn execute_on_runtime_upgrade() -> Weight {
581 let before_all_weight =
582 <AllPalletsWithSystem as BeforeAllRuntimeMigrations>::before_all_runtime_migrations();
583
584 let runtime_upgrade_weight = <(
585 COnRuntimeUpgrade,
586 <System as frame_system::Config>::SingleBlockMigrations,
587 AllPalletsWithSystem,
590 ) as OnRuntimeUpgrade>::on_runtime_upgrade();
591
592 before_all_weight.saturating_add(runtime_upgrade_weight)
593 }
594
595 pub fn initialize_block(
597 header: &frame_system::pallet_prelude::HeaderFor<System>,
598 ) -> ExtrinsicInclusionMode {
599 sp_io::init_tracing();
600 sp_tracing::enter_span!(sp_tracing::Level::TRACE, "init_block");
601 let digests = Self::extract_pre_digest(header);
602 Self::initialize_block_impl(header.number(), header.parent_hash(), &digests);
603
604 Self::extrinsic_mode()
605 }
606
607 fn extrinsic_mode() -> ExtrinsicInclusionMode {
608 if <System as frame_system::Config>::MultiBlockMigrator::ongoing() {
609 ExtrinsicInclusionMode::OnlyInherents
610 } else {
611 ExtrinsicInclusionMode::AllExtrinsics
612 }
613 }
614
615 fn extract_pre_digest(header: &frame_system::pallet_prelude::HeaderFor<System>) -> Digest {
616 let mut digest = <Digest>::default();
617 header.digest().logs().iter().for_each(|d| {
618 if d.as_pre_runtime().is_some() {
619 digest.push(d.clone())
620 }
621 });
622 digest
623 }
624
625 fn initialize_block_impl(
626 block_number: &BlockNumberFor<System>,
627 parent_hash: &System::Hash,
628 digest: &Digest,
629 ) {
630 <frame_system::Pallet<System>>::reset_events();
634
635 let mut weight = Weight::zero();
636 if Self::runtime_upgraded() {
637 weight = weight.saturating_add(Self::execute_on_runtime_upgrade());
638
639 frame_system::LastRuntimeUpgrade::<System>::put(
640 frame_system::LastRuntimeUpgradeInfo::from(
641 <System::Version as frame_support::traits::Get<_>>::get(),
642 ),
643 );
644 }
645 <frame_system::Pallet<System>>::initialize(block_number, parent_hash, digest);
646
647 weight = System::BlockWeights::get().base_block.saturating_add(weight);
648 <frame_system::Pallet<System>>::register_extra_weight_unchecked(
650 weight,
651 DispatchClass::Mandatory,
652 );
653
654 weight = weight
655 .saturating_add(<AllPalletsWithSystem as OnInitializeWithWeightRegistration<
656 System,
657 >>::on_initialize_with_weight_registration(*block_number));
658
659 log::debug!(
660 target: LOG_TARGET,
661 "[{block_number:?}]: Block initialization weight consumption: {weight:?}",
662 );
663
664 frame_system::Pallet::<System>::note_finished_initialize();
665 <System as frame_system::Config>::PreInherents::pre_inherents();
666 }
667
668 fn runtime_upgraded() -> bool {
670 let last = frame_system::LastRuntimeUpgrade::<System>::get();
671 let current = <System::Version as frame_support::traits::Get<_>>::get();
672
673 last.map(|v| v.was_upgraded(¤t)).unwrap_or(true)
674 }
675
676 fn initial_checks(header: &Block::Header) {
677 sp_tracing::enter_span!(sp_tracing::Level::TRACE, "initial_checks");
678
679 let n = *header.number();
681 assert!(
682 n > BlockNumberFor::<System>::zero() &&
683 <frame_system::Pallet<System>>::block_hash(n - BlockNumberFor::<System>::one()) ==
684 *header.parent_hash(),
685 "Parent hash should be valid.",
686 );
687 }
688
689 pub fn execute_block(block: Block::LazyBlock) {
691 sp_io::init_tracing();
692 sp_tracing::within_span! {
693 sp_tracing::info_span!("execute_block", ?block);
694 let mode = Self::initialize_block(block.header());
696 Self::initial_checks(block.header());
697
698 let extrinsics = block.extrinsics();
699 if let Err(e) = Self::apply_extrinsics(
700 mode,
701 extrinsics,
702 |uxt, is_inherent| {
703 Self::do_apply_extrinsic(uxt, is_inherent, Block::Extrinsic::check)
704 }
705 ) {
706 panic!("{:?}", e)
707 }
708
709 if !<frame_system::Pallet<System>>::inherents_applied() {
711 Self::inherents_applied();
712 }
713
714 <frame_system::Pallet<System>>::note_finished_extrinsics();
715 <System as frame_system::Config>::PostTransactions::post_transactions();
716
717 let header = block.header();
718 Self::on_idle_hook(*header.number());
719 Self::on_finalize_hook(*header.number());
720 <frame_system::Pallet<System>>::maybe_apply_pending_code_upgrade();
721 Self::final_checks(&header);
722 }
723 }
724
725 pub fn inherents_applied() {
729 <frame_system::Pallet<System>>::note_inherents_applied();
730 <System as frame_system::Config>::PostInherents::post_inherents();
731
732 if <System as frame_system::Config>::MultiBlockMigrator::ongoing() {
733 let used_weight = <System as frame_system::Config>::MultiBlockMigrator::step();
734 <frame_system::Pallet<System>>::register_extra_weight_unchecked(
735 used_weight,
736 DispatchClass::Mandatory,
737 );
738 } else {
739 let block_number = <frame_system::Pallet<System>>::block_number();
740 Self::on_poll_hook(block_number);
741 }
742 }
743
744 fn apply_extrinsics(
746 mode: ExtrinsicInclusionMode,
747 extrinsics: impl Iterator<Item = Result<Block::Extrinsic, codec::Error>>,
748 mut apply_extrinsic: impl FnMut(Block::Extrinsic, bool) -> ApplyExtrinsicResult,
749 ) -> Result<(), ExecutiveError> {
750 let mut first_non_inherent_idx = 0;
751 for (idx, maybe_uxt) in extrinsics.into_iter().enumerate() {
752 let uxt = maybe_uxt.map_err(|_| ExecutiveError::UnableToDecodeExtrinsic)?;
753 let is_inherent = System::is_inherent(&uxt);
754 if is_inherent {
755 if first_non_inherent_idx != idx {
757 return Err(ExecutiveError::InvalidInherentPosition(idx));
758 }
759 first_non_inherent_idx += 1;
760 } else {
761 if mode == ExtrinsicInclusionMode::OnlyInherents {
763 return Err(ExecutiveError::OnlyInherentsAllowed);
764 }
765 }
766
767 log::debug!(target: LOG_TARGET, "Executing transaction: {:?}", uxt);
768 if let Err(e) = apply_extrinsic(uxt, is_inherent) {
769 log::error!(
770 target: LOG_TARGET,
771 "Transaction({idx}) failed due to {e:?}. \
772 Aborting the rest of the block execution.",
773 );
774 return Err(ExecutiveError::ApplyExtrinsic(e.into()));
775 }
776 }
777
778 Ok(())
779 }
780
781 pub fn finalize_block() -> frame_system::pallet_prelude::HeaderFor<System> {
785 sp_io::init_tracing();
786 sp_tracing::enter_span!(sp_tracing::Level::TRACE, "finalize_block");
787
788 if !<frame_system::Pallet<System>>::inherents_applied() {
790 Self::inherents_applied();
791 }
792
793 <frame_system::Pallet<System>>::note_finished_extrinsics();
794 <System as frame_system::Config>::PostTransactions::post_transactions();
795 let block_number = <frame_system::Pallet<System>>::block_number();
796 Self::on_idle_hook(block_number);
797 Self::on_finalize_hook(block_number);
798 <frame_system::Pallet<System>>::maybe_apply_pending_code_upgrade();
799 <frame_system::Pallet<System>>::finalize()
800 }
801
802 fn on_idle_hook(block_number: NumberFor<Block>) {
805 if <System as frame_system::Config>::MultiBlockMigrator::ongoing() {
806 return;
807 }
808
809 let weight = <frame_system::Pallet<System>>::block_weight();
810 let max_weight = <System::BlockWeights as frame_support::traits::Get<_>>::get().max_block;
811 let remaining_weight = max_weight.saturating_sub(weight.total());
812
813 if remaining_weight.all_gt(Weight::zero()) {
814 let used_weight = <AllPalletsWithSystem as OnIdle<BlockNumberFor<System>>>::on_idle(
815 block_number,
816 remaining_weight,
817 );
818 <frame_system::Pallet<System>>::register_extra_weight_unchecked(
819 used_weight,
820 DispatchClass::Mandatory,
821 );
822 }
823 }
824
825 fn on_poll_hook(block_number: NumberFor<Block>) {
826 defensive_assert!(
827 !<System as frame_system::Config>::MultiBlockMigrator::ongoing(),
828 "on_poll should not be called during migrations"
829 );
830
831 let weight = <frame_system::Pallet<System>>::block_weight();
832 let max_weight = <System::BlockWeights as frame_support::traits::Get<_>>::get().max_block;
833 let remaining = max_weight.saturating_sub(weight.total());
834
835 if remaining.all_gt(Weight::zero()) {
836 let mut meter = WeightMeter::with_limit(remaining);
837 <AllPalletsWithSystem as OnPoll<BlockNumberFor<System>>>::on_poll(
838 block_number,
839 &mut meter,
840 );
841 <frame_system::Pallet<System>>::register_extra_weight_unchecked(
842 meter.consumed(),
843 DispatchClass::Mandatory,
844 );
845 }
846 }
847
848 fn on_finalize_hook(block_number: NumberFor<Block>) {
850 <AllPalletsWithSystem as OnFinalize<BlockNumberFor<System>>>::on_finalize(block_number);
851 }
852
853 fn do_apply_extrinsic(
858 uxt: Block::Extrinsic,
859 is_inherent: bool,
860 check: impl FnOnce(
861 Block::Extrinsic,
862 &Context,
863 ) -> Result<CheckedOf<Block::Extrinsic, Context>, TransactionValidityError>,
864 ) -> ApplyExtrinsicResult {
865 sp_io::init_tracing();
866 let encoded = uxt.encode();
867 let encoded_len = encoded.len();
868 sp_tracing::enter_span!(sp_tracing::info_span!(
869 "apply_extrinsic",
870 ext=?sp_core::hexdisplay::HexDisplay::from(&encoded)
871 ));
872
873 let uxt = <Block::Extrinsic as codec::DecodeLimit>::decode_all_with_depth_limit(
874 MAX_EXTRINSIC_DEPTH,
875 &mut &encoded[..],
876 )
877 .map_err(|_| InvalidTransaction::Call)?;
878
879 let xt = check(uxt, &Context::default())?;
881
882 let dispatch_info = xt.get_dispatch_info();
883
884 if !is_inherent && !<frame_system::Pallet<System>>::inherents_applied() {
885 Self::inherents_applied();
886 }
887
888 <frame_system::Pallet<System>>::note_extrinsic(encoded);
892
893 let r = Applyable::apply::<UnsignedValidator>(xt, &dispatch_info, encoded_len)?;
896
897 if r.is_err() && dispatch_info.class == DispatchClass::Mandatory {
902 return Err(InvalidTransaction::BadMandatory.into());
903 }
904
905 <frame_system::Pallet<System>>::note_applied_extrinsic(&r, dispatch_info);
906
907 Ok(r.map(|_| ()).map_err(|e| e.error))
908 }
909
910 pub fn apply_extrinsic(uxt: Block::Extrinsic) -> ApplyExtrinsicResult {
915 let is_inherent = System::is_inherent(&uxt);
916 Self::do_apply_extrinsic(uxt, is_inherent, Block::Extrinsic::check)
917 }
918
919 fn final_checks(header: &frame_system::pallet_prelude::HeaderFor<System>) {
920 sp_tracing::enter_span!(sp_tracing::Level::TRACE, "final_checks");
921 let new_header = <frame_system::Pallet<System>>::finalize();
923
924 assert_eq!(
926 header.digest().logs().len(),
927 new_header.digest().logs().len(),
928 "Number of digest items must match that calculated."
929 );
930 let items_zip = header.digest().logs().iter().zip(new_header.digest().logs().iter());
931 for (header_item, computed_item) in items_zip {
932 header_item.check_equal(computed_item);
933 assert!(header_item == computed_item, "Digest item must match that calculated.");
934 }
935
936 let storage_root = new_header.state_root();
938 header.state_root().check_equal(storage_root);
939 assert!(header.state_root() == storage_root, "Storage root must match that calculated.");
940
941 assert!(
942 header.extrinsics_root() == new_header.extrinsics_root(),
943 "Transaction trie root must be valid.",
944 );
945 }
946
947 pub fn validate_transaction(
953 source: TransactionSource,
954 uxt: Block::Extrinsic,
955 block_hash: Block::Hash,
956 ) -> TransactionValidity {
957 sp_io::init_tracing();
958 use sp_tracing::{enter_span, within_span};
959
960 <frame_system::Pallet<System>>::initialize(
961 &(frame_system::Pallet::<System>::block_number() + One::one()),
962 &block_hash,
963 &Default::default(),
964 );
965
966 enter_span! { sp_tracing::Level::TRACE, "validate_transaction" };
967
968 let encoded = within_span! { sp_tracing::Level::TRACE, "using_encoded";
969 uxt.encode()
970 };
971
972 let uxt = <Block::Extrinsic as codec::DecodeLimit>::decode_all_with_depth_limit(
973 MAX_EXTRINSIC_DEPTH,
974 &mut &encoded[..],
975 )
976 .map_err(|_| InvalidTransaction::Call)?;
977
978 let xt = within_span! { sp_tracing::Level::TRACE, "check";
979 uxt.check(&Default::default())
980 }?;
981
982 let dispatch_info = within_span! { sp_tracing::Level::TRACE, "dispatch_info";
983 xt.get_dispatch_info()
984 };
985
986 if dispatch_info.class == DispatchClass::Mandatory {
987 return Err(InvalidTransaction::MandatoryValidation.into());
988 }
989
990 within_span! {
991 sp_tracing::Level::TRACE, "validate";
992 xt.validate::<UnsignedValidator>(source, &dispatch_info, encoded.len())
993 }
994 }
995
996 pub fn offchain_worker(header: &frame_system::pallet_prelude::HeaderFor<System>) {
998 sp_io::init_tracing();
999 let digests = header.digest().clone();
1003
1004 let existing_digest = frame_system::Pallet::<System>::digest();
1006 for digest in digests.logs().iter().filter(|d| !existing_digest.logs.contains(d)) {
1007 frame_system::Pallet::<System>::deposit_log(digest.clone());
1008 }
1009
1010 frame_system::Pallet::<System>::initialize_intra_block_entropy(header.parent_hash());
1012
1013 frame_system::BlockHash::<System>::insert(header.number(), header.hash());
1017
1018 <AllPalletsWithSystem as OffchainWorker<BlockNumberFor<System>>>::offchain_worker(
1019 *header.number(),
1020 )
1021 }
1022}