Update block_producer for upstream changes

This commit is contained in:
Paul Hauner 2019-01-25 11:29:41 +11:00
parent 5fdad686fa
commit 643fc20063
No known key found for this signature in database
GPG Key ID: D362883A9218FCC6
4 changed files with 52 additions and 27 deletions

View File

@ -7,7 +7,9 @@ use ssz::ssz_encode;
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use types::{BeaconBlock, Hash256, ProposalSignedData, PublicKey}; use types::{BeaconBlock, Hash256, ProposalSignedData, PublicKey};
pub use self::traits::{BeaconNode, BeaconNodeError, DutiesReader, DutiesReaderError, Signer}; pub use self::traits::{
BeaconNode, BeaconNodeError, DutiesReader, DutiesReaderError, PublishOutcome, Signer,
};
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum PollOutcome { pub enum PollOutcome {
@ -46,11 +48,11 @@ pub enum Error {
/// ///
/// Relies upon an external service to keep the `EpochDutiesMap` updated. /// Relies upon an external service to keep the `EpochDutiesMap` updated.
pub struct BlockProducer<T: SlotClock, U: BeaconNode, V: DutiesReader, W: Signer> { pub struct BlockProducer<T: SlotClock, U: BeaconNode, V: DutiesReader, W: Signer> {
pub last_processed_slot: u64, pub last_processed_slot: Option<u64>,
pubkey: PublicKey, pubkey: PublicKey,
spec: Arc<ChainSpec>, spec: Arc<ChainSpec>,
epoch_map: Arc<V>, epoch_map: Arc<V>,
slot_clock: Arc<RwLock<T>>, slot_clock: Arc<T>,
beacon_node: Arc<U>, beacon_node: Arc<U>,
signer: Arc<W>, signer: Arc<W>,
} }
@ -61,12 +63,12 @@ impl<T: SlotClock, U: BeaconNode, V: DutiesReader, W: Signer> BlockProducer<T, U
spec: Arc<ChainSpec>, spec: Arc<ChainSpec>,
pubkey: PublicKey, pubkey: PublicKey,
epoch_map: Arc<V>, epoch_map: Arc<V>,
slot_clock: Arc<RwLock<T>>, slot_clock: Arc<T>,
beacon_node: Arc<U>, beacon_node: Arc<U>,
signer: Arc<W>, signer: Arc<W>,
) -> Self { ) -> Self {
Self { Self {
last_processed_slot: 0, last_processed_slot: None,
pubkey, pubkey,
spec, spec,
epoch_map, epoch_map,
@ -84,8 +86,6 @@ impl<T: SlotClock, U: BeaconNode, V: DutiesReader, W: Signer> BlockProducer<T, U
pub fn poll(&mut self) -> Result<PollOutcome, Error> { pub fn poll(&mut self) -> Result<PollOutcome, Error> {
let slot = self let slot = self
.slot_clock .slot_clock
.read()
.map_err(|_| Error::SlotClockPoisoned)?
.present_slot() .present_slot()
.map_err(|_| Error::SlotClockError)? .map_err(|_| Error::SlotClockError)?
.ok_or(Error::SlotUnknowable)?; .ok_or(Error::SlotUnknowable)?;
@ -95,9 +95,8 @@ impl<T: SlotClock, U: BeaconNode, V: DutiesReader, W: Signer> BlockProducer<T, U
.ok_or(Error::EpochLengthIsZero)?; .ok_or(Error::EpochLengthIsZero)?;
// If this is a new slot. // If this is a new slot.
if slot > self.last_processed_slot { if !self.is_processed_slot(slot) {
let is_block_production_slot = let is_block_production_slot = match self.epoch_map.is_block_production_slot(slot) {
match self.epoch_map.is_block_production_slot(epoch, slot) {
Ok(result) => result, Ok(result) => result,
Err(DutiesReaderError::UnknownEpoch) => { Err(DutiesReaderError::UnknownEpoch) => {
return Ok(PollOutcome::ProducerDutiesUnknown(slot)) return Ok(PollOutcome::ProducerDutiesUnknown(slot))
@ -109,7 +108,7 @@ impl<T: SlotClock, U: BeaconNode, V: DutiesReader, W: Signer> BlockProducer<T, U
}; };
if is_block_production_slot { if is_block_production_slot {
self.last_processed_slot = slot; self.last_processed_slot = Some(slot);
self.produce_block(slot) self.produce_block(slot)
} else { } else {
@ -120,6 +119,13 @@ impl<T: SlotClock, U: BeaconNode, V: DutiesReader, W: Signer> BlockProducer<T, U
} }
} }
fn is_processed_slot(&self, slot: u64) -> bool {
match self.last_processed_slot {
Some(processed_slot) if processed_slot <= slot => true,
_ => false,
}
}
/// Produce a block at some slot. /// Produce a block at some slot.
/// ///
/// Assumes that a block is required at this slot (does not check the duties). /// Assumes that a block is required at this slot (does not check the duties).

View File

@ -1,10 +1,10 @@
use crate::traits::{BeaconNode, BeaconNodeError}; use crate::traits::{BeaconNode, BeaconNodeError, PublishOutcome};
use std::sync::RwLock; use std::sync::RwLock;
use types::{BeaconBlock, PublicKey, Signature}; use types::{BeaconBlock, PublicKey, Signature};
type NonceResult = Result<u64, BeaconNodeError>; type NonceResult = Result<u64, BeaconNodeError>;
type ProduceResult = Result<Option<BeaconBlock>, BeaconNodeError>; type ProduceResult = Result<Option<BeaconBlock>, BeaconNodeError>;
type PublishResult = Result<bool, BeaconNodeError>; type PublishResult = Result<PublishOutcome, BeaconNodeError>;
/// A test-only struct used to simulate a Beacon Node. /// A test-only struct used to simulate a Beacon Node.
#[derive(Default)] #[derive(Default)]

View File

@ -1,11 +1,24 @@
use crate::{DutiesReader, DutiesReaderError}; use crate::{DutiesReader, DutiesReaderError};
use std::collections::HashMap; use std::collections::HashMap;
pub type TestEpochMap = HashMap<u64, u64>; pub struct TestEpochMap {
epoch_length: u64,
map: HashMap<u64, u64>,
}
impl TestEpochMap {
fn new(epoch_length: u64) -> Self {
Self {
epoch_length,
map: HashMap::new(),
}
}
}
impl DutiesReader for TestEpochMap { impl DutiesReader for TestEpochMap {
fn is_block_production_slot(&self, epoch: u64, slot: u64) -> Result<bool, DutiesReaderError> { fn is_block_production_slot(&self, slot: u64) -> Result<bool, DutiesReaderError> {
match self.get(&epoch) { let epoch = slot / self.epoch_length;
match self.map.get(&epoch) {
Some(s) if *s == slot => Ok(true), Some(s) if *s == slot => Ok(true),
Some(s) if *s != slot => Ok(false), Some(s) if *s != slot => Ok(false),
_ => Err(DutiesReaderError::UnknownEpoch), _ => Err(DutiesReaderError::UnknownEpoch),

View File

@ -6,6 +6,12 @@ pub enum BeaconNodeError {
DecodeFailure, DecodeFailure,
} }
#[derive(Debug, PartialEq, Clone)]
pub enum PublishOutcome {
ValidBlock,
InvalidBlock(String),
}
/// Defines the methods required to produce and publish blocks on a Beacon Node. /// Defines the methods required to produce and publish blocks on a Beacon Node.
pub trait BeaconNode: Send + Sync { pub trait BeaconNode: Send + Sync {
/// Requests the proposer nonce (presently named `proposer_slots`). /// Requests the proposer nonce (presently named `proposer_slots`).
@ -23,7 +29,7 @@ pub trait BeaconNode: Send + Sync {
/// Request that the node publishes a block. /// Request that the node publishes a block.
/// ///
/// Returns `true` if the publish was sucessful. /// Returns `true` if the publish was sucessful.
fn publish_beacon_block(&self, block: BeaconBlock) -> Result<bool, BeaconNodeError>; fn publish_beacon_block(&self, block: BeaconBlock) -> Result<PublishOutcome, BeaconNodeError>;
} }
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
@ -35,7 +41,7 @@ pub enum DutiesReaderError {
/// Informs a validator of their duties (e.g., block production). /// Informs a validator of their duties (e.g., block production).
pub trait DutiesReader: Send + Sync { pub trait DutiesReader: Send + Sync {
fn is_block_production_slot(&self, epoch: u64, slot: u64) -> Result<bool, DutiesReaderError>; fn is_block_production_slot(&self, slot: u64) -> Result<bool, DutiesReaderError>;
} }
/// Signs message using an internally-maintained private key. /// Signs message using an internally-maintained private key.