Total balance refactor to u128 / val balance cap

This commit is contained in:
aggris2 2023-01-10 12:27:08 +00:00 committed by Shane Bammel
parent a53830fd60
commit 798832c62d
28 changed files with 218 additions and 195 deletions

View File

@ -24,7 +24,7 @@ impl<'a, T: EthSpec> AttMaxCover<'a, T> {
att: AttestationRef<'a, T>, att: AttestationRef<'a, T>,
state: &BeaconState<T>, state: &BeaconState<T>,
reward_cache: &'a RewardCache, reward_cache: &'a RewardCache,
total_active_balance: u64, total_active_balance: u128,
spec: &ChainSpec, spec: &ChainSpec,
) -> Option<Self> { ) -> Option<Self> {
if let BeaconState::Base(ref base_state) = state { if let BeaconState::Base(ref base_state) = state {
@ -39,7 +39,7 @@ impl<'a, T: EthSpec> AttMaxCover<'a, T> {
att: AttestationRef<'a, T>, att: AttestationRef<'a, T>,
state: &BeaconState<T>, state: &BeaconState<T>,
base_state: &BeaconStateBase<T>, base_state: &BeaconStateBase<T>,
total_active_balance: u64, total_active_balance: u128,
spec: &ChainSpec, spec: &ChainSpec,
) -> Option<Self> { ) -> Option<Self> {
let fresh_validators = earliest_attestation_validators(&att, state, base_state); let fresh_validators = earliest_attestation_validators(&att, state, base_state);
@ -73,7 +73,7 @@ impl<'a, T: EthSpec> AttMaxCover<'a, T> {
att: AttestationRef<'a, T>, att: AttestationRef<'a, T>,
state: &BeaconState<T>, state: &BeaconState<T>,
reward_cache: &'a RewardCache, reward_cache: &'a RewardCache,
total_active_balance: u64, total_active_balance: u128,
spec: &ChainSpec, spec: &ChainSpec,
) -> Option<Self> { ) -> Option<Self> {
let att_data = att.attestation_data(); let att_data = att.attestation_data();

View File

@ -223,7 +223,7 @@ impl<T: EthSpec> OperationPool<T> {
all_attestations: &'a AttestationMap<T>, all_attestations: &'a AttestationMap<T>,
state: &'a BeaconState<T>, state: &'a BeaconState<T>,
reward_cache: &'a RewardCache, reward_cache: &'a RewardCache,
total_active_balance: u64, total_active_balance: u128,
validity_filter: impl FnMut(&AttestationRef<'a, T>) -> bool + Send, validity_filter: impl FnMut(&AttestationRef<'a, T>) -> bool + Send,
spec: &'a ChainSpec, spec: &'a ChainSpec,
) -> impl Iterator<Item = AttMaxCover<'a, T>> + Send { ) -> impl Iterator<Item = AttMaxCover<'a, T>> + Send {

View File

@ -56,18 +56,18 @@ pub struct Peer<T: EthSpec> {
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct GlobalValidatorInclusionData { pub struct GlobalValidatorInclusionData {
/// The total effective balance of all active validators during the _current_ epoch. /// The total effective balance of all active validators during the _current_ epoch.
pub current_epoch_active_gwei: u64, pub current_epoch_active_gwei: u128,
/// The total effective balance of all active validators during the _previous_ epoch. /// The total effective balance of all active validators during the _previous_ epoch.
pub previous_epoch_active_gwei: u64, pub previous_epoch_active_gwei: u128,
/// The total effective balance of all validators who attested during the _current_ epoch and /// The total effective balance of all validators who attested during the _current_ epoch and
/// agreed with the state about the beacon block at the first slot of the _current_ epoch. /// agreed with the state about the beacon block at the first slot of the _current_ epoch.
pub current_epoch_target_attesting_gwei: u64, pub current_epoch_target_attesting_gwei: u128,
/// The total effective balance of all validators who attested during the _previous_ epoch and /// The total effective balance of all validators who attested during the _previous_ epoch and
/// agreed with the state about the beacon block at the first slot of the _previous_ epoch. /// agreed with the state about the beacon block at the first slot of the _previous_ epoch.
pub previous_epoch_target_attesting_gwei: u64, pub previous_epoch_target_attesting_gwei: u128,
/// The total effective balance of all validators who attested during the _previous_ epoch and /// The total effective balance of all validators who attested during the _previous_ epoch and
/// agreed with the state about the beacon block at the time of attestation. /// agreed with the state about the beacon block at the time of attestation.
pub previous_epoch_head_attesting_gwei: u64, pub previous_epoch_head_attesting_gwei: u128,
} }
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]

View File

@ -1227,7 +1227,7 @@ where
} }
/// Returns the weight for the given block root. /// Returns the weight for the given block root.
pub fn get_block_weight(&self, block_root: &Hash256) -> Option<u64> { pub fn get_block_weight(&self, block_root: &Hash256) -> Option<u128> {
self.proto_array.get_weight(block_root) self.proto_array.get_weight(block_root)
} }

View File

@ -60,7 +60,7 @@ pub enum Operation {
}, },
AssertWeight { AssertWeight {
block_root: Hash256, block_root: Hash256,
weight: u64, weight: u128,
}, },
} }

View File

@ -9,7 +9,7 @@ pub struct JustifiedBalances {
/// zero. /// zero.
pub effective_balances: Vec<u64>, pub effective_balances: Vec<u64>,
/// The sum of `self.effective_balances`. /// The sum of `self.effective_balances`.
pub total_effective_balance: u64, pub total_effective_balance: u128,
/// The number of active validators included in `self.effective_balances`. /// The number of active validators included in `self.effective_balances`.
pub num_active_validators: u64, pub num_active_validators: u64,
} }
@ -17,7 +17,7 @@ pub struct JustifiedBalances {
impl JustifiedBalances { impl JustifiedBalances {
pub fn from_justified_state<T: EthSpec>(state: &BeaconState<T>) -> Result<Self, ArithError> { pub fn from_justified_state<T: EthSpec>(state: &BeaconState<T>) -> Result<Self, ArithError> {
let current_epoch = state.current_epoch(); let current_epoch = state.current_epoch();
let mut total_effective_balance = 0u64; let mut total_effective_balance = 0u128;
let mut num_active_validators = 0u64; let mut num_active_validators = 0u64;
let effective_balances = state let effective_balances = state
@ -25,7 +25,7 @@ impl JustifiedBalances {
.iter() .iter()
.map(|validator| { .map(|validator| {
if !validator.slashed && validator.is_active_at(current_epoch) { if !validator.slashed && validator.is_active_at(current_epoch) {
total_effective_balance.safe_add_assign(validator.effective_balance)?; total_effective_balance.safe_add_assign(validator.effective_balance as u128)?;
num_active_validators.safe_add_assign(1)?; num_active_validators.safe_add_assign(1)?;
Ok(validator.effective_balance) Ok(validator.effective_balance)
@ -43,12 +43,12 @@ impl JustifiedBalances {
} }
pub fn from_effective_balances(effective_balances: Vec<u64>) -> Result<Self, ArithError> { pub fn from_effective_balances(effective_balances: Vec<u64>) -> Result<Self, ArithError> {
let mut total_effective_balance = 0; let mut total_effective_balance = 0u128;
let mut num_active_validators = 0; let mut num_active_validators = 0;
for &balance in &effective_balances { for &balance in &effective_balances {
if balance != 0 { if balance != 0 {
total_effective_balance.safe_add_assign(balance)?; total_effective_balance.safe_add_assign(balance as u128)?;
num_active_validators.safe_add_assign(1)?; num_active_validators.safe_add_assign(1)?;
} }
} }

View File

@ -89,7 +89,7 @@ pub struct ProtoNode {
pub justified_checkpoint: Option<Checkpoint>, pub justified_checkpoint: Option<Checkpoint>,
#[ssz(with = "four_byte_option_checkpoint")] #[ssz(with = "four_byte_option_checkpoint")]
pub finalized_checkpoint: Option<Checkpoint>, pub finalized_checkpoint: Option<Checkpoint>,
pub weight: u64, pub weight: u128,
#[ssz(with = "four_byte_option_usize")] #[ssz(with = "four_byte_option_usize")]
pub best_child: Option<usize>, pub best_child: Option<usize>,
#[ssz(with = "four_byte_option_usize")] #[ssz(with = "four_byte_option_usize")]
@ -106,7 +106,7 @@ pub struct ProtoNode {
#[derive(PartialEq, Debug, Encode, Decode, Serialize, Deserialize, Copy, Clone)] #[derive(PartialEq, Debug, Encode, Decode, Serialize, Deserialize, Copy, Clone)]
pub struct ProposerBoost { pub struct ProposerBoost {
pub root: Hash256, pub root: Hash256,
pub score: u64, pub score: u128,
} }
impl Default for ProposerBoost { impl Default for ProposerBoost {
@ -147,7 +147,7 @@ impl ProtoArray {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn apply_score_changes<E: EthSpec>( pub fn apply_score_changes<E: EthSpec>(
&mut self, &mut self,
mut deltas: Vec<i64>, mut deltas: Vec<i128>,
justified_checkpoint: Checkpoint, justified_checkpoint: Checkpoint,
finalized_checkpoint: Checkpoint, finalized_checkpoint: Checkpoint,
new_justified_balances: &JustifiedBalances, new_justified_balances: &JustifiedBalances,
@ -190,8 +190,8 @@ impl ProtoArray {
let mut node_delta = if execution_status_is_invalid { let mut node_delta = if execution_status_is_invalid {
// If the node has an invalid execution payload, reduce its weight to zero. // If the node has an invalid execution payload, reduce its weight to zero.
0_i64 0_i128
.checked_sub(node.weight as i64) .checked_sub(node.weight as i128)
.ok_or(Error::InvalidExecutionDeltaOverflow(node_index))? .ok_or(Error::InvalidExecutionDeltaOverflow(node_index))?
} else { } else {
deltas deltas
@ -209,7 +209,7 @@ impl ProtoArray {
&& !execution_status_is_invalid && !execution_status_is_invalid
{ {
node_delta = node_delta node_delta = node_delta
.checked_sub(self.previous_proposer_boost.score as i64) .checked_sub(self.previous_proposer_boost.score as i128)
.ok_or(Error::DeltaOverflow(node_index))?; .ok_or(Error::DeltaOverflow(node_index))?;
} }
// If we find the node matching the current proposer boost root, increase // If we find the node matching the current proposer boost root, increase
@ -228,7 +228,7 @@ impl ProtoArray {
) )
.ok_or(Error::ProposerBoostOverflow(node_index))?; .ok_or(Error::ProposerBoostOverflow(node_index))?;
node_delta = node_delta node_delta = node_delta
.checked_add(proposer_score as i64) .checked_add(proposer_score as i128)
.ok_or(Error::DeltaOverflow(node_index))?; .ok_or(Error::DeltaOverflow(node_index))?;
} }
} }
@ -254,7 +254,7 @@ impl ProtoArray {
} else { } else {
node.weight = node node.weight = node
.weight .weight
.checked_add(node_delta as u64) .checked_add(node_delta as u128)
.ok_or(Error::DeltaOverflow(node_index))?; .ok_or(Error::DeltaOverflow(node_index))?;
} }
@ -1054,16 +1054,16 @@ impl ProtoArray {
pub fn calculate_committee_fraction<E: EthSpec>( pub fn calculate_committee_fraction<E: EthSpec>(
justified_balances: &JustifiedBalances, justified_balances: &JustifiedBalances,
proposer_score_boost: u64, proposer_score_boost: u64,
) -> Option<u64> { ) -> Option<u128> {
let average_balance = justified_balances let average_balance = justified_balances
.total_effective_balance .total_effective_balance
.checked_div(justified_balances.num_active_validators)?; .checked_div(justified_balances.num_active_validators as u128)?;
let committee_size = justified_balances let committee_size = justified_balances
.num_active_validators .num_active_validators
.checked_div(E::slots_per_epoch())?; .checked_div(E::slots_per_epoch())?;
let committee_weight = committee_size.checked_mul(average_balance)?; let committee_weight = (committee_size as u128).checked_mul(average_balance)?;
committee_weight committee_weight
.checked_mul(proposer_score_boost)? .checked_mul(proposer_score_boost as u128)?
.checked_div(100) .checked_div(100)
} }

View File

@ -182,7 +182,7 @@ pub struct ProposerHeadInfo {
/// for a new proposal *if* a re-org is decided on. /// for a new proposal *if* a re-org is decided on.
pub parent_node: ProtoNode, pub parent_node: ProtoNode,
/// The computed fraction of the active committee balance below which we can re-org. /// The computed fraction of the active committee balance below which we can re-org.
pub re_org_weight_threshold: u64, pub re_org_weight_threshold: u128,
/// The current slot from fork choice's point of view, may lead the wall-clock slot by upto /// The current slot from fork choice's point of view, may lead the wall-clock slot by upto
/// 500ms. /// 500ms.
pub current_slot: Slot, pub current_slot: Slot,
@ -241,8 +241,8 @@ pub enum DoNotReOrg {
epochs_since_finalization: u64, epochs_since_finalization: u64,
}, },
HeadNotWeak { HeadNotWeak {
head_weight: u64, head_weight: u128,
re_org_weight_threshold: u64, re_org_weight_threshold: u128,
}, },
HeadNotLate, HeadNotLate,
NotProposing, NotProposing,
@ -465,7 +465,7 @@ impl ProtoArrayForkChoice {
// Only re-org if the head's weight is less than the configured committee fraction. // Only re-org if the head's weight is less than the configured committee fraction.
let head_weight = info.head_node.weight; let head_weight = info.head_node.weight;
let re_org_weight_threshold = info.re_org_weight_threshold; let re_org_weight_threshold = info.re_org_weight_threshold;
let weak_head = head_weight < re_org_weight_threshold; let weak_head = head_weight < re_org_weight_threshold as u128;
if !weak_head { if !weak_head {
return Err(DoNotReOrg::HeadNotWeak { return Err(DoNotReOrg::HeadNotWeak {
head_weight, head_weight,
@ -592,7 +592,7 @@ impl ProtoArrayForkChoice {
// Restore the weight of the node, it would have been set to `0` in // Restore the weight of the node, it would have been set to `0` in
// `apply_score_changes` when it was invalidated. // `apply_score_changes` when it was invalidated.
let mut restored_weight: u64 = self let mut restored_weight: u128 = self
.votes .votes
.0 .0
.iter() .iter()
@ -601,7 +601,8 @@ impl ProtoArrayForkChoice {
if vote.current_root == node.root { if vote.current_root == node.root {
// Any voting validator that does not have a balance should be // Any voting validator that does not have a balance should be
// ignored. This is consistent with `compute_deltas`. // ignored. This is consistent with `compute_deltas`.
self.balances.effective_balances.get(validator_index) let copied_bal = self.balances.effective_balances.get(validator_index).copied().unwrap_or(0);
Some(copied_bal as u128)
} else { } else {
None None
} }
@ -732,7 +733,7 @@ impl ProtoArrayForkChoice {
} }
/// Returns the weight of a given block. /// Returns the weight of a given block.
pub fn get_weight(&self, block_root: &Hash256) -> Option<u64> { pub fn get_weight(&self, block_root: &Hash256) -> Option<u128> {
let block_index = self.proto_array.indices.get(block_root)?; let block_index = self.proto_array.indices.get(block_root)?;
self.proto_array self.proto_array
.nodes .nodes
@ -817,8 +818,8 @@ fn compute_deltas(
old_balances: &[u64], old_balances: &[u64],
new_balances: &[u64], new_balances: &[u64],
equivocating_indices: &BTreeSet<u64>, equivocating_indices: &BTreeSet<u64>,
) -> Result<Vec<i64>, Error> { ) -> Result<Vec<i128>, Error> {
let mut deltas = vec![0_i64; indices.len()]; let mut deltas = vec![0_i128; indices.len()];
for (val_index, vote) in votes.iter_mut().enumerate() { for (val_index, vote) in votes.iter_mut().enumerate() {
// There is no need to create a score change if the validator has never voted or both their // There is no need to create a score change if the validator has never voted or both their
@ -846,7 +847,7 @@ fn compute_deltas(
let delta = deltas let delta = deltas
.get(current_delta_index) .get(current_delta_index)
.ok_or(Error::InvalidNodeDelta(current_delta_index))? .ok_or(Error::InvalidNodeDelta(current_delta_index))?
.checked_sub(old_balance as i64) .checked_sub(old_balance as i128)
.ok_or(Error::DeltaOverflow(current_delta_index))?; .ok_or(Error::DeltaOverflow(current_delta_index))?;
// Array access safe due to check on previous line. // Array access safe due to check on previous line.
@ -877,7 +878,7 @@ fn compute_deltas(
let delta = deltas let delta = deltas
.get(current_delta_index) .get(current_delta_index)
.ok_or(Error::InvalidNodeDelta(current_delta_index))? .ok_or(Error::InvalidNodeDelta(current_delta_index))?
.checked_sub(old_balance as i64) .checked_sub(old_balance as i128)
.ok_or(Error::DeltaOverflow(current_delta_index))?; .ok_or(Error::DeltaOverflow(current_delta_index))?;
// Array access safe due to check on previous line. // Array access safe due to check on previous line.
@ -890,7 +891,7 @@ fn compute_deltas(
let delta = deltas let delta = deltas
.get(next_delta_index) .get(next_delta_index)
.ok_or(Error::InvalidNodeDelta(next_delta_index))? .ok_or(Error::InvalidNodeDelta(next_delta_index))?
.checked_add(new_balance as i64) .checked_add(new_balance as i128)
.ok_or(Error::DeltaOverflow(next_delta_index))?; .ok_or(Error::DeltaOverflow(next_delta_index))?;
// Array access safe due to check on previous line. // Array access safe due to check on previous line.
@ -1233,9 +1234,9 @@ mod test_compute_deltas {
#[test] #[test]
fn all_voted_the_same() { fn all_voted_the_same() {
const BALANCE: u64 = 42; const BALANCE: u64 = 32000000000000000;
let validator_count: usize = 16; let validator_count: usize = 577;
let mut indices = HashMap::new(); let mut indices = HashMap::new();
let mut votes = ElasticList::default(); let mut votes = ElasticList::default();
@ -1273,7 +1274,7 @@ mod test_compute_deltas {
if i == 0 { if i == 0 {
assert_eq!( assert_eq!(
delta, delta,
BALANCE as i64 * validator_count as i64, BALANCE as i128 * validator_count as i128,
"zero'th root should have a delta" "zero'th root should have a delta"
); );
} else { } else {
@ -1291,9 +1292,9 @@ mod test_compute_deltas {
#[test] #[test]
fn different_votes() { fn different_votes() {
const BALANCE: u64 = 42; const BALANCE: u64 = 32000000000000000;
let validator_count: usize = 16; let validator_count: usize = 577;
let mut indices = HashMap::new(); let mut indices = HashMap::new();
let mut votes = ElasticList::default(); let mut votes = ElasticList::default();
@ -1329,7 +1330,7 @@ mod test_compute_deltas {
for delta in deltas.into_iter() { for delta in deltas.into_iter() {
assert_eq!( assert_eq!(
delta, BALANCE as i64, delta, BALANCE as i128,
"each root should have the same delta" "each root should have the same delta"
); );
} }
@ -1344,9 +1345,9 @@ mod test_compute_deltas {
#[test] #[test]
fn moving_votes() { fn moving_votes() {
const BALANCE: u64 = 42; const BALANCE: u64 = 32000000000000000;
let validator_count: usize = 16; let validator_count: usize = 577;
let mut indices = HashMap::new(); let mut indices = HashMap::new();
let mut votes = ElasticList::default(); let mut votes = ElasticList::default();
@ -1380,7 +1381,7 @@ mod test_compute_deltas {
"deltas should have expected length" "deltas should have expected length"
); );
let total_delta = BALANCE as i64 * validator_count as i64; let total_delta = BALANCE as i128 * validator_count as i128;
for (i, delta) in deltas.into_iter().enumerate() { for (i, delta) in deltas.into_iter().enumerate() {
if i == 0 { if i == 0 {
@ -1406,7 +1407,7 @@ mod test_compute_deltas {
#[test] #[test]
fn move_out_of_tree() { fn move_out_of_tree() {
const BALANCE: u64 = 42; const BALANCE: u64 = 32000000000000000;
let mut indices = HashMap::new(); let mut indices = HashMap::new();
let mut votes = ElasticList::default(); let mut votes = ElasticList::default();
@ -1446,7 +1447,7 @@ mod test_compute_deltas {
assert_eq!( assert_eq!(
deltas[0], deltas[0],
0 - BALANCE as i64 * 2, 0 - BALANCE as i128 * 2,
"the block should have lost both balances" "the block should have lost both balances"
); );
@ -1460,10 +1461,10 @@ mod test_compute_deltas {
#[test] #[test]
fn changing_balances() { fn changing_balances() {
const OLD_BALANCE: u64 = 42; const OLD_BALANCE: u64 = 32000000000000000;
const NEW_BALANCE: u64 = OLD_BALANCE * 2; const NEW_BALANCE: u64 = OLD_BALANCE * 2;
let validator_count: usize = 16; let validator_count: usize = 577;
let mut indices = HashMap::new(); let mut indices = HashMap::new();
let mut votes = ElasticList::default(); let mut votes = ElasticList::default();
@ -1501,13 +1502,13 @@ mod test_compute_deltas {
if i == 0 { if i == 0 {
assert_eq!( assert_eq!(
delta, delta,
0 - OLD_BALANCE as i64 * validator_count as i64, 0 - OLD_BALANCE as i128 * validator_count as i128,
"zero'th root should have a negative delta" "zero'th root should have a negative delta"
); );
} else if i == 1 { } else if i == 1 {
assert_eq!( assert_eq!(
delta, delta,
NEW_BALANCE as i64 * validator_count as i64, NEW_BALANCE as i128 * validator_count as i128,
"first root should have positive delta" "first root should have positive delta"
); );
} else { } else {
@ -1525,7 +1526,7 @@ mod test_compute_deltas {
#[test] #[test]
fn validator_appears() { fn validator_appears() {
const BALANCE: u64 = 42; const BALANCE: u64 = 32000000000000000;
let mut indices = HashMap::new(); let mut indices = HashMap::new();
let mut votes = ElasticList::default(); let mut votes = ElasticList::default();
@ -1562,12 +1563,12 @@ mod test_compute_deltas {
assert_eq!( assert_eq!(
deltas[0], deltas[0],
0 - BALANCE as i64, 0 - BALANCE as i128,
"block 1 should have only lost one balance" "block 1 should have only lost one balance"
); );
assert_eq!( assert_eq!(
deltas[1], deltas[1],
2 * BALANCE as i64, 2 * BALANCE as i128,
"block 2 should have gained two balances" "block 2 should have gained two balances"
); );
@ -1581,7 +1582,7 @@ mod test_compute_deltas {
#[test] #[test]
fn validator_disappears() { fn validator_disappears() {
const BALANCE: u64 = 42; const BALANCE: u64 = 32000000000000000;
let mut indices = HashMap::new(); let mut indices = HashMap::new();
let mut votes = ElasticList::default(); let mut votes = ElasticList::default();
@ -1618,11 +1619,11 @@ mod test_compute_deltas {
assert_eq!( assert_eq!(
deltas[0], deltas[0],
0 - BALANCE as i64 * 2, 0 - BALANCE as i128 * 2,
"block 1 should have lost both balances" "block 1 should have lost both balances"
); );
assert_eq!( assert_eq!(
deltas[1], BALANCE as i64, deltas[1], BALANCE as i128,
"block 2 should have only gained one balance" "block 2 should have only gained one balance"
); );
@ -1636,8 +1637,8 @@ mod test_compute_deltas {
#[test] #[test]
fn validator_equivocates() { fn validator_equivocates() {
const OLD_BALANCE: u64 = 42; const OLD_BALANCE: u64 = 32000000000000000;
const NEW_BALANCE: u64 = 43; const NEW_BALANCE: u64 = 33000000000000000;
let mut indices = HashMap::new(); let mut indices = HashMap::new();
let mut votes = ElasticList::default(); let mut votes = ElasticList::default();
@ -1675,11 +1676,11 @@ mod test_compute_deltas {
assert_eq!( assert_eq!(
deltas[0], deltas[0],
-2 * OLD_BALANCE as i64, -2 * OLD_BALANCE as i128,
"block 1 should have lost two old balances" "block 1 should have lost two old balances"
); );
assert_eq!( assert_eq!(
deltas[1], NEW_BALANCE as i64, deltas[1], NEW_BALANCE as i128,
"block 2 should have gained one balance" "block 2 should have gained one balance"
); );

View File

@ -111,6 +111,7 @@ impl_safe_arith!(u8);
impl_safe_arith!(u16); impl_safe_arith!(u16);
impl_safe_arith!(u32); impl_safe_arith!(u32);
impl_safe_arith!(u64); impl_safe_arith!(u64);
impl_safe_arith!(u128);
impl_safe_arith!(usize); impl_safe_arith!(usize);
impl_safe_arith!(i8); impl_safe_arith!(i8);
impl_safe_arith!(i16); impl_safe_arith!(i16);

View File

@ -40,6 +40,7 @@ impl_decodable_for_uint!(u8, 8);
impl_decodable_for_uint!(u16, 16); impl_decodable_for_uint!(u16, 16);
impl_decodable_for_uint!(u32, 32); impl_decodable_for_uint!(u32, 32);
impl_decodable_for_uint!(u64, 64); impl_decodable_for_uint!(u64, 64);
impl_decodable_for_uint!(u128, 128);
#[cfg(target_pointer_width = "32")] #[cfg(target_pointer_width = "32")]
impl_decodable_for_uint!(usize, 32); impl_decodable_for_uint!(usize, 32);

View File

@ -31,6 +31,7 @@ impl_encodable_for_uint!(u8, 8);
impl_encodable_for_uint!(u16, 16); impl_encodable_for_uint!(u16, 16);
impl_encodable_for_uint!(u32, 32); impl_encodable_for_uint!(u32, 32);
impl_encodable_for_uint!(u64, 64); impl_encodable_for_uint!(u64, 64);
impl_encodable_for_uint!(u128, 128);
#[cfg(target_pointer_width = "32")] #[cfg(target_pointer_width = "32")]
impl_encodable_for_uint!(usize, 32); impl_encodable_for_uint!(usize, 32);
@ -581,6 +582,15 @@ mod tests {
); );
} }
#[test]
fn ssz_encode_u128() {
assert_eq!(u128::MAX.as_ssz_bytes(), vec![255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]);
assert_eq!(
(!0_u128).as_ssz_bytes(),
vec![255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
);
}
#[test] #[test]
fn ssz_encode_usize() { fn ssz_encode_usize() {
assert_eq!(1_usize.as_ssz_bytes(), vec![1, 0, 0, 0, 0, 0, 0, 0]); assert_eq!(1_usize.as_ssz_bytes(), vec![1, 0, 0, 0, 0, 0, 0, 0]);

View File

@ -22,6 +22,13 @@ mod round_trip {
round_trip(items); round_trip(items);
} }
#[test]
fn u128() {
let items: Vec<u128> = vec![9998446744072000000000, 9998446744072000000000];
round_trip(items);
}
#[test] #[test]
fn option_u16() { fn option_u16() {
let items: Vec<Option<u16>> = vec![None, Some(2u16)]; let items: Vec<Option<u16>> = vec![None, Some(2u16)];

View File

@ -8,7 +8,7 @@ use types::*;
pub struct BaseRewardPerIncrement(u64); pub struct BaseRewardPerIncrement(u64);
impl BaseRewardPerIncrement { impl BaseRewardPerIncrement {
pub fn new(total_active_balance: u64, spec: &ChainSpec) -> Result<Self, ArithError> { pub fn new(total_active_balance: u128, spec: &ChainSpec) -> Result<Self, ArithError> {
get_base_reward_per_increment(total_active_balance, spec).map(Self) get_base_reward_per_increment(total_active_balance, spec).map(Self)
} }
@ -41,10 +41,10 @@ pub fn get_base_reward<T: EthSpec>(
/// ///
/// Spec v1.1.0 /// Spec v1.1.0
fn get_base_reward_per_increment( fn get_base_reward_per_increment(
total_active_balance: u64, total_active_balance: u128,
spec: &ChainSpec, spec: &ChainSpec,
) -> Result<u64, ArithError> { ) -> Result<u64, ArithError> {
spec.effective_balance_increment spec.effective_balance_increment
.safe_mul(spec.base_reward_factor)? .safe_mul(spec.base_reward_factor)?
.safe_div(total_active_balance.integer_sqrt()) .safe_div(total_active_balance.integer_sqrt() as u64)
} }

View File

@ -7,13 +7,13 @@ pub fn get_base_reward<T: EthSpec>(
state: &BeaconState<T>, state: &BeaconState<T>,
index: usize, index: usize,
// Should be == get_total_active_balance(state, spec) // Should be == get_total_active_balance(state, spec)
total_active_balance: u64, total_active_balance: u128,
spec: &ChainSpec, spec: &ChainSpec,
) -> Result<u64, BeaconStateError> { ) -> Result<u64, BeaconStateError> {
state ((state
.get_effective_balance(index)? .get_effective_balance(index)? as u128)
.safe_mul(spec.base_reward_factor)? .safe_mul(spec.base_reward_factor as u128)?
.safe_div(total_active_balance.integer_sqrt())? .safe_div(total_active_balance.integer_sqrt())? as u64)
.safe_div(spec.base_rewards_per_epoch) .safe_div(spec.base_rewards_per_epoch)
.map_err(Into::into) .map_err(Into::into)
} }

View File

@ -18,13 +18,16 @@ pub use slash_validator::slash_validator;
use safe_arith::SafeArith; use safe_arith::SafeArith;
use types::{BeaconState, BeaconStateError, EthSpec}; use types::{BeaconState, BeaconStateError, EthSpec};
/// Increase the balance of a validator, erroring upon overflow, as per the spec. /// 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, delta: u64,
) -> Result<(), BeaconStateError> { ) -> Result<(), BeaconStateError> {
state.get_balance_mut(index)?.safe_add_assign(delta)?; let balance = state.get_balance_mut(index)?;
if let Err(_) = balance.safe_add_assign(delta) {
*balance = u64::MAX;
}
Ok(()) Ok(())
} }

View File

@ -7,19 +7,19 @@ lazy_static! {
/* /*
* Participation Metrics * Participation Metrics
*/ */
pub static ref PARTICIPATION_PREV_EPOCH_HEAD_ATTESTING_GWEI_TOTAL: Result<IntGauge> = try_create_int_gauge( pub static ref PARTICIPATION_PREV_EPOCH_HEAD_ATTESTING_GWEI_TOTAL: Result<Gauge> = try_create_float_gauge(
"beacon_participation_prev_epoch_head_attesting_gwei_total", "beacon_participation_prev_epoch_head_attesting_gwei_total",
"Total effective balance (gwei) of validators who attested to the head in the previous epoch" "Total effective balance (gwei) of validators who attested to the head in the previous epoch"
); );
pub static ref PARTICIPATION_PREV_EPOCH_TARGET_ATTESTING_GWEI_TOTAL: Result<IntGauge> = try_create_int_gauge( pub static ref PARTICIPATION_PREV_EPOCH_TARGET_ATTESTING_GWEI_TOTAL: Result<Gauge> = try_create_float_gauge(
"beacon_participation_prev_epoch_target_attesting_gwei_total", "beacon_participation_prev_epoch_target_attesting_gwei_total",
"Total effective balance (gwei) of validators who attested to the target in the previous epoch" "Total effective balance (gwei) of validators who attested to the target in the previous epoch"
); );
pub static ref PARTICIPATION_PREV_EPOCH_SOURCE_ATTESTING_GWEI_TOTAL: Result<IntGauge> = try_create_int_gauge( pub static ref PARTICIPATION_PREV_EPOCH_SOURCE_ATTESTING_GWEI_TOTAL: Result<Gauge> = try_create_float_gauge(
"beacon_participation_prev_epoch_source_attesting_gwei_total", "beacon_participation_prev_epoch_source_attesting_gwei_total",
"Total effective balance (gwei) of validators who attested to the source in the previous epoch" "Total effective balance (gwei) of validators who attested to the source in the previous epoch"
); );
pub static ref PARTICIPATION_PREV_EPOCH_ACTIVE_GWEI_TOTAL: Result<IntGauge> = try_create_int_gauge( pub static ref PARTICIPATION_PREV_EPOCH_ACTIVE_GWEI_TOTAL: Result<Gauge> = try_create_float_gauge(
"beacon_participation_prev_epoch_active_gwei_total", "beacon_participation_prev_epoch_active_gwei_total",
"Total effective balance (gwei) of validators active in the previous epoch" "Total effective balance (gwei) of validators active in the previous epoch"
); );

View File

@ -71,10 +71,10 @@ pub fn compute_sync_aggregate_rewards<T: EthSpec>(
) -> Result<(u64, u64), BlockProcessingError> { ) -> Result<(u64, u64), BlockProcessingError> {
let total_active_balance = state.get_total_active_balance()?; let total_active_balance = state.get_total_active_balance()?;
let total_active_increments = let total_active_increments =
total_active_balance.safe_div(spec.effective_balance_increment)?; total_active_balance.safe_div(spec.effective_balance_increment as u128)?;
let total_base_rewards = BaseRewardPerIncrement::new(total_active_balance, spec)? let total_base_rewards = BaseRewardPerIncrement::new(total_active_balance, spec)?
.as_u64() .as_u64()
.safe_mul(total_active_increments)?; .safe_mul(total_active_increments as u64)?;
let max_participant_rewards = total_base_rewards let max_participant_rewards = total_base_rewards
.safe_mul(SYNC_REWARD_WEIGHT)? .safe_mul(SYNC_REWARD_WEIGHT)?
.safe_div(WEIGHT_DENOMINATOR)? .safe_div(WEIGHT_DENOMINATOR)?

View File

@ -47,19 +47,19 @@ pub fn process_epoch<T: EthSpec>(
/// Used to track the changes to a validator's balance. /// Used to track the changes to a validator's balance.
#[derive(Default, Clone)] #[derive(Default, Clone)]
pub struct Delta { pub struct Delta {
pub rewards: u64, pub rewards: u128,
pub penalties: u64, pub penalties: u128,
} }
impl Delta { impl Delta {
/// Reward the validator with the `reward`. /// Reward the validator with the `reward`.
pub fn reward(&mut self, reward: u64) -> Result<(), Error> { pub fn reward(&mut self, reward: u128) -> Result<(), Error> {
self.rewards = self.rewards.safe_add(reward)?; self.rewards = self.rewards.safe_add(reward)?;
Ok(()) Ok(())
} }
/// Penalize the validator with the `penalty`. /// Penalize the validator with the `penalty`.
pub fn penalize(&mut self, penalty: u64) -> Result<(), Error> { pub fn penalize(&mut self, penalty: u128) -> Result<(), Error> {
self.penalties = self.penalties.safe_add(penalty)?; self.penalties = self.penalties.safe_add(penalty)?;
Ok(()) Ok(())
} }

View File

@ -31,23 +31,23 @@ pub enum Error {
/// This is an effort to ensure the `EFFECTIVE_BALANCE_INCREMENT` minimum is always respected. /// This is an effort to ensure the `EFFECTIVE_BALANCE_INCREMENT` minimum is always respected.
#[derive(PartialEq, Debug, Clone, Copy)] #[derive(PartialEq, Debug, Clone, Copy)]
struct Balance { struct Balance {
raw: u64, raw: u128,
minimum: u64, minimum: u128,
} }
impl Balance { impl Balance {
/// Initialize the balance to `0`, or the given `minimum`. /// Initialize the balance to `0`, or the given `minimum`.
pub fn zero(minimum: u64) -> Self { pub fn zero(minimum: u128) -> Self {
Self { raw: 0, minimum } Self { raw: 0, minimum }
} }
/// Returns the balance with respect to the initialization `minimum`. /// Returns the balance with respect to the initialization `minimum`.
pub fn get(&self) -> u64 { pub fn get(&self) -> u128 {
std::cmp::max(self.raw, self.minimum) std::cmp::max(self.raw, self.minimum)
} }
/// Add-assign to the balance. /// Add-assign to the balance.
pub fn safe_add_assign(&mut self, other: u64) -> Result<(), ArithError> { pub fn safe_add_assign(&mut self, other: u128) -> Result<(), ArithError> {
self.raw.safe_add_assign(other) self.raw.safe_add_assign(other)
} }
} }
@ -78,7 +78,7 @@ struct SingleEpochParticipationCache {
impl SingleEpochParticipationCache { impl SingleEpochParticipationCache {
fn new<T: EthSpec>(state: &BeaconState<T>, spec: &ChainSpec) -> Self { fn new<T: EthSpec>(state: &BeaconState<T>, spec: &ChainSpec) -> Self {
let num_validators = state.validators().len(); let num_validators = state.validators().len();
let zero_balance = Balance::zero(spec.effective_balance_increment); let zero_balance = Balance::zero(spec.effective_balance_increment as u128);
Self { Self {
unslashed_participating_indices: vec![None; num_validators], unslashed_participating_indices: vec![None; num_validators],
@ -88,7 +88,7 @@ impl SingleEpochParticipationCache {
} }
/// Returns the total balance of attesters who have `flag_index` set. /// Returns the total balance of attesters who have `flag_index` set.
fn total_flag_balance(&self, flag_index: usize) -> Result<u64, Error> { fn total_flag_balance(&self, flag_index: usize) -> Result<u128, Error> {
self.total_flag_balances self.total_flag_balances
.get(flag_index) .get(flag_index)
.map(Balance::get) .map(Balance::get)
@ -147,7 +147,7 @@ impl SingleEpochParticipationCache {
.ok_or(BeaconStateError::ParticipationOutOfBounds(val_index))?; .ok_or(BeaconStateError::ParticipationOutOfBounds(val_index))?;
// All active validators increase the total active balance. // All active validators increase the total active balance.
self.total_active_balance.safe_add_assign(val_balance)?; self.total_active_balance.safe_add_assign(val_balance as u128)?;
// Only unslashed validators may proceed. // Only unslashed validators may proceed.
if validator.slashed { if validator.slashed {
@ -164,7 +164,7 @@ impl SingleEpochParticipationCache {
// are set for `val_index`. // are set for `val_index`.
for (flag, balance) in self.total_flag_balances.iter_mut().enumerate() { for (flag, balance) in self.total_flag_balances.iter_mut().enumerate() {
if epoch_participation.has_flag(flag)? { if epoch_participation.has_flag(flag)? {
balance.safe_add_assign(val_balance)?; balance.safe_add_assign(val_balance as u128)?;
} }
} }
@ -282,30 +282,30 @@ impl ParticipationCache {
* Balances * Balances
*/ */
pub fn current_epoch_total_active_balance(&self) -> u64 { pub fn current_epoch_total_active_balance(&self) -> u128 {
self.current_epoch_participation.total_active_balance.get() self.current_epoch_participation.total_active_balance.get()
} }
pub fn current_epoch_target_attesting_balance(&self) -> Result<u64, Error> { pub fn current_epoch_target_attesting_balance(&self) -> Result<u128, Error> {
self.current_epoch_participation self.current_epoch_participation
.total_flag_balance(TIMELY_TARGET_FLAG_INDEX) .total_flag_balance(TIMELY_TARGET_FLAG_INDEX)
} }
pub fn previous_epoch_total_active_balance(&self) -> u64 { pub fn previous_epoch_total_active_balance(&self) -> u128 {
self.previous_epoch_participation.total_active_balance.get() self.previous_epoch_participation.total_active_balance.get()
} }
pub fn previous_epoch_target_attesting_balance(&self) -> Result<u64, Error> { pub fn previous_epoch_target_attesting_balance(&self) -> Result<u128, Error> {
self.previous_epoch_participation self.previous_epoch_participation
.total_flag_balance(TIMELY_TARGET_FLAG_INDEX) .total_flag_balance(TIMELY_TARGET_FLAG_INDEX)
} }
pub fn previous_epoch_source_attesting_balance(&self) -> Result<u64, Error> { pub fn previous_epoch_source_attesting_balance(&self) -> Result<u128, Error> {
self.previous_epoch_participation self.previous_epoch_participation
.total_flag_balance(TIMELY_SOURCE_FLAG_INDEX) .total_flag_balance(TIMELY_SOURCE_FLAG_INDEX)
} }
pub fn previous_epoch_head_attesting_balance(&self) -> Result<u64, Error> { pub fn previous_epoch_head_attesting_balance(&self) -> Result<u128, Error> {
self.previous_epoch_participation self.previous_epoch_participation
.total_flag_balance(TIMELY_HEAD_FLAG_INDEX) .total_flag_balance(TIMELY_HEAD_FLAG_INDEX)
} }
@ -400,7 +400,7 @@ impl<'a> UnslashedParticipatingIndices<'a> {
/// ## Notes /// ## Notes
/// ///
/// Respects the `EFFECTIVE_BALANCE_INCREMENT` minimum. /// Respects the `EFFECTIVE_BALANCE_INCREMENT` minimum.
pub fn total_balance(&self) -> Result<u64, Error> { pub fn total_balance(&self) -> Result<u128, Error> {
self.participation self.participation
.total_flag_balances .total_flag_balances
.get(self.flag_index) .get(self.flag_index)

View File

@ -44,8 +44,8 @@ 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)?; increase_balance(state, i, delta.rewards as u64)?;
decrease_balance(state, i, delta.penalties)?; decrease_balance(state, i, delta.penalties as u64)?;
} }
Ok(()) Ok(())
@ -58,7 +58,7 @@ pub fn get_flag_index_deltas<T: EthSpec>(
deltas: &mut [Delta], deltas: &mut [Delta],
state: &BeaconState<T>, state: &BeaconState<T>,
flag_index: usize, flag_index: usize,
total_active_balance: u64, total_active_balance: u128,
participation_cache: &ParticipationCache, participation_cache: &ParticipationCache,
spec: &ChainSpec, spec: &ChainSpec,
) -> Result<(), Error> { ) -> Result<(), Error> {
@ -68,25 +68,25 @@ pub fn get_flag_index_deltas<T: EthSpec>(
let weight = get_flag_weight(flag_index)?; let weight = get_flag_weight(flag_index)?;
let unslashed_participating_balance = unslashed_participating_indices.total_balance()?; let unslashed_participating_balance = unslashed_participating_indices.total_balance()?;
let unslashed_participating_increments = let unslashed_participating_increments =
unslashed_participating_balance.safe_div(spec.effective_balance_increment)?; unslashed_participating_balance.safe_div(spec.effective_balance_increment as u128)?;
let active_increments = total_active_balance.safe_div(spec.effective_balance_increment)?; let active_increments = total_active_balance.safe_div(spec.effective_balance_increment as u128)?;
let base_reward_per_increment = BaseRewardPerIncrement::new(total_active_balance, spec)?; let base_reward_per_increment = BaseRewardPerIncrement::new(total_active_balance, spec)?;
for &index in participation_cache.eligible_validator_indices() { for &index in participation_cache.eligible_validator_indices() {
let base_reward = get_base_reward(state, index, base_reward_per_increment, spec)?; let base_reward = get_base_reward(state, index, base_reward_per_increment, spec)? as u128;
let mut delta = Delta::default(); let mut delta = Delta::default();
if unslashed_participating_indices.contains(index)? { if unslashed_participating_indices.contains(index)? {
if !state.is_in_inactivity_leak(previous_epoch, spec) { if !state.is_in_inactivity_leak(previous_epoch, spec) {
let reward_numerator = base_reward let reward_numerator = base_reward
.safe_mul(weight)? .safe_mul(weight as u128)?
.safe_mul(unslashed_participating_increments)?; .safe_mul(unslashed_participating_increments as u128)?;
delta.reward( delta.reward(
reward_numerator.safe_div(active_increments.safe_mul(WEIGHT_DENOMINATOR)?)?, reward_numerator.safe_div((active_increments as u128).safe_mul(WEIGHT_DENOMINATOR as u128)?)?,
)?; )?;
} }
} else if flag_index != TIMELY_HEAD_FLAG_INDEX { } else if flag_index != TIMELY_HEAD_FLAG_INDEX {
delta.penalize(base_reward.safe_mul(weight)?.safe_div(WEIGHT_DENOMINATOR)?)?; delta.penalize(base_reward.safe_mul(weight as u128)?.safe_div(WEIGHT_DENOMINATOR as u128)?)?;
} }
deltas deltas
.get_mut(index) .get_mut(index)
@ -124,7 +124,7 @@ pub fn get_inactivity_penalty_deltas<T: EthSpec>(
let penalty_denominator = spec let penalty_denominator = spec
.inactivity_score_bias .inactivity_score_bias
.safe_mul(spec.inactivity_penalty_quotient_for_state(state))?; .safe_mul(spec.inactivity_penalty_quotient_for_state(state))?;
delta.penalize(penalty_numerator.safe_div(penalty_denominator)?)?; delta.penalize((penalty_numerator as u128).safe_div(penalty_denominator as u128)?)?;
} }
deltas deltas
.get_mut(index) .get_mut(index)

View File

@ -65,8 +65,8 @@ 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)?; increase_balance(state, i, combined_delta.rewards as u64)?;
decrease_balance(state, i, combined_delta.penalties)?; decrease_balance(state, i, combined_delta.penalties as u64)?;
} }
Ok(()) Ok(())
@ -135,7 +135,7 @@ pub fn get_attestation_deltas<T: EthSpec>(
fn get_attestation_component_delta( fn get_attestation_component_delta(
index_in_unslashed_attesting_indices: bool, index_in_unslashed_attesting_indices: bool,
attesting_balance: u64, attesting_balance: u128,
total_balances: &TotalBalances, total_balances: &TotalBalances,
base_reward: u64, base_reward: u64,
finality_delay: u64, finality_delay: u64,
@ -149,17 +149,17 @@ fn get_attestation_component_delta(
if finality_delay > spec.min_epochs_to_inactivity_penalty { if finality_delay > spec.min_epochs_to_inactivity_penalty {
// Since full base reward will be canceled out by inactivity penalty deltas, // Since full base reward will be canceled out by inactivity penalty deltas,
// optimal participation receives full base reward compensation here. // optimal participation receives full base reward compensation here.
delta.reward(base_reward)?; delta.reward(base_reward as u128)?;
} else { } else {
let reward_numerator = base_reward let reward_numerator = (base_reward as u128)
.safe_mul(attesting_balance.safe_div(spec.effective_balance_increment)?)?; .safe_mul((attesting_balance as u128).safe_div(spec.effective_balance_increment as u128)?)?;
delta.reward( delta.reward(
reward_numerator reward_numerator
.safe_div(total_balance.safe_div(spec.effective_balance_increment)?)?, .safe_div((total_balance as u128).safe_div(spec.effective_balance_increment as u128)?)?,
)?; )?;
} }
} else { } else {
delta.penalize(base_reward)?; delta.penalize(base_reward as u128)?;
} }
Ok(delta) Ok(delta)
@ -231,9 +231,9 @@ fn get_inclusion_delay_delta(
.ok_or(Error::ValidatorStatusesInconsistent)?; .ok_or(Error::ValidatorStatusesInconsistent)?;
let proposer_reward = get_proposer_reward(base_reward, spec)?; let proposer_reward = get_proposer_reward(base_reward, spec)?;
proposer_delta.reward(proposer_reward)?; proposer_delta.reward(proposer_reward as u128)?;
let max_attester_reward = base_reward.safe_sub(proposer_reward)?; let max_attester_reward = base_reward.safe_sub(proposer_reward)?;
delta.reward(max_attester_reward.safe_div(inclusion_info.delay)?)?; delta.reward((max_attester_reward as u128).safe_div(inclusion_info.delay as u128)?)?;
let proposer_index = inclusion_info.proposer_index; let proposer_index = inclusion_info.proposer_index;
Ok((delta, Some((proposer_index, proposer_delta)))) Ok((delta, Some((proposer_index, proposer_delta))))
@ -254,9 +254,9 @@ fn get_inactivity_penalty_delta(
if finality_delay > spec.min_epochs_to_inactivity_penalty { if finality_delay > spec.min_epochs_to_inactivity_penalty {
// If validator is performing optimally this cancels all rewards for a neutral balance // If validator is performing optimally this cancels all rewards for a neutral balance
delta.penalize( delta.penalize(
spec.base_rewards_per_epoch (spec.base_rewards_per_epoch as u128)
.safe_mul(base_reward)? .safe_mul(base_reward as u128)?
.safe_sub(get_proposer_reward(base_reward, spec)?)?, .safe_sub(get_proposer_reward(base_reward, spec)? as u128 )?,
)?; )?;
// Additionally, all validators whose FFG target didn't match are penalized extra // Additionally, all validators whose FFG target didn't match are penalized extra
@ -264,10 +264,10 @@ fn get_inactivity_penalty_delta(
// `index not in get_unslashed_attesting_indices(state, matching_target_attestations)` // `index not in get_unslashed_attesting_indices(state, matching_target_attestations)`
if validator.is_slashed || !validator.is_previous_epoch_target_attester { if validator.is_slashed || !validator.is_previous_epoch_target_attester {
delta.penalize( delta.penalize(
validator (validator
.current_epoch_effective_balance .current_epoch_effective_balance as u128)
.safe_mul(finality_delay)? .safe_mul(finality_delay as u128)?
.safe_div(spec.inactivity_penalty_quotient)?, .safe_div(spec.inactivity_penalty_quotient as u128)?,
)?; )?;
} }
} }

View File

@ -120,29 +120,29 @@ pub struct TotalBalances {
/// The effective balance increment from the spec. /// The effective balance increment from the spec.
effective_balance_increment: u64, effective_balance_increment: u64,
/// The total effective balance of all active validators during the _current_ epoch. /// The total effective balance of all active validators during the _current_ epoch.
current_epoch: u64, current_epoch: u128,
/// The total effective balance of all active validators during the _previous_ epoch. /// The total effective balance of all active validators during the _previous_ epoch.
previous_epoch: u64, previous_epoch: u128,
/// The total effective balance of all validators who attested during the _current_ epoch. /// The total effective balance of all validators who attested during the _current_ epoch.
current_epoch_attesters: u64, current_epoch_attesters: u128,
/// The total effective balance of all validators who attested during the _current_ epoch and /// The total effective balance of all validators who attested during the _current_ epoch and
/// agreed with the state about the beacon block at the first slot of the _current_ epoch. /// agreed with the state about the beacon block at the first slot of the _current_ epoch.
current_epoch_target_attesters: u64, current_epoch_target_attesters: u128,
/// The total effective balance of all validators who attested during the _previous_ epoch. /// The total effective balance of all validators who attested during the _previous_ epoch.
previous_epoch_attesters: u64, previous_epoch_attesters: u128,
/// The total effective balance of all validators who attested during the _previous_ epoch and /// The total effective balance of all validators who attested during the _previous_ epoch and
/// agreed with the state about the beacon block at the first slot of the _previous_ epoch. /// agreed with the state about the beacon block at the first slot of the _previous_ epoch.
previous_epoch_target_attesters: u64, previous_epoch_target_attesters: u128,
/// The total effective balance of all validators who attested during the _previous_ epoch and /// The total effective balance of all validators who attested during the _previous_ epoch and
/// agreed with the state about the beacon block at the time of attestation. /// agreed with the state about the beacon block at the time of attestation.
previous_epoch_head_attesters: u64, previous_epoch_head_attesters: u128,
} }
// Generate a safe accessor for a balance in `TotalBalances`, as per spec `get_total_balance`. // Generate a safe accessor for a balance in `TotalBalances`, as per spec `get_total_balance`.
macro_rules! balance_accessor { macro_rules! balance_accessor {
($field_name:ident) => { ($field_name:ident) => {
pub fn $field_name(&self) -> u64 { pub fn $field_name(&self) -> u128 {
std::cmp::max(self.effective_balance_increment, self.$field_name) std::cmp::max(self.effective_balance_increment as u128, self.$field_name)
} }
}; };
} }
@ -209,14 +209,14 @@ impl ValidatorStatuses {
status.is_active_in_current_epoch = true; status.is_active_in_current_epoch = true;
total_balances total_balances
.current_epoch .current_epoch
.safe_add_assign(effective_balance)?; .safe_add_assign(effective_balance as u128)?;
} }
if validator.is_active_at(state.previous_epoch()) { if validator.is_active_at(state.previous_epoch()) {
status.is_active_in_previous_epoch = true; status.is_active_in_previous_epoch = true;
total_balances total_balances
.previous_epoch .previous_epoch
.safe_add_assign(effective_balance)?; .safe_add_assign(effective_balance as u128)?;
} }
statuses.push(status); statuses.push(status);
@ -293,27 +293,27 @@ impl ValidatorStatuses {
if v.is_current_epoch_attester { if v.is_current_epoch_attester {
self.total_balances self.total_balances
.current_epoch_attesters .current_epoch_attesters
.safe_add_assign(validator_balance)?; .safe_add_assign(validator_balance as u128)?;
} }
if v.is_current_epoch_target_attester { if v.is_current_epoch_target_attester {
self.total_balances self.total_balances
.current_epoch_target_attesters .current_epoch_target_attesters
.safe_add_assign(validator_balance)?; .safe_add_assign(validator_balance as u128)?;
} }
if v.is_previous_epoch_attester { if v.is_previous_epoch_attester {
self.total_balances self.total_balances
.previous_epoch_attesters .previous_epoch_attesters
.safe_add_assign(validator_balance)?; .safe_add_assign(validator_balance as u128)?;
} }
if v.is_previous_epoch_target_attester { if v.is_previous_epoch_target_attester {
self.total_balances self.total_balances
.previous_epoch_target_attesters .previous_epoch_target_attesters
.safe_add_assign(validator_balance)?; .safe_add_assign(validator_balance as u128)?;
} }
if v.is_previous_epoch_head_attester { if v.is_previous_epoch_head_attester {
self.total_balances self.total_balances
.previous_epoch_head_attesters .previous_epoch_head_attesters
.safe_add_assign(validator_balance)?; .safe_add_assign(validator_balance as u128)?;
} }
} }
} }

View File

@ -11,20 +11,20 @@ pub fn process_effective_balance_updates<T: EthSpec>(
let hysteresis_increment = spec let hysteresis_increment = spec
.effective_balance_increment .effective_balance_increment
.safe_div(spec.hysteresis_quotient)?; .safe_div(spec.hysteresis_quotient)?;
let downward_threshold = hysteresis_increment.safe_mul(spec.hysteresis_downward_multiplier)?; let downward_threshold = hysteresis_increment.safe_mul(spec.hysteresis_downward_multiplier)? as u128;
let upward_threshold = hysteresis_increment.safe_mul(spec.hysteresis_upward_multiplier)?; let upward_threshold = hysteresis_increment.safe_mul(spec.hysteresis_upward_multiplier)? as u128;
let (validators, balances) = state.validators_and_balances_mut(); let (validators, balances) = state.validators_and_balances_mut();
for (index, validator) in validators.iter_mut().enumerate() { for (index, validator) in validators.iter_mut().enumerate() {
let balance = balances let balance = balances
.get(index) .get(index)
.copied() .copied()
.ok_or(BeaconStateError::BalancesOutOfBounds(index))?; .ok_or(BeaconStateError::BalancesOutOfBounds(index))? as u128;
if balance.safe_add(downward_threshold)? < validator.effective_balance if (balance).safe_add(downward_threshold)? < validator.effective_balance as u128
|| validator.effective_balance.safe_add(upward_threshold)? < balance || (validator.effective_balance as u128).safe_add(upward_threshold)? < balance
{ {
validator.effective_balance = std::cmp::min( validator.effective_balance = std::cmp::min(
balance.safe_sub(balance.safe_rem(spec.effective_balance_increment)?)?, balance.safe_sub(balance.safe_rem(spec.effective_balance_increment as u128)?)? as u64,
spec.max_effective_balance, spec.max_effective_balance,
); );
} }

View File

@ -23,21 +23,21 @@ impl<T: EthSpec> EpochProcessingSummary<T> {
/// Updates some Prometheus metrics with some values in `self`. /// Updates some Prometheus metrics with some values in `self`.
#[cfg(feature = "metrics")] #[cfg(feature = "metrics")]
pub fn observe_metrics(&self) -> Result<(), ParticipationCacheError> { pub fn observe_metrics(&self) -> Result<(), ParticipationCacheError> {
metrics::set_gauge( metrics::set_float_gauge(
&metrics::PARTICIPATION_PREV_EPOCH_HEAD_ATTESTING_GWEI_TOTAL, &metrics::PARTICIPATION_PREV_EPOCH_HEAD_ATTESTING_GWEI_TOTAL,
self.previous_epoch_head_attesting_balance()? as i64, self.previous_epoch_head_attesting_balance()? as f64,
); );
metrics::set_gauge( metrics::set_float_gauge(
&metrics::PARTICIPATION_PREV_EPOCH_TARGET_ATTESTING_GWEI_TOTAL, &metrics::PARTICIPATION_PREV_EPOCH_TARGET_ATTESTING_GWEI_TOTAL,
self.previous_epoch_target_attesting_balance()? as i64, self.previous_epoch_target_attesting_balance()? as f64,
); );
metrics::set_gauge( metrics::set_float_gauge(
&metrics::PARTICIPATION_PREV_EPOCH_SOURCE_ATTESTING_GWEI_TOTAL, &metrics::PARTICIPATION_PREV_EPOCH_SOURCE_ATTESTING_GWEI_TOTAL,
self.previous_epoch_source_attesting_balance()? as i64, self.previous_epoch_source_attesting_balance()? as f64,
); );
metrics::set_gauge( metrics::set_float_gauge(
&metrics::PARTICIPATION_PREV_EPOCH_ACTIVE_GWEI_TOTAL, &metrics::PARTICIPATION_PREV_EPOCH_ACTIVE_GWEI_TOTAL,
self.previous_epoch_total_active_balance() as i64, self.previous_epoch_total_active_balance() as f64,
); );
Ok(()) Ok(())
@ -52,7 +52,7 @@ impl<T: EthSpec> EpochProcessingSummary<T> {
} }
/// Returns the sum of the effective balance of all validators in the current epoch. /// Returns the sum of the effective balance of all validators in the current epoch.
pub fn current_epoch_total_active_balance(&self) -> u64 { pub fn current_epoch_total_active_balance(&self) -> u128 {
match self { match self {
EpochProcessingSummary::Base { total_balances, .. } => total_balances.current_epoch(), EpochProcessingSummary::Base { total_balances, .. } => total_balances.current_epoch(),
EpochProcessingSummary::Altair { EpochProcessingSummary::Altair {
@ -64,7 +64,7 @@ impl<T: EthSpec> EpochProcessingSummary<T> {
/// Returns the sum of the effective balance of all validators in the current epoch who /// Returns the sum of the effective balance of all validators in the current epoch who
/// included an attestation that matched the target. /// included an attestation that matched the target.
pub fn current_epoch_target_attesting_balance(&self) -> Result<u64, ParticipationCacheError> { pub fn current_epoch_target_attesting_balance(&self) -> Result<u128, ParticipationCacheError> {
match self { match self {
EpochProcessingSummary::Base { total_balances, .. } => { EpochProcessingSummary::Base { total_balances, .. } => {
Ok(total_balances.current_epoch_target_attesters()) Ok(total_balances.current_epoch_target_attesters())
@ -77,7 +77,7 @@ impl<T: EthSpec> EpochProcessingSummary<T> {
} }
/// Returns the sum of the effective balance of all validators in the previous epoch. /// Returns the sum of the effective balance of all validators in the previous epoch.
pub fn previous_epoch_total_active_balance(&self) -> u64 { pub fn previous_epoch_total_active_balance(&self) -> u128 {
match self { match self {
EpochProcessingSummary::Base { total_balances, .. } => total_balances.previous_epoch(), EpochProcessingSummary::Base { total_balances, .. } => total_balances.previous_epoch(),
EpochProcessingSummary::Altair { EpochProcessingSummary::Altair {
@ -140,7 +140,7 @@ impl<T: EthSpec> EpochProcessingSummary<T> {
/// Returns the sum of the effective balance of all validators in the previous epoch who /// Returns the sum of the effective balance of all validators in the previous epoch who
/// included an attestation that matched the target. /// included an attestation that matched the target.
pub fn previous_epoch_target_attesting_balance(&self) -> Result<u64, ParticipationCacheError> { pub fn previous_epoch_target_attesting_balance(&self) -> Result<u128, ParticipationCacheError> {
match self { match self {
EpochProcessingSummary::Base { total_balances, .. } => { EpochProcessingSummary::Base { total_balances, .. } => {
Ok(total_balances.previous_epoch_target_attesters()) Ok(total_balances.previous_epoch_target_attesters())
@ -159,7 +159,7 @@ impl<T: EthSpec> EpochProcessingSummary<T> {
/// ///
/// - Base: any attestation can match the head. /// - Base: any attestation can match the head.
/// - Altair: only "timely" attestations can match the head. /// - Altair: only "timely" attestations can match the head.
pub fn previous_epoch_head_attesting_balance(&self) -> Result<u64, ParticipationCacheError> { pub fn previous_epoch_head_attesting_balance(&self) -> Result<u128, ParticipationCacheError> {
match self { match self {
EpochProcessingSummary::Base { total_balances, .. } => { EpochProcessingSummary::Base { total_balances, .. } => {
Ok(total_balances.previous_epoch_head_attesters()) Ok(total_balances.previous_epoch_head_attesters())
@ -178,7 +178,7 @@ impl<T: EthSpec> EpochProcessingSummary<T> {
/// ///
/// - Base: any attestation can match the source. /// - Base: any attestation can match the source.
/// - Altair: only "timely" attestations can match the source. /// - Altair: only "timely" attestations can match the source.
pub fn previous_epoch_source_attesting_balance(&self) -> Result<u64, ParticipationCacheError> { pub fn previous_epoch_source_attesting_balance(&self) -> Result<u128, ParticipationCacheError> {
match self { match self {
EpochProcessingSummary::Base { total_balances, .. } => { EpochProcessingSummary::Base { total_balances, .. } => {
Ok(total_balances.previous_epoch_attesters()) Ok(total_balances.previous_epoch_attesters())

View File

@ -5,14 +5,14 @@ use types::{BeaconState, BeaconStateError, ChainSpec, EthSpec, Unsigned};
/// Process slashings. /// Process slashings.
pub fn process_slashings<T: EthSpec>( pub fn process_slashings<T: EthSpec>(
state: &mut BeaconState<T>, state: &mut BeaconState<T>,
total_balance: u64, total_balance: u128,
spec: &ChainSpec, spec: &ChainSpec,
) -> Result<(), Error> { ) -> Result<(), Error> {
let epoch = state.current_epoch(); let epoch = state.current_epoch();
let sum_slashings = state.get_all_slashings().iter().copied().safe_sum()?; let sum_slashings = state.get_all_slashings().iter().copied().safe_sum()? as u128;
let adjusted_total_slashing_balance = std::cmp::min( let adjusted_total_slashing_balance = std::cmp::min(
sum_slashings.safe_mul(spec.proportional_slashing_multiplier_for_state(state))?, sum_slashings.safe_mul(spec.proportional_slashing_multiplier_for_state(state) as u128)?,
total_balance, total_balance,
); );
@ -23,19 +23,19 @@ pub fn process_slashings<T: EthSpec>(
== validator.withdrawable_epoch == validator.withdrawable_epoch
{ {
let increment = spec.effective_balance_increment; let increment = spec.effective_balance_increment;
let penalty_numerator = validator let effective_balance = validator.effective_balance as u128;
.effective_balance let penalty_numerator = effective_balance
.safe_div(increment)? .safe_div(increment as u128)?
.safe_mul(adjusted_total_slashing_balance)?; .safe_mul(adjusted_total_slashing_balance)?;
let penalty = penalty_numerator let penalty = penalty_numerator
.safe_div(total_balance)? .safe_div(total_balance)?
.safe_mul(increment)?; .safe_mul(increment as u128)?;
// Equivalent to `decrease_balance(state, index, penalty)`, but avoids borrowing `state`. // Equivalent to `decrease_balance(state, index, penalty)`, but avoids borrowing `state`.
let balance = balances let balance = balances
.get_mut(index) .get_mut(index)
.ok_or(BeaconStateError::BalancesOutOfBounds(index))?; .ok_or(BeaconStateError::BalancesOutOfBounds(index))?;
*balance = balance.saturating_sub(penalty); *balance = balance.saturating_sub(penalty as u64);
} }
} }

View File

@ -7,9 +7,9 @@ use types::{Checkpoint, EthSpec};
#[allow(clippy::if_same_then_else)] // For readability and consistency with spec. #[allow(clippy::if_same_then_else)] // For readability and consistency with spec.
pub fn weigh_justification_and_finalization<T: EthSpec>( pub fn weigh_justification_and_finalization<T: EthSpec>(
mut state: JustificationAndFinalizationState<T>, mut state: JustificationAndFinalizationState<T>,
total_active_balance: u64, total_active_balance: u128,
previous_target_balance: u64, previous_target_balance: u128,
current_target_balance: u64, current_target_balance: u128,
) -> Result<JustificationAndFinalizationState<T>, Error> { ) -> Result<JustificationAndFinalizationState<T>, Error> {
let previous_epoch = state.previous_epoch(); let previous_epoch = state.previous_epoch();
let current_epoch = state.current_epoch(); let current_epoch = state.current_epoch();

View File

@ -311,7 +311,7 @@ where
#[tree_hash(skip_hashing)] #[tree_hash(skip_hashing)]
#[test_random(default)] #[test_random(default)]
#[derivative(Clone(clone_with = "clone_default"))] #[derivative(Clone(clone_with = "clone_default"))]
pub total_active_balance: Option<(Epoch, u64)>, pub total_active_balance: Option<(Epoch, u128)>,
#[serde(skip_serializing, skip_deserializing)] #[serde(skip_serializing, skip_deserializing)]
#[ssz(skip_serializing, skip_deserializing)] #[ssz(skip_serializing, skip_deserializing)]
#[tree_hash(skip_hashing)] #[tree_hash(skip_hashing)]
@ -679,11 +679,11 @@ impl<T: EthSpec> BeaconState<T> {
.get(shuffled_index) .get(shuffled_index)
.ok_or(Error::ShuffleIndexOutOfBounds(shuffled_index))?; .ok_or(Error::ShuffleIndexOutOfBounds(shuffled_index))?;
let random_byte = Self::shuffling_random_byte(i, seed)?; let random_byte = Self::shuffling_random_byte(i, seed)?;
let effective_balance = self.get_effective_balance(candidate_index)?; let effective_balance = self.get_effective_balance(candidate_index)? as u128;
if effective_balance.safe_mul(MAX_RANDOM_BYTE)? if effective_balance.safe_mul(MAX_RANDOM_BYTE as u128)?
>= spec >= (spec
.max_effective_balance .max_effective_balance as u128)
.safe_mul(u64::from(random_byte))? .safe_mul(u64::from(random_byte) as u128)?
{ {
return Ok(candidate_index); return Ok(candidate_index);
} }
@ -865,11 +865,11 @@ impl<T: EthSpec> BeaconState<T> {
.get(shuffled_index) .get(shuffled_index)
.ok_or(Error::ShuffleIndexOutOfBounds(shuffled_index))?; .ok_or(Error::ShuffleIndexOutOfBounds(shuffled_index))?;
let random_byte = Self::shuffling_random_byte(i, seed.as_bytes())?; let random_byte = Self::shuffling_random_byte(i, seed.as_bytes())?;
let effective_balance = self.get_validator(candidate_index)?.effective_balance; let effective_balance = self.get_validator(candidate_index)?.effective_balance as u128;
if effective_balance.safe_mul(MAX_RANDOM_BYTE)? if effective_balance.safe_mul(MAX_RANDOM_BYTE as u128)?
>= spec >= (spec
.max_effective_balance .max_effective_balance as u128)
.safe_mul(u64::from(random_byte))? .safe_mul(u64::from(random_byte) as u128)?
{ {
sync_committee_indices.push(candidate_index); sync_committee_indices.push(candidate_index);
} }
@ -1289,14 +1289,14 @@ impl<T: EthSpec> BeaconState<T> {
&'a self, &'a self,
validator_indices: I, validator_indices: I,
spec: &ChainSpec, spec: &ChainSpec,
) -> Result<u64, Error> { ) -> Result<u128, Error> {
let total_balance = validator_indices.into_iter().try_fold(0_u64, |acc, i| { let total_balance = validator_indices.into_iter().try_fold(0_u128, |acc, i| {
self.get_effective_balance(*i) self.get_effective_balance(*i)
.and_then(|bal| Ok(acc.safe_add(bal)?)) .and_then(|bal| Ok(acc.safe_add(bal as u128)?))
})?; })?;
Ok(std::cmp::max( Ok(std::cmp::max(
total_balance, total_balance,
spec.effective_balance_increment, spec.effective_balance_increment as u128,
)) ))
} }
@ -1306,7 +1306,7 @@ impl<T: EthSpec> BeaconState<T> {
/// the current committee cache is. /// the current committee cache is.
/// ///
/// Returns minimum `EFFECTIVE_BALANCE_INCREMENT`, to avoid div by 0. /// Returns minimum `EFFECTIVE_BALANCE_INCREMENT`, to avoid div by 0.
pub fn get_total_active_balance(&self) -> Result<u64, Error> { pub fn get_total_active_balance(&self) -> Result<u128, Error> {
let (initialized_epoch, balance) = self let (initialized_epoch, balance) = self
.total_active_balance() .total_active_balance()
.ok_or(Error::TotalActiveBalanceCacheUninitialized)?; .ok_or(Error::TotalActiveBalanceCacheUninitialized)?;

View File

@ -22,9 +22,9 @@ use types::{
#[derive(Debug, Clone, PartialEq, Decode, Encode, CompareFields)] #[derive(Debug, Clone, PartialEq, Decode, Encode, CompareFields)]
pub struct Deltas { pub struct Deltas {
#[compare_fields(as_slice)] #[compare_fields(as_slice)]
rewards: Vec<u64>, rewards: Vec<u128>,
#[compare_fields(as_slice)] #[compare_fields(as_slice)]
penalties: Vec<u64>, penalties: Vec<u128>,
} }
// Define "legacy" implementations of `Option<Epoch>`, `Option<NonZeroUsize>` which use four bytes // Define "legacy" implementations of `Option<Epoch>`, `Option<NonZeroUsize>` which use four bytes
@ -185,7 +185,7 @@ fn convert_base_deltas(attestation_deltas: &[AttestationDelta], accessor: Access
fn compute_altair_flag_deltas<E: EthSpec>( fn compute_altair_flag_deltas<E: EthSpec>(
state: &BeaconState<E>, state: &BeaconState<E>,
flag_index: usize, flag_index: usize,
total_active_balance: u64, total_active_balance: u128,
spec: &ChainSpec, spec: &ChainSpec,
) -> Result<Deltas, EpochProcessingError> { ) -> Result<Deltas, EpochProcessingError> {
let mut deltas = vec![Delta::default(); state.validators().len()]; let mut deltas = vec![Delta::default(); state.validators().len()];