Fix bug in crosslink rewards during per-epoch
This commit is contained in:
parent
7b7a44e2f2
commit
e1d6e187d1
@ -48,15 +48,10 @@ pub fn per_epoch_processing<T: EthSpec>(
|
||||
process_justification_and_finalization(state, &validator_statuses.total_balances)?;
|
||||
|
||||
// Crosslinks.
|
||||
let winning_root_for_shards = process_crosslinks(state, spec)?;
|
||||
process_crosslinks(state, spec)?;
|
||||
|
||||
// Rewards and Penalties.
|
||||
process_rewards_and_penalties(
|
||||
state,
|
||||
&mut validator_statuses,
|
||||
&winning_root_for_shards,
|
||||
spec,
|
||||
)?;
|
||||
process_rewards_and_penalties(state, &mut validator_statuses, spec)?;
|
||||
|
||||
// Registry Updates.
|
||||
process_registry_updates(state, spec)?;
|
||||
@ -160,9 +155,7 @@ pub fn process_justification_and_finalization<T: EthSpec>(
|
||||
pub fn process_crosslinks<T: EthSpec>(
|
||||
state: &mut BeaconState<T>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<WinningRootHashSet, Error> {
|
||||
let mut winning_root_for_shards: WinningRootHashSet = HashMap::new();
|
||||
|
||||
) -> Result<(), Error> {
|
||||
state.previous_crosslinks = state.current_crosslinks.clone();
|
||||
|
||||
for &relative_epoch in &[RelativeEpoch::Previous, RelativeEpoch::Current] {
|
||||
@ -182,12 +175,11 @@ pub fn process_crosslinks<T: EthSpec>(
|
||||
if 3 * winning_root.total_attesting_balance >= 2 * total_committee_balance {
|
||||
state.current_crosslinks[shard as usize] = winning_root.crosslink.clone();
|
||||
}
|
||||
winning_root_for_shards.insert(shard, winning_root);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(winning_root_for_shards)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Finish up an epoch update.
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::validator_statuses::{TotalBalances, ValidatorStatus, ValidatorStatuses};
|
||||
use super::{Error, WinningRootHashSet};
|
||||
use super::Error;
|
||||
use integer_sqrt::IntegerSquareRoot;
|
||||
use types::*;
|
||||
|
||||
@ -36,7 +36,6 @@ impl std::ops::AddAssign for Delta {
|
||||
pub fn process_rewards_and_penalties<T: EthSpec>(
|
||||
state: &mut BeaconState<T>,
|
||||
validator_statuses: &mut ValidatorStatuses,
|
||||
winning_root_for_shards: &WinningRootHashSet,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), Error> {
|
||||
if state.current_epoch() == T::genesis_epoch() {
|
||||
@ -53,15 +52,13 @@ pub fn process_rewards_and_penalties<T: EthSpec>(
|
||||
let mut deltas = vec![Delta::default(); state.balances.len()];
|
||||
|
||||
get_attestation_deltas(&mut deltas, state, &validator_statuses, spec)?;
|
||||
|
||||
// Update statuses with the information from winning roots.
|
||||
validator_statuses.process_winning_roots(state, spec)?;
|
||||
|
||||
get_crosslink_deltas(&mut deltas, state, &validator_statuses, spec)?;
|
||||
|
||||
get_proposer_deltas(
|
||||
&mut deltas,
|
||||
state,
|
||||
validator_statuses,
|
||||
winning_root_for_shards,
|
||||
spec,
|
||||
)?;
|
||||
get_proposer_deltas(&mut deltas, state, validator_statuses, spec)?;
|
||||
|
||||
// Apply the deltas, over-flowing but not under-flowing (saturating at 0 instead).
|
||||
for (i, delta) in deltas.iter().enumerate() {
|
||||
@ -79,12 +76,8 @@ fn get_proposer_deltas<T: EthSpec>(
|
||||
deltas: &mut Vec<Delta>,
|
||||
state: &BeaconState<T>,
|
||||
validator_statuses: &mut ValidatorStatuses,
|
||||
winning_root_for_shards: &WinningRootHashSet,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), Error> {
|
||||
// Update statuses with the information from winning roots.
|
||||
validator_statuses.process_winning_roots(state, winning_root_for_shards, spec)?;
|
||||
|
||||
for (index, validator) in validator_statuses.statuses.iter().enumerate() {
|
||||
if validator.is_previous_epoch_attester {
|
||||
let inclusion = validator
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::WinningRootHashSet;
|
||||
use super::{winning_root::winning_root, WinningRootHashSet};
|
||||
use crate::common::get_attesting_indices;
|
||||
use types::*;
|
||||
|
||||
@ -292,9 +292,29 @@ impl ValidatorStatuses {
|
||||
pub fn process_winning_roots<T: EthSpec>(
|
||||
&mut self,
|
||||
state: &BeaconState<T>,
|
||||
winning_roots: &WinningRootHashSet,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), BeaconStateError> {
|
||||
// We must re-calculate the winning roots here because it is possible that they have
|
||||
// changed since the first time they were calculated.
|
||||
//
|
||||
// This is because we altered the state during the first time we calculated the winning
|
||||
// roots.
|
||||
let winning_root_for_shards = {
|
||||
let mut winning_root_for_shards = WinningRootHashSet::new();
|
||||
let relative_epoch = RelativeEpoch::Previous;
|
||||
|
||||
let epoch = relative_epoch.into_epoch(state.current_epoch());
|
||||
for offset in 0..state.get_committee_count(relative_epoch)? {
|
||||
let shard = (state.get_epoch_start_shard(relative_epoch)? + offset)
|
||||
% T::ShardCount::to_u64();
|
||||
if let Some(winning_root) = winning_root(state, shard, epoch, spec)? {
|
||||
winning_root_for_shards.insert(shard, winning_root);
|
||||
}
|
||||
}
|
||||
|
||||
winning_root_for_shards
|
||||
};
|
||||
|
||||
// Loop through each slot in the previous epoch.
|
||||
for slot in state.previous_epoch().slot_iter(T::slots_per_epoch()) {
|
||||
let crosslink_committees_at_slot = state.get_crosslink_committees_at_slot(slot)?;
|
||||
@ -302,7 +322,7 @@ impl ValidatorStatuses {
|
||||
// Loop through each committee in the slot.
|
||||
for c in crosslink_committees_at_slot {
|
||||
// If there was some winning crosslink root for the committee's shard.
|
||||
if let Some(winning_root) = winning_roots.get(&c.shard) {
|
||||
if let Some(winning_root) = winning_root_for_shards.get(&c.shard) {
|
||||
let total_committee_balance = state.get_total_balance(&c.committee, spec)?;
|
||||
for &validator_index in &winning_root.attesting_validator_indices {
|
||||
// Take note of the balance information for the winning root, it will be
|
||||
|
@ -3,7 +3,7 @@ use std::collections::{HashMap, HashSet};
|
||||
use tree_hash::TreeHash;
|
||||
use types::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct WinningRoot {
|
||||
pub crosslink: Crosslink,
|
||||
pub attesting_validator_indices: Vec<usize>,
|
||||
|
Loading…
Reference in New Issue
Block a user