Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Service Provider rewards math #887

Merged
merged 7 commits into from
Nov 1, 2024
Merged

Fix Service Provider rewards math #887

merged 7 commits into from
Nov 1, 2024

Conversation

michaeldjeffrey
Copy link
Contributor

@michaeldjeffrey michaeldjeffrey commented Nov 1, 2024

TLDR;
Mixing unit is bad. mmmkay

Previously, for calculating which percentage of rewards a Service provider should receive, the calculation was suing this number as it's base.
let used_allocation = total_sp_allocation.max(all_transfer);

total_sp_allocation was the maximum number of Bones that could be rewarded in an epoch. all_transfer was all the DC transferred in the epoch. Because they were 2 different units, and Bones is at a scale far surpassing DC, the number would always be total_sp_allocation.

This is not a problem, until the amount of DC transferred when converted to Bones exceeds the amount allocated.

That leads to a situation where we would assume there is more rewards available than exist. Which in this case lead to matching rewards when there were non unallocated.


Now, we convert DC to bones as soon as possible. Since we're always working in the same units, the percentages should hold true.

Break out calculating rewards for a single service provider.
This means in a test when we only care about a single sp, we can find
that record and get all of the rewards from it without having to do any
math. So the math can not differ from prod.
Previously, half the values were representing DC, and the other half
Bones. You cannot take percentages of one unit from another unit when
they are scaled differently.

Early on, we convert dc -> bones, then calculate percentages based off
those numbers. dc_perc has been renamed to data_perc because it is the
percentage of rewards that is allocated because of data transfer.

Rounding now uses the floor function provided by rust_decimal.
we no longer need to know the rewards_per_share, because we are not
doinga  share type algorithm for computing rewards. We get percentages
of a whole, which has the same effect as multipling shares by a fraction
of reward units.
@@ -2275,7 +2275,7 @@ mod test {
// force the service provider to have spend more DC than total rewardable
ServiceProviderDCSessions::from([(sp1, total_rewards_value_in_dc * dec!(2.0))]),
ServiceProviderPromotions::default(),
total_rewards_value_in_dc,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this variable doesn't seem to be used anymore but we're still calculating it above?

Comment on lines +59 to +60
total_sp_allocation: Decimal, // Bones
mobile_bone_price: Decimal, // Price in Bones
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i didn't think fmt would let you do a line-ending comment like this but great news if it does

@bbalser bbalser merged commit 870a040 into main Nov 1, 2024
17 checks passed
@bbalser bbalser deleted the mj/sp_rewards_math_fix branch November 1, 2024 20:34
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.

3 participants