diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index b2d041654..40e30b2fb 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -357,6 +357,7 @@ where self.fork_choice.write().add_attestation( free_attestation.validator_index, &free_attestation.data.beacon_block_root, + &self.spec, )?; Ok(aggregation_outcome) } @@ -486,7 +487,9 @@ where self.state_store.put(&state_root, &ssz_encode(&state)[..])?; // run the fork_choice add_block logic - self.fork_choice.write().add_block(&block, &block_root)?; + self.fork_choice + .write() + .add_block(&block, &block_root, &self.spec)?; // If the parent block was the parent_block, automatically update the canonical head. // @@ -575,7 +578,10 @@ where pub fn fork_choice(&self) -> Result<(), Error> { let present_head = self.finalized_head().beacon_block_root; - let new_head = self.fork_choice.write().find_head(&present_head)?; + let new_head = self + .fork_choice + .write() + .find_head(&present_head, &self.spec)?; if new_head != present_head { let block = self diff --git a/eth2/fork_choice/src/longest_chain.rs b/eth2/fork_choice/src/longest_chain.rs index 8056c11f2..ea2cc33bb 100644 --- a/eth2/fork_choice/src/longest_chain.rs +++ b/eth2/fork_choice/src/longest_chain.rs @@ -1,7 +1,7 @@ use crate::{ForkChoice, ForkChoiceError}; use db::{stores::BeaconBlockStore, ClientDB}; use std::sync::Arc; -use types::{BeaconBlock, Hash256, Slot}; +use types::{BeaconBlock, ChainSpec, Hash256, Slot}; pub struct LongestChain where @@ -30,6 +30,7 @@ impl ForkChoice for LongestChain { &mut self, block: &BeaconBlock, block_hash: &Hash256, + spec: &ChainSpec, ) -> Result<(), ForkChoiceError> { // add the block hash to head_block_hashes removing the parent if it exists self.head_block_hashes @@ -38,12 +39,17 @@ impl ForkChoice for LongestChain { Ok(()) } - fn add_attestation(&mut self, _: u64, _: &Hash256) -> Result<(), ForkChoiceError> { + fn add_attestation( + &mut self, + _: u64, + _: &Hash256, + _: &ChainSpec, + ) -> Result<(), ForkChoiceError> { // do nothing Ok(()) } - fn find_head(&mut self, _: &Hash256) -> Result { + fn find_head(&mut self, _: &Hash256, _: &ChainSpec) -> Result { let mut head_blocks: Vec<(usize, BeaconBlock)> = vec![]; /* * Load all the head_block hashes from the DB as SszBeaconBlocks. diff --git a/eth2/fork_choice/src/optimised_lmd_ghost.rs b/eth2/fork_choice/src/optimised_lmd_ghost.rs index b88aa09bd..e60af4e66 100644 --- a/eth2/fork_choice/src/optimised_lmd_ghost.rs +++ b/eth2/fork_choice/src/optimised_lmd_ghost.rs @@ -347,7 +347,7 @@ impl ForkChoice for OptimisedLMDGhost { let mut current_head = *justified_block_start; - let mut latest_votes = self.get_latest_votes(&state_root, block_slot)?; + let mut latest_votes = self.get_latest_votes(&state_root, &block_slot, spec)?; // remove any votes that don't relate to our current head. latest_votes @@ -370,6 +370,7 @@ impl ForkChoice for OptimisedLMDGhost { if let Some(clear_winner) = self.get_clear_winner( &latest_votes, block_height - (block_height % u64::from(step)) + u64::from(step), + spec, ) { current_head = clear_winner; break; diff --git a/eth2/fork_choice/src/slow_lmd_ghost.rs b/eth2/fork_choice/src/slow_lmd_ghost.rs index 3184150fd..81bc5d628 100644 --- a/eth2/fork_choice/src/slow_lmd_ghost.rs +++ b/eth2/fork_choice/src/slow_lmd_ghost.rs @@ -29,17 +29,11 @@ use std::collections::HashMap; use std::sync::Arc; use types::{ readers::BeaconBlockReader, validator_registry::get_active_validator_indices, BeaconBlock, - Hash256, Slot, + ChainSpec, Hash256, Slot, }; //TODO: Pruning and syncing -//TODO: Sort out global constants -const GENESIS_SLOT: u64 = 0; -const FORK_CHOICE_BALANCE_INCREMENT: u64 = 1e9 as u64; -const MAX_DEPOSIT_AMOUNT: u64 = 32e9 as u64; -const EPOCH_LENGTH: u64 = 64; - pub struct SlowLMDGhost { /// The latest attestation targets as a map of validator index to block hash. //TODO: Could this be a fixed size vec @@ -70,12 +64,14 @@ where pub fn get_latest_votes( &self, state_root: &Hash256, - block_slot: Slot, + block_slot: &Slot, + spec: &ChainSpec, ) -> Result, ForkChoiceError> { // get latest votes // Note: Votes are weighted by min(balance, MAX_DEPOSIT_AMOUNT) // // FORK_CHOICE_BALANCE_INCREMENT // build a hashmap of block_hash to weighted votes + trace!("FORKCHOICE: Getting the latest votes"); let mut latest_votes: HashMap = HashMap::new(); // gets the current weighted votes let current_state = self @@ -84,21 +80,26 @@ where .ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?; let active_validator_indices = get_active_validator_indices( - ¤t_state.validator_registry, - block_slot.epoch(EPOCH_LENGTH), + ¤t_state.validator_registry[..], + block_slot.epoch(spec.epoch_length), + ); + trace!( + "FORKCHOICE: Active validator indicies: {:?}", + active_validator_indices ); for index in active_validator_indices { - let balance = - std::cmp::min(current_state.validator_balances[index], MAX_DEPOSIT_AMOUNT) - / FORK_CHOICE_BALANCE_INCREMENT; + let balance = std::cmp::min( + current_state.validator_balances[index], + spec.max_deposit_amount, + ) / spec.fork_choice_balance_increment; if balance > 0 { if let Some(target) = self.latest_attestation_targets.get(&(index as u64)) { *latest_votes.entry(*target).or_insert_with(|| 0) += balance; } } } - + trace!("FORKCHOICE: Latest votes: {:?}", latest_votes); Ok(latest_votes) } @@ -136,6 +137,7 @@ impl ForkChoice for SlowLMDGhost { &mut self, block: &BeaconBlock, block_hash: &Hash256, + _: &ChainSpec, ) -> Result<(), ForkChoiceError> { // build the children hashmap // add the new block to the children of parent @@ -153,6 +155,7 @@ impl ForkChoice for SlowLMDGhost { &mut self, validator_index: u64, target_block_root: &Hash256, + spec: &ChainSpec, ) -> Result<(), ForkChoiceError> { // simply add the attestation to the latest_attestation_target if the block_height is // larger @@ -168,7 +171,7 @@ impl ForkChoice for SlowLMDGhost { .get_deserialized(&target_block_root)? .ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*target_block_root))? .slot() - .height(Slot::from(GENESIS_SLOT)); + .height(Slot::from(spec.genesis_slot)); // get the height of the past target block let past_block_height = self @@ -176,7 +179,7 @@ impl ForkChoice for SlowLMDGhost { .get_deserialized(&attestation_target)? .ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*attestation_target))? .slot() - .height(Slot::from(GENESIS_SLOT)); + .height(Slot::from(spec.genesis_slot)); // update the attestation only if the new target is higher if past_block_height < block_height { *attestation_target = *target_block_root; @@ -186,7 +189,11 @@ impl ForkChoice for SlowLMDGhost { } /// A very inefficient implementation of LMD ghost. - fn find_head(&mut self, justified_block_start: &Hash256) -> Result { + fn find_head( + &mut self, + justified_block_start: &Hash256, + spec: &ChainSpec, + ) -> Result { let start = self .block_store .get_deserialized(&justified_block_start)? @@ -194,7 +201,7 @@ impl ForkChoice for SlowLMDGhost { let start_state_root = start.state_root(); - let latest_votes = self.get_latest_votes(&start_state_root, start.slot())?; + let latest_votes = self.get_latest_votes(&start_state_root, &start.slot(), spec)?; let mut head_hash = Hash256::zero();