Additional spec updates

This commit is contained in:
Paul Hauner 2019-03-05 09:51:29 +11:00
parent 663d39739f
commit 262e9cf0bc
No known key found for this signature in database
GPG Key ID: D362883A9218FCC6
4 changed files with 63 additions and 44 deletions

View File

@ -555,15 +555,15 @@ impl EpochProcessable for BeaconState {
/* /*
* Validator Registry * Validator Registry
*/ */
self.previous_calculation_epoch = self.current_calculation_epoch; self.previous_shuffling_epoch = self.current_shuffling_epoch;
self.previous_epoch_start_shard = self.current_epoch_start_shard; self.previous_epoch_start_shard = self.current_epoch_start_shard;
debug!( debug!(
"setting previous_epoch_seed to : {}", "setting previous_shuffling_seed to : {}",
self.current_epoch_seed self.current_shuffling_seed
); );
self.previous_epoch_seed = self.current_epoch_seed; self.previous_shuffling_seed = self.current_shuffling_seed;
let should_update_validator_registy = if self.finalized_epoch let should_update_validator_registy = if self.finalized_epoch
> self.validator_registry_update_epoch > self.validator_registry_update_epoch
@ -580,11 +580,11 @@ impl EpochProcessable for BeaconState {
trace!("updating validator registry."); trace!("updating validator registry.");
self.update_validator_registry(spec); self.update_validator_registry(spec);
self.current_calculation_epoch = next_epoch; self.current_shuffling_epoch = next_epoch;
self.current_epoch_start_shard = (self.current_epoch_start_shard self.current_epoch_start_shard = (self.current_epoch_start_shard
+ self.get_current_epoch_committee_count(spec) as u64) + self.get_current_epoch_committee_count(spec) as u64)
% spec.shard_count; % spec.shard_count;
self.current_epoch_seed = self.generate_seed(self.current_calculation_epoch, spec)? self.current_shuffling_seed = self.generate_seed(self.current_shuffling_epoch, spec)?
} else { } else {
trace!("not updating validator registry."); trace!("not updating validator registry.");
let epochs_since_last_registry_update = let epochs_since_last_registry_update =
@ -592,9 +592,9 @@ impl EpochProcessable for BeaconState {
if (epochs_since_last_registry_update > 1) if (epochs_since_last_registry_update > 1)
& epochs_since_last_registry_update.is_power_of_two() & epochs_since_last_registry_update.is_power_of_two()
{ {
self.current_calculation_epoch = next_epoch; self.current_shuffling_epoch = next_epoch;
self.current_epoch_seed = self.current_shuffling_seed =
self.generate_seed(self.current_calculation_epoch, spec)? self.generate_seed(self.current_shuffling_epoch, spec)?
} }
} }

View File

@ -39,8 +39,10 @@ pub enum Error {
EpochOutOfBounds, EpochOutOfBounds,
/// The supplied shard is unknown. It may be larger than the maximum shard count, or not in a /// The supplied shard is unknown. It may be larger than the maximum shard count, or not in a
/// committee for the given slot. /// committee for the given slot.
SlotOutOfBounds,
ShardOutOfBounds, ShardOutOfBounds,
UnableToShuffle, UnableToShuffle,
UnknownValidator,
InsufficientRandaoMixes, InsufficientRandaoMixes,
InsufficientValidators, InsufficientValidators,
InsufficientBlockRoots, InsufficientBlockRoots,
@ -172,7 +174,7 @@ impl BeaconState {
spec.zero_hash; spec.zero_hash;
spec.latest_active_index_roots_length as usize spec.latest_active_index_roots_length as usize
], ],
latest_slashed_balances: vec![0; spec.latest_penalized_exit_length as usize], latest_slashed_balances: vec![0; spec.latest_slashed_exit_length as usize],
latest_attestations: vec![], latest_attestations: vec![],
batched_block_roots: vec![], batched_block_roots: vec![],
@ -711,7 +713,7 @@ impl BeaconState {
/// Process the penalties and prepare the validators who are eligible to withdrawal. /// Process the penalties and prepare the validators who are eligible to withdrawal.
/// ///
/// Spec v0.2.0 /// Spec v0.2.0
pub fn process_penalties_and_exits(&mut self, spec: &ChainSpec) { pub fn process_slashings(&mut self, spec: &ChainSpec) {
let current_epoch = self.current_epoch(spec); let current_epoch = self.current_epoch(spec);
let active_validator_indices = let active_validator_indices =
get_active_validator_indices(&self.validator_registry, current_epoch); get_active_validator_indices(&self.validator_registry, current_epoch);
@ -721,13 +723,12 @@ impl BeaconState {
let validator = &self.validator_registry[index]; let validator = &self.validator_registry[index];
if current_epoch if current_epoch
== validator.penalized_epoch + Epoch::from(spec.latest_penalized_exit_length / 2) == validator.penalized_epoch + Epoch::from(spec.latest_slashed_exit_length / 2)
{ {
let epoch_index: usize = let epoch_index: usize = current_epoch.as_usize() % spec.latest_slashed_exit_length;
current_epoch.as_usize() % spec.latest_penalized_exit_length;
let total_at_start = self.latest_slashed_balances let total_at_start = self.latest_slashed_balances
[(epoch_index + 1) % spec.latest_penalized_exit_length]; [(epoch_index + 1) % spec.latest_slashed_exit_length];
let total_at_end = self.latest_slashed_balances[epoch_index]; let total_at_end = self.latest_slashed_balances[epoch_index];
let total_penalities = total_at_end.saturating_sub(total_at_start); let total_penalities = total_at_end.saturating_sub(total_at_start);
let penalty = self.get_effective_balance(index, spec) let penalty = self.get_effective_balance(index, spec)
@ -736,12 +737,22 @@ impl BeaconState {
safe_sub_assign!(self.validator_balances[index], penalty); safe_sub_assign!(self.validator_balances[index], penalty);
} }
} }
}
/// Process the penalties and prepare the validators who are eligible to withdrawal.
///
/// Spec v0.2.0
pub fn process_exit_queue(&mut self, spec: &ChainSpec) {
let current_epoch = self.current_epoch(spec);
let active_validator_indices =
get_active_validator_indices(&self.validator_registry, current_epoch);
let total_balance = self.get_total_balance(&active_validator_indices[..], spec);
let eligible = |index: usize| { let eligible = |index: usize| {
let validator = &self.validator_registry[index]; let validator = &self.validator_registry[index];
if validator.penalized_epoch <= current_epoch { if validator.penalized_epoch <= current_epoch {
let penalized_withdrawal_epochs = spec.latest_penalized_exit_length / 2; let penalized_withdrawal_epochs = spec.latest_slashed_exit_length / 2;
current_epoch >= validator.penalized_epoch + penalized_withdrawal_epochs as u64 current_epoch >= validator.penalized_epoch + penalized_withdrawal_epochs as u64
} else { } else {
current_epoch >= validator.exit_epoch + spec.min_validator_withdrawal_epochs current_epoch >= validator.exit_epoch + spec.min_validator_withdrawal_epochs
@ -881,7 +892,7 @@ impl BeaconState {
/// this hashmap, each call to `process_deposits` requires an iteration though /// this hashmap, each call to `process_deposits` requires an iteration though
/// `self.validator_registry`. This becomes highly inefficient at scale. /// `self.validator_registry`. This becomes highly inefficient at scale.
/// ///
/// Spec v0.2.0 /// Spec v0.4.0
pub fn process_deposit( pub fn process_deposit(
&mut self, &mut self,
pubkey: PublicKey, pubkey: PublicKey,
@ -893,15 +904,9 @@ impl BeaconState {
) -> Result<usize, ()> { ) -> Result<usize, ()> {
// TODO: update proof of possession to function written above ( // TODO: update proof of possession to function written above (
// requires bls::create_proof_of_possession to be updated // requires bls::create_proof_of_possession to be updated
//
// https://github.com/sigp/lighthouse/issues/239 // https://github.com/sigp/lighthouse/issues/239
if !verify_proof_of_possession(&proof_of_possession, &pubkey) if !verify_proof_of_possession(&proof_of_possession, &pubkey) {
//if !self.validate_proof_of_possession(
// pubkey.clone(),
// proof_of_possession,
// withdrawal_credentials,
// &spec,
// )
{
return Err(()); return Err(());
} }
@ -926,9 +931,9 @@ impl BeaconState {
withdrawal_credentials, withdrawal_credentials,
activation_epoch: spec.far_future_epoch, activation_epoch: spec.far_future_epoch,
exit_epoch: spec.far_future_epoch, exit_epoch: spec.far_future_epoch,
withdrawal_epoch: spec.far_future_epoch, withdrawable_epoch: spec.far_future_epoch,
penalized_epoch: spec.far_future_epoch, initiated_exit: false,
status_flags: None, slashed: false,
}; };
self.validator_registry.push(validator); self.validator_registry.push(validator);
self.validator_balances.push(amount); self.validator_balances.push(amount);
@ -977,22 +982,32 @@ impl BeaconState {
self.get_entry_exit_effect_epoch(current_epoch, spec); self.get_entry_exit_effect_epoch(current_epoch, spec);
} }
/// Penalize the validator of the given ``index``. /// Slash the validator with index ``index``.
/// ///
/// Exits the validator and assigns its effective balance to the block producer for this /// Spec v0.4.0
/// state. pub fn slash_validator(
///
/// Spec v0.2.0
pub fn penalize_validator(
&mut self, &mut self,
validator_index: usize, validator_index: usize,
spec: &ChainSpec, spec: &ChainSpec,
) -> Result<(), Error> { ) -> Result<(), Error> {
self.exit_validator(validator_index, spec);
let current_epoch = self.current_epoch(spec); let current_epoch = self.current_epoch(spec);
self.latest_slashed_balances let validator = &self
[current_epoch.as_usize() % spec.latest_penalized_exit_length] += .validator_registry
.get(validator_index)
.ok_or_else(|| Error::UnknownValidator)?;
if self.slot
>= validator
.withdrawable_epoch
.start_slot(spec.slots_per_epoch)
{
return Err(Error::SlotOutOfBounds);
}
self.exit_validator(validator_index, spec);
self.latest_slashed_balances[current_epoch.as_usize() % spec.latest_slashed_exit_length] +=
self.get_effective_balance(validator_index, spec); self.get_effective_balance(validator_index, spec);
let whistleblower_index = self.get_beacon_proposer_index(self.slot, spec)?; let whistleblower_index = self.get_beacon_proposer_index(self.slot, spec)?;
@ -1005,11 +1020,15 @@ impl BeaconState {
self.validator_balances[validator_index], self.validator_balances[validator_index],
whistleblower_reward whistleblower_reward
); );
self.validator_registry[validator_index].penalized_epoch = current_epoch; self.validator_registry[validator_index].slashed = true;
self.validator_registry[validator_index].withdrawable_epoch =
current_epoch + Epoch::from(spec.latest_slashed_exit_length);
debug!( debug!(
"Whistleblower {} penalized validator {}.", "Whistleblower {} penalized validator {}.",
whistleblower_index, validator_index whistleblower_index, validator_index
); );
Ok(()) Ok(())
} }

View File

@ -142,11 +142,11 @@ impl BeaconStateBuilder {
state.slot = slot; state.slot = slot;
state.validator_registry_update_epoch = epoch - 1; state.validator_registry_update_epoch = epoch - 1;
state.previous_calculation_epoch = epoch - 1; state.previous_shuffling_epoch = epoch - 1;
state.current_calculation_epoch = epoch; state.current_shuffling_epoch = epoch;
state.previous_epoch_seed = Hash256::from(&b"previous_seed"[..]); state.previous_shuffling_seed = Hash256::from(&b"previous_seed"[..]);
state.current_epoch_seed = Hash256::from(&b"current_seed"[..]); state.current_shuffling_seed = Hash256::from(&b"current_seed"[..]);
state.previous_justified_epoch = epoch - 2; state.previous_justified_epoch = epoch - 2;
state.justified_epoch = epoch - 1; state.justified_epoch = epoch - 1;

View File

@ -61,7 +61,7 @@ pub struct ChainSpec {
*/ */
pub latest_block_roots_length: usize, pub latest_block_roots_length: usize,
pub latest_randao_mixes_length: usize, pub latest_randao_mixes_length: usize,
pub latest_index_roots_length: usize, pub latest_active_index_roots_length: usize,
pub latest_slashed_exit_length: usize, pub latest_slashed_exit_length: usize,
/* /*
@ -157,7 +157,7 @@ impl ChainSpec {
*/ */
latest_block_roots_length: 8_192, latest_block_roots_length: 8_192,
latest_randao_mixes_length: 8_192, latest_randao_mixes_length: 8_192,
latest_index_roots_length: 8_192, latest_active_index_roots_length: 8_192,
latest_slashed_exit_length: 8_192, latest_slashed_exit_length: 8_192,
/* /*