referrerpolicy=no-referrer-when-downgrade

Module block_weight

Module block_weight 

Source
Expand description

Provides functionality to dynamically calculate the block weight for a parachain.

With block bundling, parachains are relatively free to choose whatever block interval they want. The block interval is the time between individual blocks. The available resources per block (max block weight) depend on the number of cores allocated to the parachain on the relay chain. Each relay chain cores provides an execution time of 2s and a storage size of 10MiB. Depending on the desired number of blocks to produce, the resources need to be divided between the individual blocks. With small blocks that do not have that many resources available, a problem may arises for bigger transactions not fitting into blocks anymore, e.g. a runtime upgrade. For these cases the weight of a block can be increased to use the weight of a full core. Only the first block of a core is allowed to increase its weight to use the full core weight. In the case of the first block using the full core weight, there will be no further block build on the same core. This is signaled to the node by setting the [CumulusDigestItem::UseFullCore] digest item.`

The MaxParachainBlockWeight provides a [Get] implementation that will return the max block weight as determined by the DynamicMaxBlockWeight transaction extension.

DynamicMaxBlockWeightHooks needs to be registered as a pre-inherent hook. It is used to handle the weight consumption of on_initialize and change the block weight mode based on the consumed weight.

§Setup

Setup the transaction extension:

pub type TxExtension = DynamicMaxBlockWeight<
	Runtime,
	// Here you need to set the other extensions that are required by your runtime...
	(
		frame_system::AuthorizeCall<Runtime>,
		frame_system::CheckNonZeroSender<Runtime>,
		frame_system::CheckSpecVersion<Runtime>,
		frame_system::CheckGenesis<Runtime>,
		frame_system::CheckEra<Runtime>,
		frame_system::CheckNonce<Runtime>,
		frame_system::CheckWeight<Runtime>,
	),
	ConstU32<TARGET_BLOCK_RATE>,
>;

Setting up MaximumBlockWeight:

use super::*;

type MaximumBlockWeight = MaxParachainBlockWeight<Runtime, ConstU32<TARGET_BLOCK_RATE>>;

parameter_types! {
	pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
		.base_block(BlockExecutionWeight::get())
		.for_class(DispatchClass::all(), |weights| {
			weights.base_extrinsic = ExtrinsicBaseWeight::get();
		})
		.for_class(DispatchClass::Normal, |weights| {
			weights.max_total = Some(MaximumBlockWeight::get() * NORMAL_DISPATCH_RATIO);
		})
		.for_class(DispatchClass::Operational, |weights| {
			weights.max_total = Some(MaximumBlockWeight::get());
		})
		.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
		.build_or_panic();
}

Registering of the PreInherents hook:

#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
impl frame_system::Config for Runtime {
	// Setup the block weight.
	type BlockWeights = max_block_weight_setup::RuntimeBlockWeights;
	// Set the `PreInherents` hook.
	type PreInherents = DynamicMaxBlockWeightHooks<Self, ConstU32<TARGET_BLOCK_RATE>>;

	// Just required to make it compile, but not that important for this example here.
	type Block = Block;
	type OnSetCode = crate::ParachainSetCode<Self>;
	type AccountId = u64;
	type Lookup = UintAuthorityId;
	// Rest of the types are omitted here.
}

§Weight per context

Depending on the context, MaxParachainBlockWeight may return a different max weight. The max weight is only allowed to change in the first block of a core. Otherwise, all blocks need to follow the target block weight determined based on the number of cores and the target block rate. In the case of a first block, the following contexts may allow to access the full core weight:

  • on_initialize: All logic that runs in this context up to the execution of inherents will get access to the full core weight.
  • inherents: Inherents also have access to the full core weight.
  • on_poll: Only gets access to the target block weight.
  • transactions: May get access to the full core weight, depends if they enable the access to the full core weight based on the logic of DynamicMaxBlockWeight.
  • on_finalize/on_idle: Only gets access to the target block weight.

If any context that allows to use the full core weight, pushes the used block weight above the target block weight, all other contexts will get access to the full core weight.

Re-exports§

pub use pre_inherents_hook::DynamicMaxBlockWeightHooks;
pub use transaction_extension::DynamicMaxBlockWeight;

Modules§

pre_inherents_hook
transaction_extension

Structs§

MaxParachainBlockWeight
Calculates the maximum block weight for a parachain.

Enums§

BlockWeightMode
The current block weight mode.