Skip to content
This repository has been archived by the owner on Jan 12, 2022. It is now read-only.

Commit

Permalink
update v0.6: high/low balance separation (ethereum/consensus-specs#728)
Browse files Browse the repository at this point in the history
  • Loading branch information
sorpaas committed May 2, 2019
1 parent 8aaf5ab commit deb3836
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 23 deletions.
12 changes: 6 additions & 6 deletions beacon/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub trait Config {
/// Maximum deposit amount.
fn max_deposit_amount(&self) -> Gwei;
/// Fork choice balance increment.
fn fork_choice_balance_increment(&self) -> Gwei;
fn high_balance_increment(&self) -> Gwei;
/// Ejection balance.
fn ejection_balance(&self) -> Gwei;
/// Genesis fork version.
Expand Down Expand Up @@ -241,8 +241,8 @@ pub struct NoVerificationConfig {
pub min_deposit_amount: Gwei,
/// Maximum deposit amount.
pub max_deposit_amount: Gwei,
/// Fork choice balance increment.
pub fork_choice_balance_increment: Gwei,
/// High balance increment.
pub high_balance_increment: Gwei,
/// Ejection balance.
pub ejection_balance: Gwei,
/// Genesis fork version.
Expand Down Expand Up @@ -327,7 +327,7 @@ impl Config for NoVerificationConfig {
fn deposit_contract_tree_depth(&self) -> usize { self.deposit_contract_tree_depth }
fn min_deposit_amount(&self) -> Gwei { self.min_deposit_amount }
fn max_deposit_amount(&self) -> Gwei { self.max_deposit_amount }
fn fork_choice_balance_increment(&self) -> Gwei { self.fork_choice_balance_increment }
fn high_balance_increment(&self) -> Gwei { self.high_balance_increment }
fn ejection_balance(&self) -> Gwei { self.ejection_balance }
fn genesis_fork_version(&self) -> Version { Version::from(self.genesis_fork_version) }
fn genesis_slot(&self) -> Slot { self.genesis_slot }
Expand Down Expand Up @@ -401,7 +401,7 @@ impl NoVerificationConfig {
deposit_contract_tree_depth: 32,
min_deposit_amount: 1_000_000_000,
max_deposit_amount: 32_000_000_000,
fork_choice_balance_increment: 1_000_000_000,
high_balance_increment: 1_000_000_000,
ejection_balance: 16_000_000_000,
genesis_fork_version: [0, 0, 0, 0],
genesis_slot: 4294967296,
Expand Down Expand Up @@ -452,7 +452,7 @@ impl NoVerificationConfig {
deposit_contract_tree_depth: 32,
min_deposit_amount: 1_000_000_000,
max_deposit_amount: 32_000_000_000,
fork_choice_balance_increment: 1_000_000_000,
high_balance_increment: 1_000_000_000,
ejection_balance: 16_000_000_000,
genesis_fork_version: [0, 0, 0, 0],
genesis_slot: 4294967296,
Expand Down
31 changes: 29 additions & 2 deletions beacon/src/executive/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,35 @@ impl<'state, 'config, C: Config> Executive<'state, 'config, C> {
Ok(self.earliest_attestation(index)?.inclusion_slot)
}

fn balance(&self, index: ValidatorIndex) -> Gwei {
self.state.balances[index as usize]
}

fn set_balance(&mut self, index: ValidatorIndex, balance: Gwei) {
let half_increment = self.config.high_balance_increment() / 2;

let validator = &mut self.state.validator_registry[index as usize];
if validator.high_balance > balance || validator.high_balance + 3 * half_increment < balance {
validator.high_balance = balance - balance % self.config.high_balance_increment();
}
self.state.balances[index as usize] = balance;
}

fn increase_balance(&mut self, index: ValidatorIndex, delta: Gwei) {
self.set_balance(index, self.balance(index) + delta);
}

fn decrease_balance(&mut self, index: ValidatorIndex, delta: Gwei) {
let cur_balance = self.balance(index);
self.set_balance(index, if cur_balance >= delta {
cur_balance - delta
} else {
0
});
}

fn effective_balance(&self, index: ValidatorIndex) -> Gwei {
core::cmp::min(self.state.validator_balances[index as usize], self.config.max_deposit_amount())
core::cmp::min(self.balance(index), self.config.max_deposit_amount())
}

fn total_balance(&self, indices: &[ValidatorIndex]) -> Gwei {
Expand Down Expand Up @@ -309,7 +336,7 @@ pub fn genesis_state<C: Config>(deposits: Vec<Deposit>, genesis_time: Timestamp,
},

validator_registry: Vec::new(),
validator_balances: Vec::new(),
balances: Vec::new(),
validator_registry_update_epoch: config.genesis_epoch(),

latest_randao_mixes: {
Expand Down
22 changes: 13 additions & 9 deletions beacon/src/executive/per_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ impl<'state, 'config, C: Config> Executive<'state, 'config, C> {

let whistleblower_index = self.beacon_proposer_index(self.state.slot, false)?;
let whistleblower_reward = self.effective_balance(index) / self.config.whistleblower_reward_quotient();
self.state.validator_balances[whistleblower_index as usize] += whistleblower_reward;
self.state.validator_balances[index as usize] -= whistleblower_reward;
self.increase_balance(whistleblower_index, whistleblower_reward);
self.decrease_balance(index, whistleblower_reward);
self.state.validator_registry[index as usize].slashed = true;
self.state.validator_registry[index as usize].withdrawable_epoch = self.current_epoch() + self.config.latest_slashed_exit_length() as u64;

Expand Down Expand Up @@ -324,7 +324,7 @@ impl<'state, 'config, C: Config> Executive<'state, 'config, C> {

match self.state.validator_index_by_id(&deposit.deposit_data.deposit_input.pubkey) {
Some(index) => {
self.state.validator_balances[index as usize] += deposit.deposit_data.amount;
self.increase_balance(index, deposit.deposit_data.amount);
},
None => {
if !deposit.is_proof_valid(
Expand All @@ -342,10 +342,14 @@ impl<'state, 'config, C: Config> Executive<'state, 'config, C> {
withdrawable_epoch: self.config.far_future_epoch(),
initiated_exit: false,
slashed: false,
high_balance: 0,
};
let validator_index = self.state.validator_registry.len() as u64;

self.state.validator_registry.push(validator);
self.state.validator_balances.push(deposit.deposit_data.amount);
self.state.balances.push(0);

self.set_balance(validator_index, deposit.deposit_data.amount);
},
}

Expand Down Expand Up @@ -389,11 +393,11 @@ impl<'state, 'config, C: Config> Executive<'state, 'config, C> {

/// Push a new `Transfer` to the state.
pub fn push_transfer(&mut self, transfer: Transfer) -> Result<(), Error> {
if self.state.validator_balances[transfer.sender as usize] < core::cmp::max(transfer.amount, transfer.fee) {
if self.balance(transfer.sender) < core::cmp::max(transfer.amount, transfer.fee) {
return Err(Error::TransferNoFund)
}

if !(self.state.validator_balances[transfer.sender as usize] == transfer.amount + transfer.fee || self.state.validator_balances[transfer.sender as usize] >= transfer.amount + transfer.fee + self.config.min_deposit_amount()) {
if !(self.balance(transfer.sender) == transfer.amount + transfer.fee || self.balance(transfer.sender) >= transfer.amount + transfer.fee + self.config.min_deposit_amount()) {
return Err(Error::TransferNoFund)
}

Expand All @@ -418,10 +422,10 @@ impl<'state, 'config, C: Config> Executive<'state, 'config, C> {
return Err(Error::TransferInvalidSignature)
}

self.state.validator_balances[transfer.sender as usize] -= transfer.amount + transfer.fee;
self.state.validator_balances[transfer.recipient as usize] += transfer.amount;
self.decrease_balance(transfer.sender, transfer.amount + transfer.fee);
self.increase_balance(transfer.recipient, transfer.amount);
let proposer_index = self.beacon_proposer_index(self.state.slot, false)?;
self.state.validator_balances[proposer_index as usize] += transfer.fee;
self.increase_balance(proposer_index, transfer.fee);

Ok(())
}
Expand Down
10 changes: 6 additions & 4 deletions beacon/src/executive/per_epoch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,9 @@ impl<'state, 'config, C: Config> Executive<'state, 'config, C> {
let delta1 = self.justification_and_finalization_deltas()?;
let delta2 = self.crosslink_deltas()?;
for i in 0..self.state.validator_registry.len() {
self.state.validator_balances[i] = (self.state.validator_balances[i] + delta1.0[i] + delta2.0[i]).saturating_sub(delta1.1[i] + delta2.1[i]);
let new_balance = (self.balance(i as u64) + delta1.0[i] + delta2.0[i])
.saturating_sub(delta1.1[i] + delta2.1[i]);
self.set_balance(i as u64, new_balance);
}

Ok(())
Expand All @@ -299,7 +301,7 @@ impl<'state, 'config, C: Config> Executive<'state, 'config, C> {
/// Update validator ejections.
pub fn update_ejections(&mut self) {
for index in self.state.active_validator_indices(self.current_epoch()) {
if self.state.validator_balances[index as usize] < self.config.ejection_balance() {
if self.balance(index) < self.config.ejection_balance() {
self.initiate_validator_exit(index);
}
}
Expand Down Expand Up @@ -333,7 +335,7 @@ impl<'state, 'config, C: Config> Executive<'state, 'config, C> {
let mut balance_churn = 0;
for (i, validator) in self.state.validator_registry.clone().into_iter().enumerate() {
let index = i as u64;
if validator.activation_epoch == self.config.far_future_epoch() && self.state.validator_balances[i] >= self.config.max_deposit_amount() {
if validator.activation_epoch == self.config.far_future_epoch() && self.balance(index) >= self.config.max_deposit_amount() {
balance_churn += self.effective_balance(index);
if balance_churn > max_balance_churn {
break
Expand Down Expand Up @@ -407,7 +409,7 @@ impl<'state, 'config, C: Config> Executive<'state, 'config, C> {
self.effective_balance(index) * core::cmp::min(total_penalties * 3, total_balance) / total_balance,
self.effective_balance(index) / self.config.min_penalty_quotient()
);
self.state.validator_balances[i] -= penalty;
self.decrease_balance(index, penalty);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions beacon/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ pub struct BeaconState {

/// Validator registry.
pub validator_registry: Vec<Validator>,
/// Validator balances.
pub validator_balances: Vec<u64>,
/// Balances.
pub balances: Vec<u64>,
/// Last validator registry update epoch.
pub validator_registry_update_epoch: Epoch,

Expand Down
2 changes: 2 additions & 0 deletions beacon/src/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ pub struct Validator {
pub initiated_exit: bool,
/// Was the validator slashed
pub slashed: bool,
/// High balance
pub high_balance: u64,
}

impl Validator {
Expand Down

0 comments on commit deb3836

Please sign in to comment.