1#![cfg_attr(not(feature = "std"), no_std)]
19
20#[cfg(doc)]
122#[cfg_attr(doc, aquamarine::aquamarine)]
123pub mod block_flowchart {}
150
151extern crate alloc;
152
153use codec::{Codec, Encode};
154use core::marker::PhantomData;
155use frame_support::dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, PostDispatchInfo};
156use frame_support::migrations::MultiStepMigrator;
157use frame_support::pallet_prelude::InvalidTransaction;
158use frame_support::traits::{
159 BeforeAllRuntimeMigrations, ExecuteBlock, IsInherent, OffchainWorker, OnFinalize, OnIdle,
160 OnInitialize, OnPoll, OnRuntimeUpgrade, PostInherents, PostTransactions, PreInherents,
161};
162use frame_support::weights::{Weight, WeightMeter};
163use frame_support::{MAX_EXTRINSIC_DEPTH, defensive_assert};
164use frame_system::pallet_prelude::BlockNumberFor;
165use sp_runtime::generic::Digest;
166use sp_runtime::traits::{
167 self, Applyable, CheckEqual, Checkable, Dispatchable, Header, LazyBlock, NumberFor, One,
168 ValidateUnsigned, Zero,
169};
170use sp_runtime::transaction_validity::{
171 TransactionSource, TransactionValidity, TransactionValidityError,
172};
173use sp_runtime::{ApplyExtrinsicResult, ExtrinsicInclusionMode};
174
175#[cfg(feature = "try-runtime")]
176use ::{
177 frame_support::{
178 StorageNoopGuard,
179 traits::{TryDecodeEntireStorage, TryDecodeEntireStorageError, TryState},
180 },
181 frame_try_runtime::{TryStateSelect, UpgradeCheckSelect},
182 log,
183 sp_runtime::TryRuntimeError,
184};
185
186#[allow(dead_code)]
187const LOG_TARGET: &str = "runtime::executive";
188
189pub type CheckedOf<E, C> = <E as Checkable<C>>::Checked;
190pub type CallOf<E, C> = <CheckedOf<E, C> as Applyable>::Call;
191pub type OriginOf<E, C> = <CallOf<E, C> as Dispatchable>::RuntimeOrigin;
192
193#[derive(PartialEq)]
194pub enum ExecutiveError {
195 UnableToDecodeExtrinsic,
196 InvalidInherentPosition(usize),
197 OnlyInherentsAllowed,
198 ApplyExtrinsic(TransactionValidityError),
199 Custom(&'static str),
200}
201
202impl core::fmt::Debug for ExecutiveError {
203 fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
204 match self {
205 ExecutiveError::UnableToDecodeExtrinsic => {
206 write!(fmt, "The extrinsic could not be decoded correctly")
207 }
208 ExecutiveError::InvalidInherentPosition(i) => {
209 write!(fmt, "Invalid inherent position for extrinsic at index {i}",)
210 }
211 ExecutiveError::OnlyInherentsAllowed => {
212 write!(fmt, "Only inherents are allowed in this block")
213 }
214 ExecutiveError::ApplyExtrinsic(e) => write!(
215 fmt,
216 "ExecuteBlockError applying extrinsic: {}",
217 Into::<&'static str>::into(*e)
218 ),
219 ExecutiveError::Custom(err) => write!(fmt, "{err}"),
220 }
221 }
222}
223
224pub struct Executive<
236 System,
237 Block,
238 Context,
239 UnsignedValidator,
240 AllPalletsWithSystem,
241 OnRuntimeUpgrade = (),
242>(
243 PhantomData<(
244 System,
245 Block,
246 Context,
247 UnsignedValidator,
248 AllPalletsWithSystem,
249 OnRuntimeUpgrade,
250 )>,
251);
252
253impl<
254 System: frame_system::Config + IsInherent<Block::Extrinsic>,
255 Block: traits::Block<Header = frame_system::pallet_prelude::HeaderFor<System>, Hash = System::Hash>,
256 Context: Default,
257 UnsignedValidator,
258 AllPalletsWithSystem: OnRuntimeUpgrade
259 + BeforeAllRuntimeMigrations
260 + OnInitialize<BlockNumberFor<System>>
261 + OnIdle<BlockNumberFor<System>>
262 + OnFinalize<BlockNumberFor<System>>
263 + OffchainWorker<BlockNumberFor<System>>
264 + OnPoll<BlockNumberFor<System>>,
265 COnRuntimeUpgrade: OnRuntimeUpgrade,
266> ExecuteBlock<Block>
267 for Executive<
268 System,
269 Block,
270 Context,
271 UnsignedValidator,
272 AllPalletsWithSystem,
273 COnRuntimeUpgrade,
274 >
275where
276 Block::Extrinsic: Checkable<Context> + Codec,
277 CheckedOf<Block::Extrinsic, Context>: Applyable + GetDispatchInfo,
278 CallOf<Block::Extrinsic, Context>:
279 Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
280 OriginOf<Block::Extrinsic, Context>: From<Option<System::AccountId>>,
281 UnsignedValidator: ValidateUnsigned<Call = CallOf<Block::Extrinsic, Context>>,
282{
283 fn verify_and_remove_seal(_: &mut <Block as traits::Block>::LazyBlock) {
284 }
286
287 fn execute_verified_block(block: Block::LazyBlock) {
288 Executive::<
289 System,
290 Block,
291 Context,
292 UnsignedValidator,
293 AllPalletsWithSystem,
294 COnRuntimeUpgrade,
295 >::execute_block(block);
296 }
297}
298
299#[cfg(feature = "try-runtime")]
300impl<
301 System: frame_system::Config + IsInherent<Block::Extrinsic>,
302 Block: traits::Block<Header = frame_system::pallet_prelude::HeaderFor<System>, Hash = System::Hash>,
303 Context: Default,
304 UnsignedValidator,
305 AllPalletsWithSystem: OnRuntimeUpgrade
306 + BeforeAllRuntimeMigrations
307 + OnInitialize<BlockNumberFor<System>>
308 + OnIdle<BlockNumberFor<System>>
309 + OnFinalize<BlockNumberFor<System>>
310 + OffchainWorker<BlockNumberFor<System>>
311 + OnPoll<BlockNumberFor<System>>
312 + TryState<BlockNumberFor<System>>
313 + TryDecodeEntireStorage,
314 COnRuntimeUpgrade: OnRuntimeUpgrade,
315> Executive<System, Block, Context, UnsignedValidator, AllPalletsWithSystem, COnRuntimeUpgrade>
316where
317 Block::Extrinsic: Checkable<Context> + Codec,
318 CheckedOf<Block::Extrinsic, Context>: Applyable + GetDispatchInfo,
319 CallOf<Block::Extrinsic, Context>:
320 Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
321 OriginOf<Block::Extrinsic, Context>: From<Option<System::AccountId>>,
322 UnsignedValidator: ValidateUnsigned<Call = CallOf<Block::Extrinsic, Context>>,
323{
324 pub fn try_execute_block(
333 block: Block,
334 state_root_check: bool,
335 signature_check: bool,
336 select: frame_try_runtime::TryStateSelect,
337 ) -> Result<Weight, ExecutiveError> {
338 log::info!(
339 target: LOG_TARGET,
340 "try-runtime: executing block #{:?} / state root check: {:?} / signature check: {:?} / try-state-select: {:?}",
341 block.header().number(),
342 state_root_check,
343 signature_check,
344 select,
345 );
346
347 let mode = Self::initialize_block(block.header());
348 Self::initial_checks(&block);
349 let (header, extrinsics) = block.deconstruct();
350
351 let signature_check = if signature_check {
353 Block::Extrinsic::check
354 } else {
355 Block::Extrinsic::unchecked_into_checked_i_know_what_i_am_doing
356 };
357 Self::apply_extrinsics(mode, extrinsics.into_iter(), |uxt, is_inherent| {
358 Self::do_apply_extrinsic(uxt, is_inherent, signature_check)
359 })?;
360
361 if !<frame_system::Pallet<System>>::inherents_applied() {
363 Self::inherents_applied();
364 }
365
366 <frame_system::Pallet<System>>::note_finished_extrinsics();
368 <System as frame_system::Config>::PostTransactions::post_transactions();
369
370 Self::on_idle_hook(*header.number());
371 Self::on_finalize_hook(*header.number());
372
373 let _guard = frame_support::StorageNoopGuard::default();
375 <AllPalletsWithSystem as frame_support::traits::TryState<
376 BlockNumberFor<System>,
377 >>::try_state(*header.number(), select.clone())
378 .map_err(|e| {
379 log::error!(target: LOG_TARGET, "failure: {e:?}");
380 ExecutiveError::Custom(e.into())
381 })?;
382 if select.any() {
383 let res = AllPalletsWithSystem::try_decode_entire_state();
384 Self::log_decode_result(res).map_err(|e| ExecutiveError::Custom(e.into()))?;
385 }
386 drop(_guard);
387
388 {
391 let new_header = <frame_system::Pallet<System>>::finalize();
392 let items_zip = header
393 .digest()
394 .logs()
395 .iter()
396 .zip(new_header.digest().logs().iter());
397 for (header_item, computed_item) in items_zip {
398 header_item.check_equal(computed_item);
399 assert!(
400 header_item == computed_item,
401 "Digest item must match that calculated."
402 );
403 }
404
405 if state_root_check {
406 let storage_root = new_header.state_root();
407 header.state_root().check_equal(storage_root);
408 assert!(
409 header.state_root() == storage_root,
410 "Storage root must match that calculated."
411 );
412 }
413
414 assert!(
415 header.extrinsics_root() == new_header.extrinsics_root(),
416 "Transaction trie root must be valid.",
417 );
418 }
419
420 log::info!(
421 target: LOG_TARGET,
422 "try-runtime: Block #{:?} successfully executed",
423 header.number(),
424 );
425
426 Ok(frame_system::Pallet::<System>::block_weight().total())
427 }
428
429 pub fn try_runtime_upgrade(checks: UpgradeCheckSelect) -> Result<Weight, TryRuntimeError> {
437 let before_all_weight =
438 <AllPalletsWithSystem as BeforeAllRuntimeMigrations>::before_all_runtime_migrations();
439 let try_on_runtime_upgrade_weight =
440 <(COnRuntimeUpgrade, AllPalletsWithSystem) as OnRuntimeUpgrade>::try_on_runtime_upgrade(
441 checks.pre_and_post(),
442 )?;
443
444 frame_system::LastRuntimeUpgrade::<System>::put(
445 frame_system::LastRuntimeUpgradeInfo::from(
446 <System::Version as frame_support::traits::Get<_>>::get(),
447 ),
448 );
449
450 let _guard = StorageNoopGuard::default();
452
453 if checks.any() {
455 let res = AllPalletsWithSystem::try_decode_entire_state();
456 Self::log_decode_result(res)?;
457 }
458
459 if checks.try_state() {
461 AllPalletsWithSystem::try_state(
462 frame_system::Pallet::<System>::block_number(),
463 TryStateSelect::All,
464 )?;
465 }
466
467 Ok(before_all_weight.saturating_add(try_on_runtime_upgrade_weight))
468 }
469
470 fn log_decode_result(
472 res: Result<usize, alloc::vec::Vec<TryDecodeEntireStorageError>>,
473 ) -> Result<(), TryRuntimeError> {
474 match res {
475 Ok(bytes) => {
476 log::info!(
477 target: LOG_TARGET,
478 "✅ Entire runtime state decodes without error. {bytes} bytes total.",
479 );
480
481 Ok(())
482 }
483 Err(errors) => {
484 log::error!(
485 target: LOG_TARGET,
486 "`try_decode_entire_state` failed with {} errors",
487 errors.len(),
488 );
489
490 for (i, err) in errors.iter().enumerate() {
491 log::error!(target: LOG_TARGET, "- {i}. error: {err}");
493 log::debug!(target: LOG_TARGET, "- {i}. error: {err:?}");
494 }
495
496 Err("`try_decode_entire_state` failed".into())
497 }
498 }
499 }
500}
501
502impl<
503 System: frame_system::Config + IsInherent<Block::Extrinsic>,
504 Block: traits::Block<Header = frame_system::pallet_prelude::HeaderFor<System>, Hash = System::Hash>,
505 Context: Default,
506 UnsignedValidator,
507 AllPalletsWithSystem: OnRuntimeUpgrade
508 + BeforeAllRuntimeMigrations
509 + OnInitialize<BlockNumberFor<System>>
510 + OnIdle<BlockNumberFor<System>>
511 + OnFinalize<BlockNumberFor<System>>
512 + OffchainWorker<BlockNumberFor<System>>
513 + OnPoll<BlockNumberFor<System>>,
514 COnRuntimeUpgrade: OnRuntimeUpgrade,
515> Executive<System, Block, Context, UnsignedValidator, AllPalletsWithSystem, COnRuntimeUpgrade>
516where
517 Block::Extrinsic: Checkable<Context> + Codec,
518 CheckedOf<Block::Extrinsic, Context>: Applyable + GetDispatchInfo,
519 CallOf<Block::Extrinsic, Context>:
520 Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
521 OriginOf<Block::Extrinsic, Context>: From<Option<System::AccountId>>,
522 UnsignedValidator: ValidateUnsigned<Call = CallOf<Block::Extrinsic, Context>>,
523{
524 pub fn execute_on_runtime_upgrade() -> Weight {
526 let before_all_weight =
527 <AllPalletsWithSystem as BeforeAllRuntimeMigrations>::before_all_runtime_migrations();
528
529 let runtime_upgrade_weight = <(
530 COnRuntimeUpgrade,
531 <System as frame_system::Config>::SingleBlockMigrations,
532 AllPalletsWithSystem,
535 ) as OnRuntimeUpgrade>::on_runtime_upgrade();
536
537 before_all_weight.saturating_add(runtime_upgrade_weight)
538 }
539
540 pub fn initialize_block(
542 header: &frame_system::pallet_prelude::HeaderFor<System>,
543 ) -> ExtrinsicInclusionMode {
544 sp_io::init_tracing();
545 sp_tracing::enter_span!(sp_tracing::Level::TRACE, "init_block");
546 let digests = Self::extract_pre_digest(header);
547 Self::initialize_block_impl(header.number(), header.parent_hash(), &digests);
548
549 Self::extrinsic_mode()
550 }
551
552 fn extrinsic_mode() -> ExtrinsicInclusionMode {
553 if <System as frame_system::Config>::MultiBlockMigrator::ongoing() {
554 ExtrinsicInclusionMode::OnlyInherents
555 } else {
556 ExtrinsicInclusionMode::AllExtrinsics
557 }
558 }
559
560 fn extract_pre_digest(header: &frame_system::pallet_prelude::HeaderFor<System>) -> Digest {
561 let mut digest = <Digest>::default();
562 header.digest().logs().iter().for_each(|d| {
563 if d.as_pre_runtime().is_some() {
564 digest.push(d.clone())
565 }
566 });
567 digest
568 }
569
570 fn initialize_block_impl(
571 block_number: &BlockNumberFor<System>,
572 parent_hash: &System::Hash,
573 digest: &Digest,
574 ) {
575 <frame_system::Pallet<System>>::reset_events();
579
580 let mut weight = Weight::zero();
581 if Self::runtime_upgraded() {
582 weight = weight.saturating_add(Self::execute_on_runtime_upgrade());
583
584 frame_system::LastRuntimeUpgrade::<System>::put(
585 frame_system::LastRuntimeUpgradeInfo::from(
586 <System::Version as frame_support::traits::Get<_>>::get(),
587 ),
588 );
589 }
590 <frame_system::Pallet<System>>::initialize(block_number, parent_hash, digest);
591 weight = weight.saturating_add(<AllPalletsWithSystem as OnInitialize<
592 BlockNumberFor<System>,
593 >>::on_initialize(*block_number));
594 weight = weight.saturating_add(
595 <System::BlockWeights as frame_support::traits::Get<_>>::get().base_block,
596 );
597 <frame_system::Pallet<System>>::register_extra_weight_unchecked(
598 weight,
599 DispatchClass::Mandatory,
600 );
601
602 frame_system::Pallet::<System>::note_finished_initialize();
603 <System as frame_system::Config>::PreInherents::pre_inherents();
604 }
605
606 fn runtime_upgraded() -> bool {
608 let last = frame_system::LastRuntimeUpgrade::<System>::get();
609 let current = <System::Version as frame_support::traits::Get<_>>::get();
610
611 last.map(|v| v.was_upgraded(¤t)).unwrap_or(true)
612 }
613
614 fn initial_checks(header: &Block::Header) {
615 sp_tracing::enter_span!(sp_tracing::Level::TRACE, "initial_checks");
616
617 let n = *header.number();
619 assert!(
620 n > BlockNumberFor::<System>::zero()
621 && <frame_system::Pallet<System>>::block_hash(n - BlockNumberFor::<System>::one())
622 == *header.parent_hash(),
623 "Parent hash should be valid.",
624 );
625 }
626
627 pub fn execute_block(block: Block::LazyBlock) {
629 Self::execute_block_inner(block, true)
630 }
631
632 pub fn execute_block_without_state_root_check(block: Block::LazyBlock) {
633 Self::execute_block_inner(block, false)
634 }
635
636 fn execute_block_inner(block: Block::LazyBlock, state_root_check: bool) {
637 sp_io::init_tracing();
638 sp_tracing::within_span! {
639 sp_tracing::info_span!("execute_block", ?block);
640 let mode = Self::initialize_block(block.header());
642 Self::initial_checks(block.header());
643
644 let extrinsics = block.extrinsics();
645 if let Err(e) = Self::apply_extrinsics(
646 mode,
647 extrinsics,
648 |uxt, is_inherent| {
649 Self::do_apply_extrinsic(uxt, is_inherent, Block::Extrinsic::check)
650 }
651 ) {
652 panic!("{e:?}")
653 }
654
655 if !<frame_system::Pallet<System>>::inherents_applied() {
657 Self::inherents_applied();
658 }
659
660 <frame_system::Pallet<System>>::note_finished_extrinsics();
661 <System as frame_system::Config>::PostTransactions::post_transactions();
662
663 let header = block.header();
664 Self::on_idle_hook(*header.number());
665 Self::on_finalize_hook(*header.number());
666 Self::final_checks(header, state_root_check, true);
667 }
668 }
669
670 pub fn inherents_applied() {
674 <frame_system::Pallet<System>>::note_inherents_applied();
675 <System as frame_system::Config>::PostInherents::post_inherents();
676
677 if <System as frame_system::Config>::MultiBlockMigrator::ongoing() {
678 let used_weight = <System as frame_system::Config>::MultiBlockMigrator::step();
679 <frame_system::Pallet<System>>::register_extra_weight_unchecked(
680 used_weight,
681 DispatchClass::Mandatory,
682 );
683 } else {
684 let block_number = <frame_system::Pallet<System>>::block_number();
685 Self::on_poll_hook(block_number);
686 }
687 }
688
689 fn apply_extrinsics(
691 mode: ExtrinsicInclusionMode,
692 extrinsics: impl Iterator<Item = Result<Block::Extrinsic, codec::Error>>,
693 mut apply_extrinsic: impl FnMut(Block::Extrinsic, bool) -> ApplyExtrinsicResult,
694 ) -> Result<(), ExecutiveError> {
695 let mut first_non_inherent_idx = 0;
696 for (idx, maybe_uxt) in extrinsics.into_iter().enumerate() {
697 let uxt = maybe_uxt.map_err(|_| ExecutiveError::UnableToDecodeExtrinsic)?;
698 let is_inherent = System::is_inherent(&uxt);
699 if is_inherent {
700 if first_non_inherent_idx != idx {
702 return Err(ExecutiveError::InvalidInherentPosition(idx));
703 }
704 first_non_inherent_idx += 1;
705 } else {
706 if mode == ExtrinsicInclusionMode::OnlyInherents {
708 return Err(ExecutiveError::OnlyInherentsAllowed);
709 }
710 }
711
712 log::debug!(target: LOG_TARGET, "Executing transaction: {uxt:?}");
713 if let Err(e) = apply_extrinsic(uxt, is_inherent) {
714 log::error!(
715 target: LOG_TARGET,
716 "Transaction({idx}) failed due to {e:?}. \
717 Aborting the rest of the block execution.",
718 );
719 return Err(ExecutiveError::ApplyExtrinsic(e));
720 }
721 }
722
723 Ok(())
724 }
725
726 pub fn finalize_block() -> frame_system::pallet_prelude::HeaderFor<System> {
730 sp_io::init_tracing();
731 sp_tracing::enter_span!(sp_tracing::Level::TRACE, "finalize_block");
732
733 if !<frame_system::Pallet<System>>::inherents_applied() {
735 Self::inherents_applied();
736 }
737
738 <frame_system::Pallet<System>>::note_finished_extrinsics();
739 <System as frame_system::Config>::PostTransactions::post_transactions();
740 let block_number = <frame_system::Pallet<System>>::block_number();
741 Self::on_idle_hook(block_number);
742 Self::on_finalize_hook(block_number);
743 <frame_system::Pallet<System>>::finalize()
744 }
745
746 pub fn finalize_block_without_checks(header: frame_system::pallet_prelude::HeaderFor<System>) {
747 sp_io::init_tracing();
748 sp_tracing::enter_span!(sp_tracing::Level::TRACE, "finalize_block_without_checks");
749
750 if !<frame_system::Pallet<System>>::inherents_applied() {
752 Self::inherents_applied();
753 }
754
755 <frame_system::Pallet<System>>::note_finished_extrinsics();
756
757 Self::on_finalize_hook(*header.number());
758 Self::final_checks(&header, false, false);
759 }
760
761 fn on_idle_hook(block_number: NumberFor<Block>) {
764 if <System as frame_system::Config>::MultiBlockMigrator::ongoing() {
765 return;
766 }
767
768 let weight = <frame_system::Pallet<System>>::block_weight();
769 let max_weight = <System::BlockWeights as frame_support::traits::Get<_>>::get().max_block;
770 let remaining_weight = max_weight.saturating_sub(weight.total());
771
772 if remaining_weight.all_gt(Weight::zero()) {
773 let used_weight = <AllPalletsWithSystem as OnIdle<BlockNumberFor<System>>>::on_idle(
774 block_number,
775 remaining_weight,
776 );
777 <frame_system::Pallet<System>>::register_extra_weight_unchecked(
778 used_weight,
779 DispatchClass::Mandatory,
780 );
781 }
782 }
783
784 fn on_poll_hook(block_number: NumberFor<Block>) {
785 defensive_assert!(
786 !<System as frame_system::Config>::MultiBlockMigrator::ongoing(),
787 "on_poll should not be called during migrations"
788 );
789
790 let weight = <frame_system::Pallet<System>>::block_weight();
791 let max_weight = <System::BlockWeights as frame_support::traits::Get<_>>::get().max_block;
792 let remaining = max_weight.saturating_sub(weight.total());
793
794 if remaining.all_gt(Weight::zero()) {
795 let mut meter = WeightMeter::with_limit(remaining);
796 <AllPalletsWithSystem as OnPoll<BlockNumberFor<System>>>::on_poll(
797 block_number,
798 &mut meter,
799 );
800 <frame_system::Pallet<System>>::register_extra_weight_unchecked(
801 meter.consumed(),
802 DispatchClass::Mandatory,
803 );
804 }
805 }
806
807 fn on_finalize_hook(block_number: NumberFor<Block>) {
809 <AllPalletsWithSystem as OnFinalize<BlockNumberFor<System>>>::on_finalize(block_number);
810 }
811
812 fn do_apply_extrinsic(
817 uxt: Block::Extrinsic,
818 is_inherent: bool,
819 check: impl FnOnce(
820 Block::Extrinsic,
821 &Context,
822 )
823 -> Result<CheckedOf<Block::Extrinsic, Context>, TransactionValidityError>,
824 ) -> ApplyExtrinsicResult {
825 sp_io::init_tracing();
826 let encoded = uxt.encode();
827 let encoded_len = encoded.len();
828 sp_tracing::enter_span!(sp_tracing::info_span!("apply_extrinsic",
829 ext=?sp_core::hexdisplay::HexDisplay::from(&encoded)));
830
831 let uxt = <Block::Extrinsic as codec::DecodeLimit>::decode_all_with_depth_limit(
832 MAX_EXTRINSIC_DEPTH,
833 &mut &encoded[..],
834 )
835 .map_err(|_| InvalidTransaction::Call)?;
836
837 let xt = check(uxt, &Context::default())?;
839
840 let dispatch_info = xt.get_dispatch_info();
841
842 if !is_inherent && !<frame_system::Pallet<System>>::inherents_applied() {
843 Self::inherents_applied();
844 }
845
846 <frame_system::Pallet<System>>::note_extrinsic(encoded);
850
851 let r = Applyable::apply::<UnsignedValidator>(xt, &dispatch_info, encoded_len)?;
854
855 if r.is_err() && dispatch_info.class == DispatchClass::Mandatory {
860 return Err(InvalidTransaction::BadMandatory.into());
861 }
862
863 <frame_system::Pallet<System>>::note_applied_extrinsic(&r, dispatch_info);
864
865 Ok(r.map(|_| ()).map_err(|e| e.error))
866 }
867
868 pub fn apply_extrinsic(uxt: Block::Extrinsic) -> ApplyExtrinsicResult {
873 let is_inherent = System::is_inherent(&uxt);
874 Self::do_apply_extrinsic(uxt, is_inherent, Block::Extrinsic::check)
875 }
876
877 fn final_checks(
878 header: &frame_system::pallet_prelude::HeaderFor<System>,
879 check_state_root: bool,
880 check_extrinsics_root: bool,
881 ) {
882 sp_tracing::enter_span!(sp_tracing::Level::TRACE, "final_checks");
883 let new_header = <frame_system::Pallet<System>>::finalize();
885
886 assert_eq!(
888 header.digest().logs().len(),
889 new_header.digest().logs().len(),
890 "Number of digest items must match that calculated."
891 );
892 let items_zip = header
893 .digest()
894 .logs()
895 .iter()
896 .zip(new_header.digest().logs().iter());
897 for (header_item, computed_item) in items_zip {
898 header_item.check_equal(computed_item);
899 assert!(
900 header_item == computed_item,
901 "Digest item must match that calculated."
902 );
903 }
904
905 if check_state_root {
906 let storage_root = new_header.state_root();
908 header.state_root().check_equal(storage_root);
909 assert!(
910 header.state_root() == storage_root,
911 "Storage root must match that calculated."
912 );
913 }
914
915 if check_extrinsics_root {
916 assert!(
917 header.extrinsics_root() == new_header.extrinsics_root(),
918 "Transaction trie root must be valid.",
919 );
920 }
921 }
922
923 pub fn validate_transaction(
929 source: TransactionSource,
930 uxt: Block::Extrinsic,
931 block_hash: Block::Hash,
932 ) -> TransactionValidity {
933 sp_io::init_tracing();
934 use sp_tracing::{enter_span, within_span};
935
936 <frame_system::Pallet<System>>::initialize(
937 &(frame_system::Pallet::<System>::block_number() + One::one()),
938 &block_hash,
939 &Default::default(),
940 );
941
942 enter_span! { sp_tracing::Level::TRACE, "validate_transaction" };
943
944 let encoded = within_span! { sp_tracing::Level::TRACE, "using_encoded";
945 uxt.encode()
946 };
947
948 let uxt = <Block::Extrinsic as codec::DecodeLimit>::decode_all_with_depth_limit(
949 MAX_EXTRINSIC_DEPTH,
950 &mut &encoded[..],
951 )
952 .map_err(|_| InvalidTransaction::Call)?;
953
954 let xt = within_span! { sp_tracing::Level::TRACE, "check";
955 uxt.check(&Default::default())
956 }?;
957
958 let dispatch_info = within_span! { sp_tracing::Level::TRACE, "dispatch_info";
959 xt.get_dispatch_info()
960 };
961
962 if dispatch_info.class == DispatchClass::Mandatory {
963 return Err(InvalidTransaction::MandatoryValidation.into());
964 }
965
966 within_span! {
967 sp_tracing::Level::TRACE, "validate";
968 xt.validate::<UnsignedValidator>(source, &dispatch_info, encoded.len())
969 }
970 }
971
972 pub fn offchain_worker(header: &frame_system::pallet_prelude::HeaderFor<System>) {
974 sp_io::init_tracing();
975 let digests = header.digest().clone();
979
980 <frame_system::Pallet<System>>::initialize(header.number(), header.parent_hash(), &digests);
981
982 frame_system::BlockHash::<System>::insert(header.number(), header.hash());
986
987 <AllPalletsWithSystem as OffchainWorker<BlockNumberFor<System>>>::offchain_worker(
988 *header.number(),
989 )
990 }
991}