mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-14 10:22:38 +00:00
merge with upstream
This commit is contained in:
195
beacon_node/beacon_chain/src/attestation_rewards.rs
Normal file
195
beacon_node/beacon_chain/src/attestation_rewards.rs
Normal file
@@ -0,0 +1,195 @@
|
||||
use crate::{BeaconChain, BeaconChainError, BeaconChainTypes};
|
||||
use eth2::lighthouse::attestation_rewards::{IdealAttestationRewards, TotalAttestationRewards};
|
||||
use eth2::lighthouse::StandardAttestationRewards;
|
||||
use participation_cache::ParticipationCache;
|
||||
use safe_arith::SafeArith;
|
||||
use slog::{debug, Logger};
|
||||
use state_processing::{
|
||||
common::altair::BaseRewardPerIncrement,
|
||||
per_epoch_processing::altair::{participation_cache, rewards_and_penalties::get_flag_weight},
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use store::consts::altair::{
|
||||
PARTICIPATION_FLAG_WEIGHTS, TIMELY_HEAD_FLAG_INDEX, TIMELY_SOURCE_FLAG_INDEX,
|
||||
TIMELY_TARGET_FLAG_INDEX,
|
||||
};
|
||||
use types::consts::altair::WEIGHT_DENOMINATOR;
|
||||
|
||||
use types::{Epoch, EthSpec};
|
||||
|
||||
use eth2::types::ValidatorId;
|
||||
|
||||
impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
pub fn compute_attestation_rewards(
|
||||
&self,
|
||||
epoch: Epoch,
|
||||
validators: Vec<ValidatorId>,
|
||||
log: Logger,
|
||||
) -> Result<StandardAttestationRewards, BeaconChainError> {
|
||||
debug!(log, "computing attestation rewards"; "epoch" => epoch, "validator_count" => validators.len());
|
||||
|
||||
// Get state
|
||||
let spec = &self.spec;
|
||||
|
||||
let state_slot = (epoch + 1).end_slot(T::EthSpec::slots_per_epoch());
|
||||
|
||||
let state_root = self
|
||||
.state_root_at_slot(state_slot)?
|
||||
.ok_or(BeaconChainError::NoStateForSlot(state_slot))?;
|
||||
|
||||
let mut state = self
|
||||
.get_state(&state_root, Some(state_slot))?
|
||||
.ok_or(BeaconChainError::MissingBeaconState(state_root))?;
|
||||
|
||||
// Calculate ideal_rewards
|
||||
let participation_cache = ParticipationCache::new(&state, spec)?;
|
||||
|
||||
let previous_epoch = state.previous_epoch();
|
||||
|
||||
let mut ideal_rewards_hashmap = HashMap::new();
|
||||
|
||||
for flag_index in 0..PARTICIPATION_FLAG_WEIGHTS.len() {
|
||||
let weight = get_flag_weight(flag_index)
|
||||
.map_err(|_| BeaconChainError::AttestationRewardsError)?;
|
||||
|
||||
let unslashed_participating_indices = participation_cache
|
||||
.get_unslashed_participating_indices(flag_index, previous_epoch)?;
|
||||
|
||||
let unslashed_participating_balance =
|
||||
unslashed_participating_indices
|
||||
.total_balance()
|
||||
.map_err(|_| BeaconChainError::AttestationRewardsError)?;
|
||||
|
||||
let unslashed_participating_increments =
|
||||
unslashed_participating_balance.safe_div(spec.effective_balance_increment)?;
|
||||
|
||||
let total_active_balance = participation_cache.current_epoch_total_active_balance();
|
||||
|
||||
let active_increments =
|
||||
total_active_balance.safe_div(spec.effective_balance_increment)?;
|
||||
|
||||
let base_reward_per_increment =
|
||||
BaseRewardPerIncrement::new(total_active_balance, spec)?;
|
||||
|
||||
for effective_balance_eth in 0..=32 {
|
||||
let effective_balance =
|
||||
effective_balance_eth.safe_mul(spec.effective_balance_increment)?;
|
||||
let base_reward =
|
||||
effective_balance_eth.safe_mul(base_reward_per_increment.as_u64())?;
|
||||
|
||||
let penalty = -(base_reward.safe_mul(weight)?.safe_div(WEIGHT_DENOMINATOR)? as i64);
|
||||
|
||||
let reward_numerator = base_reward
|
||||
.safe_mul(weight)?
|
||||
.safe_mul(unslashed_participating_increments)?;
|
||||
|
||||
let ideal_reward = reward_numerator
|
||||
.safe_div(active_increments)?
|
||||
.safe_div(WEIGHT_DENOMINATOR)?;
|
||||
if !state.is_in_inactivity_leak(previous_epoch, spec) {
|
||||
ideal_rewards_hashmap
|
||||
.insert((flag_index, effective_balance), (ideal_reward, penalty));
|
||||
} else {
|
||||
ideal_rewards_hashmap.insert((flag_index, effective_balance), (0, penalty));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate total_rewards
|
||||
let mut total_rewards: Vec<TotalAttestationRewards> = Vec::new();
|
||||
|
||||
let validators = if validators.is_empty() {
|
||||
participation_cache.eligible_validator_indices().to_vec()
|
||||
} else {
|
||||
validators
|
||||
.into_iter()
|
||||
.map(|validator| match validator {
|
||||
ValidatorId::Index(i) => Ok(i as usize),
|
||||
ValidatorId::PublicKey(pubkey) => state
|
||||
.get_validator_index(&pubkey)?
|
||||
.ok_or(BeaconChainError::ValidatorPubkeyUnknown(pubkey)),
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?
|
||||
};
|
||||
|
||||
for validator_index in &validators {
|
||||
let eligible = state.is_eligible_validator(previous_epoch, *validator_index)?;
|
||||
let mut head_reward = 0u64;
|
||||
let mut target_reward = 0i64;
|
||||
let mut source_reward = 0i64;
|
||||
|
||||
if eligible {
|
||||
let effective_balance = state.get_effective_balance(*validator_index)?;
|
||||
|
||||
for flag_index in 0..PARTICIPATION_FLAG_WEIGHTS.len() {
|
||||
let (ideal_reward, penalty) = ideal_rewards_hashmap
|
||||
.get(&(flag_index, effective_balance))
|
||||
.ok_or(BeaconChainError::AttestationRewardsError)?;
|
||||
let voted_correctly = participation_cache
|
||||
.get_unslashed_participating_indices(flag_index, previous_epoch)
|
||||
.map_err(|_| BeaconChainError::AttestationRewardsError)?
|
||||
.contains(*validator_index)
|
||||
.map_err(|_| BeaconChainError::AttestationRewardsError)?;
|
||||
if voted_correctly {
|
||||
if flag_index == TIMELY_HEAD_FLAG_INDEX {
|
||||
head_reward += ideal_reward;
|
||||
} else if flag_index == TIMELY_TARGET_FLAG_INDEX {
|
||||
target_reward += *ideal_reward as i64;
|
||||
} else if flag_index == TIMELY_SOURCE_FLAG_INDEX {
|
||||
source_reward += *ideal_reward as i64;
|
||||
}
|
||||
} else if flag_index == TIMELY_HEAD_FLAG_INDEX {
|
||||
head_reward = 0;
|
||||
} else if flag_index == TIMELY_TARGET_FLAG_INDEX {
|
||||
target_reward = *penalty;
|
||||
} else if flag_index == TIMELY_SOURCE_FLAG_INDEX {
|
||||
source_reward = *penalty;
|
||||
}
|
||||
}
|
||||
}
|
||||
total_rewards.push(TotalAttestationRewards {
|
||||
validator_index: *validator_index as u64,
|
||||
head: head_reward,
|
||||
target: target_reward,
|
||||
source: source_reward,
|
||||
});
|
||||
}
|
||||
|
||||
// Convert hashmap to vector
|
||||
let mut ideal_rewards: Vec<IdealAttestationRewards> = ideal_rewards_hashmap
|
||||
.iter()
|
||||
.map(
|
||||
|((flag_index, effective_balance), (ideal_reward, _penalty))| {
|
||||
(flag_index, effective_balance, ideal_reward)
|
||||
},
|
||||
)
|
||||
.fold(
|
||||
HashMap::new(),
|
||||
|mut acc, (flag_index, &effective_balance, ideal_reward)| {
|
||||
let entry = acc
|
||||
.entry(effective_balance)
|
||||
.or_insert(IdealAttestationRewards {
|
||||
effective_balance,
|
||||
head: 0,
|
||||
target: 0,
|
||||
source: 0,
|
||||
});
|
||||
match *flag_index {
|
||||
TIMELY_SOURCE_FLAG_INDEX => entry.source += ideal_reward,
|
||||
TIMELY_TARGET_FLAG_INDEX => entry.target += ideal_reward,
|
||||
TIMELY_HEAD_FLAG_INDEX => entry.head += ideal_reward,
|
||||
_ => {}
|
||||
}
|
||||
acc
|
||||
},
|
||||
)
|
||||
.into_values()
|
||||
.collect::<Vec<IdealAttestationRewards>>();
|
||||
ideal_rewards.sort_by(|a, b| a.effective_balance.cmp(&b.effective_balance));
|
||||
|
||||
Ok(StandardAttestationRewards {
|
||||
ideal_rewards,
|
||||
total_rewards,
|
||||
})
|
||||
}
|
||||
}
|
||||
237
beacon_node/beacon_chain/src/beacon_block_reward.rs
Normal file
237
beacon_node/beacon_chain/src/beacon_block_reward.rs
Normal file
@@ -0,0 +1,237 @@
|
||||
use crate::{BeaconChain, BeaconChainError, BeaconChainTypes};
|
||||
use eth2::lighthouse::StandardBlockReward;
|
||||
use operation_pool::RewardCache;
|
||||
use safe_arith::SafeArith;
|
||||
use slog::error;
|
||||
use state_processing::{
|
||||
common::{
|
||||
altair, get_attestation_participation_flag_indices, get_attesting_indices_from_state,
|
||||
},
|
||||
per_block_processing::{
|
||||
altair::sync_committee::compute_sync_aggregate_rewards, get_slashable_indices,
|
||||
},
|
||||
};
|
||||
use store::{
|
||||
consts::altair::{PARTICIPATION_FLAG_WEIGHTS, PROPOSER_WEIGHT, WEIGHT_DENOMINATOR},
|
||||
RelativeEpoch,
|
||||
};
|
||||
use types::{AbstractExecPayload, BeaconBlockRef, BeaconState, BeaconStateError, Hash256};
|
||||
|
||||
type BeaconBlockSubRewardValue = u64;
|
||||
|
||||
impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
pub fn compute_beacon_block_reward<Payload: AbstractExecPayload<T::EthSpec>>(
|
||||
&self,
|
||||
block: BeaconBlockRef<'_, T::EthSpec, Payload>,
|
||||
block_root: Hash256,
|
||||
state: &mut BeaconState<T::EthSpec>,
|
||||
) -> Result<StandardBlockReward, BeaconChainError> {
|
||||
if block.slot() != state.slot() {
|
||||
return Err(BeaconChainError::BlockRewardSlotError);
|
||||
}
|
||||
|
||||
state.build_committee_cache(RelativeEpoch::Previous, &self.spec)?;
|
||||
state.build_committee_cache(RelativeEpoch::Current, &self.spec)?;
|
||||
|
||||
let proposer_index = block.proposer_index();
|
||||
|
||||
let sync_aggregate_reward =
|
||||
self.compute_beacon_block_sync_aggregate_reward(block, state)?;
|
||||
|
||||
let proposer_slashing_reward = self
|
||||
.compute_beacon_block_proposer_slashing_reward(block, state)
|
||||
.map_err(|e| {
|
||||
error!(
|
||||
self.log,
|
||||
"Error calculating proposer slashing reward";
|
||||
"error" => ?e
|
||||
);
|
||||
BeaconChainError::BlockRewardError
|
||||
})?;
|
||||
|
||||
let attester_slashing_reward = self
|
||||
.compute_beacon_block_attester_slashing_reward(block, state)
|
||||
.map_err(|e| {
|
||||
error!(
|
||||
self.log,
|
||||
"Error calculating attester slashing reward";
|
||||
"error" => ?e
|
||||
);
|
||||
BeaconChainError::BlockRewardError
|
||||
})?;
|
||||
|
||||
let block_attestation_reward = if let BeaconState::Base(_) = state {
|
||||
self.compute_beacon_block_attestation_reward_base(block, block_root, state)
|
||||
.map_err(|e| {
|
||||
error!(
|
||||
self.log,
|
||||
"Error calculating base block attestation reward";
|
||||
"error" => ?e
|
||||
);
|
||||
BeaconChainError::BlockRewardAttestationError
|
||||
})?
|
||||
} else {
|
||||
self.compute_beacon_block_attestation_reward_altair(block, state)
|
||||
.map_err(|e| {
|
||||
error!(
|
||||
self.log,
|
||||
"Error calculating altair block attestation reward";
|
||||
"error" => ?e
|
||||
);
|
||||
BeaconChainError::BlockRewardAttestationError
|
||||
})?
|
||||
};
|
||||
|
||||
let total_reward = sync_aggregate_reward
|
||||
.safe_add(proposer_slashing_reward)?
|
||||
.safe_add(attester_slashing_reward)?
|
||||
.safe_add(block_attestation_reward)?;
|
||||
|
||||
Ok(StandardBlockReward {
|
||||
proposer_index,
|
||||
total: total_reward,
|
||||
attestations: block_attestation_reward,
|
||||
sync_aggregate: sync_aggregate_reward,
|
||||
proposer_slashings: proposer_slashing_reward,
|
||||
attester_slashings: attester_slashing_reward,
|
||||
})
|
||||
}
|
||||
|
||||
fn compute_beacon_block_sync_aggregate_reward<Payload: AbstractExecPayload<T::EthSpec>>(
|
||||
&self,
|
||||
block: BeaconBlockRef<'_, T::EthSpec, Payload>,
|
||||
state: &BeaconState<T::EthSpec>,
|
||||
) -> Result<BeaconBlockSubRewardValue, BeaconChainError> {
|
||||
if let Ok(sync_aggregate) = block.body().sync_aggregate() {
|
||||
let (_, proposer_reward_per_bit) = compute_sync_aggregate_rewards(state, &self.spec)
|
||||
.map_err(|_| BeaconChainError::BlockRewardSyncError)?;
|
||||
Ok(sync_aggregate.sync_committee_bits.num_set_bits() as u64 * proposer_reward_per_bit)
|
||||
} else {
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_beacon_block_proposer_slashing_reward<Payload: AbstractExecPayload<T::EthSpec>>(
|
||||
&self,
|
||||
block: BeaconBlockRef<'_, T::EthSpec, Payload>,
|
||||
state: &BeaconState<T::EthSpec>,
|
||||
) -> Result<BeaconBlockSubRewardValue, BeaconChainError> {
|
||||
let mut proposer_slashing_reward = 0;
|
||||
|
||||
let proposer_slashings = block.body().proposer_slashings();
|
||||
|
||||
for proposer_slashing in proposer_slashings {
|
||||
proposer_slashing_reward.safe_add_assign(
|
||||
state
|
||||
.get_validator(proposer_slashing.proposer_index() as usize)?
|
||||
.effective_balance
|
||||
.safe_div(self.spec.whistleblower_reward_quotient)?,
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(proposer_slashing_reward)
|
||||
}
|
||||
|
||||
fn compute_beacon_block_attester_slashing_reward<Payload: AbstractExecPayload<T::EthSpec>>(
|
||||
&self,
|
||||
block: BeaconBlockRef<'_, T::EthSpec, Payload>,
|
||||
state: &BeaconState<T::EthSpec>,
|
||||
) -> Result<BeaconBlockSubRewardValue, BeaconChainError> {
|
||||
let mut attester_slashing_reward = 0;
|
||||
|
||||
let attester_slashings = block.body().attester_slashings();
|
||||
|
||||
for attester_slashing in attester_slashings {
|
||||
for attester_index in get_slashable_indices(state, attester_slashing)? {
|
||||
attester_slashing_reward.safe_add_assign(
|
||||
state
|
||||
.get_validator(attester_index as usize)?
|
||||
.effective_balance
|
||||
.safe_div(self.spec.whistleblower_reward_quotient)?,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(attester_slashing_reward)
|
||||
}
|
||||
|
||||
fn compute_beacon_block_attestation_reward_base<Payload: AbstractExecPayload<T::EthSpec>>(
|
||||
&self,
|
||||
block: BeaconBlockRef<'_, T::EthSpec, Payload>,
|
||||
block_root: Hash256,
|
||||
state: &BeaconState<T::EthSpec>,
|
||||
) -> Result<BeaconBlockSubRewardValue, BeaconChainError> {
|
||||
// Call compute_block_reward in the base case
|
||||
// Since base does not have sync aggregate, we only grab attesation portion of the returned
|
||||
// value
|
||||
let mut reward_cache = RewardCache::default();
|
||||
let block_attestation_reward = self
|
||||
.compute_block_reward(block, block_root, state, &mut reward_cache, true)?
|
||||
.attestation_rewards
|
||||
.total;
|
||||
|
||||
Ok(block_attestation_reward)
|
||||
}
|
||||
|
||||
fn compute_beacon_block_attestation_reward_altair<Payload: AbstractExecPayload<T::EthSpec>>(
|
||||
&self,
|
||||
block: BeaconBlockRef<'_, T::EthSpec, Payload>,
|
||||
state: &mut BeaconState<T::EthSpec>,
|
||||
) -> Result<BeaconBlockSubRewardValue, BeaconChainError> {
|
||||
let total_active_balance = state.get_total_active_balance()?;
|
||||
let base_reward_per_increment =
|
||||
altair::BaseRewardPerIncrement::new(total_active_balance, &self.spec)?;
|
||||
|
||||
let mut total_proposer_reward = 0;
|
||||
|
||||
let proposer_reward_denominator = WEIGHT_DENOMINATOR
|
||||
.safe_sub(PROPOSER_WEIGHT)?
|
||||
.safe_mul(WEIGHT_DENOMINATOR)?
|
||||
.safe_div(PROPOSER_WEIGHT)?;
|
||||
|
||||
for attestation in block.body().attestations() {
|
||||
let data = &attestation.data;
|
||||
let inclusion_delay = state.slot().safe_sub(data.slot)?.as_u64();
|
||||
let participation_flag_indices = get_attestation_participation_flag_indices(
|
||||
state,
|
||||
data,
|
||||
inclusion_delay,
|
||||
&self.spec,
|
||||
)?;
|
||||
|
||||
let attesting_indices = get_attesting_indices_from_state(state, attestation)?;
|
||||
|
||||
let mut proposer_reward_numerator = 0;
|
||||
for index in attesting_indices {
|
||||
let index = index as usize;
|
||||
for (flag_index, &weight) in PARTICIPATION_FLAG_WEIGHTS.iter().enumerate() {
|
||||
let epoch_participation =
|
||||
state.get_epoch_participation_mut(data.target.epoch)?;
|
||||
let validator_participation = epoch_participation
|
||||
.get_mut(index)
|
||||
.ok_or(BeaconStateError::ParticipationOutOfBounds(index))?;
|
||||
|
||||
if participation_flag_indices.contains(&flag_index)
|
||||
&& !validator_participation.has_flag(flag_index)?
|
||||
{
|
||||
validator_participation.add_flag(flag_index)?;
|
||||
proposer_reward_numerator.safe_add_assign(
|
||||
altair::get_base_reward(
|
||||
state,
|
||||
index,
|
||||
base_reward_per_increment,
|
||||
&self.spec,
|
||||
)?
|
||||
.safe_mul(weight)?,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
total_proposer_reward.safe_add_assign(
|
||||
proposer_reward_numerator.safe_div(proposer_reward_denominator)?,
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(total_proposer_reward)
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ use crate::blob_cache::BlobCache;
|
||||
use crate::blob_verification::{AsBlock, AvailableBlock, BlockWrapper};
|
||||
use crate::block_times_cache::BlockTimesCache;
|
||||
use crate::block_verification::{
|
||||
check_block_is_finalized_descendant, check_block_relevancy, get_block_root,
|
||||
check_block_is_finalized_checkpoint_or_descendant, check_block_relevancy, get_block_root,
|
||||
signature_verify_chain_segment, BlockError, ExecutionPendingBlock, GossipVerifiedBlock,
|
||||
IntoExecutionPendingBlock, PayloadVerificationOutcome, POS_PANDA_BANNER,
|
||||
};
|
||||
@@ -1025,11 +1025,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
})?
|
||||
.ok_or(Error::BlockHashMissingFromExecutionLayer(exec_block_hash))?;
|
||||
|
||||
//FIXME(sean) avoid the clone by comparing refs to headers (`as_execution_payload_header` method ?)
|
||||
let full_payload: FullPayload<T::EthSpec> = execution_payload.clone().into();
|
||||
|
||||
// Verify payload integrity.
|
||||
let header_from_payload = full_payload.to_execution_payload_header();
|
||||
let header_from_payload = ExecutionPayloadHeader::from(execution_payload.to_ref());
|
||||
if header_from_payload != execution_payload_header {
|
||||
for txn in execution_payload.transactions() {
|
||||
debug!(
|
||||
@@ -2900,7 +2897,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
let mut fork_choice = self.canonical_head.fork_choice_write_lock();
|
||||
|
||||
// Do not import a block that doesn't descend from the finalized root.
|
||||
let signed_block = check_block_is_finalized_descendant(self, &fork_choice, signed_block)?;
|
||||
let signed_block = check_block_is_finalized_checkpoint_or_descendant(self, &fork_choice, signed_block)?;
|
||||
let block = signed_block.message();
|
||||
|
||||
// Register the new block with the fork choice service.
|
||||
|
||||
@@ -792,7 +792,7 @@ impl<T: BeaconChainTypes> GossipVerifiedBlock<T> {
|
||||
// Do not process a block that doesn't descend from the finalized root.
|
||||
//
|
||||
// We check this *before* we load the parent so that we can return a more detailed error.
|
||||
let block = check_block_is_finalized_descendant(
|
||||
let block =check_block_is_finalized_checkpoint_or_descendant(
|
||||
chain,
|
||||
&chain.canonical_head.fork_choice_write_lock(),
|
||||
block,
|
||||
@@ -1647,12 +1647,12 @@ fn check_block_against_finalized_slot<T: BeaconChainTypes>(
|
||||
/// ## Warning
|
||||
///
|
||||
/// Taking a lock on the `chain.canonical_head.fork_choice` might cause a deadlock here.
|
||||
pub fn check_block_is_finalized_descendant<T: BeaconChainTypes, B: IntoBlockWrapper<T::EthSpec>>(
|
||||
pub fn check_block_is_finalized_checkpoint_or_descendant<T: BeaconChainTypes, B: IntoBlockWrapper<T::EthSpec>>(
|
||||
chain: &BeaconChain<T>,
|
||||
fork_choice: &BeaconForkChoice<T>,
|
||||
block: B,
|
||||
block: &Arc<SignedBeaconBlock<T::EthSpec>>,
|
||||
) -> Result<B, BlockError<T::EthSpec>> {
|
||||
if fork_choice.is_descendant_of_finalized(block.parent_root()) {
|
||||
if fork_choice.is_finalized_checkpoint_or_descendant(block.parent_root()) {
|
||||
Ok(block)
|
||||
} else {
|
||||
// If fork choice does *not* consider the parent to be a descendant of the finalized block,
|
||||
|
||||
@@ -51,7 +51,6 @@ pub enum BeaconChainError {
|
||||
},
|
||||
SlotClockDidNotStart,
|
||||
NoStateForSlot(Slot),
|
||||
UnableToFindTargetRoot(Slot),
|
||||
BeaconStateError(BeaconStateError),
|
||||
DBInconsistent(String),
|
||||
DBError(store::Error),
|
||||
@@ -157,10 +156,12 @@ pub enum BeaconChainError {
|
||||
ExecutionForkChoiceUpdateInvalid {
|
||||
status: PayloadStatus,
|
||||
},
|
||||
BlockRewardError,
|
||||
BlockRewardSlotError,
|
||||
BlockRewardAttestationError,
|
||||
BlockRewardSyncError,
|
||||
SyncCommitteeRewardsSyncError,
|
||||
AttestationRewardsError,
|
||||
HeadMissingFromForkChoice(Hash256),
|
||||
FinalizedBlockMissingFromForkChoice(Hash256),
|
||||
HeadBlockMissingFromForkChoice(Hash256),
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#![recursion_limit = "128"] // For lazy-static
|
||||
pub mod attestation_rewards;
|
||||
pub mod attestation_verification;
|
||||
mod attester_cache;
|
||||
pub mod beacon_block_reward;
|
||||
mod beacon_chain;
|
||||
mod beacon_fork_choice_store;
|
||||
pub mod beacon_proposer_cache;
|
||||
|
||||
Reference in New Issue
Block a user