mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-14 10:22:38 +00:00
166 lines
6.0 KiB
Rust
166 lines
6.0 KiB
Rust
use super::crystallized_state::CrystallizedState;
|
|
use super::utils::types::{ Bitfield, U256 };
|
|
|
|
pub fn process_ffg_deposits(
|
|
cry_state: &CrystallizedState,
|
|
ffg_vote_bitfield: &Bitfield)
|
|
-> (Vec<i64>, u64, U256, bool, bool)
|
|
{
|
|
let active_validators: usize = cry_state.num_active_validators();
|
|
let finality_distance: u64 = cry_state.finality_distance();
|
|
let online_reward: u64 = if finality_distance <= 2 { 6 } else { 0 };
|
|
let offline_penalty: u64 = finality_distance.saturating_mul(3);
|
|
let mut total_vote_count: u64 = 0;
|
|
let mut total_vote_deposits = U256::zero();
|
|
|
|
let mut deltas = vec![0_i64; active_validators];
|
|
for i in 0..active_validators {
|
|
if ffg_vote_bitfield.get_bit(&i) {
|
|
total_vote_deposits = total_vote_deposits
|
|
.saturating_add(cry_state.active_validators[i].balance);
|
|
deltas[i] += online_reward as i64;
|
|
total_vote_count += 1;
|
|
} else {
|
|
deltas[i] -= offline_penalty as i64;
|
|
}
|
|
}
|
|
|
|
// Justify if total voting deposits is greater than 2/3 the total deposits.
|
|
let should_justify = total_vote_deposits.saturating_mul(U256::from(3))
|
|
>= cry_state.total_deposits.saturating_mul(U256::from(2));
|
|
let mut should_finalize = false;
|
|
if should_justify {
|
|
if cry_state.last_justified_epoch == cry_state.current_epoch - 1 {
|
|
should_finalize = true;
|
|
}
|
|
}
|
|
(deltas, total_vote_count, total_vote_deposits, should_justify, should_finalize)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use super::super::utils::types::{ Address, Sha256Digest };
|
|
use super::super::super::validator_record::ValidatorRecord;
|
|
use super::super::
|
|
utils::test_helpers::get_dangerous_test_keypair;
|
|
|
|
#[test]
|
|
fn test_deposit_processing_scenario_1() {
|
|
let mut cry_state = CrystallizedState::zero();
|
|
let mut bitfield = Bitfield::new();
|
|
let mut total_deposits = U256::zero();
|
|
let individual_deposit = U256::from(1);
|
|
|
|
|
|
// load some validators into the cry state and flag
|
|
// they have all voted
|
|
for i in 0..10 {
|
|
cry_state.active_validators.push(ValidatorRecord {
|
|
pubkey: get_dangerous_test_keypair().public,
|
|
withdrawal_shard: 0,
|
|
withdrawal_address: Address::zero(),
|
|
randao_commitment: Sha256Digest::zero(),
|
|
balance: individual_deposit,
|
|
switch_dynasty: 0
|
|
});
|
|
total_deposits = total_deposits + individual_deposit;
|
|
bitfield.set_bit(&i, &true);
|
|
}
|
|
|
|
cry_state.current_epoch = 100;
|
|
cry_state.last_justified_epoch = 99;
|
|
cry_state.last_finalized_epoch = 98;
|
|
cry_state.total_deposits = total_deposits;
|
|
|
|
let (deltas, total_vote_count, total_vote_deposits,
|
|
should_justify, should_finalize) = process_ffg_deposits(
|
|
&cry_state, &bitfield);
|
|
|
|
assert_eq!(deltas, [6; 10]);
|
|
assert_eq!(total_vote_count, 10);
|
|
assert_eq!(total_vote_deposits, total_deposits);
|
|
assert_eq!(should_justify, true);
|
|
assert_eq!(should_finalize, true);
|
|
}
|
|
|
|
#[test]
|
|
fn test_deposit_processing_scenario_2() {
|
|
let mut cry_state = CrystallizedState::zero();
|
|
let bitfield = Bitfield::new();
|
|
let individual_deposit = U256::from(0);
|
|
|
|
|
|
// load some validators into the cry state and flag
|
|
// they have all voted
|
|
for _ in 0..10 {
|
|
cry_state.active_validators.push(ValidatorRecord {
|
|
pubkey: get_dangerous_test_keypair().public,
|
|
withdrawal_shard: 0,
|
|
withdrawal_address: Address::zero(),
|
|
randao_commitment: Sha256Digest::zero(),
|
|
balance: individual_deposit,
|
|
switch_dynasty: 0
|
|
});
|
|
}
|
|
|
|
cry_state.current_epoch = 100;
|
|
cry_state.last_justified_epoch = 99;
|
|
cry_state.last_finalized_epoch = 98;
|
|
cry_state.total_deposits = U256::from(10);
|
|
|
|
let (deltas, total_vote_count, total_vote_deposits,
|
|
should_justify, should_finalize) = process_ffg_deposits(
|
|
&cry_state, &bitfield);
|
|
|
|
assert_eq!(deltas, [-6; 10]);
|
|
assert_eq!(total_vote_count, 0);
|
|
assert_eq!(total_vote_deposits, U256::zero());
|
|
assert_eq!(should_justify, false);
|
|
assert_eq!(should_finalize, false);
|
|
}
|
|
|
|
#[test]
|
|
fn test_deposit_processing_scenario_3() {
|
|
let mut cry_state = CrystallizedState::zero();
|
|
let mut bitfield = Bitfield::new();
|
|
let mut total_deposits = U256::zero();
|
|
let individual_deposit = U256::from(50);
|
|
|
|
|
|
// load some validators into the cry state and flag
|
|
// some have voted
|
|
for i in 0..10 {
|
|
cry_state.active_validators.push(ValidatorRecord {
|
|
pubkey: get_dangerous_test_keypair().public,
|
|
withdrawal_shard: 0,
|
|
withdrawal_address: Address::zero(),
|
|
randao_commitment: Sha256Digest::zero(),
|
|
balance: individual_deposit,
|
|
switch_dynasty: 0,
|
|
});
|
|
|
|
if i < 5 {
|
|
bitfield.set_bit(&i, &true);
|
|
total_deposits = total_deposits + individual_deposit;
|
|
}
|
|
}
|
|
|
|
cry_state.current_epoch = 100;
|
|
cry_state.last_justified_epoch = 99;
|
|
cry_state.last_finalized_epoch = 98;
|
|
cry_state.total_deposits = U256::from(5);
|
|
|
|
let (deltas, total_vote_count, total_vote_deposits,
|
|
should_justify, should_finalize) = process_ffg_deposits(
|
|
&cry_state, &bitfield);
|
|
|
|
assert_eq!(deltas[0..5].to_vec(), [6;5]);
|
|
assert_eq!(deltas[5..10].to_vec(), [-6;5]);
|
|
assert_eq!(total_vote_count, 5);
|
|
assert_eq!(total_vote_deposits, total_deposits);
|
|
assert_eq!(should_justify, true);
|
|
assert_eq!(should_finalize, true);
|
|
}
|
|
}
|