Add attester to beacon chain test harness
This commit is contained in:
parent
e1698102e0
commit
5bbffcb053
@ -9,12 +9,14 @@ pub struct AttestationAggregator {
|
||||
store: HashMap<Vec<u8>, Attestation>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum ProcessOutcome {
|
||||
AggregationNotRequired,
|
||||
Aggregated,
|
||||
NewAttestationCreated,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum ProcessError {
|
||||
BadValidatorIndex,
|
||||
BadSignature,
|
47
beacon_node/beacon_chain/src/attestation_processing.rs
Normal file
47
beacon_node/beacon_chain/src/attestation_processing.rs
Normal file
@ -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<T, U> BeaconChain<T, U>
|
||||
where
|
||||
T: ClientDB,
|
||||
U: SlotClock,
|
||||
{
|
||||
pub fn process_free_attestation(
|
||||
&self,
|
||||
attestation_data: &AttestationData,
|
||||
signature: &Signature,
|
||||
validator_index: u64,
|
||||
) -> Result<ProcessOutcome, Error> {
|
||||
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<AggregatorError> for Error {
|
||||
fn from(e: AggregatorError) -> Error {
|
||||
Error::AggregatorError(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<HeadError> for Error {
|
||||
fn from(e: HeadError) -> Error {
|
||||
Error::HeadError(e)
|
||||
}
|
||||
}
|
@ -3,11 +3,6 @@ use types::{AttestationData, Hash256};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Error {
|
||||
/*
|
||||
DBError(String),
|
||||
StateTransitionError(TransitionError),
|
||||
PresentSlotIsNone,
|
||||
*/
|
||||
SlotTooOld,
|
||||
PresentSlotUnknown,
|
||||
StateError,
|
||||
|
@ -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,
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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" }
|
||||
|
@ -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<T: ClientDB, U: SlotClock> {
|
||||
beacon_chain: Arc<BeaconChain<T, U>>,
|
||||
}
|
||||
|
||||
impl<T: ClientDB, U: SlotClock> DirectBeaconNode<T, U> {
|
||||
pub fn new(beacon_chain: Arc<BeaconChain<T, U>>) -> Self {
|
||||
Self { beacon_chain }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ClientDB, U: SlotClock> BeaconBlockNode for DirectBeaconNode<T, U>
|
||||
where
|
||||
BlockProductionError: From<<U>::Error>,
|
||||
ProcessingError: From<<U as SlotClock>::Error>,
|
||||
{
|
||||
fn proposer_nonce(&self, pubkey: &PublicKey) -> Result<u64, BeaconBlockNodeError> {
|
||||
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<Option<BeaconBlock>, 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<PublishOutcome, BeaconBlockNodeError> {
|
||||
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))),
|
||||
}
|
||||
}
|
||||
}
|
@ -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<T: ClientDB, U: SlotClock> {
|
||||
beacon_chain: Arc<BeaconChain<T, U>>,
|
||||
pubkey: PublicKey,
|
||||
}
|
||||
|
||||
impl<T: ClientDB, U: SlotClock> DirectDuties<T, U> {
|
||||
pub fn new(pubkey: PublicKey, beacon_chain: Arc<BeaconChain<T, U>>) -> Self {
|
||||
Self {
|
||||
beacon_chain,
|
||||
pubkey,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ClientDB, U: SlotClock> DutiesReader for DirectDuties<T, U>
|
||||
where
|
||||
BlockProductionError: From<<U>::Error>,
|
||||
{
|
||||
fn is_block_production_slot(&self, slot: u64) -> Result<bool, DutiesReaderError> {
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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<T: ClientDB, U: SlotClock> AttesterBeaconNode for BenchingBeaconNode<T, U>
|
||||
where
|
||||
BlockProductionError: From<<U>::Error>,
|
||||
ProcessingError: From<<U as SlotClock>::Error>,
|
||||
{
|
||||
fn produce_attestation_data(
|
||||
&self,
|
||||
slot: u64,
|
||||
shard: u64,
|
||||
) -> Result<Option<AttestationData>, 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<PublishOutcome, NodeError> {
|
||||
match self.beacon_chain.process_free_attestation(
|
||||
&attestation_data,
|
||||
&signature,
|
||||
validator_index,
|
||||
) {
|
||||
Ok(_) => Ok(PublishOutcome::ValidAttestation),
|
||||
Err(e) => Err(NodeError::RemoteFailure(format!("{:?}", e))),
|
||||
}
|
||||
}
|
||||
}
|
@ -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<T: ClientDB, U: SlotClock> {
|
||||
beacon_chain: Arc<BeaconChain<T, U>>,
|
||||
published_blocks: RwLock<Vec<BeaconBlock>>,
|
||||
published_attestations: RwLock<Vec<FreeAttestation>>,
|
||||
}
|
||||
|
||||
impl<T: ClientDB, U: SlotClock> BenchingBeaconNode<T, U> {
|
||||
pub fn new(beacon_chain: Arc<BeaconChain<T, U>>) -> Self {
|
||||
Self {
|
||||
beacon_chain,
|
||||
published_blocks: RwLock::new(vec![]),
|
||||
published_attestations: RwLock::new(vec![]),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn last_published_block(&self) -> Option<BeaconBlock> {
|
||||
Some(self.published_blocks.read().last()?.clone())
|
||||
}
|
||||
}
|
@ -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<T: ClientDB, U: SlotClock> {
|
||||
beacon_chain: Arc<BeaconChain<T, U>>,
|
||||
published_blocks: RwLock<Vec<BeaconBlock>>,
|
||||
}
|
||||
|
||||
impl<T: ClientDB, U: SlotClock> BenchingBeaconNode<T, U> {
|
||||
pub fn new(beacon_chain: Arc<BeaconChain<T, U>>) -> Self {
|
||||
Self {
|
||||
beacon_chain,
|
||||
published_blocks: RwLock::new(vec![]),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn last_published_block(&self) -> Option<BeaconBlock> {
|
||||
Some(
|
||||
self.published_blocks
|
||||
.read()
|
||||
.expect("Unable to unlock `published_blocks` for reading.")
|
||||
.last()?
|
||||
.clone(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ClientDB, U: SlotClock> BeaconBlockNode for BenchingBeaconNode<T, U>
|
||||
where
|
||||
BlockProductionError: From<<U>::Error>,
|
||||
@ -56,8 +32,7 @@ where
|
||||
&self,
|
||||
slot: u64,
|
||||
randao_reveal: &Signature,
|
||||
) -> Result<Option<BeaconBlock>, BeaconBlockNodeError>
|
||||
where {
|
||||
) -> Result<Option<BeaconBlock>, BeaconBlockNodeError> {
|
||||
let (block, _state) = self
|
||||
.beacon_chain
|
||||
.produce_block(randao_reveal.clone())
|
||||
@ -81,10 +56,7 @@ where {
|
||||
&self,
|
||||
block: BeaconBlock,
|
||||
) -> Result<PublishOutcome, BeaconBlockNodeError> {
|
||||
self.published_blocks
|
||||
.write()
|
||||
.expect("Unable to unlock `published_blocks` for writing.")
|
||||
.push(block);
|
||||
self.published_blocks.write().push(block);
|
||||
Ok(PublishOutcome::ValidBlock)
|
||||
}
|
||||
}
|
@ -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<T: ClientDB, U: SlotClock> {
|
||||
beacon_chain: Arc<BeaconChain<T, U>>,
|
||||
pubkey: PublicKey,
|
||||
}
|
||||
|
||||
impl<T: ClientDB, U: SlotClock> DirectDuties<T, U> {
|
||||
pub fn new(pubkey: PublicKey, beacon_chain: Arc<BeaconChain<T, U>>) -> Self {
|
||||
Self {
|
||||
beacon_chain,
|
||||
pubkey,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ClientDB, U: SlotClock> ProducerDutiesReader for DirectDuties<T, U>
|
||||
where
|
||||
BlockProductionError: From<<U>::Error>,
|
||||
{
|
||||
fn is_block_production_slot(&self, slot: u64) -> Result<bool, ProducerDutiesReaderError> {
|
||||
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<T: ClientDB, U: SlotClock> AttesterDutiesReader for DirectDuties<T, U>
|
||||
where
|
||||
BlockProductionError: From<<U>::Error>,
|
||||
{
|
||||
fn validator_index(&self) -> Option<u64> {
|
||||
match self.beacon_chain.validator_index(&self.pubkey) {
|
||||
Some(index) => Some(index as u64),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn attestation_shard(&self, slot: u64) -> Result<Option<u64>, 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)
|
||||
}
|
||||
}
|
||||
}
|
@ -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<MemoryDB, TestingSlotClock>,
|
||||
TestSigner,
|
||||
>,
|
||||
pub attester: Attester<
|
||||
TestingSlotClock,
|
||||
BenchingBeaconNode<MemoryDB, TestingSlotClock>,
|
||||
DirectDuties<MemoryDB, TestingSlotClock>,
|
||||
TestSigner,
|
||||
>,
|
||||
pub spec: Arc<ChainSpec>,
|
||||
pub epoch_map: Arc<DirectDuties<MemoryDB, TestingSlotClock>>,
|
||||
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,
|
@ -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<bool>,
|
||||
}
|
||||
|
||||
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<Signature> {
|
||||
Some(Signature::new(message, &self.keypair.sk))
|
||||
}
|
||||
}
|
||||
|
||||
impl BlockProposerSigner for TestSigner {
|
||||
fn sign_block_proposal(&self, message: &[u8]) -> Option<Signature> {
|
||||
self.bls_sign(message)
|
||||
}
|
||||
|
||||
fn sign_randao_reveal(&self, message: &[u8]) -> Option<Signature> {
|
||||
self.bls_sign(message)
|
||||
}
|
||||
}
|
||||
|
||||
impl AttesterSigner for TestSigner {
|
||||
fn sign_attestation_message(&self, message: &[u8]) -> Option<Signature> {
|
||||
self.bls_sign(message)
|
||||
}
|
||||
}
|
@ -131,7 +131,7 @@ impl<T: SlotClock, U: BeaconNode, V: DutiesReader, W: Signer> Attester<T, U, V,
|
||||
self.store_produce(attestation_data);
|
||||
|
||||
self.signer
|
||||
.bls_sign(&attestation_data.signable_message(PHASE_0_CUSTODY_BIT)[..])
|
||||
.sign_attestation_message(&attestation_data.signable_message(PHASE_0_CUSTODY_BIT)[..])
|
||||
}
|
||||
|
||||
/// Returns `true` if signing some attestation_data is safe (non-slashable).
|
||||
|
@ -25,7 +25,7 @@ impl TestSigner {
|
||||
}
|
||||
|
||||
impl Signer for TestSigner {
|
||||
fn bls_sign(&self, message: &[u8]) -> Option<Signature> {
|
||||
fn sign_attestation_message(&self, message: &[u8]) -> Option<Signature> {
|
||||
Some(Signature::new(message, &self.keypair.sk))
|
||||
}
|
||||
}
|
||||
|
@ -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<Signature>;
|
||||
fn sign_attestation_message(&self, message: &[u8]) -> Option<Signature>;
|
||||
}
|
||||
|
@ -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<T: SlotClock, U: BeaconNode, V: DutiesReader, W: Signer> BlockProducer<T, U
|
||||
// TODO: add domain, etc to this message.
|
||||
let message = ssz_encode(&producer_nonce);
|
||||
|
||||
match self.signer.bls_sign(&message) {
|
||||
match self.signer.sign_randao_reveal(&message) {
|
||||
None => return Ok(PollOutcome::SignerRejection(slot)),
|
||||
Some(signature) => signature,
|
||||
}
|
||||
@ -171,7 +171,10 @@ impl<T: SlotClock, U: BeaconNode, V: DutiesReader, W: Signer> BlockProducer<T, U
|
||||
fn sign_block(&mut self, mut block: BeaconBlock) -> Option<BeaconBlock> {
|
||||
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;
|
||||
|
@ -25,7 +25,11 @@ impl TestSigner {
|
||||
}
|
||||
|
||||
impl Signer for TestSigner {
|
||||
fn bls_sign(&self, message: &[u8]) -> Option<Signature> {
|
||||
fn sign_block_proposal(&self, message: &[u8]) -> Option<Signature> {
|
||||
Some(Signature::new(message, &self.keypair.sk))
|
||||
}
|
||||
|
||||
fn sign_randao_reveal(&self, message: &[u8]) -> Option<Signature> {
|
||||
Some(Signature::new(message, &self.keypair.sk))
|
||||
}
|
||||
}
|
||||
|
@ -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<Signature>;
|
||||
fn sign_block_proposal(&self, message: &[u8]) -> Option<Signature>;
|
||||
fn sign_randao_reveal(&self, message: &[u8]) -> Option<Signature>;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user