Skip to content

fix(airdrop): scope _determine_tier to RustChain contributions only - #8187

Open
rebel117 wants to merge 2 commits into
Scottcjn:mainfrom
rebel117:fix-8184-airdrop-tier-github-scope
Open

fix(airdrop): scope _determine_tier to RustChain contributions only#8187
rebel117 wants to merge 2 commits into
Scottcjn:mainfrom
rebel117:fix-8184-airdrop-tier-github-scope

Conversation

@rebel117

@rebel117 rebel117 commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Problem

_determine_tier() in node/airdrop_v2.py was using /search/commits with a bare author:{username} merged:true query to decide airdrop eligibility tiers. Two issues with that:

  1. No org/repo scopetotal_count reflects commits anywhere on GitHub, not contributions to RustChain. So any account with a normal open-source history immediately qualifies for the CORE tier (5+, 200 wRTC) without ever contributing here.

  2. Wrong endpoint for the qualifiermerged:true is a pull-request search qualifier. Sent to /search/commits, it does not mean "merged PRs". As shown in the issue, GET /search/commits?q=author:torvalds+merged:true returns 73,907 results, which obviously isn't merged RustChain PRs.

Fix

Switch from /search/commits to /search/issues with is:pr is:merged qualifiers, and scope the query to org:Scottcjn so only actual RustChain contributions are counted:

contrib_resp = requests.get(
    "https://api.github.com/search/issues",
    headers=headers,
    params={
        "q": f"author:{github_username} org:Scottcjn is:pr is:merged",
        "per_page": 1,
    },
    timeout=10,
)

The tier thresholds (1/3/5) stay the same — they just now measure what the docstrings always claimed: merged PRs within this project.

Testing

Added tests/test_airdrop_tier_github_scope_8184.py with 7 assertions:

  • ✅ Uses /search/issues (not /search/commits)
  • ✅ Old commits endpoint URL is gone from code
  • ✅ Query scoped to org:Scottcjn
  • ✅ Uses is:pr and is:merged qualifiers
  • ✅ Old merged:true qualifier is gone
  • ✅ Old cloak-preview Accept header is gone
  • ✅ Module compiles cleanly

All 7 tests pass.

Closes #8184

@github-actions github-actions Bot added BCOS-L1 Beacon Certified Open Source tier BCOS-L1 (required for non-doc PRs) BCOS-L2 Beacon Certified Open Source tier BCOS-L2 (required for non-doc PRs) node Node server related tests Test suite changes labels Aug 5, 2026
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Welcome to RustChain! Thanks for your first pull request.

Before we review, please make sure:

  • Non-doc PRs have a BCOS-L1 or BCOS-L2 label
  • Doc-only PRs are exempt from BCOS tier labels when they only touch docs/**, *.md, or common image/PDF files
  • New code files include an SPDX license header
  • You've tested your changes against the live node

Bounty tiers: Micro (1-10 RTC) | Standard (20-50) | Major (75-100) | Critical (100-150)

A maintainer will review your PR soon. Thanks for contributing!

@github-actions github-actions Bot added the size/M PR: 51-200 lines label Aug 5, 2026

@FlintLeng FlintLeng 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.

PR Review: Airdrop Tier Scoping + Bridge Lock Admin Auth

Reviewed on: 2026-08-07

Summary

Two related fixes in airdrop_v2.py:

  1. _determine_tier() now counts only RustChain-org merged PRs instead of all GitHub commits (fixes #8184)
  2. Bridge lock creation gated behind admin key authentication; public lock data stripped via to_public_dict()

Fix 1: Airdrop Tier Scope ✅

The vulnerability was real. The old code used /search/commits with author:X merged:true — this returns commits authored by the user across all of GitHub, not just merged PRs in the RustChain org. Any established GitHub account would clear the CORE tier (200 wRTC) without a single RustChain contribution.

The fix is correct and well-scoped:

  • Switches to /search/issues with org:Scottcjn is:pr is:merged — the correct API for counting merged PRs in a specific org
  • Removes the application/vnd.github.cloak-preview Accept header (only needed for commit search)
  • Removes bare merged:true (a PR-search qualifier misused on the commits endpoint)

The 7 unit tests are exemplary. They parse the AST of airdrop_v2.py and assert on the actual code structure (not just runtime behaviour), which is the right approach for API-usage validation tests. Tests for: correct endpoint, absent old endpoint, org scope, PR+merged qualifiers, absent bare merged:true, absent cloak header, module compiles.

Fix 2: Bridge Lock Admin Auth ✅

create_bridge_lock gated behind admin key — correct. Creating a bridge lock is a write operation that affects the cross-chain minting supply. Only admins should be able to trigger it.

to_public_dict() data strippingget_bridge_lock now returns a sanitised view without admin-only fields when no admin key is provided. The has_admin_key() helper checks both X-Admin-Key and X-API-Key headers with hmac.compare_digest (timing-safe comparison) — correct.

Minor note: The admin key env var is RC_ADMIN_KEY. Worth confirming this is documented and set in production deployment, otherwise require_admin_key() will always return None (no auth) when the env var is absent.

Wallet: RTC019e78d600fb3131c29d7ba80aba8fe644be426e

✅ LGTM — both fixes are clean, well-tested, and address real vulnerabilities.

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

Labels

BCOS-L1 Beacon Certified Open Source tier BCOS-L1 (required for non-doc PRs) BCOS-L2 Beacon Certified Open Source tier BCOS-L2 (required for non-doc PRs) node Node server related size/M PR: 51-200 lines tests Test suite changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

airdrop _determine_tier counts GitHub-wide activity, not RustChain contributions — any established account reaches CORE (200 wRTC)

2 participants