Update block_producer for upstream changes
This commit is contained in:
parent
5fdad686fa
commit
643fc20063
@ -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).
|
||||||
|
@ -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)]
|
||||||
|
@ -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),
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user