Skip to content

Commit

Permalink
fix: u512 on reward computation (#10909)
Browse files Browse the repository at this point in the history
Fix overflow found at
https://near.zulipchat.com/#narrow/stream/422293-core.2Fstake-wars-iv/topic/StatelessNet.20v84.20issue/near/430321806.

It happened with values
```
epoch_validator_reward = 1303530277894885217220048460336356
uptime_numer = 5149480000
stake = 19417599724822422137067484572677335
```
and `log2(epoch_validator_reward * uptime_numer * stake) is ~= 256.17`,
so it couldn't fit in `U256`.

However, it can fit in U512, because epoch_validator_reward and stake
are Balances = u128; uptime_numer fits in u64.

Note that final conversion to u128 is valid because
uptime_numer/uptime_denom and stake/total_stake are <= 1.

Co-authored-by: Longarithm <the.aleksandr.logunov@gmail.com>
  • Loading branch information
Longarithm and Looogarithm authored Apr 1, 2024
1 parent cfa97d8 commit 79017e2
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions chain/epoch-manager/src/reward_calculator.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::collections::HashMap;

use num_rational::Rational32;
use primitive_types::U256;
use primitive_types::{U256, U512};

use near_chain_configs::GenesisConfig;
use near_primitives::checked_feature;
Expand Down Expand Up @@ -138,9 +138,9 @@ impl RewardCalculator {
// Apply min between 1. and computed uptime.
uptime_numer =
if uptime_numer > uptime_denum { uptime_denum } else { uptime_numer };
(U256::from(epoch_validator_reward) * uptime_numer * U256::from(stake)
/ uptime_denum
/ U256::from(total_stake))
(U512::from(epoch_validator_reward) * U512::from(uptime_numer) * U512::from(stake)
/ U512::from(uptime_denum)
/ U512::from(total_stake))
.as_u128()
};
res.insert(account_id, reward);
Expand Down

0 comments on commit 79017e2

Please sign in to comment.