Wrap the duty manager in a future for its own thread
This commit is contained in:
parent
33d0f29221
commit
ffb3d94355
@ -32,3 +32,4 @@ tokio = "0.1.18"
|
|||||||
tokio-timer = "0.2.10"
|
tokio-timer = "0.2.10"
|
||||||
error-chain = "0.12.0"
|
error-chain = "0.12.0"
|
||||||
bincode = "^1.1.2"
|
bincode = "^1.1.2"
|
||||||
|
futures = "0.1.25"
|
||||||
|
@ -8,6 +8,8 @@ pub use self::epoch_duties::EpochDutiesMap;
|
|||||||
use self::epoch_duties::{EpochDuties, EpochDutiesMapError};
|
use self::epoch_duties::{EpochDuties, EpochDutiesMapError};
|
||||||
use self::traits::{BeaconNode, BeaconNodeError};
|
use self::traits::{BeaconNode, BeaconNodeError};
|
||||||
use bls::PublicKey;
|
use bls::PublicKey;
|
||||||
|
use futures::Async;
|
||||||
|
use slog::{debug, error, info};
|
||||||
use slot_clock::SlotClock;
|
use slot_clock::SlotClock;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use types::{ChainSpec, Epoch, Slot};
|
use types::{ChainSpec, Epoch, Slot};
|
||||||
@ -52,7 +54,7 @@ impl<T: SlotClock, U: BeaconNode> DutiesManager<T, U> {
|
|||||||
///
|
///
|
||||||
/// The present `epoch` will be learned from the supplied `SlotClock`. In production this will
|
/// The present `epoch` will be learned from the supplied `SlotClock`. In production this will
|
||||||
/// be a wall-clock (e.g., system time, remote server time, etc.).
|
/// be a wall-clock (e.g., system time, remote server time, etc.).
|
||||||
pub fn update(&self, slot: Slot) -> Result<UpdateOutcome, Error> {
|
fn update(&self, slot: Slot) -> Result<UpdateOutcome, Error> {
|
||||||
let epoch = slot.epoch(self.spec.slots_per_epoch);
|
let epoch = slot.epoch(self.spec.slots_per_epoch);
|
||||||
|
|
||||||
if let Some(duties) = self
|
if let Some(duties) = self
|
||||||
@ -75,6 +77,27 @@ impl<T: SlotClock, U: BeaconNode> DutiesManager<T, U> {
|
|||||||
Ok(UpdateOutcome::UnknownValidatorOrEpoch(epoch))
|
Ok(UpdateOutcome::UnknownValidatorOrEpoch(epoch))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A future wrapping around `update()`. This will perform logic based upon the update
|
||||||
|
/// process and complete once the update has completed.
|
||||||
|
pub fn run_update(&self, slot: Slot, log: slog::Logger) -> Result<Async<()>, ()> {
|
||||||
|
match self.update(slot) {
|
||||||
|
Err(error) => error!(log, "Epoch duties poll error"; "error" => format!("{:?}", error)),
|
||||||
|
Ok(UpdateOutcome::NoChange(epoch)) => {
|
||||||
|
debug!(log, "No change in duties"; "epoch" => epoch)
|
||||||
|
}
|
||||||
|
Ok(UpdateOutcome::DutiesChanged(epoch, duties)) => {
|
||||||
|
info!(log, "Duties changed (potential re-org)"; "epoch" => epoch, "duties" => format!("{:?}", duties))
|
||||||
|
}
|
||||||
|
Ok(UpdateOutcome::NewDuties(epoch, duties)) => {
|
||||||
|
info!(log, "New duties obtained"; "epoch" => epoch, "duties" => format!("{:?}", duties))
|
||||||
|
}
|
||||||
|
Ok(UpdateOutcome::UnknownValidatorOrEpoch(epoch)) => {
|
||||||
|
error!(log, "Epoch or validator unknown"; "epoch" => epoch)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(Async::Ready(()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<BeaconNodeError> for Error {
|
impl From<BeaconNodeError> for Error {
|
||||||
|
@ -222,21 +222,22 @@ impl Service {
|
|||||||
// build requisite objects to pass to core thread.
|
// build requisite objects to pass to core thread.
|
||||||
let duties_map = Arc::new(EpochDutiesMap::new(config.spec.slots_per_epoch));
|
let duties_map = Arc::new(EpochDutiesMap::new(config.spec.slots_per_epoch));
|
||||||
let epoch_map_for_attester = Arc::new(EpochMap::new(config.spec.slots_per_epoch));
|
let epoch_map_for_attester = Arc::new(EpochMap::new(config.spec.slots_per_epoch));
|
||||||
let manager = DutiesManager {
|
let manager = Arc::new(DutiesManager {
|
||||||
duties_map,
|
duties_map,
|
||||||
pubkeys: keypairs.iter().map(|keypair| keypair.pk.clone()).collect(),
|
pubkeys: keypairs.iter().map(|keypair| keypair.pk.clone()).collect(),
|
||||||
spec: Arc::new(config.spec),
|
spec: Arc::new(config.spec),
|
||||||
slot_clock: service.slot_clock.clone(),
|
slot_clock: service.slot_clock.clone(),
|
||||||
beacon_node: service.validator_client.clone(),
|
beacon_node: service.validator_client.clone(),
|
||||||
};
|
});
|
||||||
|
|
||||||
// run the core thread
|
// run the core thread
|
||||||
runtime
|
runtime
|
||||||
.block_on(interval.for_each(move |_| {
|
.block_on(interval.for_each(move |_| {
|
||||||
|
let log = service.log.clone();
|
||||||
// get the current slot
|
// get the current slot
|
||||||
let current_slot = match service.slot_clock.present_slot() {
|
let current_slot = match service.slot_clock.present_slot() {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!(service.log, "SystemTimeError {:?}", e);
|
error!(log, "SystemTimeError {:?}", e);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
Ok(slot) => slot.expect("Genesis is in the future"),
|
Ok(slot) => slot.expect("Genesis is in the future"),
|
||||||
@ -247,28 +248,14 @@ impl Service {
|
|||||||
"The Timer should poll a new slot"
|
"The Timer should poll a new slot"
|
||||||
);
|
);
|
||||||
|
|
||||||
info!(service.log, "Processing slot: {}", current_slot.as_u64());
|
info!(log, "Processing slot: {}", current_slot.as_u64());
|
||||||
|
|
||||||
|
let cloned_manager = manager.clone();
|
||||||
|
|
||||||
// check for new duties
|
// check for new duties
|
||||||
// TODO: Convert to its own thread
|
tokio::spawn(futures::future::poll_fn(move || {
|
||||||
match manager.update(current_slot) {
|
cloned_manager.run_update(current_slot.clone(), log.clone())
|
||||||
Err(error) => {
|
}));
|
||||||
error!(service.log, "Epoch duties poll error"; "error" => format!("{:?}", error))
|
|
||||||
}
|
|
||||||
Ok(UpdateOutcome::NoChange(epoch)) => {
|
|
||||||
debug!(service.log, "No change in duties"; "epoch" => epoch)
|
|
||||||
}
|
|
||||||
Ok(UpdateOutcome::DutiesChanged(epoch, duties)) => {
|
|
||||||
info!(service.log, "Duties changed (potential re-org)"; "epoch" => epoch, "duties" => format!("{:?}", duties))
|
|
||||||
}
|
|
||||||
Ok(UpdateOutcome::NewDuties(epoch, duties)) => {
|
|
||||||
info!(service.log, "New duties obtained"; "epoch" => epoch, "duties" => format!("{:?}", duties))
|
|
||||||
}
|
|
||||||
Ok(UpdateOutcome::UnknownValidatorOrEpoch(epoch)) => {
|
|
||||||
error!(service.log, "Epoch or validator unknown"; "epoch" => epoch)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}))
|
}))
|
||||||
.map_err(|e| format!("Service thread failed: {:?}", e))?;
|
.map_err(|e| format!("Service thread failed: {:?}", e))?;
|
||||||
|
Loading…
Reference in New Issue
Block a user