Skip to content

Referenda benchmarks#2626

Merged
l0r1s merged 16 commits into
governancefrom
referenda-benchmarks
May 4, 2026
Merged

Referenda benchmarks#2626
l0r1s merged 16 commits into
governancefrom
referenda-benchmarks

Conversation

@l0r1s

@l0r1s l0r1s commented Apr 29, 2026

Copy link
Copy Markdown
Collaborator

Referenda & multi-collective: split hook traits and add benchmarks

Summary

Adds proper benchmarks to pallet-referenda and pallet-multi-collective,
and reshapes the cross-pallet hook surface (poll hooks, members hook) so
each notification carries its own weight bound. Both pallets' extrinsics
are now weighted from real benchmarks instead of dev_mode's zero
defaults.

Motivation

Both pallet-referenda and pallet-multi-collective were running with
dev_mode enabled, silently zero-weighting every extrinsic. Several of
their extrinsics fan out into hooks living in other pallets (the voting
backend, the vote-cleanup hook), so even benchmarking each pallet's own
logic isn't enough — the static charge needs to include each hook's
worst case too. To weight them honestly we needed the hook traits to
publish their weight, and we needed real benchmarks for the extrinsics
themselves.

Changes

pallet-referenda

  • Split the bundled PollHooks into per-event traits
    (OnPollCreated, OnPollCompleted); folded on_tally_updated into
    Polls since it shares the same provider type.
  • Each hook trait now exposes a worst-case weight() so callers can
    charge the right static budget upfront.
  • Dropped dev_mode, added a WeightInfo trait, and benchmarked
    submit, kill, advance_referendum, and on_tally_updated.
    advance_referendum is benchmarked on the worst-case branch
    (approve-with-Review, which fires both hooks); other branches are
    bounded conservatively from above.

pallet-multi-collective

  • Members storage is now kept sorted by AccountId. Every write path
    (add_member, remove_member, swap_member, set_members) uses
    binary_search plus try_insert/remove, and set_members diffs
    against the previous set via
    ChangeMembers::compute_members_diff_sorted. The sorted invariant
    bounds the per-call cost so the extrinsics are actually benchmarkable.
  • Renamed reset_membersset_members and SetMembersOrigin
    SetOrigin; the call takes the full member list and overwrites, so
    "set" is what it actually does.
  • force_rotate now returns DispatchResult and pays the static
    worst-case instead of refunding via OnNewTerm's returned weight.
  • Added a WeightInfo trait, benchmarked every extrinsic, and wired
    weights as
    WeightInfo::*().saturating_add(T::OnMembersChanged::weight()).

Cross-pallet hook traits

  • Moved OnMembersChanged from pallet-multi-collective into
    subtensor-runtime-common::traits, alongside Polls,
    OnPollCreated, and OnPollCompleted.
  • All four traits now expose a worst-case weight(). The runtime's
    GovernanceVoteCleanup (the OnMembersChanged impl that wipes
    signed-voting state for outgoing members) bounds itself by
    MaxMembers × MaxQueued × (per-poll storage cost + on_tally_updated_weight).

Runtime wiring

  • BenchmarkHelper config fields on both pallets, wired against the
    existing governance tracks and the Proposers / Economic
    collectives so the per-pallet benchmarks have a non-rotatable
    collective to fill freely and a rotatable one for force_rotate.

@shamil-gadelshin

Copy link
Copy Markdown
Collaborator

Cargo clippy failed.

@l0r1s l0r1s merged commit 836bd82 into governance May 4, 2026
20 of 24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants