Skip to content

[RWF] pallet-scored-pool: fix pool sort logic - #12333

Open
naijauser wants to merge 7 commits into
paritytech:masterfrom
naijauser:12259-fix-pallet-scored-pool-score
Open

[RWF] pallet-scored-pool: fix pool sort logic#12333
naijauser wants to merge 7 commits into
paritytech:masterfrom
naijauser:12259-fix-pallet-scored-pool-score

Conversation

@naijauser

@naijauser naijauser commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Closes #12259.

Summary

score() used Reverse(maybe_score.unwrap_or_default()) as its binary-search key, which maps both None and Some(0) to Reverse(0). Rescoring a candidate to 0 could then insert it after existing None entries, violating the documented "descending by score, None last" invariant. Same issue existed in the genesis pool.sort_by_key.

Fix: key on Reverse(Option<Score>) instead (Reverse(*maybe_score) / Reverse(Some(score))), since Option's Ord places None before all Some(_) (None < Some(_)).

Test: added scoring_to_zero_must_sort_before_none_entries covering this case.

@naijauser
naijauser requested a review from a team as a code owner June 10, 2026 16:42
@naijauser

Copy link
Copy Markdown
Contributor Author

/cmd prdoc --audience runtime_dev --bump patch

@github-actions

Copy link
Copy Markdown
Contributor

Command "prdoc --audience runtime_dev --bump patch" has failed ❌! See logs here

@naijauser

Copy link
Copy Markdown
Contributor Author

/cmd prdoc --audience runtime_dev --bump patch

@naijauser

Copy link
Copy Markdown
Contributor Author

@xlc, please review.

@xlc

xlc commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Code change looks right. One wording nit here

// we binary search the pool (which is sorted descending by score, with `None`
// last). `Option`'s `Ord` impl places `None` after `Some(_)` regardless of the
// scored value, so wrapping in `Reverse` keeps `None` entries last while sorting
// `Some(_)` entries by descending score.

natural Option order is None < Some(_); Reverse<Option<_>> is what makes None end up last. Sorting fix itself looks good.

@naijauser

Copy link
Copy Markdown
Contributor Author

Code change looks right. One wording nit here

// we binary search the pool (which is sorted descending by score, with `None`
// last). `Option`'s `Ord` impl places `None` after `Some(_)` regardless of the
// scored value, so wrapping in `Reverse` keeps `None` entries last while sorting
// `Some(_)` entries by descending score.

natural Option order is None < Some(_); Reverse<Option<_>> is what makes None end up last. Sorting fix itself looks good.

Oops! You're right. The comment had it the other way round.

I've updated the code comment, the prdoc, and the PR description.

@bkchr bkchr added the T2-pallets This PR/Issue is related to a particular pallet. label Jun 11, 2026
@bkchr
bkchr requested a review from ggwpez June 11, 2026 19:55
.binary_search_by_key(&Reverse(score), |(_, maybe_score)| {
Reverse(maybe_score.unwrap_or_default())
.binary_search_by_key(&Reverse(Some(score)), |(_, maybe_score)| {
Reverse(*maybe_score)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Would need to check if this causes issues with the current staking system, if that pallet is still used.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Staking does not interact with this pallet.

@Ank4n

Ank4n commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

This pallet doesn't seem to be used by any of our runtimes. Any reason to keep it, or should we deprecate and remove?

@naijauser

Copy link
Copy Markdown
Contributor Author

/cmd fmt

1 similar comment
@naijauser

Copy link
Copy Markdown
Contributor Author

/cmd fmt

@sigurpol sigurpol left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM - +1 on Ankan's question (do we need to keep this pallet around? ) but that's a separate discussion

@Ank4n

Ank4n commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Following up on my question above — I've opened #12746 to remove this pallet.

Rationale: it isn't used by any runtime in the repo, has had no functional changes in years (only mechanical maintenance touches), and the membership/ranking use cases are covered by pallet-membership / pallet-ranked-collective / pallet-core-fellowship.

@naijauser sorry for the wasted effort here — the bug you found is real, and it's part of why the removal came up. If reviewers on #12746 decide to keep the pallet (or to follow the deprecate-then-remove path in the deprecation checklist first), then this PR should go in and I'll rebase mine on top. Let's hold this one until #12746 is resolved either way.

@naijauser

Copy link
Copy Markdown
Contributor Author

Following up on my question above — I've opened #12746 to remove this pallet.

Rationale: it isn't used by any runtime in the repo, has had no functional changes in years (only mechanical maintenance touches), and the membership/ranking use cases are covered by pallet-membership / pallet-ranked-collective / pallet-core-fellowship.

@naijauser sorry for the wasted effort here — the bug you found is real, and it's part of why the removal came up. If reviewers on #12746 decide to keep the pallet (or to follow the deprecate-then-remove path in the deprecation checklist first), then this PR should go in and I'll rebase mine on top. Let's hold this one until #12746 is resolved either way.

No worries, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T2-pallets This PR/Issue is related to a particular pallet.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[RWF] pallet-scored-pool: score can sort Some(0) after None entries

6 participants