Add PulseChain burn

This commit is contained in:
Shane Bammel 2022-12-20 00:21:11 -06:00
parent b085f5e7ab
commit 05feeaec2a
7 changed files with 55 additions and 9 deletions

View File

@ -3,6 +3,7 @@ mod get_attestation_participation;
mod get_attesting_indices; mod get_attesting_indices;
mod get_indexed_attestation; mod get_indexed_attestation;
mod initiate_validator_exit; mod initiate_validator_exit;
mod pulse;
mod slash_validator; mod slash_validator;
pub mod altair; pub mod altair;
@ -17,14 +18,19 @@ pub use initiate_validator_exit::initiate_validator_exit;
pub use slash_validator::slash_validator; pub use slash_validator::slash_validator;
use safe_arith::SafeArith; use safe_arith::SafeArith;
use types::{BeaconState, BeaconStateError, EthSpec}; use types::{BeaconState, BeaconStateError, ChainSpec, EthSpec};
/// Increase the balance of a validator, upon overflow set the balance to u64 MAX. /// Increase the balance of a validator, upon overflow set the balance to u64 MAX.
pub fn increase_balance<E: EthSpec>( pub fn increase_balance<E: EthSpec>(
state: &mut BeaconState<E>, state: &mut BeaconState<E>,
index: usize, index: usize,
delta: u64, mut delta: u64,
spec: &ChainSpec,
apply_burn: bool,
) -> Result<(), BeaconStateError> { ) -> Result<(), BeaconStateError> {
if apply_burn {
delta = pulse::apply_burn(delta, spec)
}
let balance = state.get_balance_mut(index)?; let balance = state.get_balance_mut(index)?;
if let Err(_) = balance.safe_add_assign(delta) { if let Err(_) = balance.safe_add_assign(delta) {
*balance = u64::MAX; *balance = u64::MAX;

View File

@ -0,0 +1,36 @@
use types::ChainSpec;
pub fn apply_burn(base_reward: u64, spec: &ChainSpec) -> u64 {
let seconds_per_slot = spec.seconds_per_slot;
// First we compensate for the increased block frequency.
let after_burn = base_reward * seconds_per_slot / 12;
// Then we burn an additional 25%.
after_burn * 3 / 4
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_apply_burn() {
let before_burn: u64 = 1000000;
let mut spec = ChainSpec::mainnet();
// Default 12 second slots => 25% general burn.
let after_burn = apply_burn(before_burn, &spec);
assert_eq!(after_burn, 750000);
// 6 second slots => 50% burn then 25% general burn.
spec.seconds_per_slot = 6;
let after_burn = apply_burn(before_burn, &spec);
assert_eq!(after_burn, 375000);
// 3 second slots => 75% burn then 25% general burn.
spec.seconds_per_slot = 3;
let after_burn = apply_burn(before_burn, &spec);
assert_eq!(after_burn, 187500);
}
}

View File

@ -66,11 +66,14 @@ pub fn slash_validator<T: EthSpec>(
return Err(BeaconStateError::UnknownValidator(whistleblower_index).into()); return Err(BeaconStateError::UnknownValidator(whistleblower_index).into());
} }
increase_balance(state, proposer_index, proposer_reward)?; // Do not apply burn to slashing rewards.
increase_balance(state, proposer_index, proposer_reward, spec, false)?;
increase_balance( increase_balance(
state, state,
whistleblower_index, whistleblower_index,
whistleblower_reward.safe_sub(proposer_reward)?, whistleblower_reward.safe_sub(proposer_reward)?,
spec,
false,
)?; )?;
Ok(()) Ok(())

View File

@ -52,8 +52,8 @@ pub fn process_sync_aggregate<T: EthSpec>(
.zip(aggregate.sync_committee_bits.iter()) .zip(aggregate.sync_committee_bits.iter())
{ {
if participation_bit { if participation_bit {
increase_balance(state, participant_index, participant_reward)?; increase_balance(state, participant_index, participant_reward, spec, true)?;
increase_balance(state, proposer_index as usize, proposer_reward)?; increase_balance(state, proposer_index as usize, proposer_reward, spec, true)?;
} else { } else {
decrease_balance(state, participant_index, participant_reward)?; decrease_balance(state, participant_index, participant_reward)?;
} }

View File

@ -181,7 +181,7 @@ pub mod altair_deneb {
.safe_mul(WEIGHT_DENOMINATOR)? .safe_mul(WEIGHT_DENOMINATOR)?
.safe_div(PROPOSER_WEIGHT)?; .safe_div(PROPOSER_WEIGHT)?;
let proposer_reward = proposer_reward_numerator.safe_div(proposer_reward_denominator)?; let proposer_reward = proposer_reward_numerator.safe_div(proposer_reward_denominator)?;
increase_balance(state, proposer_index as usize, proposer_reward)?; increase_balance(state, proposer_index as usize, proposer_reward, spec, true)?;
Ok(()) Ok(())
} }
} }
@ -391,7 +391,8 @@ pub fn process_deposit<T: EthSpec>(
if let Some(index) = validator_index { if let Some(index) = validator_index {
// Update the existing validator balance. // Update the existing validator balance.
increase_balance(state, index as usize, amount)?; // Do not apply burn to deposits.
increase_balance(state, index as usize, amount, spec, false)?;
} else { } else {
// The signature should be checked for new validators. Return early for a bad // The signature should be checked for new validators. Return early for a bad
// signature. // signature.

View File

@ -44,7 +44,7 @@ pub fn process_rewards_and_penalties<T: EthSpec>(
// Apply the deltas, erroring on overflow above but not on overflow below (saturating at 0 // Apply the deltas, erroring on overflow above but not on overflow below (saturating at 0
// instead). // instead).
for (i, delta) in deltas.into_iter().enumerate() { for (i, delta) in deltas.into_iter().enumerate() {
increase_balance(state, i, delta.rewards as u64)?; increase_balance(state, i, delta.rewards as u64, spec, true)?;
decrease_balance(state, i, delta.penalties as u64)?; decrease_balance(state, i, delta.penalties as u64)?;
} }

View File

@ -65,7 +65,7 @@ pub fn process_rewards_and_penalties<T: EthSpec>(
// instead). // instead).
for (i, delta) in deltas.into_iter().enumerate() { for (i, delta) in deltas.into_iter().enumerate() {
let combined_delta = delta.flatten()?; let combined_delta = delta.flatten()?;
increase_balance(state, i, combined_delta.rewards as u64)?; increase_balance(state, i, combined_delta.rewards as u64, spec, true)?;
decrease_balance(state, i, combined_delta.penalties as u64)?; decrease_balance(state, i, combined_delta.penalties as u64)?;
} }