From cd864f3f2dfb12f2047261c7ff3918652c9bc685 Mon Sep 17 00:00:00 2001 From: muXxer Date: Sun, 3 Nov 2024 21:13:02 +0100 Subject: [PATCH] fix(node): simplify `compute_adjusted_reward_distribution` --- .../iota-system/sources/validator_set.move | 102 ++++++++---------- .../packages_compiled/iota-system | Bin 42160 -> 42143 bytes 2 files changed, 47 insertions(+), 55 deletions(-) diff --git a/crates/iota-framework/packages/iota-system/sources/validator_set.move b/crates/iota-framework/packages/iota-system/sources/validator_set.move index 09f8b55e256..5c90b9231a4 100644 --- a/crates/iota-framework/packages/iota-system/sources/validator_set.move +++ b/crates/iota-framework/packages/iota-system/sources/validator_set.move @@ -341,15 +341,15 @@ module iota_system::validator_set { // punished. let slashed_validators = compute_slashed_validators(self, *validator_report_records); - // Compute the adjusted amounts of stake each validator should get given the tallying rule - // reward adjustments we computed before. - // `compute_adjusted_reward_distribution` must be called before `distribute_reward` and `adjust_stake_and_gas_price` to - // make sure we are using the current epoch's stake information to compute reward distribution. + // Compute the adjusted amounts of stake each validator should get given the tallying rule + // reward adjustments we computed before. + // `compute_adjusted_reward_distribution` must be called before `distribute_reward` and `adjust_stake_and_gas_price` to + // make sure we are using the current epoch's stake information to compute reward distribution. let adjusted_staking_reward_amounts = compute_adjusted_reward_distribution( - &self.active_validators, - unadjusted_staking_reward_amounts, - get_validator_indices(&self.active_validators, &slashed_validators), - reward_slashing_rate + &self.active_validators, + unadjusted_staking_reward_amounts, + get_validator_indices(&self.active_validators, &slashed_validators), + reward_slashing_rate, ); // Distribute the rewards before adjusting stake so that we immediately start compounding @@ -625,7 +625,6 @@ module iota_system::validator_set { option::none() } - /// Given a vector of validator addresses, return their indices in the validator set. /// Aborts if any address isn't in the given validator set. fun get_validator_indices(validators: &vector, validator_addresses: &vector
): vector { @@ -980,53 +979,46 @@ module iota_system::validator_set { /// Returns the staking rewards each validator gets. /// The staking rewards are shared with the stakers. fun compute_adjusted_reward_distribution( - validators: &vector, - unadjusted_staking_reward_amounts: vector, - mut slashed_validator_indices: vector, - reward_slashing_rate: u64, + validators: &vector, + unadjusted_staking_reward_amounts: vector, + mut slashed_validator_indices: vector, + reward_slashing_rate: u64, ): vector { - let mut adjusted_staking_reward_amounts = vector[]; - let mut individual_staking_reward_adjustments = vec_map::empty(); - - while (!slashed_validator_indices.is_empty()) { - let validator_index = slashed_validator_indices.pop_back(); - - // Use the slashing rate to compute the amount of staking rewards slashed from this punished validator. - let unadjusted_staking_reward = unadjusted_staking_reward_amounts[validator_index]; - let staking_reward_adjustment_u128 = - unadjusted_staking_reward as u128 * (reward_slashing_rate as u128) - / BASIS_POINT_DENOMINATOR; - - // Insert into individual mapping. - individual_staking_reward_adjustments.insert(validator_index, staking_reward_adjustment_u128 as u64); - }; - - let length = validators.length(); - - let mut i = 0; - while (i < length) { - // Integer divisions will truncate the results. - // Additionally, in case some validator is slashed, the slashed reward is not redistributed to other validators. - // Because of this, we expect that at the end there will be some reward remaining in `total_reward`. - // Use u128 to avoid multiplication overflow. - // Compute adjusted staking reward. - let unadjusted_staking_reward_amount = unadjusted_staking_reward_amounts[i]; - let adjusted_staking_reward_amount = - // If the validator is one of the slashed ones, then subtract the adjustment. - if (individual_staking_reward_adjustments.contains(&i)) { - let adjustment = individual_staking_reward_adjustments[&i]; - unadjusted_staking_reward_amount - adjustment - } else { - // Otherwise, unadjusted staking reward amount is assigned to the unslashed validators - unadjusted_staking_reward_amount - }; - adjusted_staking_reward_amounts.push_back(adjusted_staking_reward_amount); - - i = i + 1; - }; - - adjusted_staking_reward_amounts - } + let mut adjusted_staking_reward_amounts = vector[]; + let mut slashed_indices_set = vec_map::empty(); + + // Store slashed validators in a map for quick lookup + while (!slashed_validator_indices.is_empty()) { + slashed_indices_set.insert(slashed_validator_indices.pop_back(), true); + }; + + // Loop through each validator and adjust rewards as necessary + let length = validators.length(); + let mut i = 0; + while (i < length) { + let unadjusted_staking_reward_amount = unadjusted_staking_reward_amounts[i]; + + // Check if the validator is slashed + let adjusted_staking_reward_amount = if (slashed_indices_set.contains(&i)) { + // Use the slashing rate to compute the amount of staking rewards slashed from this punished validator. + // Use u128 to avoid multiplication overflow. + let staking_reward_adjustment_u128 = ((unadjusted_staking_reward_amount as u128) * (reward_slashing_rate as u128)) / BASIS_POINT_DENOMINATOR; + unadjusted_staking_reward_amount - (staking_reward_adjustment_u128 as u64) + } else { + // Otherwise, unadjusted staking reward amount is assigned to the unslashed validators + unadjusted_staking_reward_amount + }; + + adjusted_staking_reward_amounts.push_back(adjusted_staking_reward_amount); + + // Move to the next validator + i = i + 1; + }; + + // The sum of the adjusted staking rewards may not be equal to the total staking reward, + // because of integer division truncation and the slashing of the rewards for the slashed validators. + adjusted_staking_reward_amounts + } fun distribute_reward( validators: &mut vector, diff --git a/crates/iota-framework/packages_compiled/iota-system b/crates/iota-framework/packages_compiled/iota-system index 07bd624d43cbbedc66fa3632853b5bf0118a00ef..23dc84351b70d23b2e97e06ff423b7f23ebc3696 100644 GIT binary patch delta 355 zcmWlUyDtPm9Dw(?GqbZhzu9%-+<66s#Iq1?-M9xLNE8y{5rq|nQX%LyqLGl8<2a9t zLZ`UcR)VNVl>P#up`y}=^A%sd_A5P_#YeN$r?S5j7Y!e18HORj@J)Y}TtdO3w|p1a zv;A%JyUMS)ecirf?RPwYc&?$t!3;wD^I?|^wAV3<2_2zkAn+JqzhmfC}3 zy^(GsCvX}T(-LAin9spX4zklzPG)*;3$`IWcoyDes%WK6h#-WZYZ9QOtnhVct-fi1 zN2R5DrQ?~ZrI}VR$8}tDG-9g+qiE<-P(7JpwH^pQ9EnQw9FHrXb_?_c@oPA#lL8S% zA}%TGL6j7!WUhs5B!b+6^7B72$ypRFGg0mX{kbp+eL5S&%bpF|c#@4HDy6rARw(GJ lAQ|hAsvgN$Bd?YWnG}M0Ql<1yFa~Kow0H^U;rrs#=pUYjP4@r* delta 407 zcmXYsy-OWI6vg-M%HGtNtLAXHhg-h;MTHaudXbx>oW_^>w{E?wa@BJw5~d{mEN8?f%ymoQy|Rm+7+k4Y&;q9Crgg zz_wjTR$<3pC0np-SBjl%5BAf;B0+8Cb!ECTQyH9^^h;ASYp@Q*p-<`8QVowZW0@HS zZZ91!?O{*_tjy&^}{LnRz+IWlb19vo{AOsyek8-hQaf4)ygn^F%V&3EhM`t)8 zeOu;Eq_onyosWr*j8Yjz6#AhuF;DKYKSvS?Wj%3GLL!cwMBt$qi5gIO@c&L7De(|J zH=phA?a$d)4+`X=jJ4{ieslkY&M2KX1v^silt#QnGy`_I+yNi$ez{PW