diff --git a/beacon_node/beacon_chain/src/attestation_aggregation.rs b/beacon_node/beacon_chain/src/attestation_aggregator.rs similarity index 98% rename from beacon_node/beacon_chain/src/attestation_aggregation.rs rename to beacon_node/beacon_chain/src/attestation_aggregator.rs index 4cac5056cb..4b83bbebcb 100644 --- a/beacon_node/beacon_chain/src/attestation_aggregation.rs +++ b/beacon_node/beacon_chain/src/attestation_aggregator.rs @@ -9,12 +9,14 @@ pub struct AttestationAggregator { store: HashMap, Attestation>, } +#[derive(Debug, PartialEq)] pub enum ProcessOutcome { AggregationNotRequired, Aggregated, NewAttestationCreated, } +#[derive(Debug, PartialEq)] pub enum ProcessError { BadValidatorIndex, BadSignature, diff --git a/beacon_node/beacon_chain/src/attestation_processing.rs b/beacon_node/beacon_chain/src/attestation_processing.rs new file mode 100644 index 0000000000..90107dd97b --- /dev/null +++ b/beacon_node/beacon_chain/src/attestation_processing.rs @@ -0,0 +1,47 @@ +use super::{BeaconChain, ClientDB, SlotClock}; +pub use crate::attestation_aggregator::{ProcessError as AggregatorError, ProcessOutcome}; +use crate::canonical_head::Error as HeadError; +use types::{AttestationData, Signature}; + +#[derive(Debug, PartialEq)] +pub enum Error { + PresentSlotUnknown, + AggregatorError(AggregatorError), + HeadError(HeadError), +} + +impl BeaconChain +where + T: ClientDB, + U: SlotClock, +{ + pub fn process_free_attestation( + &self, + attestation_data: &AttestationData, + signature: &Signature, + validator_index: u64, + ) -> Result { + let present_slot = self + .present_slot() + .ok_or_else(|| Error::PresentSlotUnknown)?; + let state = self.state(present_slot)?; + + self.attestation_aggregator + .write() + .expect("Aggregator unlock failed.") + .process_free_attestation(&state, attestation_data, signature, validator_index) + .map_err(|e| e.into()) + } +} + +impl From for Error { + fn from(e: AggregatorError) -> Error { + Error::AggregatorError(e) + } +} + +impl From for Error { + fn from(e: HeadError) -> Error { + Error::HeadError(e) + } +} diff --git a/beacon_node/beacon_chain/src/attestation_production.rs b/beacon_node/beacon_chain/src/attestation_production.rs index 33d220b7f7..5adf70a4ac 100644 --- a/beacon_node/beacon_chain/src/attestation_production.rs +++ b/beacon_node/beacon_chain/src/attestation_production.rs @@ -3,11 +3,6 @@ use types::{AttestationData, Hash256}; #[derive(Debug, PartialEq)] pub enum Error { - /* - DBError(String), - StateTransitionError(TransitionError), - PresentSlotIsNone, - */ SlotTooOld, PresentSlotUnknown, StateError, diff --git a/beacon_node/beacon_chain/src/canonical_head.rs b/beacon_node/beacon_chain/src/canonical_head.rs index 121ded7676..04bbe57ed7 100644 --- a/beacon_node/beacon_chain/src/canonical_head.rs +++ b/beacon_node/beacon_chain/src/canonical_head.rs @@ -2,6 +2,7 @@ use crate::{BeaconChain, CheckPoint, ClientDB, SlotClock}; use std::sync::RwLockReadGuard; use types::{beacon_state::SlotProcessingError, BeaconBlock, BeaconState, Hash256}; +#[derive(Debug, PartialEq)] pub enum Error { PastSlot, UnableToDetermineProducer, diff --git a/beacon_node/beacon_chain/src/info.rs b/beacon_node/beacon_chain/src/info.rs index 441d56b784..fd23c0906c 100644 --- a/beacon_node/beacon_chain/src/info.rs +++ b/beacon_node/beacon_chain/src/info.rs @@ -52,4 +52,11 @@ where .beacon_block .slot } + + pub fn validator_attestion_slot_and_shard(&self, validator_index: usize) -> Option<(u64, u64)> { + let present_slot = self.present_slot()?; + let state = self.state(present_slot).ok()?; + + Some(state.attestation_slot_and_shard_for_validator(validator_index, &self.spec)) + } } diff --git a/beacon_node/beacon_chain/src/lib.rs b/beacon_node/beacon_chain/src/lib.rs index c4da9099f1..401479e5a8 100644 --- a/beacon_node/beacon_chain/src/lib.rs +++ b/beacon_node/beacon_chain/src/lib.rs @@ -1,4 +1,5 @@ -mod attestation_aggregation; +mod attestation_aggregator; +pub mod attestation_processing; mod attestation_production; mod attestation_targets; mod block_graph; @@ -14,7 +15,7 @@ mod state_transition; use self::attestation_targets::AttestationTargets; use self::block_graph::BlockGraph; -use attestation_aggregation::AttestationAggregator; +use attestation_aggregator::AttestationAggregator; use db::{ stores::{BeaconBlockStore, BeaconStateStore}, ClientDB, DBError, diff --git a/beacon_node/beacon_chain/test_harness/Cargo.toml b/beacon_node/beacon_chain/test_harness/Cargo.toml index 72fdf7164d..5aa57b0b46 100644 --- a/beacon_node/beacon_chain/test_harness/Cargo.toml +++ b/beacon_node/beacon_chain/test_harness/Cargo.toml @@ -12,11 +12,13 @@ harness = false criterion = "0.2" [dependencies] +attester = { path = "../../../eth2/attester" } beacon_chain = { path = "../../beacon_chain" } block_producer = { path = "../../../eth2/block_producer" } bls = { path = "../../../eth2/utils/bls" } boolean-bitfield = { path = "../../../eth2/utils/boolean-bitfield" } db = { path = "../../db" } +parking_lot = "0.7" failure = "0.1" failure_derive = "0.1" genesis = { path = "../../../eth2/genesis" } diff --git a/beacon_node/beacon_chain/test_harness/src/direct_beacon_node.rs b/beacon_node/beacon_chain/test_harness/src/direct_beacon_node.rs deleted file mode 100644 index 9fcd7c2862..0000000000 --- a/beacon_node/beacon_chain/test_harness/src/direct_beacon_node.rs +++ /dev/null @@ -1,71 +0,0 @@ -use beacon_chain::block_processing::{Error as ProcessingError, Outcome as ProcessingOutcome}; -use beacon_chain::{block_production::Error as BlockProductionError, BeaconChain}; -use block_producer::{ - BeaconNode as BeaconBlockNode, BeaconNodeError as BeaconBlockNodeError, PublishOutcome, -}; -use db::ClientDB; -use slot_clock::SlotClock; -use std::sync::Arc; -use types::{BeaconBlock, PublicKey, Signature}; - -pub struct DirectBeaconNode { - beacon_chain: Arc>, -} - -impl DirectBeaconNode { - pub fn new(beacon_chain: Arc>) -> Self { - Self { beacon_chain } - } -} - -impl BeaconBlockNode for DirectBeaconNode -where - BlockProductionError: From<::Error>, - ProcessingError: From<::Error>, -{ - fn proposer_nonce(&self, pubkey: &PublicKey) -> Result { - let validator_index = self - .beacon_chain - .validator_index(pubkey) - .ok_or_else(|| BeaconBlockNodeError::RemoteFailure("pubkey unknown.".to_string()))?; - - self.beacon_chain - .proposer_slots(validator_index) - .ok_or_else(|| { - BeaconBlockNodeError::RemoteFailure("validator_index unknown.".to_string()) - }) - } - - fn produce_beacon_block( - &self, - slot: u64, - randao_reveal: &Signature, - ) -> Result, BeaconBlockNodeError> -where { - let (block, _state) = self - .beacon_chain - .produce_block(randao_reveal.clone()) - .map_err(|e| BeaconBlockNodeError::RemoteFailure(format!("{:?}", e)))?; - - if block.slot == slot { - Ok(Some(block)) - } else { - Err(BeaconBlockNodeError::RemoteFailure( - "Unable to produce at non-current slot.".to_string(), - )) - } - } - - fn publish_beacon_block( - &self, - block: BeaconBlock, - ) -> Result { - match self.beacon_chain.process_block(block) { - Ok(ProcessingOutcome::ValidBlock(_)) => Ok(PublishOutcome::ValidBlock), - Ok(ProcessingOutcome::InvalidBlock(reason)) => { - Ok(PublishOutcome::InvalidBlock(format!("{:?}", reason))) - } - Err(error) => Err(BeaconBlockNodeError::RemoteFailure(format!("{:?}", error))), - } - } -} diff --git a/beacon_node/beacon_chain/test_harness/src/direct_duties.rs b/beacon_node/beacon_chain/test_harness/src/direct_duties.rs deleted file mode 100644 index ff2cd7223f..0000000000 --- a/beacon_node/beacon_chain/test_harness/src/direct_duties.rs +++ /dev/null @@ -1,38 +0,0 @@ -use beacon_chain::{block_production::Error as BlockProductionError, BeaconChain}; -use block_producer::{DutiesReader, DutiesReaderError}; -use db::ClientDB; -use slot_clock::SlotClock; -use std::sync::Arc; -use types::PublicKey; - -pub struct DirectDuties { - beacon_chain: Arc>, - pubkey: PublicKey, -} - -impl DirectDuties { - pub fn new(pubkey: PublicKey, beacon_chain: Arc>) -> Self { - Self { - beacon_chain, - pubkey, - } - } -} - -impl DutiesReader for DirectDuties -where - BlockProductionError: From<::Error>, -{ - fn is_block_production_slot(&self, slot: u64) -> Result { - let validator_index = self - .beacon_chain - .validator_index(&self.pubkey) - .ok_or_else(|| DutiesReaderError::UnknownValidator)?; - - match self.beacon_chain.block_proposer(slot) { - Some(proposer) if proposer == validator_index => Ok(true), - Some(_) => Ok(false), - None => Err(DutiesReaderError::UnknownEpoch), - } - } -} diff --git a/beacon_node/beacon_chain/test_harness/src/beacon_chain_harness.rs b/beacon_node/beacon_chain/test_harness/src/harness.rs similarity index 100% rename from beacon_node/beacon_chain/test_harness/src/beacon_chain_harness.rs rename to beacon_node/beacon_chain/test_harness/src/harness.rs diff --git a/beacon_node/beacon_chain/test_harness/src/lib.rs b/beacon_node/beacon_chain/test_harness/src/lib.rs index efdc39e1e5..71f9a88558 100644 --- a/beacon_node/beacon_chain/test_harness/src/lib.rs +++ b/beacon_node/beacon_chain/test_harness/src/lib.rs @@ -1,11 +1,5 @@ -mod beacon_chain_harness; -mod benching_beacon_node; -mod direct_beacon_node; -mod direct_duties; +mod harness; mod validator; -pub use self::beacon_chain_harness::BeaconChainHarness; -pub use self::benching_beacon_node::BenchingBeaconNode; -pub use self::direct_beacon_node::DirectBeaconNode; -pub use self::direct_duties::DirectDuties; +pub use self::harness::BeaconChainHarness; pub use self::validator::TestValidator; diff --git a/beacon_node/beacon_chain/test_harness/src/validator/beacon_node/attester.rs b/beacon_node/beacon_chain/test_harness/src/validator/beacon_node/attester.rs new file mode 100644 index 0000000000..71c45dd314 --- /dev/null +++ b/beacon_node/beacon_chain/test_harness/src/validator/beacon_node/attester.rs @@ -0,0 +1,40 @@ +use super::BenchingBeaconNode; +use attester::{BeaconNode as AttesterBeaconNode, BeaconNodeError as NodeError, PublishOutcome}; +use beacon_chain::block_processing::Error as ProcessingError; +use beacon_chain::block_production::Error as BlockProductionError; +use db::ClientDB; +use slot_clock::SlotClock; +use types::{AttestationData, Signature}; + +impl AttesterBeaconNode for BenchingBeaconNode +where + BlockProductionError: From<::Error>, + ProcessingError: From<::Error>, +{ + fn produce_attestation_data( + &self, + slot: u64, + shard: u64, + ) -> Result, NodeError> { + match self.beacon_chain.produce_attestation_data(slot, shard) { + Ok(attestation_data) => Ok(Some(attestation_data)), + Err(e) => Err(NodeError::RemoteFailure(format!("{:?}", e))), + } + } + + fn publish_attestation_data( + &self, + attestation_data: AttestationData, + signature: Signature, + validator_index: u64, + ) -> Result { + match self.beacon_chain.process_free_attestation( + &attestation_data, + &signature, + validator_index, + ) { + Ok(_) => Ok(PublishOutcome::ValidAttestation), + Err(e) => Err(NodeError::RemoteFailure(format!("{:?}", e))), + } + } +} diff --git a/beacon_node/beacon_chain/test_harness/src/validator/beacon_node/mod.rs b/beacon_node/beacon_chain/test_harness/src/validator/beacon_node/mod.rs new file mode 100644 index 0000000000..60664468df --- /dev/null +++ b/beacon_node/beacon_chain/test_harness/src/validator/beacon_node/mod.rs @@ -0,0 +1,34 @@ +use beacon_chain::BeaconChain; +use db::ClientDB; +use parking_lot::RwLock; +use slot_clock::SlotClock; +use std::sync::Arc; +use types::{AttestationData, BeaconBlock, Signature}; + +mod attester; +mod producer; + +/// An attestation that hasn't been aggregated into an `Attestation`. +/// +/// (attestation_data, signature, validator_index) +pub type FreeAttestation = (AttestationData, Signature, u64); + +pub struct BenchingBeaconNode { + beacon_chain: Arc>, + published_blocks: RwLock>, + published_attestations: RwLock>, +} + +impl BenchingBeaconNode { + pub fn new(beacon_chain: Arc>) -> Self { + Self { + beacon_chain, + published_blocks: RwLock::new(vec![]), + published_attestations: RwLock::new(vec![]), + } + } + + pub fn last_published_block(&self) -> Option { + Some(self.published_blocks.read().last()?.clone()) + } +} diff --git a/beacon_node/beacon_chain/test_harness/src/benching_beacon_node.rs b/beacon_node/beacon_chain/test_harness/src/validator/beacon_node/producer.rs similarity index 67% rename from beacon_node/beacon_chain/test_harness/src/benching_beacon_node.rs rename to beacon_node/beacon_chain/test_harness/src/validator/beacon_node/producer.rs index 551fbff99c..70ca4ff0cb 100644 --- a/beacon_node/beacon_chain/test_harness/src/benching_beacon_node.rs +++ b/beacon_node/beacon_chain/test_harness/src/validator/beacon_node/producer.rs @@ -1,37 +1,13 @@ +use super::BenchingBeaconNode; use beacon_chain::block_processing::Error as ProcessingError; -use beacon_chain::{block_production::Error as BlockProductionError, BeaconChain}; +use beacon_chain::block_production::Error as BlockProductionError; use block_producer::{ BeaconNode as BeaconBlockNode, BeaconNodeError as BeaconBlockNodeError, PublishOutcome, }; use db::ClientDB; use slot_clock::SlotClock; -use std::sync::{Arc, RwLock}; use types::{BeaconBlock, PublicKey, Signature}; -pub struct BenchingBeaconNode { - beacon_chain: Arc>, - published_blocks: RwLock>, -} - -impl BenchingBeaconNode { - pub fn new(beacon_chain: Arc>) -> Self { - Self { - beacon_chain, - published_blocks: RwLock::new(vec![]), - } - } - - pub fn last_published_block(&self) -> Option { - Some( - self.published_blocks - .read() - .expect("Unable to unlock `published_blocks` for reading.") - .last()? - .clone(), - ) - } -} - impl BeaconBlockNode for BenchingBeaconNode where BlockProductionError: From<::Error>, @@ -56,8 +32,7 @@ where &self, slot: u64, randao_reveal: &Signature, - ) -> Result, BeaconBlockNodeError> -where { + ) -> Result, BeaconBlockNodeError> { let (block, _state) = self .beacon_chain .produce_block(randao_reveal.clone()) @@ -81,10 +56,7 @@ where { &self, block: BeaconBlock, ) -> Result { - self.published_blocks - .write() - .expect("Unable to unlock `published_blocks` for writing.") - .push(block); + self.published_blocks.write().push(block); Ok(PublishOutcome::ValidBlock) } } diff --git a/beacon_node/beacon_chain/test_harness/src/validator/direct_duties.rs b/beacon_node/beacon_chain/test_harness/src/validator/direct_duties.rs new file mode 100644 index 0000000000..3259817ad1 --- /dev/null +++ b/beacon_node/beacon_chain/test_harness/src/validator/direct_duties.rs @@ -0,0 +1,70 @@ +use attester::{ + DutiesReader as AttesterDutiesReader, DutiesReaderError as AttesterDutiesReaderError, +}; +use beacon_chain::{block_production::Error as BlockProductionError, BeaconChain}; +use block_producer::{ + DutiesReader as ProducerDutiesReader, DutiesReaderError as ProducerDutiesReaderError, +}; +use db::ClientDB; +use slot_clock::SlotClock; +use std::sync::Arc; +use types::PublicKey; + +pub struct DirectDuties { + beacon_chain: Arc>, + pubkey: PublicKey, +} + +impl DirectDuties { + pub fn new(pubkey: PublicKey, beacon_chain: Arc>) -> Self { + Self { + beacon_chain, + pubkey, + } + } +} + +impl ProducerDutiesReader for DirectDuties +where + BlockProductionError: From<::Error>, +{ + fn is_block_production_slot(&self, slot: u64) -> Result { + let validator_index = self + .beacon_chain + .validator_index(&self.pubkey) + .ok_or_else(|| ProducerDutiesReaderError::UnknownValidator)?; + + match self.beacon_chain.block_proposer(slot) { + Some(proposer) if proposer == validator_index => Ok(true), + Some(_) => Ok(false), + None => Err(ProducerDutiesReaderError::UnknownEpoch), + } + } +} + +impl AttesterDutiesReader for DirectDuties +where + BlockProductionError: From<::Error>, +{ + fn validator_index(&self) -> Option { + match self.beacon_chain.validator_index(&self.pubkey) { + Some(index) => Some(index as u64), + None => None, + } + } + + fn attestation_shard(&self, slot: u64) -> Result, AttesterDutiesReaderError> { + if let Some(validator_index) = self.validator_index() { + match self + .beacon_chain + .validator_attestion_slot_and_shard(validator_index as usize) + { + Some((attest_slot, attest_shard)) if attest_slot == slot => Ok(Some(attest_shard)), + Some(_) => Ok(None), + None => Err(AttesterDutiesReaderError::UnknownEpoch), + } + } else { + Err(AttesterDutiesReaderError::UnknownValidator) + } + } +} diff --git a/beacon_node/beacon_chain/test_harness/src/validator.rs b/beacon_node/beacon_chain/test_harness/src/validator/mod.rs similarity index 79% rename from beacon_node/beacon_chain/test_harness/src/validator.rs rename to beacon_node/beacon_chain/test_harness/src/validator/mod.rs index 1d7f7bd4a1..f2ac960755 100644 --- a/beacon_node/beacon_chain/test_harness/src/validator.rs +++ b/beacon_node/beacon_chain/test_harness/src/validator/mod.rs @@ -1,11 +1,18 @@ -use super::{BenchingBeaconNode, DirectDuties}; +use attester::Attester; use beacon_chain::BeaconChain; -use block_producer::{test_utils::TestSigner, BlockProducer, Error as PollError}; +use block_producer::{BlockProducer, Error as PollError}; use db::MemoryDB; +use signer::TestSigner; use slot_clock::TestingSlotClock; use std::sync::Arc; use types::{BeaconBlock, ChainSpec, Keypair}; +mod beacon_node; +mod direct_duties; +mod signer; + +pub use self::beacon_node::BenchingBeaconNode; +pub use self::direct_duties::DirectDuties; pub use block_producer::PollOutcome; #[derive(Debug, PartialEq)] @@ -21,6 +28,12 @@ pub struct TestValidator { DirectDuties, TestSigner, >, + pub attester: Attester< + TestingSlotClock, + BenchingBeaconNode, + DirectDuties, + TestSigner, + >, pub spec: Arc, pub epoch_map: Arc>, pub keypair: Keypair, @@ -49,8 +62,16 @@ impl TestValidator { signer.clone(), ); + let attester = Attester::new( + epoch_map.clone(), + slot_clock.clone(), + beacon_node.clone(), + signer.clone(), + ); + Self { block_producer, + attester, spec, epoch_map, keypair, diff --git a/beacon_node/beacon_chain/test_harness/src/validator/signer.rs b/beacon_node/beacon_chain/test_harness/src/validator/signer.rs new file mode 100644 index 0000000000..572a870ffc --- /dev/null +++ b/beacon_node/beacon_chain/test_harness/src/validator/signer.rs @@ -0,0 +1,46 @@ +use attester::Signer as AttesterSigner; +use block_producer::Signer as BlockProposerSigner; +use std::sync::RwLock; +use types::{Keypair, Signature}; + +/// A test-only struct used to simulate a Beacon Node. +pub struct TestSigner { + keypair: Keypair, + should_sign: RwLock, +} + +impl TestSigner { + /// Produce a new TestSigner with signing enabled by default. + pub fn new(keypair: Keypair) -> Self { + Self { + keypair, + should_sign: RwLock::new(true), + } + } + + /// If set to `false`, the service will refuse to sign all messages. Otherwise, all messages + /// will be signed. + pub fn enable_signing(&self, enabled: bool) { + *self.should_sign.write().unwrap() = enabled; + } + + fn bls_sign(&self, message: &[u8]) -> Option { + Some(Signature::new(message, &self.keypair.sk)) + } +} + +impl BlockProposerSigner for TestSigner { + fn sign_block_proposal(&self, message: &[u8]) -> Option { + self.bls_sign(message) + } + + fn sign_randao_reveal(&self, message: &[u8]) -> Option { + self.bls_sign(message) + } +} + +impl AttesterSigner for TestSigner { + fn sign_attestation_message(&self, message: &[u8]) -> Option { + self.bls_sign(message) + } +} diff --git a/eth2/attester/src/lib.rs b/eth2/attester/src/lib.rs index 7e3f0eb6b8..6047626346 100644 --- a/eth2/attester/src/lib.rs +++ b/eth2/attester/src/lib.rs @@ -131,7 +131,7 @@ impl Attester Option { + fn sign_attestation_message(&self, message: &[u8]) -> Option { Some(Signature::new(message, &self.keypair.sk)) } } diff --git a/eth2/attester/src/traits.rs b/eth2/attester/src/traits.rs index bc3ccf63f1..ce6a635e71 100644 --- a/eth2/attester/src/traits.rs +++ b/eth2/attester/src/traits.rs @@ -47,5 +47,5 @@ pub trait DutiesReader: Send + Sync { /// Signs message using an internally-maintained private key. pub trait Signer { - fn bls_sign(&self, message: &[u8]) -> Option; + fn sign_attestation_message(&self, message: &[u8]) -> Option; } diff --git a/eth2/block_producer/src/lib.rs b/eth2/block_producer/src/lib.rs index 4ea08647df..ed65622d4d 100644 --- a/eth2/block_producer/src/lib.rs +++ b/eth2/block_producer/src/lib.rs @@ -4,7 +4,7 @@ mod traits; use slot_clock::SlotClock; use ssz::ssz_encode; use std::sync::Arc; -use types::{BeaconBlock, ChainSpec, Hash256, ProposalSignedData, PublicKey}; +use types::{BeaconBlock, ChainSpec, PublicKey}; pub use self::traits::{ BeaconNode, BeaconNodeError, DutiesReader, DutiesReaderError, PublishOutcome, Signer, @@ -139,7 +139,7 @@ impl BlockProducer return Ok(PollOutcome::SignerRejection(slot)), Some(signature) => signature, } @@ -171,7 +171,10 @@ impl BlockProducer Option { self.store_produce(&block); - match self.signer.bls_sign(&block.proposal_root(&self.spec)[..]) { + match self + .signer + .sign_block_proposal(&block.proposal_root(&self.spec)[..]) + { None => None, Some(signature) => { block.signature = signature; diff --git a/eth2/block_producer/src/test_utils/signer.rs b/eth2/block_producer/src/test_utils/signer.rs index d43c0feb0c..62163f5b21 100644 --- a/eth2/block_producer/src/test_utils/signer.rs +++ b/eth2/block_producer/src/test_utils/signer.rs @@ -25,7 +25,11 @@ impl TestSigner { } impl Signer for TestSigner { - fn bls_sign(&self, message: &[u8]) -> Option { + fn sign_block_proposal(&self, message: &[u8]) -> Option { + Some(Signature::new(message, &self.keypair.sk)) + } + + fn sign_randao_reveal(&self, message: &[u8]) -> Option { Some(Signature::new(message, &self.keypair.sk)) } } diff --git a/eth2/block_producer/src/traits.rs b/eth2/block_producer/src/traits.rs index 451ce6cc76..b09b81e672 100644 --- a/eth2/block_producer/src/traits.rs +++ b/eth2/block_producer/src/traits.rs @@ -47,5 +47,6 @@ pub trait DutiesReader: Send + Sync { /// Signs message using an internally-maintained private key. pub trait Signer { - fn bls_sign(&self, message: &[u8]) -> Option; + fn sign_block_proposal(&self, message: &[u8]) -> Option; + fn sign_randao_reveal(&self, message: &[u8]) -> Option; } diff --git a/eth2/types/src/beacon_state/slot_processing.rs b/eth2/types/src/beacon_state/slot_processing.rs index e3be9cceeb..2070d57cb0 100644 --- a/eth2/types/src/beacon_state/slot_processing.rs +++ b/eth2/types/src/beacon_state/slot_processing.rs @@ -38,6 +38,20 @@ impl BeaconState { let validator_count = self.validator_registry.len(); Some((slot as usize) % validator_count) } + + pub fn attestation_slot_and_shard_for_validator( + &self, + validator_index: usize, + spec: &ChainSpec, + ) -> (u64, u64) { + // TODO: this is a stub; implement it properly. + let validator_index = validator_index as u64; + + let slot = validator_index % spec.epoch_length; + let shard = validator_index % spec.shard_count; + + (slot, shard) + } } fn merkle_root(_input: &[Hash256]) -> Hash256 {