mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-08 01:05:47 +00:00
Add comments, more validity checks
This commit is contained in:
@@ -82,6 +82,7 @@ impl<T: SlotClock + 'static, E: EthSpec> BlockServiceBuilder<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper to minimise `Arc` usage.
|
||||||
pub struct Inner<T, E: EthSpec> {
|
pub struct Inner<T, E: EthSpec> {
|
||||||
duties_service: DutiesService<T, E>,
|
duties_service: DutiesService<T, E>,
|
||||||
validator_store: ValidatorStore<T, E>,
|
validator_store: ValidatorStore<T, E>,
|
||||||
@@ -90,6 +91,7 @@ pub struct Inner<T, E: EthSpec> {
|
|||||||
context: RuntimeContext<E>,
|
context: RuntimeContext<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempts to produce attestations for any block producer(s) at the start of the epoch.
|
||||||
pub struct BlockService<T, E: EthSpec> {
|
pub struct BlockService<T, E: EthSpec> {
|
||||||
inner: Arc<Inner<T, E>>,
|
inner: Arc<Inner<T, E>>,
|
||||||
}
|
}
|
||||||
@@ -111,6 +113,7 @@ impl<T, E: EthSpec> Deref for BlockService<T, E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: SlotClock + 'static, E: EthSpec> BlockService<T, E> {
|
impl<T: SlotClock + 'static, E: EthSpec> BlockService<T, E> {
|
||||||
|
/// Starts the service that periodically attempts to produce blocks.
|
||||||
pub fn start_update_service(&self, spec: &ChainSpec) -> Result<Signal, String> {
|
pub fn start_update_service(&self, spec: &ChainSpec) -> Result<Signal, String> {
|
||||||
let log = self.context.log.clone();
|
let log = self.context.log.clone();
|
||||||
|
|
||||||
@@ -153,6 +156,7 @@ impl<T: SlotClock + 'static, E: EthSpec> BlockService<T, E> {
|
|||||||
Ok(exit_signal)
|
Ok(exit_signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempt to produce a block for any block producers in the `ValidatorStore`.
|
||||||
fn do_update(self) -> impl Future<Item = (), Error = ()> {
|
fn do_update(self) -> impl Future<Item = (), Error = ()> {
|
||||||
let service = self.clone();
|
let service = self.clone();
|
||||||
let log = self.context.log.clone();
|
let log = self.context.log.clone();
|
||||||
|
|||||||
@@ -22,9 +22,15 @@ const PRUNE_DEPTH: u64 = 4;
|
|||||||
type BaseHashMap = HashMap<PublicKey, HashMap<Epoch, ValidatorDuty>>;
|
type BaseHashMap = HashMap<PublicKey, HashMap<Epoch, ValidatorDuty>>;
|
||||||
|
|
||||||
enum InsertOutcome {
|
enum InsertOutcome {
|
||||||
|
/// The duties were previously unknown and have been stored.
|
||||||
New,
|
New,
|
||||||
|
/// The duties were identical to some already in the store.
|
||||||
Identical,
|
Identical,
|
||||||
|
/// There were duties for this validator and epoch in the store that were different to the ones
|
||||||
|
/// provided. The existing duties were replaced.
|
||||||
Replaced,
|
Replaced,
|
||||||
|
/// The given duties were invalid.
|
||||||
|
Invalid,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
@@ -74,9 +80,13 @@ impl DutiesStore {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert(&self, epoch: Epoch, duties: ValidatorDuty) -> InsertOutcome {
|
fn insert(&self, epoch: Epoch, duties: ValidatorDuty, slots_per_epoch: u64) -> InsertOutcome {
|
||||||
let mut store = self.store.write();
|
let mut store = self.store.write();
|
||||||
|
|
||||||
|
if !duties_match_epoch(&duties, epoch, slots_per_epoch) {
|
||||||
|
return InsertOutcome::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
if store.contains_key(&duties.validator_pubkey) {
|
if store.contains_key(&duties.validator_pubkey) {
|
||||||
let validator_map = store.get_mut(&duties.validator_pubkey).expect(
|
let validator_map = store.get_mut(&duties.validator_pubkey).expect(
|
||||||
"Store is exclusively locked and this path is guarded to ensure the key exists.",
|
"Store is exclusively locked and this path is guarded to ensure the key exists.",
|
||||||
@@ -340,15 +350,26 @@ impl<T: SlotClock + 'static, E: EthSpec> DutiesService<T, E> {
|
|||||||
let mut new = 0;
|
let mut new = 0;
|
||||||
let mut identical = 0;
|
let mut identical = 0;
|
||||||
let mut replaced = 0;
|
let mut replaced = 0;
|
||||||
|
let mut invalid = 0;
|
||||||
|
|
||||||
all_duties.into_iter().for_each(|duties| {
|
all_duties.into_iter().for_each(|duties| {
|
||||||
match service_2.store.insert(epoch, duties) {
|
match service_2.store.insert(epoch, duties, E::slots_per_epoch()) {
|
||||||
InsertOutcome::New => new += 1,
|
InsertOutcome::New => new += 1,
|
||||||
InsertOutcome::Identical => identical += 1,
|
InsertOutcome::Identical => identical += 1,
|
||||||
InsertOutcome::Replaced => replaced += 1,
|
InsertOutcome::Replaced => replaced += 1,
|
||||||
|
InsertOutcome::Invalid => invalid += 1,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if invalid > 0 {
|
||||||
|
error!(
|
||||||
|
service_2.context.log,
|
||||||
|
"Received invalid duties from beacon node";
|
||||||
|
"bad_duty_count" => invalid,
|
||||||
|
"info" => "Duties are from wrong epoch."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
trace!(
|
trace!(
|
||||||
service_2.context.log,
|
service_2.context.log,
|
||||||
"Performed duties update";
|
"Performed duties update";
|
||||||
@@ -368,3 +389,20 @@ impl<T: SlotClock + 'static, E: EthSpec> DutiesService<T, E> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the slots in the `duties` are from the given `epoch`
|
||||||
|
fn duties_match_epoch(duties: &ValidatorDuty, epoch: Epoch, slots_per_epoch: u64) -> bool {
|
||||||
|
if let Some(attestation_slot) = duties.attestation_slot {
|
||||||
|
if attestation_slot.epoch(slots_per_epoch) != epoch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(block_proposal_slot) = duties.block_proposal_slot {
|
||||||
|
if block_proposal_slot.epoch(slots_per_epoch) != epoch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ use types::{ChainSpec, EthSpec, Fork};
|
|||||||
/// Delay this period of time after the slot starts. This allows the node to process the new slot.
|
/// Delay this period of time after the slot starts. This allows the node to process the new slot.
|
||||||
const TIME_DELAY_FROM_SLOT: Duration = Duration::from_millis(80);
|
const TIME_DELAY_FROM_SLOT: Duration = Duration::from_millis(80);
|
||||||
|
|
||||||
|
/// Builds a `ForkService`.
|
||||||
pub struct ForkServiceBuilder<T, E: EthSpec> {
|
pub struct ForkServiceBuilder<T, E: EthSpec> {
|
||||||
fork: Option<Fork>,
|
fork: Option<Fork>,
|
||||||
slot_clock: Option<T>,
|
slot_clock: Option<T>,
|
||||||
@@ -64,6 +65,7 @@ impl<T: SlotClock + 'static, E: EthSpec> ForkServiceBuilder<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper to minimise `Arc` usage.
|
||||||
pub struct Inner<T, E: EthSpec> {
|
pub struct Inner<T, E: EthSpec> {
|
||||||
fork: RwLock<Option<Fork>>,
|
fork: RwLock<Option<Fork>>,
|
||||||
beacon_node: RemoteBeaconNode<E>,
|
beacon_node: RemoteBeaconNode<E>,
|
||||||
@@ -71,6 +73,7 @@ pub struct Inner<T, E: EthSpec> {
|
|||||||
slot_clock: T,
|
slot_clock: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempts to download the `Fork` struct from the beacon node at the start of each epoch.
|
||||||
pub struct ForkService<T, E: EthSpec> {
|
pub struct ForkService<T, E: EthSpec> {
|
||||||
inner: Arc<Inner<T, E>>,
|
inner: Arc<Inner<T, E>>,
|
||||||
}
|
}
|
||||||
@@ -92,10 +95,12 @@ impl<T, E: EthSpec> Deref for ForkService<T, E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: SlotClock + 'static, E: EthSpec> ForkService<T, E> {
|
impl<T: SlotClock + 'static, E: EthSpec> ForkService<T, E> {
|
||||||
|
/// Returns the last fork downloaded from the beacon node, if any.
|
||||||
pub fn fork(&self) -> Option<Fork> {
|
pub fn fork(&self) -> Option<Fork> {
|
||||||
self.fork.read().clone()
|
self.fork.read().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Starts the service that periodically polls for the `Fork`.
|
||||||
pub fn start_update_service(&self, spec: &ChainSpec) -> Result<Signal, String> {
|
pub fn start_update_service(&self, spec: &ChainSpec) -> Result<Signal, String> {
|
||||||
let log = self.context.log.clone();
|
let log = self.context.log.clone();
|
||||||
|
|
||||||
@@ -141,6 +146,7 @@ impl<T: SlotClock + 'static, E: EthSpec> ForkService<T, E> {
|
|||||||
Ok(exit_signal)
|
Ok(exit_signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempts to download the `Fork` from the server.
|
||||||
fn do_update(&self) -> impl Future<Item = (), Error = ()> {
|
fn do_update(&self) -> impl Future<Item = (), Error = ()> {
|
||||||
let service_1 = self.clone();
|
let service_1 = self.clone();
|
||||||
let log_1 = service_1.context.log.clone();
|
let log_1 = service_1.context.log.clone();
|
||||||
|
|||||||
Reference in New Issue
Block a user