referrerpolicy=no-referrer-when-downgrade

cumulus_pallet_parachain_system/block_weight/
pre_inherents_hook.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Cumulus.
3// SPDX-License-Identifier: Apache-2.0
4
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// 	http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17use super::{
18	block_weight_over_target_block_weight, is_first_block_in_core, BlockWeightMode, LOG_TARGET,
19};
20use crate::block_weight::FULL_CORE_WEIGHT;
21use cumulus_primitives_core::CumulusDigestItem;
22use frame_support::{migrations::MultiStepMigrator, traits::PreInherents};
23use sp_core::Get;
24
25/// A pre-inherent hook that may increases max block weight after `on_initialize`.
26///
27/// The hook is called before applying the first inherent. It checks the used block weight of
28/// `on_initialize`. If the used block weight is above the target block weight, the hook will set
29/// the [`CumulusDigestItem::UseFullCore`] digest. Regardless on if this is the first block in a
30/// core or not. This is done to inform the node that this is the last block for the current core.
31pub struct DynamicMaxBlockWeightHooks<Config, TargetBlockRate>(
32	pub core::marker::PhantomData<(Config, TargetBlockRate)>,
33);
34
35impl<Config, TargetBlockRate> PreInherents for DynamicMaxBlockWeightHooks<Config, TargetBlockRate>
36where
37	Config: crate::Config,
38	TargetBlockRate: Get<u32>,
39{
40	fn pre_inherents() {
41		if !block_weight_over_target_block_weight::<Config, TargetBlockRate>() {
42			let new_mode = if Config::MultiBlockMigrator::ongoing() {
43				log::debug!(
44					target: LOG_TARGET,
45					"Multi block migrations are still ongoing, allowing the full core.",
46				);
47
48				// Inform the node that this block uses the full core.
49				frame_system::Pallet::<Config>::deposit_log(
50					CumulusDigestItem::UseFullCore.to_digest_item(),
51				);
52
53				BlockWeightMode::<Config>::full_core()
54			} else {
55				BlockWeightMode::<Config>::fraction_of_core(None)
56			};
57
58			crate::BlockWeightMode::<Config>::put(new_mode);
59
60			return;
61		}
62
63		let is_first_block_in_core = is_first_block_in_core::<Config>().unwrap_or(false);
64
65		if !is_first_block_in_core {
66			log::error!(
67				target: LOG_TARGET,
68				"Block initialization logic took longer than the target block weight, THIS IS A BUG!!!",
69			);
70
71			// We are already above the allowed maximum and do not want to accept any more
72			// extrinsics.
73			frame_system::Pallet::<Config>::register_extra_weight_unchecked(
74				FULL_CORE_WEIGHT,
75				frame_support::dispatch::DispatchClass::Mandatory,
76			);
77		} else {
78			log::debug!(
79				target: LOG_TARGET,
80				"Block initialization logic took longer than the target block weight, going to use the full core",
81			);
82		}
83
84		crate::BlockWeightMode::<Config>::put(BlockWeightMode::<Config>::full_core());
85
86		// Inform the node that this block uses the full core.
87		frame_system::Pallet::<Config>::deposit_log(
88			CumulusDigestItem::UseFullCore.to_digest_item(),
89		);
90	}
91}