Remove dupe info between ChainSpec and EthSpec

This commit is contained in:
Paul Hauner 2019-06-08 07:57:25 -04:00
parent f69d9093a3
commit e74d49fc8a
No known key found for this signature in database
GPG Key ID: 303E4494BB28068C
57 changed files with 299 additions and 252 deletions

View File

@ -96,6 +96,7 @@ pub trait BeaconChainTypes {
/// Represents the "Beacon Chain" component of Ethereum 2.0. Allows import of blocks and block /// Represents the "Beacon Chain" component of Ethereum 2.0. Allows import of blocks and block
/// operations and chooses a canonical head. /// operations and chooses a canonical head.
pub struct BeaconChain<T: BeaconChainTypes> { pub struct BeaconChain<T: BeaconChainTypes> {
pub spec: ChainSpec,
/// Persistent storage for blocks, states, etc. Typically an on-disk store, such as LevelDB. /// Persistent storage for blocks, states, etc. Typically an on-disk store, such as LevelDB.
pub store: Arc<T::Store>, pub store: Arc<T::Store>,
/// Reports the current slot, typically based upon the system clock. /// Reports the current slot, typically based upon the system clock.
@ -148,6 +149,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
genesis_state.build_all_caches(&spec)?; genesis_state.build_all_caches(&spec)?;
Ok(Self { Ok(Self {
spec,
store, store,
slot_clock, slot_clock,
op_pool: OperationPool::new(), op_pool: OperationPool::new(),
@ -160,7 +162,10 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
} }
/// Attempt to load an existing instance from the given `store`. /// Attempt to load an existing instance from the given `store`.
pub fn from_store(store: Arc<T::Store>) -> Result<Option<BeaconChain<T>>, Error> { pub fn from_store(
store: Arc<T::Store>,
spec: ChainSpec,
) -> Result<Option<BeaconChain<T>>, Error> {
let key = Hash256::from_slice(&BEACON_CHAIN_DB_KEY.as_bytes()); let key = Hash256::from_slice(&BEACON_CHAIN_DB_KEY.as_bytes());
let p: PersistedBeaconChain<T> = match store.get(&key) { let p: PersistedBeaconChain<T> = match store.get(&key) {
Err(e) => return Err(e.into()), Err(e) => return Err(e.into()),
@ -168,8 +173,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
Ok(Some(p)) => p, Ok(Some(p)) => p,
}; };
let spec = T::EthSpec::spec();
let slot_clock = T::SlotClock::new( let slot_clock = T::SlotClock::new(
spec.genesis_slot, spec.genesis_slot,
p.state.genesis_time, p.state.genesis_time,
@ -179,6 +182,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
let fork_choice = T::ForkChoice::new(store.clone()); let fork_choice = T::ForkChoice::new(store.clone());
Ok(Some(BeaconChain { Ok(Some(BeaconChain {
spec,
store, store,
slot_clock, slot_clock,
op_pool: OperationPool::default(), op_pool: OperationPool::default(),
@ -363,10 +367,10 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
// If required, transition the new state to the present slot. // If required, transition the new state to the present slot.
for _ in state.slot.as_u64()..present_slot.as_u64() { for _ in state.slot.as_u64()..present_slot.as_u64() {
per_slot_processing(&mut state, &T::EthSpec::spec())?; per_slot_processing(&mut state, &self.spec)?;
} }
state.build_all_caches(&T::EthSpec::spec())?; state.build_all_caches(&self.spec)?;
state state
}; };
@ -400,7 +404,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
/// Ensures the current canonical `BeaconState` has been transitioned to match the `slot_clock`. /// Ensures the current canonical `BeaconState` has been transitioned to match the `slot_clock`.
pub fn catchup_state(&self) -> Result<(), Error> { pub fn catchup_state(&self) -> Result<(), Error> {
let spec = &T::EthSpec::spec(); let spec = &self.spec;
let present_slot = match self.slot_clock.present_slot() { let present_slot = match self.slot_clock.present_slot() {
Ok(Some(slot)) => slot, Ok(Some(slot)) => slot,
@ -426,7 +430,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
/// ///
/// Ideally this shouldn't be required, however we leave it here for testing. /// Ideally this shouldn't be required, however we leave it here for testing.
pub fn ensure_state_caches_are_built(&self) -> Result<(), Error> { pub fn ensure_state_caches_are_built(&self) -> Result<(), Error> {
self.state.write().build_all_caches(&T::EthSpec::spec())?; self.state.write().build_all_caches(&self.spec)?;
Ok(()) Ok(())
} }
@ -469,7 +473,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
/// genesis. /// genesis.
pub fn slots_since_genesis(&self) -> Option<SlotHeight> { pub fn slots_since_genesis(&self) -> Option<SlotHeight> {
let now = self.read_slot_clock()?; let now = self.read_slot_clock()?;
let genesis_slot = T::EthSpec::spec().genesis_slot; let genesis_slot = self.spec.genesis_slot;
if now < genesis_slot { if now < genesis_slot {
None None
@ -494,12 +498,12 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
pub fn block_proposer(&self, slot: Slot) -> Result<usize, BeaconStateError> { pub fn block_proposer(&self, slot: Slot) -> Result<usize, BeaconStateError> {
self.state self.state
.write() .write()
.build_committee_cache(RelativeEpoch::Current, &T::EthSpec::spec())?; .build_committee_cache(RelativeEpoch::Current, &self.spec)?;
let index = self.state.read().get_beacon_proposer_index( let index = self.state.read().get_beacon_proposer_index(
slot, slot,
RelativeEpoch::Current, RelativeEpoch::Current,
&T::EthSpec::spec(), &self.spec,
)?; )?;
Ok(index) Ok(index)
@ -530,7 +534,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
/// Produce an `AttestationData` that is valid for the present `slot` and given `shard`. /// Produce an `AttestationData` that is valid for the present `slot` and given `shard`.
pub fn produce_attestation_data(&self, shard: u64) -> Result<AttestationData, Error> { pub fn produce_attestation_data(&self, shard: u64) -> Result<AttestationData, Error> {
let slots_per_epoch = T::EthSpec::spec().slots_per_epoch; let slots_per_epoch = T::EthSpec::slots_per_epoch();
self.metrics.attestation_production_requests.inc(); self.metrics.attestation_production_requests.inc();
let timer = self.metrics.attestation_production_times.start_timer(); let timer = self.metrics.attestation_production_times.start_timer();
@ -591,9 +595,9 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
self.metrics.attestation_processing_requests.inc(); self.metrics.attestation_processing_requests.inc();
let timer = self.metrics.attestation_processing_times.start_timer(); let timer = self.metrics.attestation_processing_times.start_timer();
let result = let result = self
self.op_pool .op_pool
.insert_attestation(attestation, &*self.state.read(), &T::EthSpec::spec()); .insert_attestation(attestation, &*self.state.read(), &self.spec);
if result.is_ok() { if result.is_ok() {
self.metrics.attestation_processing_successes.inc(); self.metrics.attestation_processing_successes.inc();
@ -610,19 +614,19 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
deposit: Deposit, deposit: Deposit,
) -> Result<DepositInsertStatus, DepositValidationError> { ) -> Result<DepositInsertStatus, DepositValidationError> {
self.op_pool self.op_pool
.insert_deposit(deposit, &*self.state.read(), &T::EthSpec::spec()) .insert_deposit(deposit, &*self.state.read(), &self.spec)
} }
/// Accept some exit and queue it for inclusion in an appropriate block. /// Accept some exit and queue it for inclusion in an appropriate block.
pub fn process_voluntary_exit(&self, exit: VoluntaryExit) -> Result<(), ExitValidationError> { pub fn process_voluntary_exit(&self, exit: VoluntaryExit) -> Result<(), ExitValidationError> {
self.op_pool self.op_pool
.insert_voluntary_exit(exit, &*self.state.read(), &T::EthSpec::spec()) .insert_voluntary_exit(exit, &*self.state.read(), &self.spec)
} }
/// Accept some transfer and queue it for inclusion in an appropriate block. /// Accept some transfer and queue it for inclusion in an appropriate block.
pub fn process_transfer(&self, transfer: Transfer) -> Result<(), TransferValidationError> { pub fn process_transfer(&self, transfer: Transfer) -> Result<(), TransferValidationError> {
self.op_pool self.op_pool
.insert_transfer(transfer, &*self.state.read(), &T::EthSpec::spec()) .insert_transfer(transfer, &*self.state.read(), &self.spec)
} }
/// Accept some proposer slashing and queue it for inclusion in an appropriate block. /// Accept some proposer slashing and queue it for inclusion in an appropriate block.
@ -630,11 +634,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
&self, &self,
proposer_slashing: ProposerSlashing, proposer_slashing: ProposerSlashing,
) -> Result<(), ProposerSlashingValidationError> { ) -> Result<(), ProposerSlashingValidationError> {
self.op_pool.insert_proposer_slashing( self.op_pool
proposer_slashing, .insert_proposer_slashing(proposer_slashing, &*self.state.read(), &self.spec)
&*self.state.read(),
&T::EthSpec::spec(),
)
} }
/// Accept some attester slashing and queue it for inclusion in an appropriate block. /// Accept some attester slashing and queue it for inclusion in an appropriate block.
@ -642,11 +643,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
&self, &self,
attester_slashing: AttesterSlashing, attester_slashing: AttesterSlashing,
) -> Result<(), AttesterSlashingValidationError> { ) -> Result<(), AttesterSlashingValidationError> {
self.op_pool.insert_attester_slashing( self.op_pool
attester_slashing, .insert_attester_slashing(attester_slashing, &*self.state.read(), &self.spec)
&*self.state.read(),
&T::EthSpec::spec(),
)
} }
/// Accept some block and attempt to add it to block DAG. /// Accept some block and attempt to add it to block DAG.
@ -708,18 +706,18 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
// Transition the parent state to the block slot. // Transition the parent state to the block slot.
let mut state: BeaconState<T::EthSpec> = parent_state; let mut state: BeaconState<T::EthSpec> = parent_state;
for _ in state.slot.as_u64()..block.slot.as_u64() { for _ in state.slot.as_u64()..block.slot.as_u64() {
if let Err(e) = per_slot_processing(&mut state, &T::EthSpec::spec()) { if let Err(e) = per_slot_processing(&mut state, &self.spec) {
return Ok(BlockProcessingOutcome::InvalidBlock( return Ok(BlockProcessingOutcome::InvalidBlock(
InvalidBlock::SlotProcessingError(e), InvalidBlock::SlotProcessingError(e),
)); ));
} }
} }
state.build_committee_cache(RelativeEpoch::Current, &T::EthSpec::spec())?; state.build_committee_cache(RelativeEpoch::Current, &self.spec)?;
// Apply the received block to its parent state (which has been transitioned into this // Apply the received block to its parent state (which has been transitioned into this
// slot). // slot).
if let Err(e) = per_block_processing(&mut state, &block, &T::EthSpec::spec()) { if let Err(e) = per_block_processing(&mut state, &block, &self.spec) {
return Ok(BlockProcessingOutcome::InvalidBlock( return Ok(BlockProcessingOutcome::InvalidBlock(
InvalidBlock::PerBlockProcessingError(e), InvalidBlock::PerBlockProcessingError(e),
)); ));
@ -740,7 +738,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
// Register the new block with the fork choice service. // Register the new block with the fork choice service.
self.fork_choice self.fork_choice
.write() .write()
.add_block(&block, &block_root, &T::EthSpec::spec())?; .add_block(&block, &block_root, &self.spec)?;
// Execute the fork choice algorithm, enthroning a new head if discovered. // Execute the fork choice algorithm, enthroning a new head if discovered.
// //
@ -771,7 +769,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
let mut state = self.state.read().clone(); let mut state = self.state.read().clone();
state.build_committee_cache(RelativeEpoch::Current, &T::EthSpec::spec())?; state.build_committee_cache(RelativeEpoch::Current, &self.spec)?;
trace!("Finding attestations for new block..."); trace!("Finding attestations for new block...");
@ -783,9 +781,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
state.latest_block_header.canonical_root() state.latest_block_header.canonical_root()
}; };
let (proposer_slashings, attester_slashings) = self let (proposer_slashings, attester_slashings) =
.op_pool self.op_pool.get_slashings(&*self.state.read(), &self.spec);
.get_slashings(&*self.state.read(), &T::EthSpec::spec());
let mut block = BeaconBlock { let mut block = BeaconBlock {
slot: state.slot, slot: state.slot,
@ -806,16 +803,12 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
attester_slashings, attester_slashings,
attestations: self attestations: self
.op_pool .op_pool
.get_attestations(&*self.state.read(), &T::EthSpec::spec()), .get_attestations(&*self.state.read(), &self.spec),
deposits: self deposits: self.op_pool.get_deposits(&*self.state.read(), &self.spec),
.op_pool
.get_deposits(&*self.state.read(), &T::EthSpec::spec()),
voluntary_exits: self voluntary_exits: self
.op_pool .op_pool
.get_voluntary_exits(&*self.state.read(), &T::EthSpec::spec()), .get_voluntary_exits(&*self.state.read(), &self.spec),
transfers: self transfers: self.op_pool.get_transfers(&*self.state.read(), &self.spec),
.op_pool
.get_transfers(&*self.state.read(), &T::EthSpec::spec()),
}, },
}; };
@ -824,11 +817,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
block.body.attestations.len() block.body.attestations.len()
); );
per_block_processing_without_verifying_block_signature( per_block_processing_without_verifying_block_signature(&mut state, &block, &self.spec)?;
&mut state,
&block,
&T::EthSpec::spec(),
)?;
let state_root = state.canonical_root(); let state_root = state.canonical_root();
@ -849,7 +838,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
let justified_root = { let justified_root = {
let root = self.head().beacon_state.current_justified_root; let root = self.head().beacon_state.current_justified_root;
if root == T::EthSpec::spec().zero_hash { if root == self.spec.zero_hash {
self.genesis_block_root self.genesis_block_root
} else { } else {
root root
@ -860,7 +849,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
let beacon_block_root = self let beacon_block_root = self
.fork_choice .fork_choice
.write() .write()
.find_head(&justified_root, &T::EthSpec::spec())?; .find_head(&justified_root, &self.spec)?;
// End fork choice metrics timer. // End fork choice metrics timer.
timer.observe_duration(); timer.observe_duration();
@ -920,7 +909,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
loop { loop {
let beacon_block_root = last_slot.beacon_block.previous_block_root; let beacon_block_root = last_slot.beacon_block.previous_block_root;
if beacon_block_root == T::EthSpec::spec().zero_hash { if beacon_block_root == self.spec.zero_hash {
break; // Genesis has been reached. break; // Genesis has been reached.
} }

View File

@ -85,8 +85,11 @@ mod test {
use types::{test_utils::TestingBeaconStateBuilder, FoundationEthSpec, Keypair}; use types::{test_utils::TestingBeaconStateBuilder, FoundationEthSpec, Keypair};
fn get_state<T: EthSpec>() -> BeaconState<T> { fn get_state<T: EthSpec>() -> BeaconState<T> {
let builder = let builder = TestingBeaconStateBuilder::from_single_keypair(
TestingBeaconStateBuilder::from_single_keypair(0, &Keypair::random(), &T::spec()); 0,
&Keypair::random(),
&T::default_spec(),
);
let (state, _keypairs) = builder.build(); let (state, _keypairs) = builder.build();
state state
} }

View File

@ -10,7 +10,8 @@ use slot_clock::SlotClock;
use std::sync::Arc; use std::sync::Arc;
use tree_hash::TreeHash; use tree_hash::TreeHash;
use types::{ use types::{
test_utils::TestingBeaconStateBuilder, BeaconBlock, EthSpec, Hash256, LighthouseTestnetEthSpec, test_utils::TestingBeaconStateBuilder, BeaconBlock, ChainSpec, EthSpec, Hash256,
LighthouseTestnetEthSpec,
}; };
/// The number initial validators when starting the `LighthouseTestnet`. /// The number initial validators when starting the `LighthouseTestnet`.
@ -18,8 +19,12 @@ const TESTNET_VALIDATOR_COUNT: usize = 16;
/// Provides a new, initialized `BeaconChain` /// Provides a new, initialized `BeaconChain`
pub trait InitialiseBeaconChain<T: BeaconChainTypes> { pub trait InitialiseBeaconChain<T: BeaconChainTypes> {
fn initialise_beacon_chain(store: Arc<T::Store>, log: Logger) -> BeaconChain<T> { fn initialise_beacon_chain(
maybe_load_from_store_for_testnet::<_, T::Store, T::EthSpec>(store, log) store: Arc<T::Store>,
spec: ChainSpec,
log: Logger,
) -> BeaconChain<T> {
maybe_load_from_store_for_testnet::<_, T::Store, T::EthSpec>(store, spec, log)
} }
} }
@ -48,13 +53,14 @@ impl<T: BeaconChainTypes> InitialiseBeaconChain<T> for TestnetDiskBeaconChainTyp
/// Loads a `BeaconChain` from `store`, if it exists. Otherwise, create a new chain from genesis. /// Loads a `BeaconChain` from `store`, if it exists. Otherwise, create a new chain from genesis.
fn maybe_load_from_store_for_testnet<T, U: Store, V: EthSpec>( fn maybe_load_from_store_for_testnet<T, U: Store, V: EthSpec>(
store: Arc<U>, store: Arc<U>,
spec: ChainSpec,
log: Logger, log: Logger,
) -> BeaconChain<T> ) -> BeaconChain<T>
where where
T: BeaconChainTypes<Store = U>, T: BeaconChainTypes<Store = U>,
T::ForkChoice: ForkChoice<U>, T::ForkChoice: ForkChoice<U>,
{ {
if let Ok(Some(beacon_chain)) = BeaconChain::from_store(store.clone()) { if let Ok(Some(beacon_chain)) = BeaconChain::from_store(store.clone(), spec.clone()) {
info!( info!(
log, log,
"Loaded BeaconChain from store"; "Loaded BeaconChain from store";
@ -65,8 +71,6 @@ where
beacon_chain beacon_chain
} else { } else {
info!(log, "Initializing new BeaconChain from genesis"); info!(log, "Initializing new BeaconChain from genesis");
let spec = T::EthSpec::spec();
let state_builder = TestingBeaconStateBuilder::from_default_keypairs_file_if_exists( let state_builder = TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(
TESTNET_VALIDATOR_COUNT, TESTNET_VALIDATOR_COUNT,
&spec, &spec,
@ -92,7 +96,7 @@ where
slot_clock, slot_clock,
genesis_state, genesis_state,
genesis_block, genesis_block,
spec.clone(), spec,
fork_choice, fork_choice,
) )
.expect("Terminate if beacon chain generation fails") .expect("Terminate if beacon chain generation fails")

View File

@ -4,24 +4,26 @@ use network::NetworkConfig;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
use types::ChainSpec;
/// The core configuration of a Lighthouse beacon node. /// The core configuration of a Lighthouse beacon node.
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ClientConfig { pub struct ClientConfig {
pub data_dir: String, pub data_dir: String,
pub spec: String, pub spec_constants: String,
pub db_type: String, pub db_type: String,
db_name: String, db_name: String,
pub network: network::NetworkConfig, pub network: network::NetworkConfig,
pub rpc: rpc::RPCConfig, pub rpc: rpc::RPCConfig,
pub http: HttpServerConfig, //pub ipc_conf: pub http: HttpServerConfig, //pub ipc_conf:
pub spec: ChainSpec,
} }
impl Default for ClientConfig { impl Default for ClientConfig {
fn default() -> Self { fn default() -> Self {
Self { Self {
data_dir: ".lighthouse".to_string(), data_dir: ".lighthouse".to_string(),
spec: "testnet".to_string(), spec_constants: "testnet".to_string(),
db_type: "disk".to_string(), db_type: "disk".to_string(),
db_name: "chain_db".to_string(), db_name: "chain_db".to_string(),
// Note: there are no default bootnodes specified. // Note: there are no default bootnodes specified.
@ -29,6 +31,7 @@ impl Default for ClientConfig {
network: NetworkConfig::new(vec![]), network: NetworkConfig::new(vec![]),
rpc: rpc::RPCConfig::default(), rpc: rpc::RPCConfig::default(),
http: HttpServerConfig::default(), http: HttpServerConfig::default(),
spec: ChainSpec::lighthouse_testnet(8),
} }
} }
} }

View File

@ -17,7 +17,6 @@ use std::sync::Arc;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use tokio::runtime::TaskExecutor; use tokio::runtime::TaskExecutor;
use tokio::timer::Interval; use tokio::timer::Interval;
use types::EthSpec;
pub use beacon_chain::BeaconChainTypes; pub use beacon_chain::BeaconChainTypes;
pub use beacon_chain_types::InitialiseBeaconChain; pub use beacon_chain_types::InitialiseBeaconChain;
@ -58,10 +57,14 @@ where
) -> error::Result<Self> { ) -> error::Result<Self> {
let metrics_registry = Registry::new(); let metrics_registry = Registry::new();
let store = Arc::new(store); let store = Arc::new(store);
let spec = T::EthSpec::spec(); let seconds_per_slot = config.spec.seconds_per_slot;
// Load a `BeaconChain` from the store, or create a new one if it does not exist. // Load a `BeaconChain` from the store, or create a new one if it does not exist.
let beacon_chain = Arc::new(T::initialise_beacon_chain(store, log.clone())); let beacon_chain = Arc::new(T::initialise_beacon_chain(
store,
config.spec.clone(),
log.clone(),
));
// Registry all beacon chain metrics with the global registry. // Registry all beacon chain metrics with the global registry.
beacon_chain beacon_chain
.metrics .metrics
@ -143,7 +146,7 @@ where
// set up the validator work interval - start at next slot and proceed every slot // set up the validator work interval - start at next slot and proceed every slot
let interval = { let interval = {
// Set the interval to start at the next slot, and every slot after // Set the interval to start at the next slot, and every slot after
let slot_duration = Duration::from_secs(spec.seconds_per_slot); let slot_duration = Duration::from_secs(seconds_per_slot);
//TODO: Handle checked add correctly //TODO: Handle checked add correctly
Interval::new(Instant::now() + duration_to_next_slot, slot_duration) Interval::new(Instant::now() + duration_to_next_slot, slot_duration)
}; };

View File

@ -261,7 +261,7 @@ mod test {
#[test] #[test]
fn ssz_encoding() { fn ssz_encoding() {
let original = PubsubMessage::Block(BeaconBlock::empty(&FoundationEthSpec::spec())); let original = PubsubMessage::Block(BeaconBlock::empty(&FoundationEthSpec::default_spec()));
let encoded = ssz_encode(&original); let encoded = ssz_encode(&original);

View File

@ -10,7 +10,6 @@ use persistent::Read;
use router::Router; use router::Router;
use serde_json::json; use serde_json::json;
use std::sync::Arc; use std::sync::Arc;
use types::EthSpec;
/// Yields a handler for the HTTP API. /// Yields a handler for the HTTP API.
pub fn build_handler<T: BeaconChainTypes + 'static>( pub fn build_handler<T: BeaconChainTypes + 'static>(
@ -65,7 +64,7 @@ fn handle_fork<T: BeaconChainTypes + 'static>(req: &mut Request) -> IronResult<R
let response = json!({ let response = json!({
"fork": beacon_chain.head().beacon_state.fork, "fork": beacon_chain.head().beacon_state.fork,
"chain_id": T::EthSpec::spec().chain_id "chain_id": beacon_chain.spec.chain_id
}); });
Ok(Response::with((Status::Ok, response.to_string()))) Ok(Response::with((Status::Ok, response.to_string())))

View File

@ -158,7 +158,7 @@ impl<T: BeaconChainTypes> SimpleSync<T> {
hello: HelloMessage, hello: HelloMessage,
network: &mut NetworkContext, network: &mut NetworkContext,
) { ) {
let spec = T::EthSpec::spec(); let spec = &self.chain.spec;
let remote = PeerSyncInfo::from(hello); let remote = PeerSyncInfo::from(hello);
let local = PeerSyncInfo::from(&self.chain); let local = PeerSyncInfo::from(&self.chain);
@ -214,7 +214,7 @@ impl<T: BeaconChainTypes> SimpleSync<T> {
debug!(self.log, "Peer has high finalized epoch"; "peer" => format!("{:?}", peer_id)); debug!(self.log, "Peer has high finalized epoch"; "peer" => format!("{:?}", peer_id));
let start_slot = local let start_slot = local
.latest_finalized_epoch .latest_finalized_epoch
.start_slot(spec.slots_per_epoch); .start_slot(T::EthSpec::slots_per_epoch());
let required_slots = remote.best_slot - start_slot; let required_slots = remote.best_slot - start_slot;
self.request_block_roots( self.request_block_roots(
@ -231,7 +231,7 @@ impl<T: BeaconChainTypes> SimpleSync<T> {
debug!(self.log, "Peer has higher best slot"; "peer" => format!("{:?}", peer_id)); debug!(self.log, "Peer has higher best slot"; "peer" => format!("{:?}", peer_id));
let start_slot = local let start_slot = local
.latest_finalized_epoch .latest_finalized_epoch
.start_slot(spec.slots_per_epoch); .start_slot(T::EthSpec::slots_per_epoch());
let required_slots = remote.best_slot - start_slot; let required_slots = remote.best_slot - start_slot;
self.request_block_roots( self.request_block_roots(
@ -795,7 +795,7 @@ impl<T: BeaconChainTypes> SimpleSync<T> {
fn slot_is_finalized(&self, slot: Slot) -> bool { fn slot_is_finalized(&self, slot: Slot) -> bool {
slot <= hello_message(&self.chain) slot <= hello_message(&self.chain)
.latest_finalized_epoch .latest_finalized_epoch
.start_slot(T::EthSpec::spec().slots_per_epoch) .start_slot(T::EthSpec::slots_per_epoch())
} }
/// Generates our current state in the form of a HELLO RPC message. /// Generates our current state in the form of a HELLO RPC message.
@ -806,7 +806,7 @@ impl<T: BeaconChainTypes> SimpleSync<T> {
/// Build a `HelloMessage` representing the state of the given `beacon_chain`. /// Build a `HelloMessage` representing the state of the given `beacon_chain`.
fn hello_message<T: BeaconChainTypes>(beacon_chain: &BeaconChain<T>) -> HelloMessage { fn hello_message<T: BeaconChainTypes>(beacon_chain: &BeaconChain<T>) -> HelloMessage {
let spec = T::EthSpec::spec(); let spec = &beacon_chain.spec;
let state = &beacon_chain.head().beacon_state; let state = &beacon_chain.head().beacon_state;
HelloMessage { HelloMessage {

View File

@ -5,7 +5,6 @@ use protos::services::{Empty, Fork, NodeInfoResponse};
use protos::services_grpc::BeaconNodeService; use protos::services_grpc::BeaconNodeService;
use slog::{trace, warn}; use slog::{trace, warn};
use std::sync::Arc; use std::sync::Arc;
use types::EthSpec;
#[derive(Clone)] #[derive(Clone)]
pub struct BeaconNodeServiceInstance<T: BeaconChainTypes> { pub struct BeaconNodeServiceInstance<T: BeaconChainTypes> {
@ -33,7 +32,7 @@ impl<T: BeaconChainTypes> BeaconNodeService for BeaconNodeServiceInstance<T> {
fork.set_current_version(state_fork.current_version.to_vec()); fork.set_current_version(state_fork.current_version.to_vec());
fork.set_epoch(state_fork.epoch.into()); fork.set_epoch(state_fork.epoch.into());
let spec = T::EthSpec::spec(); let spec = &self.chain.spec;
node_info.set_fork(fork); node_info.set_fork(fork);
node_info.set_genesis_time(genesis_time); node_info.set_genesis_time(genesis_time);

View File

@ -14,7 +14,6 @@ pub struct ValidatorServiceInstance<T: BeaconChainTypes> {
pub chain: Arc<BeaconChain<T>>, pub chain: Arc<BeaconChain<T>>,
pub log: slog::Logger, pub log: slog::Logger,
} }
//TODO: Refactor Errors
impl<T: BeaconChainTypes> ValidatorService for ValidatorServiceInstance<T> { impl<T: BeaconChainTypes> ValidatorService for ValidatorServiceInstance<T> {
/// For a list of validator public keys, this function returns the slot at which each /// For a list of validator public keys, this function returns the slot at which each
@ -29,14 +28,15 @@ impl<T: BeaconChainTypes> ValidatorService for ValidatorServiceInstance<T> {
let validators = req.get_validators(); let validators = req.get_validators();
trace!(self.log, "RPC request"; "endpoint" => "GetValidatorDuties", "epoch" => req.get_epoch()); trace!(self.log, "RPC request"; "endpoint" => "GetValidatorDuties", "epoch" => req.get_epoch());
let spec = T::EthSpec::spec(); let spec = &self.chain.spec;
let state = &self.chain.current_state(); let state = &self.chain.current_state();
let epoch = Epoch::from(req.get_epoch()); let epoch = Epoch::from(req.get_epoch());
let mut resp = GetDutiesResponse::new(); let mut resp = GetDutiesResponse::new();
let resp_validators = resp.mut_active_validators(); let resp_validators = resp.mut_active_validators();
let relative_epoch = let relative_epoch =
match RelativeEpoch::from_epoch(state.slot.epoch(spec.slots_per_epoch), epoch) { match RelativeEpoch::from_epoch(state.slot.epoch(T::EthSpec::slots_per_epoch()), epoch)
{
Ok(v) => v, Ok(v) => v,
Err(e) => { Err(e) => {
// incorrect epoch // incorrect epoch
@ -52,7 +52,7 @@ impl<T: BeaconChainTypes> ValidatorService for ValidatorServiceInstance<T> {
}; };
let validator_proposers: Result<Vec<usize>, _> = epoch let validator_proposers: Result<Vec<usize>, _> = epoch
.slot_iter(spec.slots_per_epoch) .slot_iter(T::EthSpec::slots_per_epoch())
.map(|slot| state.get_beacon_proposer_index(slot, relative_epoch, &spec)) .map(|slot| state.get_beacon_proposer_index(slot, relative_epoch, &spec))
.collect(); .collect();
let validator_proposers = match validator_proposers { let validator_proposers = match validator_proposers {
@ -148,7 +148,7 @@ impl<T: BeaconChainTypes> ValidatorService for ValidatorServiceInstance<T> {
// check if the validator needs to propose a block // check if the validator needs to propose a block
if let Some(slot) = validator_proposers.iter().position(|&v| val_index == v) { if let Some(slot) = validator_proposers.iter().position(|&v| val_index == v) {
duty.set_block_production_slot( duty.set_block_production_slot(
epoch.start_slot(spec.slots_per_epoch).as_u64() + slot as u64, epoch.start_slot(T::EthSpec::slots_per_epoch()).as_u64() + slot as u64,
); );
} else { } else {
// no blocks to propose this epoch // no blocks to propose this epoch

View File

@ -27,11 +27,11 @@ pub fn run_beacon_node(config: ClientConfig, log: &slog::Logger) -> error::Resul
.db_path() .db_path()
.ok_or_else::<error::Error, _>(|| "Unable to access database path".into())?; .ok_or_else::<error::Error, _>(|| "Unable to access database path".into())?;
let db_type = &config.db_type; let db_type = &config.db_type;
let spec = &config.spec; let spec_constants = &config.spec_constants;
let other_config = config.clone(); let other_config = config.clone();
let result = match (db_type.as_str(), spec.as_str()) { let result = match (db_type.as_str(), spec_constants.as_str()) {
("disk", "testnet") => { ("disk", "testnet") => {
run::<TestnetDiskBeaconChainTypes>(&db_path, config, executor, runtime, log) run::<TestnetDiskBeaconChainTypes>(&db_path, config, executor, runtime, log)
} }
@ -50,7 +50,7 @@ pub fn run_beacon_node(config: ClientConfig, log: &slog::Logger) -> error::Resul
"Started beacon node"; "Started beacon node";
"p2p_listen_addresses" => format!("{:?}", &other_config.network.listen_addresses()), "p2p_listen_addresses" => format!("{:?}", &other_config.network.listen_addresses()),
"data_dir" => format!("{:?}", other_config.data_dir()), "data_dir" => format!("{:?}", other_config.data_dir()),
"spec" => &other_config.spec, "spec_constants" => &other_config.spec_constants,
"db_type" => &other_config.db_type, "db_type" => &other_config.db_type,
); );
} }

View File

@ -61,7 +61,7 @@ mod tests {
#[test] #[test]
fn read_slot() { fn read_slot() {
let spec = FewValidatorsEthSpec::spec(); let spec = FewValidatorsEthSpec::default_spec();
let test_slot = |slot: Slot| { let test_slot = |slot: Slot| {
let mut block = BeaconBlock::empty(&spec); let mut block = BeaconBlock::empty(&spec);
@ -85,7 +85,7 @@ mod tests {
#[test] #[test]
fn read_previous_block_root() { fn read_previous_block_root() {
let spec = FewValidatorsEthSpec::spec(); let spec = FewValidatorsEthSpec::default_spec();
let test_root = |root: Hash256| { let test_root = |root: Hash256| {
let mut block = BeaconBlock::empty(&spec); let mut block = BeaconBlock::empty(&spec);
@ -130,7 +130,7 @@ mod tests {
fn chain_without_skips() { fn chain_without_skips() {
let n: usize = 10; let n: usize = 10;
let store = MemoryStore::open(); let store = MemoryStore::open();
let spec = FewValidatorsEthSpec::spec(); let spec = FewValidatorsEthSpec::default_spec();
let slots: Vec<usize> = (0..n).collect(); let slots: Vec<usize> = (0..n).collect();
let blocks_and_roots = build_chain(&store, &slots, &spec); let blocks_and_roots = build_chain(&store, &slots, &spec);
@ -154,7 +154,7 @@ mod tests {
#[test] #[test]
fn chain_with_skips() { fn chain_with_skips() {
let store = MemoryStore::open(); let store = MemoryStore::open();
let spec = FewValidatorsEthSpec::spec(); let spec = FewValidatorsEthSpec::default_spec();
let slots = vec![0, 1, 2, 5]; let slots = vec![0, 1, 2, 5];

View File

@ -19,7 +19,7 @@ fn setup(
let store = MemoryStore::open(); let store = MemoryStore::open();
let builder: TestingForkChoiceBuilder<MemoryStore, TestedEthSpec> = let builder: TestingForkChoiceBuilder<MemoryStore, TestedEthSpec> =
TestingForkChoiceBuilder::new(validator_count, chain_length, Arc::new(store)); TestingForkChoiceBuilder::new(validator_count, chain_length, Arc::new(store));
let spec = TestedEthSpec::spec(); let spec = TestedEthSpec::default_spec();
(builder, spec) (builder, spec)
} }

View File

@ -17,7 +17,7 @@ fn main() {
.map(|_| builder.build()) .map(|_| builder.build())
.collect(); .collect();
let spec = &FoundationEthSpec::spec(); let spec = &FoundationEthSpec::default_spec();
println!("Running {} times...", repetitions); println!("Running {} times...", repetitions);
for fc in fork_choosers { for fc in fork_choosers {

View File

@ -68,7 +68,7 @@ impl<T: Store, E: EthSpec> BitwiseLMDGhost<T, E> {
.ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?; .ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?;
let active_validator_indices = let active_validator_indices =
current_state.get_active_validator_indices(block_slot.epoch(spec.slots_per_epoch)); current_state.get_active_validator_indices(block_slot.epoch(E::slots_per_epoch()));
for index in active_validator_indices { for index in active_validator_indices {
let balance = std::cmp::min(current_state.balances[index], spec.max_effective_balance) let balance = std::cmp::min(current_state.balances[index], spec.max_effective_balance)

View File

@ -68,7 +68,7 @@ impl<T: Store, E: EthSpec> OptimizedLMDGhost<T, E> {
.ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?; .ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?;
let active_validator_indices = let active_validator_indices =
current_state.get_active_validator_indices(block_slot.epoch(spec.slots_per_epoch)); current_state.get_active_validator_indices(block_slot.epoch(E::slots_per_epoch()));
for index in active_validator_indices { for index in active_validator_indices {
let balance = std::cmp::min(current_state.balances[index], spec.max_effective_balance) let balance = std::cmp::min(current_state.balances[index], spec.max_effective_balance)

View File

@ -40,7 +40,7 @@ impl<T: Store, E: EthSpec> SlowLMDGhost<T, E> {
.ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?; .ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?;
let active_validator_indices = let active_validator_indices =
current_state.get_active_validator_indices(block_slot.epoch(spec.slots_per_epoch)); current_state.get_active_validator_indices(block_slot.epoch(E::slots_per_epoch()));
for index in active_validator_indices { for index in active_validator_indices {
let balance = std::cmp::min(current_state.balances[index], spec.max_effective_balance) let balance = std::cmp::min(current_state.balances[index], spec.max_effective_balance)

View File

@ -40,10 +40,10 @@ impl<S: Store, E: EthSpec> TestingForkChoiceBuilder<S, E> {
} }
fn get_state<T: EthSpec>(validator_count: usize) -> BeaconState<T> { fn get_state<T: EthSpec>(validator_count: usize) -> BeaconState<T> {
let spec = &T::spec(); let spec = T::default_spec();
let builder: TestingBeaconStateBuilder<T> = let builder: TestingBeaconStateBuilder<T> =
TestingBeaconStateBuilder::from_single_keypair(validator_count, &Keypair::random(), spec); TestingBeaconStateBuilder::from_single_keypair(validator_count, &Keypair::random(), &spec);
let (state, _keypairs) = builder.build(); let (state, _keypairs) = builder.build();
state state
} }
@ -58,7 +58,7 @@ fn get_chain_of_blocks<T: EthSpec, U: Store>(
validator_count: usize, validator_count: usize,
store: Arc<U>, store: Arc<U>,
) -> Vec<(Hash256, BeaconBlock)> { ) -> Vec<(Hash256, BeaconBlock)> {
let spec = T::spec(); let spec = T::default_spec();
let mut blocks_and_roots: Vec<(Hash256, BeaconBlock)> = vec![]; let mut blocks_and_roots: Vec<(Hash256, BeaconBlock)> = vec![];
let mut unique_hashes = (0..).into_iter().map(|i| Hash256::from(i)); let mut unique_hashes = (0..).into_iter().map(|i| Hash256::from(i));
let mut random_block = BeaconBlock::random_for_test(&mut XorShiftRng::from_seed([42; 16])); let mut random_block = BeaconBlock::random_for_test(&mut XorShiftRng::from_seed([42; 16]));

View File

@ -61,7 +61,7 @@ fn test_yaml_vectors<T: ForkChoice<MemoryStore>>(
let test_cases = load_test_cases_from_yaml(yaml_file_path); let test_cases = load_test_cases_from_yaml(yaml_file_path);
// default vars // default vars
let spec = FoundationEthSpec::spec(); let spec = FoundationEthSpec::default_spec();
let zero_hash = Hash256::zero(); let zero_hash = Hash256::zero();
let eth1_data = Eth1Data { let eth1_data = Eth1Data {
deposit_count: 0, deposit_count: 0,
@ -204,7 +204,7 @@ where
let store = Arc::new(MemoryStore::open()); let store = Arc::new(MemoryStore::open());
let fork_choice = ForkChoice::new(store.clone()); let fork_choice = ForkChoice::new(store.clone());
let spec = FoundationEthSpec::spec(); let spec = FoundationEthSpec::default_spec();
let mut state_builder: TestingBeaconStateBuilder<FoundationEthSpec> = let mut state_builder: TestingBeaconStateBuilder<FoundationEthSpec> =
TestingBeaconStateBuilder::from_single_keypair(num_validators, &Keypair::random(), &spec); TestingBeaconStateBuilder::from_single_keypair(num_validators, &Keypair::random(), &spec);

View File

@ -676,7 +676,7 @@ mod tests {
} }
fn test_state(rng: &mut XorShiftRng) -> (ChainSpec, BeaconState<FoundationEthSpec>) { fn test_state(rng: &mut XorShiftRng) -> (ChainSpec, BeaconState<FoundationEthSpec>) {
let spec = FoundationEthSpec::spec(); let spec = FoundationEthSpec::default_spec();
let mut state = BeaconState::random_for_test(rng); let mut state = BeaconState::random_for_test(rng);
@ -721,21 +721,21 @@ mod tests {
fn attestation_test_state<E: EthSpec>( fn attestation_test_state<E: EthSpec>(
num_committees: usize, num_committees: usize,
) -> (BeaconState<E>, Vec<Keypair>, ChainSpec) { ) -> (BeaconState<E>, Vec<Keypair>, ChainSpec) {
let spec = E::spec(); let spec = E::default_spec();
let num_validators = let num_validators =
num_committees * spec.slots_per_epoch as usize * spec.target_committee_size; num_committees * T::slots_per_epoch() as usize * spec.target_committee_size;
let mut state_builder = TestingBeaconStateBuilder::from_default_keypairs_file_if_exists( let mut state_builder = TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(
num_validators, num_validators,
&spec, &spec,
); );
let slot_offset = 1000 * spec.slots_per_epoch + spec.slots_per_epoch / 2; let slot_offset = 1000 * T::slots_per_epoch() + T::slots_per_epoch() / 2;
let slot = spec.genesis_slot + slot_offset; let slot = spec.genesis_slot + slot_offset;
state_builder.teleport_to_slot(slot, &spec); state_builder.teleport_to_slot(slot, &spec);
state_builder.build_caches(&spec).unwrap(); state_builder.build_caches(&spec).unwrap();
let (state, keypairs) = state_builder.build(); let (state, keypairs) = state_builder.build();
(state, keypairs, FoundationEthSpec::spec()) (state, keypairs, FoundationEthSpec::default_spec())
} }
#[test] #[test]
@ -852,7 +852,7 @@ mod tests {
// But once we advance to more than an epoch after the attestation, it should prune it // But once we advance to more than an epoch after the attestation, it should prune it
// out of existence. // out of existence.
state.slot += 2 * spec.slots_per_epoch; state.slot += 2 * T::slots_per_epoch();
op_pool.prune_attestations(state); op_pool.prune_attestations(state);
assert_eq!(op_pool.num_attestations(), 0); assert_eq!(op_pool.num_attestations(), 0);
} }

View File

@ -23,7 +23,7 @@ pub fn bench_epoch_processing_n_validators(c: &mut Criterion, validator_count: u
TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(validator_count, &spec); TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(validator_count, &spec);
// Set the state to be just before an epoch transition. // Set the state to be just before an epoch transition.
let target_slot = (spec.genesis_epoch + 4).end_slot(spec.slots_per_epoch); let target_slot = (spec.genesis_epoch + 4).end_slot(T::slots_per_epoch());
builder.teleport_to_slot(target_slot, &spec); builder.teleport_to_slot(target_slot, &spec);
// Builds all caches; benches will not contain shuffling/committee building times. // Builds all caches; benches will not contain shuffling/committee building times.
@ -38,10 +38,10 @@ pub fn bench_epoch_processing_n_validators(c: &mut Criterion, validator_count: u
// Assert that the state has an attestations for each committee that is able to include an // Assert that the state has an attestations for each committee that is able to include an
// attestation in the state. // attestation in the state.
let committees_per_epoch = spec.get_epoch_committee_count(validator_count); let committees_per_epoch = spec.get_epoch_committee_count(validator_count);
let committees_per_slot = committees_per_epoch / spec.slots_per_epoch; let committees_per_slot = committees_per_epoch / T::slots_per_epoch();
let previous_epoch_attestations = committees_per_epoch; let previous_epoch_attestations = committees_per_epoch;
let current_epoch_attestations = let current_epoch_attestations =
committees_per_slot * (spec.slots_per_epoch - spec.min_attestation_inclusion_delay); committees_per_slot * (T::slots_per_epoch() - spec.min_attestation_inclusion_delay);
assert_eq!( assert_eq!(
state.latest_attestations.len() as u64, state.latest_attestations.len() as u64,
previous_epoch_attestations + current_epoch_attestations, previous_epoch_attestations + current_epoch_attestations,

View File

@ -34,7 +34,7 @@ pub fn block_processing_worst_case(c: &mut Criterion) {
bench_builder.maximize_block_operations(&spec); bench_builder.maximize_block_operations(&spec);
// Set the state and block to be in the last slot of the 4th epoch. // Set the state and block to be in the last slot of the 4th epoch.
let last_slot_of_epoch = (spec.genesis_epoch + 4).end_slot(spec.slots_per_epoch); let last_slot_of_epoch = (spec.genesis_epoch + 4).end_slot(T::slots_per_epoch());
bench_builder.set_slot(last_slot_of_epoch, &spec); bench_builder.set_slot(last_slot_of_epoch, &spec);
// Build all the state caches so the build times aren't included in the benches. // Build all the state caches so the build times aren't included in the benches.
@ -67,13 +67,13 @@ pub fn block_processing_reasonable_case(c: &mut Criterion) {
// Set the number of included operations to what we might expect normally. // Set the number of included operations to what we might expect normally.
bench_builder.num_proposer_slashings = 0; bench_builder.num_proposer_slashings = 0;
bench_builder.num_attester_slashings = 0; bench_builder.num_attester_slashings = 0;
bench_builder.num_attestations = (spec.shard_count / spec.slots_per_epoch) as usize; bench_builder.num_attestations = (spec.shard_count / T::slots_per_epoch()) as usize;
bench_builder.num_deposits = 2; bench_builder.num_deposits = 2;
bench_builder.num_exits = 2; bench_builder.num_exits = 2;
bench_builder.num_transfers = 2; bench_builder.num_transfers = 2;
// Set the state and block to be in the last slot of the 4th epoch. // Set the state and block to be in the last slot of the 4th epoch.
let last_slot_of_epoch = (spec.genesis_epoch + 4).end_slot(spec.slots_per_epoch); let last_slot_of_epoch = (spec.genesis_epoch + 4).end_slot(T::slots_per_epoch());
bench_builder.set_slot(last_slot_of_epoch, &spec); bench_builder.set_slot(last_slot_of_epoch, &spec);
// Build all the state caches so the build times aren't included in the benches. // Build all the state caches so the build times aren't included in the benches.

View File

@ -140,7 +140,7 @@ pub fn verify_block_signature<T: EthSpec>(
[state.get_beacon_proposer_index(block.slot, RelativeEpoch::Current, spec)?]; [state.get_beacon_proposer_index(block.slot, RelativeEpoch::Current, spec)?];
let domain = spec.get_domain( let domain = spec.get_domain(
block.slot.epoch(spec.slots_per_epoch), block.slot.epoch(T::slots_per_epoch()),
Domain::BeaconProposer, Domain::BeaconProposer,
&state.fork, &state.fork,
); );
@ -172,7 +172,7 @@ pub fn process_randao<T: EthSpec>(
block.body.randao_reveal.verify( block.body.randao_reveal.verify(
&state.current_epoch().tree_hash_root()[..], &state.current_epoch().tree_hash_root()[..],
spec.get_domain( spec.get_domain(
block.slot.epoch(spec.slots_per_epoch), block.slot.epoch(T::slots_per_epoch()),
Domain::Randao, Domain::Randao,
&state.fork &state.fork
), ),

View File

@ -55,11 +55,13 @@ impl<T: EthSpec> BlockProcessingBuilder<T> {
let keypair = &keypairs[proposer_index]; let keypair = &keypairs[proposer_index];
match randao_sk { match randao_sk {
Some(sk) => builder.set_randao_reveal(&sk, &state.fork, spec), Some(sk) => builder.set_randao_reveal::<T>(&sk, &state.fork, spec),
None => builder.set_randao_reveal(&keypair.sk, &state.fork, spec), None => builder.set_randao_reveal::<T>(&keypair.sk, &state.fork, spec),
} }
let block = self.block_builder.build(&keypair.sk, &state.fork, spec); let block = self
.block_builder
.build::<T>(&keypair.sk, &state.fork, spec);
(block, state) (block, state)
} }

View File

@ -9,7 +9,7 @@ pub const VALIDATOR_COUNT: usize = 10;
#[test] #[test]
fn valid_block_ok() { fn valid_block_ok() {
let spec = FoundationEthSpec::spec(); let spec = FoundationEthSpec::default_spec();
let builder = get_builder(&spec); let builder = get_builder(&spec);
let (block, mut state) = builder.build(None, None, &spec); let (block, mut state) = builder.build(None, None, &spec);
@ -20,7 +20,7 @@ fn valid_block_ok() {
#[test] #[test]
fn invalid_block_header_state_slot() { fn invalid_block_header_state_slot() {
let spec = FoundationEthSpec::spec(); let spec = FoundationEthSpec::default_spec();
let builder = get_builder(&spec); let builder = get_builder(&spec);
let (mut block, mut state) = builder.build(None, None, &spec); let (mut block, mut state) = builder.build(None, None, &spec);
@ -39,7 +39,7 @@ fn invalid_block_header_state_slot() {
#[test] #[test]
fn invalid_parent_block_root() { fn invalid_parent_block_root() {
let spec = FoundationEthSpec::spec(); let spec = FoundationEthSpec::default_spec();
let builder = get_builder(&spec); let builder = get_builder(&spec);
let invalid_parent_root = Hash256::from([0xAA; 32]); let invalid_parent_root = Hash256::from([0xAA; 32]);
let (block, mut state) = builder.build(None, Some(invalid_parent_root), &spec); let (block, mut state) = builder.build(None, Some(invalid_parent_root), &spec);
@ -59,14 +59,14 @@ fn invalid_parent_block_root() {
#[test] #[test]
fn invalid_block_signature() { fn invalid_block_signature() {
let spec = FoundationEthSpec::spec(); let spec = FoundationEthSpec::default_spec();
let builder = get_builder(&spec); let builder = get_builder(&spec);
let (mut block, mut state) = builder.build(None, None, &spec); let (mut block, mut state) = builder.build(None, None, &spec);
// sign the block with a keypair that is not the expected proposer // sign the block with a keypair that is not the expected proposer
let keypair = Keypair::random(); let keypair = Keypair::random();
let message = block.signed_root(); let message = block.signed_root();
let epoch = block.slot.epoch(spec.slots_per_epoch); let epoch = block.slot.epoch(FoundationEthSpec::slots_per_epoch());
let domain = spec.get_domain(epoch, Domain::BeaconProposer, &state.fork); let domain = spec.get_domain(epoch, Domain::BeaconProposer, &state.fork);
block.signature = Signature::new(&message, domain, &keypair.sk); block.signature = Signature::new(&message, domain, &keypair.sk);
@ -82,7 +82,7 @@ fn invalid_block_signature() {
#[test] #[test]
fn invalid_randao_reveal_signature() { fn invalid_randao_reveal_signature() {
let spec = FoundationEthSpec::spec(); let spec = FoundationEthSpec::default_spec();
let builder = get_builder(&spec); let builder = get_builder(&spec);
// sign randao reveal with random keypair // sign randao reveal with random keypair
@ -104,7 +104,8 @@ fn get_builder(spec: &ChainSpec) -> (BlockProcessingBuilder<FoundationEthSpec>)
let mut builder = BlockProcessingBuilder::new(VALIDATOR_COUNT, &spec); let mut builder = BlockProcessingBuilder::new(VALIDATOR_COUNT, &spec);
// Set the state and block to be in the last slot of the 4th epoch. // Set the state and block to be in the last slot of the 4th epoch.
let last_slot_of_epoch = (spec.genesis_epoch + 4).end_slot(spec.slots_per_epoch); let last_slot_of_epoch =
(spec.genesis_epoch + 4).end_slot(FoundationEthSpec::slots_per_epoch());
builder.set_slot(last_slot_of_epoch, &spec); builder.set_slot(last_slot_of_epoch, &spec);
builder.build_caches(&spec); builder.build_caches(&spec);

View File

@ -68,7 +68,7 @@ fn validate_attestation_parametric<T: EthSpec>(
} }
); );
verify!( verify!(
state.slot <= attestation_slot + spec.slots_per_epoch, state.slot <= attestation_slot + T::slots_per_epoch(),
Invalid::IncludedTooLate { Invalid::IncludedTooLate {
state: state.slot, state: state.slot,
attestation: attestation_slot attestation: attestation_slot

View File

@ -21,8 +21,8 @@ pub fn verify_proposer_slashing<T: EthSpec>(
})?; })?;
verify!( verify!(
proposer_slashing.header_1.slot.epoch(spec.slots_per_epoch) proposer_slashing.header_1.slot.epoch(T::slots_per_epoch())
== proposer_slashing.header_2.slot.epoch(spec.slots_per_epoch), == proposer_slashing.header_2.slot.epoch(T::slots_per_epoch()),
Invalid::ProposalEpochMismatch( Invalid::ProposalEpochMismatch(
proposer_slashing.header_1.slot, proposer_slashing.header_1.slot,
proposer_slashing.header_2.slot proposer_slashing.header_2.slot
@ -40,7 +40,7 @@ pub fn verify_proposer_slashing<T: EthSpec>(
); );
verify!( verify!(
verify_header_signature( verify_header_signature::<T>(
&proposer_slashing.header_1, &proposer_slashing.header_1,
&proposer.pubkey, &proposer.pubkey,
&state.fork, &state.fork,
@ -49,7 +49,7 @@ pub fn verify_proposer_slashing<T: EthSpec>(
Invalid::BadProposal1Signature Invalid::BadProposal1Signature
); );
verify!( verify!(
verify_header_signature( verify_header_signature::<T>(
&proposer_slashing.header_2, &proposer_slashing.header_2,
&proposer.pubkey, &proposer.pubkey,
&state.fork, &state.fork,
@ -66,7 +66,7 @@ pub fn verify_proposer_slashing<T: EthSpec>(
/// Returns `true` if the signature is valid. /// Returns `true` if the signature is valid.
/// ///
/// Spec v0.6.1 /// Spec v0.6.1
fn verify_header_signature( fn verify_header_signature<T: EthSpec>(
header: &BeaconBlockHeader, header: &BeaconBlockHeader,
pubkey: &PublicKey, pubkey: &PublicKey,
fork: &Fork, fork: &Fork,
@ -74,7 +74,7 @@ fn verify_header_signature(
) -> bool { ) -> bool {
let message = header.signed_root(); let message = header.signed_root();
let domain = spec.get_domain( let domain = spec.get_domain(
header.slot.epoch(spec.slots_per_epoch), header.slot.epoch(T::slots_per_epoch()),
Domain::BeaconProposer, Domain::BeaconProposer,
fork, fork,
); );

View File

@ -101,7 +101,7 @@ fn verify_transfer_parametric<T: EthSpec>(
.get(transfer.sender as usize) .get(transfer.sender as usize)
.ok_or_else(|| Error::Invalid(Invalid::FromValidatorUnknown(transfer.sender)))?; .ok_or_else(|| Error::Invalid(Invalid::FromValidatorUnknown(transfer.sender)))?;
let epoch = state.slot.epoch(spec.slots_per_epoch); let epoch = state.slot.epoch(T::slots_per_epoch());
// Ensure one of the following is met: // Ensure one of the following is met:
// //
@ -136,7 +136,7 @@ fn verify_transfer_parametric<T: EthSpec>(
// Verify the transfer signature. // Verify the transfer signature.
let message = transfer.signed_root(); let message = transfer.signed_root();
let domain = spec.get_domain( let domain = spec.get_domain(
transfer.slot.epoch(spec.slots_per_epoch), transfer.slot.epoch(T::slots_per_epoch()),
Domain::Transfer, Domain::Transfer,
&state.fork, &state.fork,
); );

View File

@ -237,7 +237,7 @@ pub fn process_final_updates<T: EthSpec>(
state.slot -= 1; state.slot -= 1;
} }
if next_epoch.as_u64() % (T::SlotsPerHistoricalRoot::to_u64() / spec.slots_per_epoch) == 0 { if next_epoch.as_u64() % (T::SlotsPerHistoricalRoot::to_u64() / T::slots_per_epoch()) == 0 {
let historical_batch = state.historical_batch(); let historical_batch = state.historical_batch();
state state
.historical_roots .historical_roots

View File

@ -8,12 +8,12 @@ use types::*;
fn runs_without_error() { fn runs_without_error() {
Builder::from_env(Env::default().default_filter_or("error")).init(); Builder::from_env(Env::default().default_filter_or("error")).init();
let spec = FewValidatorsEthSpec::spec(); let spec = FewValidatorsEthSpec::default_spec();
let mut builder: TestingBeaconStateBuilder<FewValidatorsEthSpec> = let mut builder: TestingBeaconStateBuilder<FewValidatorsEthSpec> =
TestingBeaconStateBuilder::from_deterministic_keypairs(8, &spec); TestingBeaconStateBuilder::from_deterministic_keypairs(8, &spec);
let target_slot = (spec.genesis_epoch + 4).end_slot(spec.slots_per_epoch); let target_slot = (spec.genesis_epoch + 4).end_slot(FewValidatorsEthSpec::slots_per_epoch());
builder.teleport_to_slot(target_slot, &spec); builder.teleport_to_slot(target_slot, &spec);
let (mut state, _keypairs) = builder.build(); let (mut state, _keypairs) = builder.build();

View File

@ -233,7 +233,7 @@ impl ValidatorStatuses {
let attestation_slot = state.get_attestation_slot(&a.data)?; let attestation_slot = state.get_attestation_slot(&a.data)?;
let inclusion_slot = attestation_slot + a.inclusion_delay; let inclusion_slot = attestation_slot + a.inclusion_delay;
let relative_epoch = let relative_epoch =
RelativeEpoch::from_slot(state.slot, inclusion_slot, spec.slots_per_epoch)?; RelativeEpoch::from_slot(state.slot, inclusion_slot, T::slots_per_epoch())?;
status.inclusion_info = Some(InclusionInfo { status.inclusion_info = Some(InclusionInfo {
slot: inclusion_slot, slot: inclusion_slot,
distance: a.inclusion_delay, distance: a.inclusion_delay,
@ -297,7 +297,7 @@ impl ValidatorStatuses {
spec: &ChainSpec, spec: &ChainSpec,
) -> Result<(), BeaconStateError> { ) -> Result<(), BeaconStateError> {
// Loop through each slot in the previous epoch. // Loop through each slot in the previous epoch.
for slot in state.previous_epoch().slot_iter(spec.slots_per_epoch) { for slot in state.previous_epoch().slot_iter(T::slots_per_epoch()) {
let crosslink_committees_at_slot = state.get_crosslink_committees_at_slot(slot)?; let crosslink_committees_at_slot = state.get_crosslink_committees_at_slot(slot)?;
// Loop through each committee in the slot. // Loop through each committee in the slot.
@ -338,7 +338,7 @@ fn target_matches_epoch_start_block<T: EthSpec>(
epoch: Epoch, epoch: Epoch,
spec: &ChainSpec, spec: &ChainSpec,
) -> Result<bool, BeaconStateError> { ) -> Result<bool, BeaconStateError> {
let slot = epoch.start_slot(spec.slots_per_epoch); let slot = epoch.start_slot(T::slots_per_epoch());
let state_boundary_root = *state.get_block_root(slot)?; let state_boundary_root = *state.get_block_root(slot)?;
Ok(a.data.target_root == state_boundary_root) Ok(a.data.target_root == state_boundary_root)

View File

@ -16,7 +16,7 @@ pub fn per_slot_processing<T: EthSpec>(
) -> Result<(), Error> { ) -> Result<(), Error> {
cache_state(state, spec)?; cache_state(state, spec)?;
if (state.slot > spec.genesis_slot) && ((state.slot + 1) % spec.slots_per_epoch == 0) { if (state.slot > spec.genesis_slot) && ((state.slot + 1) % T::slots_per_epoch() == 0) {
per_epoch_processing(state, spec)?; per_epoch_processing(state, spec)?;
} }

View File

@ -458,7 +458,7 @@ impl<T: EthSpec> BeaconState<T> {
epoch: Epoch, epoch: Epoch,
spec: &ChainSpec, spec: &ChainSpec,
) -> Result<&Hash256, BeaconStateError> { ) -> Result<&Hash256, BeaconStateError> {
self.get_block_root(epoch.start_slot(spec.slots_per_epoch)) self.get_block_root(epoch.start_slot(T::slots_per_epoch()))
} }
/// Sets the block root for some given slot. /// Sets the block root for some given slot.

View File

@ -1,5 +1,5 @@
use crate::*; use crate::*;
use fixed_len_vec::typenum::{Unsigned, U1024, U8, U8192}; use fixed_len_vec::typenum::{Unsigned, U0, U1024, U64, U8, U8192};
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use std::fmt::Debug; use std::fmt::Debug;
@ -9,14 +9,24 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq {
type LatestRandaoMixesLength: Unsigned + Clone + Sync + Send + Debug + PartialEq; type LatestRandaoMixesLength: Unsigned + Clone + Sync + Send + Debug + PartialEq;
type LatestActiveIndexRootsLength: Unsigned + Clone + Sync + Send + Debug + PartialEq; type LatestActiveIndexRootsLength: Unsigned + Clone + Sync + Send + Debug + PartialEq;
type LatestSlashedExitLength: Unsigned + Clone + Sync + Send + Debug + PartialEq; type LatestSlashedExitLength: Unsigned + Clone + Sync + Send + Debug + PartialEq;
/// Note: `SlotsPerEpoch` is not necessarily required to be a compile-time constant. We include
/// it here just for the convenience of not passing `slots_per_epoch` around all the time.
type SlotsPerEpoch: Unsigned + Clone + Sync + Send + Debug + PartialEq;
type GenesisEpoch: Unsigned + Clone + Sync + Send + Debug + PartialEq;
fn spec() -> ChainSpec; fn default_spec() -> ChainSpec;
fn genesis_epoch() -> Epoch {
Epoch::new(Self::GenesisEpoch::to_u64())
}
/// Return the number of committees in one epoch. /// Return the number of committees in one epoch.
/// ///
/// Spec v0.6.1 /// Spec v0.6.1
fn get_epoch_committee_count(active_validator_count: usize) -> usize { fn get_epoch_committee_count(
let target_committee_size = Self::spec().target_committee_size; active_validator_count: usize,
target_committee_size: usize,
) -> usize {
let shard_count = Self::shard_count(); let shard_count = Self::shard_count();
let slots_per_epoch = Self::slots_per_epoch() as usize; let slots_per_epoch = Self::slots_per_epoch() as usize;
@ -35,21 +45,14 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq {
/// basic sense. This count is not required to provide any security guarantees regarding /// basic sense. This count is not required to provide any security guarantees regarding
/// decentralization, entropy, etc. /// decentralization, entropy, etc.
fn minimum_validator_count() -> usize { fn minimum_validator_count() -> usize {
Self::slots_per_epoch() as usize Self::SlotsPerEpoch::to_usize()
} }
/// Returns the `SLOTS_PER_EPOCH` constant for this specification. /// Returns the `SLOTS_PER_EPOCH` constant for this specification.
/// ///
/// Spec v0.6.1 /// Spec v0.6.1
fn slots_per_epoch() -> u64 { fn slots_per_epoch() -> u64 {
Self::spec().slots_per_epoch Self::SlotsPerEpoch::to_u64()
}
/// Returns the `SLOTS_PER_EPOCH` constant for this specification.
///
/// Spec v0.6.1
fn genesis_epoch() -> Epoch {
Self::spec().genesis_epoch
} }
/// Returns the `SHARD_COUNT` constant for this specification. /// Returns the `SHARD_COUNT` constant for this specification.
@ -100,8 +103,10 @@ impl EthSpec for FoundationEthSpec {
type LatestRandaoMixesLength = U8192; type LatestRandaoMixesLength = U8192;
type LatestActiveIndexRootsLength = U8192; type LatestActiveIndexRootsLength = U8192;
type LatestSlashedExitLength = U8192; type LatestSlashedExitLength = U8192;
type SlotsPerEpoch = U64;
type GenesisEpoch = U0;
fn spec() -> ChainSpec { fn default_spec() -> ChainSpec {
ChainSpec::foundation() ChainSpec::foundation()
} }
} }
@ -118,9 +123,11 @@ impl EthSpec for FewValidatorsEthSpec {
type LatestRandaoMixesLength = U8192; type LatestRandaoMixesLength = U8192;
type LatestActiveIndexRootsLength = U8192; type LatestActiveIndexRootsLength = U8192;
type LatestSlashedExitLength = U8192; type LatestSlashedExitLength = U8192;
type SlotsPerEpoch = U8;
type GenesisEpoch = U0;
fn spec() -> ChainSpec { fn default_spec() -> ChainSpec {
ChainSpec::few_validators() ChainSpec::few_validators(Self::slots_per_epoch())
} }
} }
@ -136,9 +143,11 @@ impl EthSpec for LighthouseTestnetEthSpec {
type LatestRandaoMixesLength = U8192; type LatestRandaoMixesLength = U8192;
type LatestActiveIndexRootsLength = U8192; type LatestActiveIndexRootsLength = U8192;
type LatestSlashedExitLength = U8192; type LatestSlashedExitLength = U8192;
type SlotsPerEpoch = U8;
type GenesisEpoch = U0;
fn spec() -> ChainSpec { fn default_spec() -> ChainSpec {
ChainSpec::lighthouse_testnet() ChainSpec::lighthouse_testnet(Self::slots_per_epoch())
} }
} }

View File

@ -45,13 +45,18 @@ impl CommitteeCache {
return Err(Error::InsufficientValidators); return Err(Error::InsufficientValidators);
} }
let committee_count = T::get_epoch_committee_count(active_validator_indices.len()) as usize; let committee_count = T::get_epoch_committee_count(
active_validator_indices.len(),
spec.target_committee_size,
) as usize;
let shuffling_start_shard = match relative_epoch { let shuffling_start_shard = match relative_epoch {
RelativeEpoch::Current => state.latest_start_shard, RelativeEpoch::Current => state.latest_start_shard,
RelativeEpoch::Previous => { RelativeEpoch::Previous => {
let committees_in_previous_epoch = let committees_in_previous_epoch = T::get_epoch_committee_count(
T::get_epoch_committee_count(active_validator_indices.len()) as u64; active_validator_indices.len(),
spec.target_committee_size,
) as u64;
(state.latest_start_shard + T::shard_count() as u64 - committees_in_previous_epoch) (state.latest_start_shard + T::shard_count() as u64 - committees_in_previous_epoch)
% T::shard_count() as u64 % T::shard_count() as u64
@ -59,8 +64,10 @@ impl CommitteeCache {
RelativeEpoch::Next => { RelativeEpoch::Next => {
let current_active_validators = let current_active_validators =
get_active_validator_count(&state.validator_registry, state.current_epoch()); get_active_validator_count(&state.validator_registry, state.current_epoch());
let committees_in_current_epoch = let committees_in_current_epoch = T::get_epoch_committee_count(
T::get_epoch_committee_count(current_active_validators) as u64; current_active_validators,
spec.target_committee_size,
) as u64;
(state.latest_start_shard + committees_in_current_epoch) % T::shard_count() as u64 (state.latest_start_shard + committees_in_current_epoch) % T::shard_count() as u64
} }

View File

@ -20,7 +20,7 @@ fn default_values() {
} }
fn new_state<T: EthSpec>(validator_count: usize, slot: Slot) -> BeaconState<T> { fn new_state<T: EthSpec>(validator_count: usize, slot: Slot) -> BeaconState<T> {
let spec = &T::spec(); let spec = &T::default_spec();
let mut builder = let mut builder =
TestingBeaconStateBuilder::from_single_keypair(validator_count, &Keypair::random(), spec); TestingBeaconStateBuilder::from_single_keypair(validator_count, &Keypair::random(), spec);
@ -35,7 +35,7 @@ fn new_state<T: EthSpec>(validator_count: usize, slot: Slot) -> BeaconState<T> {
#[test] #[test]
fn fails_without_validators() { fn fails_without_validators() {
let state = new_state::<FewValidatorsEthSpec>(0, Slot::new(0)); let state = new_state::<FewValidatorsEthSpec>(0, Slot::new(0));
let spec = &FewValidatorsEthSpec::spec(); let spec = &FewValidatorsEthSpec::default_spec();
assert_eq!( assert_eq!(
CommitteeCache::initialized(&state, state.current_epoch(), &spec), CommitteeCache::initialized(&state, state.current_epoch(), &spec),
@ -46,7 +46,7 @@ fn fails_without_validators() {
#[test] #[test]
fn initializes_with_the_right_epoch() { fn initializes_with_the_right_epoch() {
let state = new_state::<FewValidatorsEthSpec>(16, Slot::new(0)); let state = new_state::<FewValidatorsEthSpec>(16, Slot::new(0));
let spec = &FewValidatorsEthSpec::spec(); let spec = &FewValidatorsEthSpec::default_spec();
let cache = CommitteeCache::default(); let cache = CommitteeCache::default();
assert_eq!(cache.initialized_epoch, None); assert_eq!(cache.initialized_epoch, None);
@ -68,7 +68,7 @@ fn shuffles_for_the_right_epoch() {
let slot = epoch.start_slot(FewValidatorsEthSpec::slots_per_epoch()); let slot = epoch.start_slot(FewValidatorsEthSpec::slots_per_epoch());
let mut state = new_state::<FewValidatorsEthSpec>(num_validators, slot); let mut state = new_state::<FewValidatorsEthSpec>(num_validators, slot);
let spec = &FewValidatorsEthSpec::spec(); let spec = &FewValidatorsEthSpec::default_spec();
let distinct_hashes: Vec<Hash256> = (0..FewValidatorsEthSpec::latest_randao_mixes_length()) let distinct_hashes: Vec<Hash256> = (0..FewValidatorsEthSpec::latest_randao_mixes_length())
.into_iter() .into_iter()
@ -123,7 +123,7 @@ fn can_start_on_any_shard() {
let slot = epoch.start_slot(FewValidatorsEthSpec::slots_per_epoch()); let slot = epoch.start_slot(FewValidatorsEthSpec::slots_per_epoch());
let mut state = new_state::<FewValidatorsEthSpec>(num_validators, slot); let mut state = new_state::<FewValidatorsEthSpec>(num_validators, slot);
let spec = &FewValidatorsEthSpec::spec(); let spec = &FewValidatorsEthSpec::default_spec();
for i in 0..FewValidatorsEthSpec::shard_count() as u64 { for i in 0..FewValidatorsEthSpec::shard_count() as u64 {
state.latest_start_shard = i; state.latest_start_shard = i;
@ -150,15 +150,17 @@ impl EthSpec for ExcessShardsEthSpec {
type LatestRandaoMixesLength = U8192; type LatestRandaoMixesLength = U8192;
type LatestActiveIndexRootsLength = U8192; type LatestActiveIndexRootsLength = U8192;
type LatestSlashedExitLength = U8192; type LatestSlashedExitLength = U8192;
type SlotsPerEpoch = U8;
type GenesisEpoch = U0;
fn spec() -> ChainSpec { fn default_spec() -> ChainSpec {
ChainSpec::few_validators() ChainSpec::few_validators(Self::slots_per_epoch())
} }
} }
#[test] #[test]
fn starts_on_the_correct_shard() { fn starts_on_the_correct_shard() {
let spec = &ExcessShardsEthSpec::spec(); let spec = &ExcessShardsEthSpec::default_spec();
let num_validators = ExcessShardsEthSpec::shard_count(); let num_validators = ExcessShardsEthSpec::shard_count();
@ -200,14 +202,16 @@ fn starts_on_the_correct_shard() {
let previous_shards = ExcessShardsEthSpec::get_epoch_committee_count( let previous_shards = ExcessShardsEthSpec::get_epoch_committee_count(
get_active_validator_count(&state.validator_registry, previous_epoch), get_active_validator_count(&state.validator_registry, previous_epoch),
spec.target_committee_size,
); );
let current_shards = ExcessShardsEthSpec::get_epoch_committee_count( let current_shards = ExcessShardsEthSpec::get_epoch_committee_count(
get_active_validator_count(&state.validator_registry, current_epoch), get_active_validator_count(&state.validator_registry, current_epoch),
spec.target_committee_size,
);
let next_shards = ExcessShardsEthSpec::get_epoch_committee_count(
get_active_validator_count(&state.validator_registry, next_epoch),
spec.target_committee_size,
); );
let next_shards = ExcessShardsEthSpec::get_epoch_committee_count(get_active_validator_count(
&state.validator_registry,
next_epoch,
));
assert_eq!( assert_eq!(
previous_shards as usize, previous_shards as usize,

View File

@ -7,7 +7,7 @@ ssz_tests!(FoundationBeaconState);
cached_tree_hash_tests!(FoundationBeaconState); cached_tree_hash_tests!(FoundationBeaconState);
fn test_beacon_proposer_index<T: EthSpec>() { fn test_beacon_proposer_index<T: EthSpec>() {
let spec = T::spec(); let spec = T::default_spec();
let relative_epoch = RelativeEpoch::Current; let relative_epoch = RelativeEpoch::Current;
// Build a state for testing. // Build a state for testing.
@ -61,7 +61,7 @@ fn beacon_proposer_index() {
/// (current_epoch - LATEST_ACTIVE_INDEX_ROOTS_LENGTH + ACTIVATION_EXIT_DELAY, current_epoch + /// (current_epoch - LATEST_ACTIVE_INDEX_ROOTS_LENGTH + ACTIVATION_EXIT_DELAY, current_epoch +
/// ACTIVATION_EXIT_DELAY] /// ACTIVATION_EXIT_DELAY]
fn active_index_range<T: EthSpec>(current_epoch: Epoch) -> RangeInclusive<Epoch> { fn active_index_range<T: EthSpec>(current_epoch: Epoch) -> RangeInclusive<Epoch> {
let delay = T::spec().activation_exit_delay; let delay = T::default_spec().activation_exit_delay;
let start: i32 = let start: i32 =
current_epoch.as_u64() as i32 - T::latest_active_index_roots() as i32 + delay as i32; current_epoch.as_u64() as i32 - T::latest_active_index_roots() as i32 + delay as i32;
@ -79,7 +79,7 @@ fn active_index_range<T: EthSpec>(current_epoch: Epoch) -> RangeInclusive<Epoch>
/// Test getting an active index root at the start and end of the valid range, and one either side /// Test getting an active index root at the start and end of the valid range, and one either side
/// of that range. /// of that range.
fn test_active_index<T: EthSpec>(state_slot: Slot) { fn test_active_index<T: EthSpec>(state_slot: Slot) {
let spec = T::spec(); let spec = T::default_spec();
let builder: TestingBeaconStateBuilder<T> = let builder: TestingBeaconStateBuilder<T> =
TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(16, &spec); TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(16, &spec);
let (mut state, _keypairs) = builder.build(); let (mut state, _keypairs) = builder.build();
@ -133,8 +133,8 @@ fn test_cache_initialization<'a, T: EthSpec>(
spec: &ChainSpec, spec: &ChainSpec,
) { ) {
let slot = relative_epoch let slot = relative_epoch
.into_epoch(state.slot.epoch(spec.slots_per_epoch)) .into_epoch(state.slot.epoch(T::slots_per_epoch()))
.start_slot(spec.slots_per_epoch); .start_slot(T::slots_per_epoch());
// Assuming the cache isn't already built, assert that a call to a cache-using function fails. // Assuming the cache isn't already built, assert that a call to a cache-using function fails.
assert_eq!( assert_eq!(
@ -166,13 +166,13 @@ fn test_cache_initialization<'a, T: EthSpec>(
#[test] #[test]
fn cache_initialization() { fn cache_initialization() {
let spec = FewValidatorsEthSpec::spec(); let spec = FewValidatorsEthSpec::default_spec();
let builder: TestingBeaconStateBuilder<FewValidatorsEthSpec> = let builder: TestingBeaconStateBuilder<FewValidatorsEthSpec> =
TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(16, &spec); TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(16, &spec);
let (mut state, _keypairs) = builder.build(); let (mut state, _keypairs) = builder.build();
state.slot = (spec.genesis_epoch + 1).start_slot(spec.slots_per_epoch); state.slot = (spec.genesis_epoch + 1).start_slot(FewValidatorsEthSpec::slots_per_epoch());
test_cache_initialization(&mut state, RelativeEpoch::Previous, &spec); test_cache_initialization(&mut state, RelativeEpoch::Previous, &spec);
test_cache_initialization(&mut state, RelativeEpoch::Current, &spec); test_cache_initialization(&mut state, RelativeEpoch::Current, &spec);
@ -234,7 +234,7 @@ mod committees {
(start_shard..start_shard + T::shard_count() as u64).into_iter(); (start_shard..start_shard + T::shard_count() as u64).into_iter();
// Loop through all slots in the epoch being tested. // Loop through all slots in the epoch being tested.
for slot in epoch.slot_iter(spec.slots_per_epoch) { for slot in epoch.slot_iter(T::slots_per_epoch()) {
let crosslink_committees = state.get_crosslink_committees_at_slot(slot).unwrap(); let crosslink_committees = state.get_crosslink_committees_at_slot(slot).unwrap();
// Assert that the number of committees in this slot is consistent with the reported number // Assert that the number of committees in this slot is consistent with the reported number
@ -290,7 +290,7 @@ mod committees {
state_epoch: Epoch, state_epoch: Epoch,
cache_epoch: RelativeEpoch, cache_epoch: RelativeEpoch,
) { ) {
let spec = &T::spec(); let spec = &T::default_spec();
let mut builder = TestingBeaconStateBuilder::from_single_keypair( let mut builder = TestingBeaconStateBuilder::from_single_keypair(
validator_count, validator_count,
@ -298,7 +298,7 @@ mod committees {
spec, spec,
); );
let slot = state_epoch.start_slot(spec.slots_per_epoch); let slot = state_epoch.start_slot(T::slots_per_epoch());
builder.teleport_to_slot(slot, spec); builder.teleport_to_slot(slot, spec);
let (mut state, _keypairs): (BeaconState<T>, _) = builder.build(); let (mut state, _keypairs): (BeaconState<T>, _) = builder.build();
@ -325,7 +325,7 @@ mod committees {
} }
fn committee_consistency_test_suite<T: EthSpec>(cached_epoch: RelativeEpoch) { fn committee_consistency_test_suite<T: EthSpec>(cached_epoch: RelativeEpoch) {
let spec = T::spec(); let spec = T::default_spec();
let validator_count = (T::shard_count() * spec.target_committee_size) + 1; let validator_count = (T::shard_count() * spec.target_committee_size) + 1;

View File

@ -1,6 +1,6 @@
use crate::*; use crate::*;
use int_to_bytes::int_to_bytes4; use int_to_bytes::int_to_bytes4;
use serde_derive::Deserialize; use serde_derive::{Deserialize, Serialize};
use test_utils::u8_from_hex_str; use test_utils::u8_from_hex_str;
/// Each of the BLS signature domains. /// Each of the BLS signature domains.
@ -18,7 +18,7 @@ pub enum Domain {
/// Holds all the "constants" for a BeaconChain. /// Holds all the "constants" for a BeaconChain.
/// ///
/// Spec v0.6.1 /// Spec v0.6.1
#[derive(PartialEq, Debug, Clone, Deserialize)] #[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
#[serde(default)] #[serde(default)]
pub struct ChainSpec { pub struct ChainSpec {
/* /*
@ -59,7 +59,7 @@ pub struct ChainSpec {
*/ */
pub seconds_per_slot: u64, pub seconds_per_slot: u64,
pub min_attestation_inclusion_delay: u64, pub min_attestation_inclusion_delay: u64,
pub slots_per_epoch: u64, //pub slots_per_epoch: u64,
pub min_seed_lookahead: Epoch, pub min_seed_lookahead: Epoch,
pub activation_exit_delay: u64, pub activation_exit_delay: u64,
pub slots_per_eth1_voting_period: u64, pub slots_per_eth1_voting_period: u64,
@ -137,7 +137,7 @@ impl ChainSpec {
/// Returns a `ChainSpec` compatible with the Ethereum Foundation specification. /// Returns a `ChainSpec` compatible with the Ethereum Foundation specification.
/// ///
/// Spec v0.6.1 /// Spec v0.6.1
pub(crate) fn foundation() -> Self { pub fn foundation() -> Self {
Self { Self {
/* /*
* Misc * Misc
@ -176,7 +176,7 @@ impl ChainSpec {
*/ */
seconds_per_slot: 6, seconds_per_slot: 6,
min_attestation_inclusion_delay: 4, min_attestation_inclusion_delay: 4,
slots_per_epoch: 64, // slots_per_epoch: 64,
min_seed_lookahead: Epoch::new(1), min_seed_lookahead: Epoch::new(1),
activation_exit_delay: 4, activation_exit_delay: 4,
slots_per_eth1_voting_period: 1_024, slots_per_eth1_voting_period: 1_024,
@ -226,7 +226,7 @@ impl ChainSpec {
/// Returns a `ChainSpec` compatible with the Lighthouse testnet specification. /// Returns a `ChainSpec` compatible with the Lighthouse testnet specification.
/// ///
/// Spec v0.4.0 /// Spec v0.4.0
pub(crate) fn lighthouse_testnet() -> Self { pub fn lighthouse_testnet(slots_per_epoch: u64) -> Self {
/* /*
* Lighthouse testnet bootnodes * Lighthouse testnet bootnodes
*/ */
@ -237,21 +237,19 @@ impl ChainSpec {
Self { Self {
boot_nodes, boot_nodes,
chain_id: 2, // lighthouse testnet chain id chain_id: 2, // lighthouse testnet chain id
..ChainSpec::few_validators() ..ChainSpec::few_validators(slots_per_epoch)
} }
} }
/// Returns a `ChainSpec` compatible with the specification suitable for 8 validators. /// Returns a `ChainSpec` compatible with the specification suitable for 8 validators.
pub(crate) fn few_validators() -> Self { pub fn few_validators(slots_per_epoch: u64) -> Self {
let genesis_slot = Slot::new(0); let genesis_slot = Slot::new(0);
let slots_per_epoch = 8;
let genesis_epoch = genesis_slot.epoch(slots_per_epoch); let genesis_epoch = genesis_slot.epoch(slots_per_epoch);
Self { Self {
target_committee_size: 1, target_committee_size: 1,
genesis_slot, genesis_slot,
genesis_epoch, genesis_epoch,
slots_per_epoch,
..ChainSpec::foundation() ..ChainSpec::foundation()
} }
} }

View File

@ -21,7 +21,7 @@ impl TestingAttestationDataBuilder {
let previous_epoch = state.previous_epoch(); let previous_epoch = state.previous_epoch();
let is_previous_epoch = let is_previous_epoch =
state.slot.epoch(spec.slots_per_epoch) != slot.epoch(spec.slots_per_epoch); state.slot.epoch(T::slots_per_epoch()) != slot.epoch(T::slots_per_epoch());
let source_epoch = if is_previous_epoch { let source_epoch = if is_previous_epoch {
state.previous_justified_epoch state.previous_justified_epoch
@ -37,11 +37,11 @@ impl TestingAttestationDataBuilder {
let target_root = if is_previous_epoch { let target_root = if is_previous_epoch {
*state *state
.get_block_root(previous_epoch.start_slot(spec.slots_per_epoch)) .get_block_root(previous_epoch.start_slot(T::slots_per_epoch()))
.unwrap() .unwrap()
} else { } else {
*state *state
.get_block_root(current_epoch.start_slot(spec.slots_per_epoch)) .get_block_root(current_epoch.start_slot(T::slots_per_epoch()))
.unwrap() .unwrap()
}; };
@ -57,7 +57,7 @@ impl TestingAttestationDataBuilder {
}; };
let source_root = *state let source_root = *state
.get_block_root(source_epoch.start_slot(spec.slots_per_epoch)) .get_block_root(source_epoch.start_slot(T::slots_per_epoch()))
.unwrap(); .unwrap();
let data = AttestationData { let data = AttestationData {

View File

@ -36,9 +36,9 @@ impl TestingBeaconBlockBuilder {
/// Signs the block. /// Signs the block.
/// ///
/// Modifying the block after signing may invalidate the signature. /// Modifying the block after signing may invalidate the signature.
pub fn sign(&mut self, sk: &SecretKey, fork: &Fork, spec: &ChainSpec) { pub fn sign<T: EthSpec>(&mut self, sk: &SecretKey, fork: &Fork, spec: &ChainSpec) {
let message = self.block.signed_root(); let message = self.block.signed_root();
let epoch = self.block.slot.epoch(spec.slots_per_epoch); let epoch = self.block.slot.epoch(T::slots_per_epoch());
let domain = spec.get_domain(epoch, Domain::BeaconProposer, fork); let domain = spec.get_domain(epoch, Domain::BeaconProposer, fork);
self.block.signature = Signature::new(&message, domain, sk); self.block.signature = Signature::new(&message, domain, sk);
} }
@ -46,8 +46,8 @@ impl TestingBeaconBlockBuilder {
/// Sets the randao to be a signature across the blocks epoch. /// Sets the randao to be a signature across the blocks epoch.
/// ///
/// Modifying the block's slot after signing may invalidate the signature. /// Modifying the block's slot after signing may invalidate the signature.
pub fn set_randao_reveal(&mut self, sk: &SecretKey, fork: &Fork, spec: &ChainSpec) { pub fn set_randao_reveal<T: EthSpec>(&mut self, sk: &SecretKey, fork: &Fork, spec: &ChainSpec) {
let epoch = self.block.slot.epoch(spec.slots_per_epoch); let epoch = self.block.slot.epoch(T::slots_per_epoch());
let message = epoch.tree_hash_root(); let message = epoch.tree_hash_root();
let domain = spec.get_domain(epoch, Domain::Randao, fork); let domain = spec.get_domain(epoch, Domain::Randao, fork);
self.block.body.randao_reveal = Signature::new(&message, domain, sk); self.block.body.randao_reveal = Signature::new(&message, domain, sk);
@ -59,14 +59,15 @@ impl TestingBeaconBlockBuilder {
} }
/// Inserts a signed, valid `ProposerSlashing` for the validator. /// Inserts a signed, valid `ProposerSlashing` for the validator.
pub fn insert_proposer_slashing( pub fn insert_proposer_slashing<T: EthSpec>(
&mut self, &mut self,
validator_index: u64, validator_index: u64,
secret_key: &SecretKey, secret_key: &SecretKey,
fork: &Fork, fork: &Fork,
spec: &ChainSpec, spec: &ChainSpec,
) { ) {
let proposer_slashing = build_proposer_slashing(validator_index, secret_key, fork, spec); let proposer_slashing =
build_proposer_slashing::<T>(validator_index, secret_key, fork, spec);
self.block.body.proposer_slashings.push(proposer_slashing); self.block.body.proposer_slashings.push(proposer_slashing);
} }
@ -115,7 +116,7 @@ impl TestingBeaconBlockBuilder {
// - The slot is too old to be included in a block at this slot. // - The slot is too old to be included in a block at this slot.
// - The `MAX_ATTESTATIONS`. // - The `MAX_ATTESTATIONS`.
loop { loop {
if state.slot >= slot + spec.slots_per_epoch { if state.slot >= slot + T::slots_per_epoch() {
break; break;
} }
@ -194,7 +195,7 @@ impl TestingBeaconBlockBuilder {
builder.set_index(index); builder.set_index(index);
builder.sign( builder.sign(
&keypair, &keypair,
state.slot.epoch(spec.slots_per_epoch), state.slot.epoch(T::slots_per_epoch()),
&state.fork, &state.fork,
spec, spec,
); );
@ -211,7 +212,7 @@ impl TestingBeaconBlockBuilder {
spec: &ChainSpec, spec: &ChainSpec,
) { ) {
let mut builder = TestingVoluntaryExitBuilder::new( let mut builder = TestingVoluntaryExitBuilder::new(
state.slot.epoch(spec.slots_per_epoch), state.slot.epoch(T::slots_per_epoch()),
validator_index, validator_index,
); );
@ -234,14 +235,19 @@ impl TestingBeaconBlockBuilder {
spec: &ChainSpec, spec: &ChainSpec,
) { ) {
let mut builder = TestingTransferBuilder::new(from, to, amount, state.slot); let mut builder = TestingTransferBuilder::new(from, to, amount, state.slot);
builder.sign(keypair, &state.fork, spec); builder.sign::<T>(keypair, &state.fork, spec);
self.block.body.transfers.push(builder.build()) self.block.body.transfers.push(builder.build())
} }
/// Signs and returns the block, consuming the builder. /// Signs and returns the block, consuming the builder.
pub fn build(mut self, sk: &SecretKey, fork: &Fork, spec: &ChainSpec) -> BeaconBlock { pub fn build<T: EthSpec>(
self.sign(sk, fork, spec); mut self,
sk: &SecretKey,
fork: &Fork,
spec: &ChainSpec,
) -> BeaconBlock {
self.sign::<T>(sk, fork, spec);
self.block self.block
} }
@ -254,7 +260,7 @@ impl TestingBeaconBlockBuilder {
/// Builds an `ProposerSlashing` for some `validator_index`. /// Builds an `ProposerSlashing` for some `validator_index`.
/// ///
/// Signs the message using a `BeaconChainHarness`. /// Signs the message using a `BeaconChainHarness`.
fn build_proposer_slashing( fn build_proposer_slashing<T: EthSpec>(
validator_index: u64, validator_index: u64,
secret_key: &SecretKey, secret_key: &SecretKey,
fork: &Fork, fork: &Fork,
@ -265,7 +271,7 @@ fn build_proposer_slashing(
Signature::new(message, domain, secret_key) Signature::new(message, domain, secret_key)
}; };
TestingProposerSlashingBuilder::double_vote(validator_index, signer, spec) TestingProposerSlashingBuilder::double_vote::<T, _>(validator_index, signer, spec)
} }
/// Builds an `AttesterSlashing` for some `validator_indices`. /// Builds an `AttesterSlashing` for some `validator_indices`.

View File

@ -173,7 +173,7 @@ impl<T: EthSpec> TestingBeaconStateBuilder<T> {
/// Sets the `BeaconState` to be in a slot, calling `teleport_to_epoch` to update the epoch. /// Sets the `BeaconState` to be in a slot, calling `teleport_to_epoch` to update the epoch.
pub fn teleport_to_slot(&mut self, slot: Slot, spec: &ChainSpec) { pub fn teleport_to_slot(&mut self, slot: Slot, spec: &ChainSpec) {
self.teleport_to_epoch(slot.epoch(spec.slots_per_epoch), spec); self.teleport_to_epoch(slot.epoch(T::slots_per_epoch()), spec);
self.state.slot = slot; self.state.slot = slot;
} }
@ -184,7 +184,7 @@ impl<T: EthSpec> TestingBeaconStateBuilder<T> {
fn teleport_to_epoch(&mut self, epoch: Epoch, spec: &ChainSpec) { fn teleport_to_epoch(&mut self, epoch: Epoch, spec: &ChainSpec) {
let state = &mut self.state; let state = &mut self.state;
let slot = epoch.start_slot(spec.slots_per_epoch); let slot = epoch.start_slot(T::slots_per_epoch());
state.slot = slot; state.slot = slot;
@ -214,8 +214,8 @@ impl<T: EthSpec> TestingBeaconStateBuilder<T> {
let current_epoch = state.current_epoch(); let current_epoch = state.current_epoch();
let previous_epoch = state.previous_epoch(); let previous_epoch = state.previous_epoch();
let first_slot = previous_epoch.start_slot(spec.slots_per_epoch).as_u64(); let first_slot = previous_epoch.start_slot(T::slots_per_epoch()).as_u64();
let last_slot = current_epoch.end_slot(spec.slots_per_epoch).as_u64() let last_slot = current_epoch.end_slot(T::slots_per_epoch()).as_u64()
- spec.min_attestation_inclusion_delay; - spec.min_attestation_inclusion_delay;
let last_slot = std::cmp::min(state.slot.as_u64(), last_slot); let last_slot = std::cmp::min(state.slot.as_u64(), last_slot);

View File

@ -17,8 +17,9 @@ impl TestingProposerSlashingBuilder {
/// - `domain: Domain` /// - `domain: Domain`
/// ///
/// Where domain is a domain "constant" (e.g., `spec.domain_attestation`). /// Where domain is a domain "constant" (e.g., `spec.domain_attestation`).
pub fn double_vote<F>(proposer_index: u64, signer: F, spec: &ChainSpec) -> ProposerSlashing pub fn double_vote<T, F>(proposer_index: u64, signer: F, spec: &ChainSpec) -> ProposerSlashing
where where
T: EthSpec,
F: Fn(u64, &[u8], Epoch, Domain) -> Signature, F: Fn(u64, &[u8], Epoch, Domain) -> Signature,
{ {
let slot = Slot::new(0); let slot = Slot::new(0);
@ -40,13 +41,13 @@ impl TestingProposerSlashingBuilder {
header_1.signature = { header_1.signature = {
let message = header_1.signed_root(); let message = header_1.signed_root();
let epoch = slot.epoch(spec.slots_per_epoch); let epoch = slot.epoch(T::slots_per_epoch());
signer(proposer_index, &message[..], epoch, Domain::BeaconProposer) signer(proposer_index, &message[..], epoch, Domain::BeaconProposer)
}; };
header_2.signature = { header_2.signature = {
let message = header_2.signed_root(); let message = header_2.signed_root();
let epoch = slot.epoch(spec.slots_per_epoch); let epoch = slot.epoch(T::slots_per_epoch());
signer(proposer_index, &message[..], epoch, Domain::BeaconProposer) signer(proposer_index, &message[..], epoch, Domain::BeaconProposer)
}; };

View File

@ -29,10 +29,10 @@ impl TestingTransferBuilder {
/// Signs the transfer. /// Signs the transfer.
/// ///
/// The keypair must match that of the `from` validator index. /// The keypair must match that of the `from` validator index.
pub fn sign(&mut self, keypair: Keypair, fork: &Fork, spec: &ChainSpec) { pub fn sign<T: EthSpec>(&mut self, keypair: Keypair, fork: &Fork, spec: &ChainSpec) {
self.transfer.pubkey = keypair.pk; self.transfer.pubkey = keypair.pk;
let message = self.transfer.signed_root(); let message = self.transfer.signed_root();
let epoch = self.transfer.slot.epoch(spec.slots_per_epoch); let epoch = self.transfer.slot.epoch(T::slots_per_epoch());
let domain = spec.get_domain(epoch, Domain::Transfer, fork); let domain = spec.get_domain(epoch, Domain::Transfer, fork);
self.transfer.signature = Signature::new(&message, domain, &keypair.sk); self.transfer.signature = Signature::new(&message, domain, &keypair.sk);

View File

@ -29,9 +29,9 @@ impl<E: EthSpec> Case for EpochProcessingCrosslinks<E> {
let mut expected = self.post.clone(); let mut expected = self.post.clone();
// Processing requires the epoch cache. // Processing requires the epoch cache.
state.build_all_caches(&E::spec()).unwrap(); state.build_all_caches(&E::default_spec()).unwrap();
let mut result = process_crosslinks(&mut state, &E::spec()).map(|_| state); let mut result = process_crosslinks(&mut state, &E::default_spec()).map(|_| state);
compare_beacon_state_results_without_caches(&mut result, &mut expected) compare_beacon_state_results_without_caches(&mut result, &mut expected)
} }

View File

@ -27,7 +27,7 @@ impl<E: EthSpec> Case for EpochProcessingRegistryUpdates<E> {
fn result(&self, _case_index: usize) -> Result<(), Error> { fn result(&self, _case_index: usize) -> Result<(), Error> {
let mut state = self.pre.clone(); let mut state = self.pre.clone();
let mut expected = self.post.clone(); let mut expected = self.post.clone();
let spec = &E::spec(); let spec = &E::default_spec();
// Processing requires the epoch cache. // Processing requires the epoch cache.
state.build_all_caches(spec).unwrap(); state.build_all_caches(spec).unwrap();

View File

@ -31,9 +31,10 @@ impl<E: EthSpec> Case for OperationsAttesterSlashing<E> {
let mut expected = self.post.clone(); let mut expected = self.post.clone();
// Processing requires the epoch cache. // Processing requires the epoch cache.
state.build_all_caches(&E::spec()).unwrap(); state.build_all_caches(&E::default_spec()).unwrap();
let result = process_attester_slashings(&mut state, &[attester_slashing], &E::spec()); let result =
process_attester_slashings(&mut state, &[attester_slashing], &E::default_spec());
let mut result = result.and_then(|_| Ok(state)); let mut result = result.and_then(|_| Ok(state));

View File

@ -34,7 +34,7 @@ impl<E: EthSpec> Case for OperationsDeposit<E> {
let deposit = self.deposit.clone(); let deposit = self.deposit.clone();
let mut expected = self.post.clone(); let mut expected = self.post.clone();
let result = process_deposits(&mut state, &[deposit], &E::spec()); let result = process_deposits(&mut state, &[deposit], &E::default_spec());
let mut result = result.and_then(|_| Ok(state)); let mut result = result.and_then(|_| Ok(state));

View File

@ -31,9 +31,9 @@ impl<E: EthSpec> Case for OperationsExit<E> {
let mut expected = self.post.clone(); let mut expected = self.post.clone();
// Exit processing requires the epoch cache. // Exit processing requires the epoch cache.
state.build_all_caches(&E::spec()).unwrap(); state.build_all_caches(&E::default_spec()).unwrap();
let result = process_exits(&mut state, &[exit], &E::spec()); let result = process_exits(&mut state, &[exit], &E::default_spec());
let mut result = result.and_then(|_| Ok(state)); let mut result = result.and_then(|_| Ok(state));

View File

@ -31,9 +31,10 @@ impl<E: EthSpec> Case for OperationsProposerSlashing<E> {
let mut expected = self.post.clone(); let mut expected = self.post.clone();
// Processing requires the epoch cache. // Processing requires the epoch cache.
state.build_all_caches(&E::spec()).unwrap(); state.build_all_caches(&E::default_spec()).unwrap();
let result = process_proposer_slashings(&mut state, &[proposer_slashing], &E::spec()); let result =
process_proposer_slashings(&mut state, &[proposer_slashing], &E::default_spec());
let mut result = result.and_then(|_| Ok(state)); let mut result = result.and_then(|_| Ok(state));

View File

@ -31,9 +31,9 @@ impl<E: EthSpec> Case for OperationsTransfer<E> {
let mut expected = self.post.clone(); let mut expected = self.post.clone();
// Transfer processing requires the epoch cache. // Transfer processing requires the epoch cache.
state.build_all_caches(&E::spec()).unwrap(); state.build_all_caches(&E::default_spec()).unwrap();
let mut spec = E::spec(); let mut spec = E::default_spec();
spec.max_transfers = 1; spec.max_transfers = 1;
let result = process_transfers(&mut state, &[transfer], &spec); let result = process_transfers(&mut state, &[transfer], &spec);

View File

@ -24,7 +24,7 @@ impl<T: EthSpec> Case for Shuffling<T> {
if self.count == 0 { if self.count == 0 {
compare_result::<_, Error>(&Ok(vec![]), &Some(self.shuffled.clone()))?; compare_result::<_, Error>(&Ok(vec![]), &Some(self.shuffled.clone()))?;
} else { } else {
let spec = T::spec(); let spec = T::default_spec();
let seed = hex::decode(&self.seed[2..]) let seed = hex::decode(&self.seed[2..])
.map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?; .map_err(|e| Error::FailedToParseTest(format!("{:?}", e)))?;

View File

@ -1,6 +1,6 @@
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use types::{ use types::{
typenum::{U64, U8}, typenum::{U0, U64, U8},
ChainSpec, EthSpec, FewValidatorsEthSpec, FoundationEthSpec, ChainSpec, EthSpec, FewValidatorsEthSpec, FoundationEthSpec,
}; };
@ -18,10 +18,12 @@ impl EthSpec for MinimalEthSpec {
type LatestRandaoMixesLength = U64; type LatestRandaoMixesLength = U64;
type LatestActiveIndexRootsLength = U64; type LatestActiveIndexRootsLength = U64;
type LatestSlashedExitLength = U64; type LatestSlashedExitLength = U64;
type SlotsPerEpoch = U8;
type GenesisEpoch = U0;
fn spec() -> ChainSpec { fn default_spec() -> ChainSpec {
// TODO: this spec is likely incorrect! // TODO: this spec is likely incorrect!
let mut spec = FewValidatorsEthSpec::spec(); let mut spec = FewValidatorsEthSpec::default_spec();
spec.shuffle_round_count = 10; spec.shuffle_round_count = 10;
spec spec
} }

View File

@ -39,6 +39,8 @@ pub struct AttestationProducer<'a, B: BeaconNodeAttestation, S: Signer> {
pub beacon_node: Arc<B>, pub beacon_node: Arc<B>,
/// The signer to sign the block. /// The signer to sign the block.
pub signer: &'a S, pub signer: &'a S,
/// Used for caclulating epoch.
pub slots_per_epoch: u64,
} }
impl<'a, B: BeaconNodeAttestation, S: Signer> AttestationProducer<'a, B, S> { impl<'a, B: BeaconNodeAttestation, S: Signer> AttestationProducer<'a, B, S> {
@ -78,7 +80,7 @@ impl<'a, B: BeaconNodeAttestation, S: Signer> AttestationProducer<'a, B, S> {
/// The slash-protection code is not yet implemented. There is zero protection against /// The slash-protection code is not yet implemented. There is zero protection against
/// slashing. /// slashing.
pub fn produce_attestation(&mut self) -> Result<ValidatorEvent, Error> { pub fn produce_attestation(&mut self) -> Result<ValidatorEvent, Error> {
let epoch = self.duty.slot.epoch(self.spec.slots_per_epoch); let epoch = self.duty.slot.epoch(self.slots_per_epoch);
let attestation = self let attestation = self
.beacon_node .beacon_node

View File

@ -48,6 +48,8 @@ pub struct BlockProducer<'a, B: BeaconNodeBlock, S: Signer> {
pub beacon_node: Arc<B>, pub beacon_node: Arc<B>,
/// The signer to sign the block. /// The signer to sign the block.
pub signer: &'a S, pub signer: &'a S,
/// Used for caclulating epoch.
pub slots_per_epoch: u64,
} }
impl<'a, B: BeaconNodeBlock, S: Signer> BlockProducer<'a, B, S> { impl<'a, B: BeaconNodeBlock, S: Signer> BlockProducer<'a, B, S> {
@ -84,7 +86,7 @@ impl<'a, B: BeaconNodeBlock, S: Signer> BlockProducer<'a, B, S> {
/// The slash-protection code is not yet implemented. There is zero protection against /// The slash-protection code is not yet implemented. There is zero protection against
/// slashing. /// slashing.
pub fn produce_block(&mut self) -> Result<ValidatorEvent, Error> { pub fn produce_block(&mut self) -> Result<ValidatorEvent, Error> {
let epoch = self.slot.epoch(self.spec.slots_per_epoch); let epoch = self.slot.epoch(self.slots_per_epoch);
let message = epoch.tree_hash_root(); let message = epoch.tree_hash_root();
let randao_reveal = match self.signer.sign_message( let randao_reveal = match self.signer.sign_message(
@ -186,9 +188,9 @@ mod tests {
let beacon_node = Arc::new(SimulatedBeaconNode::default()); let beacon_node = Arc::new(SimulatedBeaconNode::default());
let signer = Arc::new(LocalSigner::new(Keypair::random())); let signer = Arc::new(LocalSigner::new(Keypair::random()));
let mut epoch_map = EpochMap::new(spec.slots_per_epoch); let mut epoch_map = EpochMap::new(T::slots_per_epoch());
let produce_slot = Slot::new(100); let produce_slot = Slot::new(100);
let produce_epoch = produce_slot.epoch(spec.slots_per_epoch); let produce_epoch = produce_slot.epoch(T::slots_per_epoch());
epoch_map.map.insert(produce_epoch, produce_slot); epoch_map.map.insert(produce_epoch, produce_slot);
let epoch_map = Arc::new(epoch_map); let epoch_map = Arc::new(epoch_map);
@ -233,7 +235,7 @@ mod tests {
); );
// In an epoch without known duties... // In an epoch without known duties...
let slot = (produce_epoch.as_u64() + 1) * spec.slots_per_epoch; let slot = (produce_epoch.as_u64() + 1) * T::slots_per_epoch();
slot_clock.set_slot(slot); slot_clock.set_slot(slot);
assert_eq!( assert_eq!(
block_proposer.poll(), block_proposer.poll(),

View File

@ -19,6 +19,7 @@ pub struct Config {
pub server: String, pub server: String,
/// The chain specification that we are connecting to /// The chain specification that we are connecting to
pub spec: ChainSpec, pub spec: ChainSpec,
pub slots_per_epoch: u64,
} }
const DEFAULT_PRIVATE_KEY_FILENAME: &str = "private.key"; const DEFAULT_PRIVATE_KEY_FILENAME: &str = "private.key";
@ -33,12 +34,13 @@ impl Default for Config {
let server = "localhost:5051".to_string(); let server = "localhost:5051".to_string();
let spec = FoundationEthSpec::spec(); let spec = FoundationEthSpec::default_spec();
Self { Self {
data_dir, data_dir,
server, server,
spec, spec,
slots_per_epoch: FoundationEthSpec::slots_per_epoch(),
} }
} }
} }
@ -67,9 +69,9 @@ impl Config {
if let Some(spec_str) = args.value_of("spec") { if let Some(spec_str) = args.value_of("spec") {
info!(log, "Using custom spec: {:?}", spec_str); info!(log, "Using custom spec: {:?}", spec_str);
config.spec = match spec_str { config.spec = match spec_str {
"foundation" => FoundationEthSpec::spec(), "foundation" => FoundationEthSpec::default_spec(),
"few_validators" => FewValidatorsEthSpec::spec(), "few_validators" => FewValidatorsEthSpec::default_spec(),
"lighthouse_testnet" => LighthouseTestnetEthSpec::spec(), "lighthouse_testnet" => LighthouseTestnetEthSpec::default_spec(),
// Should be impossible due to clap's `possible_values(..)` function. // Should be impossible due to clap's `possible_values(..)` function.
_ => unreachable!(), _ => unreachable!(),
}; };

View File

@ -164,7 +164,7 @@ mod tests {
#[test] #[test]
pub fn polling() { pub fn polling() {
let spec = Arc::new(ChainSpec::foundation()); let spec = Arc::new(ChainSpec::foundation());
let duties_map = Arc::new(EpochDutiesMap::new(spec.slots_per_epoch)); let duties_map = Arc::new(EpochDutiesMap::new(T::slots_per_epoch()));
let keypair = Keypair::random(); let keypair = Keypair::random();
let slot_clock = Arc::new(TestingSlotClock::new(0)); let slot_clock = Arc::new(TestingSlotClock::new(0));
let beacon_node = Arc::new(TestBeaconNode::default()); let beacon_node = Arc::new(TestBeaconNode::default());

View File

@ -47,6 +47,7 @@ pub struct Service<B: BeaconNodeDuties + 'static, S: Signer + 'static> {
slot_clock: SystemTimeSlotClock, slot_clock: SystemTimeSlotClock,
/// The current slot we are processing. /// The current slot we are processing.
current_slot: Slot, current_slot: Slot,
slots_per_epoch: u64,
/// The chain specification for this clients instance. /// The chain specification for this clients instance.
spec: Arc<ChainSpec>, spec: Arc<ChainSpec>,
/// The duties manager which maintains the state of when to perform actions. /// The duties manager which maintains the state of when to perform actions.
@ -177,7 +178,7 @@ impl<B: BeaconNodeDuties + 'static, S: Signer + 'static> Service<B, S> {
// Builds a mapping of Epoch -> Map(PublicKey, EpochDuty) // Builds a mapping of Epoch -> Map(PublicKey, EpochDuty)
// where EpochDuty contains slot numbers and attestation data that each validator needs to // where EpochDuty contains slot numbers and attestation data that each validator needs to
// produce work on. // produce work on.
let duties_map = RwLock::new(EpochDutiesMap::new(config.spec.slots_per_epoch)); let duties_map = RwLock::new(EpochDutiesMap::new(config.slots_per_epoch));
// builds a manager which maintains the list of current duties for all known validators // builds a manager which maintains the list of current duties for all known validators
// and can check when a validator needs to perform a task. // and can check when a validator needs to perform a task.
@ -194,6 +195,7 @@ impl<B: BeaconNodeDuties + 'static, S: Signer + 'static> Service<B, S> {
fork, fork,
slot_clock, slot_clock,
current_slot, current_slot,
slots_per_epoch: config.slots_per_epoch,
spec, spec,
duties_manager, duties_manager,
beacon_block_client, beacon_block_client,
@ -204,7 +206,10 @@ impl<B: BeaconNodeDuties + 'static, S: Signer + 'static> Service<B, S> {
/// Initialise the service then run the core thread. /// Initialise the service then run the core thread.
// TODO: Improve handling of generic BeaconNode types, to stub grpcClient // TODO: Improve handling of generic BeaconNode types, to stub grpcClient
pub fn start(config: ValidatorConfig, log: slog::Logger) -> error_chain::Result<()> { pub fn start(
config: ValidatorConfig,
log: slog::Logger,
) -> error_chain::Result<()> {
// connect to the node and retrieve its properties and initialize the gRPC clients // connect to the node and retrieve its properties and initialize the gRPC clients
let mut service = let mut service =
Service::<ValidatorServiceClient, Keypair>::initialize_service(config, log)?; Service::<ValidatorServiceClient, Keypair>::initialize_service(config, log)?;
@ -274,7 +279,7 @@ impl<B: BeaconNodeDuties + 'static, S: Signer + 'static> Service<B, S> {
Ok(slot) => slot.expect("Genesis is in the future"), Ok(slot) => slot.expect("Genesis is in the future"),
}; };
let current_epoch = current_slot.epoch(self.spec.slots_per_epoch); let current_epoch = current_slot.epoch(self.slots_per_epoch);
// this is a fatal error. If the slot clock repeats, there is something wrong with // this is a fatal error. If the slot clock repeats, there is something wrong with
// the timer, terminate immediately. // the timer, terminate immediately.
@ -291,7 +296,7 @@ impl<B: BeaconNodeDuties + 'static, S: Signer + 'static> Service<B, S> {
fn check_for_duties(&mut self) { fn check_for_duties(&mut self) {
let cloned_manager = self.duties_manager.clone(); let cloned_manager = self.duties_manager.clone();
let cloned_log = self.log.clone(); let cloned_log = self.log.clone();
let current_epoch = self.current_slot.epoch(self.spec.slots_per_epoch); let current_epoch = self.current_slot.epoch(self.slots_per_epoch);
// spawn a new thread separate to the runtime // spawn a new thread separate to the runtime
// TODO: Handle thread termination/timeout // TODO: Handle thread termination/timeout
// TODO: Add duties thread back in, with channel to process duties in duty change. // TODO: Add duties thread back in, with channel to process duties in duty change.
@ -316,6 +321,7 @@ impl<B: BeaconNodeDuties + 'static, S: Signer + 'static> Service<B, S> {
let spec = self.spec.clone(); let spec = self.spec.clone();
let beacon_node = self.beacon_block_client.clone(); let beacon_node = self.beacon_block_client.clone();
let log = self.log.clone(); let log = self.log.clone();
let slots_per_epoch = self.slots_per_epoch;
std::thread::spawn(move || { std::thread::spawn(move || {
info!(log, "Producing a block"; "Validator"=> format!("{}", signers[signer_index])); info!(log, "Producing a block"; "Validator"=> format!("{}", signers[signer_index]));
let signer = &signers[signer_index]; let signer = &signers[signer_index];
@ -325,6 +331,7 @@ impl<B: BeaconNodeDuties + 'static, S: Signer + 'static> Service<B, S> {
spec, spec,
beacon_node, beacon_node,
signer, signer,
slots_per_epoch,
}; };
block_producer.handle_produce_block(log); block_producer.handle_produce_block(log);
}); });
@ -337,6 +344,7 @@ impl<B: BeaconNodeDuties + 'static, S: Signer + 'static> Service<B, S> {
let spec = self.spec.clone(); let spec = self.spec.clone();
let beacon_node = self.attestation_client.clone(); let beacon_node = self.attestation_client.clone();
let log = self.log.clone(); let log = self.log.clone();
let slots_per_epoch = self.slots_per_epoch;
std::thread::spawn(move || { std::thread::spawn(move || {
info!(log, "Producing an attestation"; "Validator"=> format!("{}", signers[signer_index])); info!(log, "Producing an attestation"; "Validator"=> format!("{}", signers[signer_index]));
let signer = &signers[signer_index]; let signer = &signers[signer_index];
@ -346,6 +354,7 @@ impl<B: BeaconNodeDuties + 'static, S: Signer + 'static> Service<B, S> {
spec, spec,
beacon_node, beacon_node,
signer, signer,
slots_per_epoch,
}; };
attestation_producer.handle_produce_attestation(log); attestation_producer.handle_produce_attestation(log);
}); });