Skip to content

Do not rate unrated contests when DQ'ing users; (Issue #2414) - #2481

Open
Rishiii57 wants to merge 1 commit into
DMOJ:masterfrom
Rishiii57:do-not-rate-unrated-contests-on-dq-2414
Open

Rishiii57 wants to merge 1 commit into
DMOJ:masterfrom
Rishiii57:do-not-rate-unrated-contests-on-dq-2414

Conversation

@Rishiii57

Copy link
Copy Markdown

Hey team,

This fixes #2414 so contests that haven't been rated yet aren't prematurely rated when re-rating after a disqualification.

What was happening

When a user is disqualified from a past contest, contest.rate() runs to recalculate ratings for that contest and every later contest up to the current time. The query previously grabbed all contests where is_rated=True in (self.end_time, self._now) without checking if those contests had ever been rated yet.

If a contest finished recently but organizers were still holding off on rating it (for example, while reviewing plagiarism or waiting on editorial releases), re-rating an older contest would prematurely publish ratings for that newer contest.

What changed

In judge/models/contest.py, I updated Contest.rate():

  1. Filter contests to only include self (to ensure the target contest is always rated, even when rating it for the first time) or contests that already have ratings (ratings__isnull=False):
    contests = list(Contest.objects.filter(
        Q(id=self.id) | Q(ratings__isnull=False),
        is_rated=True, end_time__range=(self.end_time, self._now),
    ).order_by('end_time').distinct())
  2. Evaluate contests into a list before deleting old ratings, ensuring Rating.objects.filter(contest__in=contests).delete() only targets the contests that are actually being re-rated, without wiping out the query's ability to detect which contests were already rated.
  3. Re-rate only the filtered list of contests. Any contest in the time window that has never had ratings computed remains unrated until its organizers explicitly trigger its rating.

Testing

  • Verified with a standalone reproducer (reproduce_dmoj_2414.py) confirming that an unrated contest in the time window is prematurely rated on unpatched code and cleanly skipped on patched code.
  • Added ContestRateTestCase in judge/models/tests/test_contest.py testing the Q filter expression and verifying that only self and already-rated contests are deleted and passed to rate_contest().
  • Passed all unit tests via manage.py test with 0 errors.
  • Passed flake8 with 0 warnings.

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.

Do not rate contests that have not yet been rated when DQ'ing users

2 participants