Skip to content

Implement ratability locking at time of join; (Issue #2463) - #2480

Open
Rishiii57 wants to merge 1 commit into
DMOJ:masterfrom
Rishiii57:implement-ratability-locking-2463
Open

Rishiii57 wants to merge 1 commit into
DMOJ:masterfrom
Rishiii57:implement-ratability-locking-2463

Conversation

@Rishiii57

Copy link
Copy Markdown

Hey team,

This implements ratability locking for rated contests as requested in #2463.

What was happening

When someone is retroactively disqualified from a contest, all future rated contests get re-rated. During re-rating, rate_contest() previously re-evaluated each user's eligibility against rating_floor and rating_ceiling dynamically based on their recalculated last_rating.

If a past disqualification shifted a user's rating across the floor or ceiling boundary, participants could suddenly flip between rated and unrated after the contest was long over. For example, someone who joined a Div. 2 contest expecting to be unrated could suddenly get rated, or a rated participant could unexpectedly lose their contest rating.

What changed

  1. Added a ratable_users ManyToManyField on Contest to track which users are eligible to be rated.
  2. Added a helper method contest.is_ratable_for(profile) that checks whether the contest is rated, verifies the user is not in rate_exclude, and checks that their current rating falls between rating_floor and rating_ceiling (defaulting newcomers to 1200 / RATING_INIT).
  3. In ContestJoin.join_contest(), when a user enters as a live participant, if contest.is_ratable_for(profile) is True, they are added to contest.ratable_users. This locks their ratability at the time they actually enter.
  4. In rate_contest(), if contest.ratable_users.exists() is True, it filters participants by ratable_users.all(). If ratable_users is empty (such as older legacy contests), it falls back to the previous dynamic floor/ceiling check for complete backward compatibility.
  5. Added ratable_users to the Django admin contest form with filter_horizontal and readonly lock enforcement.
  6. Added migration 0153_contest_ratable_users.py.

Testing

  • Verified with a standalone reproducer (reproduce_dmoj_2463.py) demonstrating how retroactive rating shifts flip user status on unpatched code and stay completely stable on patched code.
  • Added RatabilityLockingTestCase in judge/models/tests/test_contest.py covering boundary checks, newcomer defaults, exclude lists, and queryset logic.
  • Passed all 24 native unit tests in manage.py test with 0 failures.
  • Passed flake8 with 0 warnings or errors.

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