Skip to content

Bug: variable shadowing in score_organic_jobs makes DYNAMIC_SCORE_ORGANIC_JOBS_LIMIT cap a no-op #846

Description

@Grizouforever

Summary

In validator/app/src/compute_horde_validator/validator/scoring/calculations.py, the function score_organic_jobs (lines ~167-180) contains a variable-shadowing bug that silently disables the organic job score cap configured via DYNAMIC_SCORE_ORGANIC_JOBS_LIMIT.

Root Cause

def score_organic_jobs(jobs: Sequence[OrganicJob]) -> dict[str, float]:
    batch_scores: defaultdict[str, float] = defaultdict(float)
    score = get_config("DYNAMIC_ORGANIC_JOB_SCORE")          # per-job score (e.g. 1.0)
    limit = get_config("DYNAMIC_SCORE_ORGANIC_JOBS_LIMIT")

    for job in jobs:
        batch_scores[job.miner.hotkey] += score

    if limit >= 0:
        for hotkey, score in batch_scores.items():            # ← shadows outer `score`!
            batch_scores[hotkey] = min(score, limit * score)  # always = score (no cap)

The for hotkey, score in batch_scores.items() loop rebinds score to the accumulated total for each hotkey. Inside the loop, min(score, limit * score) where score is already the accumulated total — not the per-job score — evaluates to min(total, limit * total). For any limit >= 1 this always equals total, so the cap is never applied.

Impact

DYNAMIC_SCORE_ORGANIC_JOBS_LIMIT is entirely ignored whenever limit >= 0. Miners can accumulate organic-job scores without bound regardless of the configured cap.

Fix

per_job_score = get_config("DYNAMIC_ORGANIC_JOB_SCORE")
limit = get_config("DYNAMIC_SCORE_ORGANIC_JOBS_LIMIT")

for job in jobs:
    batch_scores[job.miner.hotkey] += per_job_score

if limit >= 0:
    cap = per_job_score * limit
    for hotkey, accumulated in batch_scores.items():
        batch_scores[hotkey] = min(accumulated, cap)

A fix with 12 unit tests (including a regression test) is available in PR #[to be linked].

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions