3

I'm writing a hook that will pop Calls out of storage and dispatch them. I want to dispatch as many of those calls as possible in the limits of max_block.
My approach was to store the cumulated weight of thoses calls in a variable, and check before each new dispatch that cumulated_weight + next_call.get_dispatch_info().weight < max_block. This way I make sure that even in the worst case scenario, dispatching this call won't lead to an excess of weigh in the block.

My question is:
Should I use cumulated_weight + next_call.get_dispatch_info().weight < max_block - base_block instead ? It's not clear in the documentation if max_block exist on top of base_block or if base_block is to take into account as consuming part of max_block.

1
  • I think max_block only refers to weights of non-reserve extrinsics and base_block refers to the base weight. And I think the closeness of the names is confusing. Probably the max_block should be named max_extrinsics_weight. So I think you are right base_weight is not included. Commented Jun 11, 2022 at 20:47

1 Answer 1

2

on_initialize has the advantage of being in the Mandatory dispatch class.
It can consume an unlimited amount of weight; even stall the chain if necessary.
This is what often happens for large runtime migrations that do not fit in one block.

In your case you want to stay within max_block as not to stall the chain.
Good examples for this are the scheduler and state-trie-migration pallets.
The scheduler has a pallet constant to configure a limit. Currently set to 80% of max_block:

pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) *
        BlockWeights::get().max_block;

To analyze what is a good value here, you can directly look at the BlockWeights of your runtime. Just print it in a test. For Polkadot this print:

base_block: 53_99_176_000
max_block: 2_000_000_000_000

per_class:
    normal:
        base_extrinsic: 85_212_000
        max_extrinsic: Some(1_479_914_788_000)
        max_total: Some(1_500_000_000_000)
        reserved: Some(0)

    operational:
        base_extrinsic: 85_212_000
        max_extrinsic: Some(1_979_914_788_000)
        max_total: Some(2_000_000_000_000)
        reserved: Some(500_000_000_000)

    mandatory:
        base_extrinsic: 85_212_000
        max_extrinsic: None
        max_total: None
        reserved: None

Personally I am not sure if it makes sense to aim for a perfect value here, since you either:

  1. Want to get it done ASAP: don't track the weight and just stall the chain. This may or may not be a good idea depending on your needs.
  2. Have a preemptable task: Pick some limit like 80% and leave some room for other important extrinsics.

Hopefully this answers your question. For completeness I will still try to find out what the theoretical maximum value would be and update this answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.