fix(rip-200 v2): apply the modern_x86 loyalty bonus to epoch reward weight#7972
Open
Vyacheslav-Tomashevskiy wants to merge 1 commit into
Conversation
…eight calculate_epoch_rewards_v2 computed the loyalty-aware multiplier into base_mult (passing db_path + miner_id) and then discarded it, taking the weight from get_time_aged_multiplier() instead -- which called get_device_multiplier() without db_path/miner_id, so the 'if db_path and miner_id' guard was always false and get_loyalty_bonus() was never reached. Every modern_x86 miner was weighted at the flat 0.1 base, dropping the 15%/year loyalty bonus the module documents. Thread db_path/miner_id through get_time_aged_multiplier (optional args, existing callers unaffected) and drop the dead base_mult store. Tolerate a NULL device_arch in the decay branch: calculate_epoch_rewards_v2 passes the raw nullable column, and that branch is only reachable once loyalty lifts the base above 0.1.
Contributor
|
Welcome to RustChain! Thanks for your first pull request. Before we review, please make sure:
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! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Wiring status first (so it's weighed correctly)
This fixes
node/rip_200_round_robin_1cpu1vote_v2.py, which nothing currently imports — the live node (node/rustchain_v2_integrated_v2.2.1_rip200.py) andnode/claims_eligibility.pyboth import the v1 module, whoseget_time_aged_multiplierhas no loyalty concept at all. So this is not a live payout bug and no miner is losing RTC today; it's the v2 module failing its own documented contract before anyone wires it up. Flagging that up front rather than letting it ride under a scarier title.Problem
calculate_epoch_rewards_v2computes the loyalty-aware multiplier and then throws it away:get_time_aged_multiplierinternally callsget_device_multiplier(device_info)withoutdb_path/miner_id, so theif db_path and miner_id:guard is always false andget_loyalty_bonus()is unreachable from the reward path. Everymodern_x86miner is weighted at the flat 0.1 base.That contradicts the module's own docstring ("Modern x86 (<5 years): Starts at 0.1x, earns 15%/year loyalty bonus") and its
__main__banner ("Loyalty bonuses do NOT decay"). The deadbase_multstore is what convinced me this is an oversight and not a deliberate design choice — the intent to use the loyalty-aware value is right there.Concretely: a miner with 4 years of attestation history should weigh 0.70 against a brand-new miner's 0.10 — 87.5% / 12.5% of the epoch. Instead both weigh 0.10 and split it 50/50.
Fix
Thread
db_path/miner_idthroughget_time_aged_multiplieras optional args (defaultNone, so every existing caller — including v1-style two-arg calls — is unaffected) and drop the dead store.The
(device_arch or "")hunk is load-bearing, not cosmetic: with loyalty applied,base_multiplierclears 0.1 and execution reachesdevice_arch.lower()for the first time.calculate_epoch_rewards_v2passes the raw nullabledevice_archcolumn, so without that guard the fix would introduce anAttributeErroron NULL-arch miners. There's a test pinning it.Tests —
tests/test_rip200_v2_loyalty_bonus_reward_weight.pyOn current main:
With the fix:
3 passed.The two that pass on main are deliberate no-regression guards, so they hold on both sides:
test_vintage_weights_unchanged— a G4's decayed 2.5x weight is asserted against the decay formula through the public reward path; loyalty must not perturb it.test_null_device_arch_does_not_crash— covers the hunk above.The failing test's precondition (
get_device_multiplier(..., db, "veteran") == 0.70) passes on main, which is the proof that the loyalty machinery works and is simply never invoked.Regression check:
tests/test_epoch_window_consistency.py,node/tests/test_time_aged_multiplier_penalty.py,node/tests/test_arch_multiplier_guard_t32.py→ 26 passed.RTC payout address: RTCd1554f0f35576faf01d386a6be1c947f560dd0b7