Handle NaN and inifinite point values (#4839)

This commit is contained in:
Sagar Dhawan 2019-06-26 18:33:52 -07:00 committed by GitHub
parent 531679eeaf
commit 8cea650535
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 46 additions and 5 deletions

View File

@ -465,13 +465,13 @@ impl Bank {
let storage_points = self.storage_accounts.write().unwrap().claim_points();
let (validator_point_value, storage_point_value) = self.check_point_values(
validator_rewards / validator_points as f64,
storage_rewards / storage_points as f64,
);
self.store_account(
&rewards::id(),
&rewards::create_account(
1,
validator_rewards / validator_points as f64,
storage_rewards / storage_points as f64,
),
&rewards::create_account(1, validator_point_value, storage_point_value),
);
self.capitalization.fetch_add(
@ -480,6 +480,28 @@ impl Bank {
);
}
// If the point values are not `normal`, bring them back into range and
// set them to the last value or 0.
fn check_point_values(
&self,
mut validator_point_value: f64,
mut storage_point_value: f64,
) -> (f64, f64) {
let rewards = rewards::Rewards::from(
&self
.get_account(&rewards::id())
.unwrap_or_else(|| rewards::create_account(1, 0.0, 0.0)),
)
.unwrap_or_else(Default::default);
if !validator_point_value.is_normal() {
validator_point_value = rewards.validator_point_value;
}
if !storage_point_value.is_normal() {
storage_point_value = rewards.storage_point_value
}
(validator_point_value, storage_point_value)
}
fn set_hash(&self) -> bool {
let mut hash = self.hash.write().unwrap();
if *hash == Hash::default() {
@ -2628,4 +2650,23 @@ mod tests {
assert_eq!(dbank.get_balance(&key.pubkey()), 10);
bank.compare_bank(&dbank);
}
#[test]
fn test_check_point_values() {
let (genesis_block, _) = create_genesis_block(500);
let bank = Arc::new(Bank::new(&genesis_block));
// check that point values are 0 if no previous value was known and current values are not normal
assert_eq!(
bank.check_point_values(std::f64::INFINITY, std::f64::NAN),
(0.0, 0.0)
);
bank.store_account(&rewards::id(), &rewards::create_account(1, 1.0, 1.0));
// check that point values are the previous value if current values are not normal
assert_eq!(
bank.check_point_values(std::f64::INFINITY, std::f64::NAN),
(1.0, 1.0)
);
}
}