Skip to content

FRAME: Register on_initialize after each pallet#9756

Merged
bkchr merged 11 commits intomasterfrom
bkchr-weight-on-initialize-direct-accounting
Sep 23, 2025
Merged

FRAME: Register on_initialize after each pallet#9756
bkchr merged 11 commits intomasterfrom
bkchr-weight-on-initialize-direct-accounting

Conversation

@bkchr
Copy link
Member

@bkchr bkchr commented Sep 17, 2025

Before this pull request, FRAME was executing all pallets on_initialize and then register the weight, including the weight of on_runtime_upgrade. Thus, other pallets were not aware on how much weight was already used when they were executing their on_initialize code. As some pallets are doing some work in on_initialize, they need to be aware of how much weight is still left.
To register the weight after each on_initialize call, a new trait is added. This new trait is implemented for tuples of types that implement OnInitialize and then it registers the weight after each call to on_initialize.

pallet-scheduler is changed to take the remaining weight into account and to not just assume that its configured weight is always available.

@bkchr bkchr requested a review from a team as a code owner September 17, 2025 07:39
@bkchr bkchr added the T1-FRAME This PR/Issue is related to core FRAME, the framework. label Sep 17, 2025
@kianenigma
Copy link
Contributor

A few comments/questions:

  • what is the motivation behind this?
  • This API is overall much better, and in-line with on_poll, which was added later and has access to an ongoing weight meter.
  • That being said, I think the ultimate solution is that all parachains (incl. AH) should use on_poll, including our own pallets (minus the scheduler perhaps)

Part of our worries in #9619 also related to this. On AH, a single block might might:

  • Have a lot of inherents
  • scheduler on-onit
  • message-queue on-init
  • staking election on-init

And all of this is Mandatory, and can cause the chain to stall. Our solution for this was to move the staking part to on_poll, as it can safely happen with gaps, if weight is not available.

@sigurpol
Copy link
Contributor

A few comments/questions:

* That being said, I think the ultimate solution is that all parachains (incl. AH) should use `on_poll`, including our own pallets (minus the scheduler perhaps)

Part of our worries in #9619 also related to this. On AH, a single block might might:

* Have a lot of inherents

* scheduler on-onit

* message-queue on-init

* staking election on-init

And all of this is Mandatory, and can cause the chain to stall. Our solution for this was to move the staking part to on_poll, as it can safely happen with gaps, if weight is not available.

from the discussion we had on Element, my take-aways are the following:

  • on_poll is indeed still the way to go for us in staking-async (and not only for us)
  • the current PR should help / make easier to improve stuff in the short term until we move what we can to on_poll

@bkchr
Copy link
Member Author

bkchr commented Sep 17, 2025

  • what is the motivation behind this?

The 500ms blocks, where I'm afraid someone will do something bad :) And overall I think it is just better to have there a correct weight tracking. For sure it is not perfect, but still better than the status quo.

  • That being said, I think the ultimate solution is that all parachains (incl. AH) should use on_poll, including our own pallets (minus the scheduler perhaps)

Yes on_poll is the future. I'm totally in line with this. Scheduler should actually go to tasks, because this is actually much better for the use case.

  • Have a lot of inherents

  • scheduler on-onit

  • message-queue on-init

  • staking election on-init

Inherents, scheduler on-init, message-queue etc all should honor the weight much better and should be more tightly controlled when it comes to this.

@bkchr bkchr requested a review from gui1117 September 17, 2025 13:23
Copy link
Contributor

@gui1117 gui1117 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the trait doesn't need the generic BlockNumber otherwise looks good to me

frame_support::impl_for_tuples_attr! {
#[tuple_types_custom_trait_bound(OnInitialize<BlockNumber>)]
impl<BlockNumber: Clone, T: frame_system::Config> OnInitializeWithWeightRegistration<T, BlockNumber> for Tuple {
fn on_initialize_with_weight_registration(n: BlockNumber) -> Weight {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fortunately we define all pallets as a single tuple like: type AllPallet = (System, Balances, Assets); and not type AllPallet = (System, (Balances, Assets));. Otherwise this will not help.

But we have to be careful not to change this, maybe we can have a test specifically written for this.

(We could also generate OnInitializeWithWeightRegistration with the macro pallet, and make this trait implemented for tuple of OnInitializeWithWeightRegistration.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fortunately we define all pallets as a single tuple like: type AllPallet = (System, Balances, Assets); and not type AllPallet = (System, (Balances, Assets));. Otherwise this will not help.

Yeah I know. I also checked this.

But we have to be careful not to change this, maybe we can have a test specifically written for this.

I first thought about writing a integrity_test, but this is right now not supported by Executive.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the worst case we have some pallets that don't register the weight immediately.

Copy link
Contributor

@gui1117 gui1117 Sep 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I first thought about writing a integrity_test, but this is right now not supported by Executive.

yes, I was a thinking a test that ensure construct_runtime defines AllPallets as we expect, with 2 defined pallet that ensure the weight is updated inside each on_initialize. The test you wrote in scheduler already tests for it also. So in all case it is good to me

@kianenigma
Copy link
Contributor

Would you be willing to backport this to 2507 and 2509? Not sure if it has added risk for us.

If yes, we can use this in EPMB and no migrate it to poll yet. The change would be simpler there if so.

@bkchr
Copy link
Member Author

bkchr commented Sep 19, 2025

@kianenigma if you approve, I can backport it. :P

@paritytech-workflow-stopper
Copy link

All GitHub workflows were cancelled due to failure one of the required jobs.
Failed workflow url: https://github.com/paritytech/polkadot-sdk/actions/runs/17856405890
Failed job name: cargo-clippy

@bkchr
Copy link
Member Author

bkchr commented Sep 19, 2025

/cmd prdoc --audience runtime_dev --bump patch

@bkchr bkchr added this pull request to the merge queue Sep 23, 2025
@sigurpol
Copy link
Contributor

@bkchr , @kianenigma, @ggwpez : how confident are we in backporting to 2509 for the early October deployment on Westend? Additionally, how do we feel about using 2507 in the post-KAHM and pre- or post-PAHM phases with EPMB using it?

@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Sep 23, 2025
@kianenigma
Copy link
Contributor

This seems pretty innocent to me, I think we can safely backport.

But lemme see if it is will be useful for EPMB, will let you know. If I can migrate to poll already, it will be easier and done once and for all.

@kianenigma
Copy link
Contributor

(this PR is basically making on-init able to 👺 as poll)

@bkchr bkchr added this pull request to the merge queue Sep 23, 2025
@bkchr
Copy link
Member Author

bkchr commented Sep 23, 2025

I'm also fine with backporting. It doesn't change that much.

Merged via the queue into master with commit 19320f1 Sep 23, 2025
246 of 248 checks passed
@bkchr bkchr deleted the bkchr-weight-on-initialize-direct-accounting branch September 23, 2025 18:01
@bkchr bkchr added A4-backport-unstable2507 Pull request must be backported to the unstable2507 release branch A4-backport-stable2509 Pull request must be backported to the stable2509 release branch labels Sep 24, 2025
@paritytech-release-backport-bot

Created backport PR for unstable2507:

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin backport-9756-to-unstable2507
git worktree add --checkout .worktree/backport-9756-to-unstable2507 backport-9756-to-unstable2507
cd .worktree/backport-9756-to-unstable2507
git reset --hard HEAD^
git cherry-pick -x 19320f104fc4b5cb6663cffc41f340b6b5239be8
git push --force-with-lease

@paritytech-release-backport-bot

Created backport PR for stable2509:

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin backport-9756-to-stable2509
git worktree add --checkout .worktree/backport-9756-to-stable2509 backport-9756-to-stable2509
cd .worktree/backport-9756-to-stable2509
git reset --hard HEAD^
git cherry-pick -x 19320f104fc4b5cb6663cffc41f340b6b5239be8
git push --force-with-lease

@bkchr
Copy link
Member Author

bkchr commented Sep 24, 2025

@sigurpol the backports are prepared.

EgorPopelyaev pushed a commit that referenced this pull request Sep 24, 2025
Backport #9756 into `stable2509` from bkchr.

See the
[documentation](https://github.com/paritytech/polkadot-sdk/blob/master/docs/BACKPORT.md)
on how to use this bot.

<!--
  # To be used by other automation, do not modify:
  original-pr-number: #${pull_number}
-->

---------

Co-authored-by: Bastian Köcher <git@kchr.de>
Co-authored-by: Bastian Köcher <info@kchr.de>
alvicsam pushed a commit that referenced this pull request Oct 17, 2025
Before this pull request, FRAME was executing all pallets
`on_initialize` and then register the weight, including the weight of
`on_runtime_upgrade`. Thus, other pallets were not aware on how much
weight was already used when they were executing their `on_initialize`
code. As some pallets are doing some work in `on_initialize`, they need
to be aware of how much weight is still left.
To register the weight after each `on_initialize` call, a new trait is
added. This new trait is implemented for tuples of types that implement
`OnInitialize` and then it registers the weight after each call to
`on_initialize`.

`pallet-scheduler` is changed to take the remaining weight into account
and to not just assume that its configured weight is always available.

---------

Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A4-backport-stable2509 Pull request must be backported to the stable2509 release branch A4-backport-unstable2507 Pull request must be backported to the unstable2507 release branch T1-FRAME This PR/Issue is related to core FRAME, the framework.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants