Checking if the an attestation contains a latest message
This commit is contained in:
parent
3b8a584c55
commit
b2471eca49
@ -494,9 +494,11 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
let timer = self.metrics.attestation_processing_times.start_timer();
|
let timer = self.metrics.attestation_processing_times.start_timer();
|
||||||
|
|
||||||
if let Some(state) = self.get_attestation_state(&attestation) {
|
if let Some(state) = self.get_attestation_state(&attestation) {
|
||||||
let indexed_attestation = common::convert_to_indexed(&state, &attestation)?;
|
if self.fork_choice.should_process_attestation(&state, &attestation) {
|
||||||
per_block_processing::verify_indexed_attestation(&state, &indexed_attestation, &self.spec)?;
|
let indexed_attestation = common::convert_to_indexed(&state, &attestation)?;
|
||||||
self.fork_choice.process_attestation(&state, &attestation);
|
per_block_processing::verify_indexed_attestation(&state, &indexed_attestation, &self.spec)?;
|
||||||
|
self.fork_choice.process_attestation(&state, &attestation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = self
|
let result = self
|
||||||
@ -509,17 +511,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
self.metrics.attestation_processing_successes.inc();
|
self.metrics.attestation_processing_successes.inc();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: process attestation. Please consider:
|
|
||||||
//
|
|
||||||
// - Because a block was not added to the op pool does not mean it's invalid (it might
|
|
||||||
// just be old).
|
|
||||||
// - The attestation should be rejected if we don't know the block (ideally it should be
|
|
||||||
// queued, but this may be overkill).
|
|
||||||
// - The attestation _must_ be validated against it's state before being added to fork
|
|
||||||
// choice.
|
|
||||||
// - You can avoid verifying some attestations by first checking if they're a latest
|
|
||||||
// message. This would involve expanding the `LmdGhost` API.
|
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ use state_processing::common::get_attesting_indices_unsorted;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use store::{Error as StoreError, Store};
|
use store::{Error as StoreError, Store};
|
||||||
use types::{Attestation, BeaconBlock, BeaconState, BeaconStateError, Epoch, EthSpec, Hash256};
|
use types::{Attestation, BeaconBlock, BeaconState, BeaconStateError, Epoch, EthSpec, Hash256};
|
||||||
|
use state_processing::common;
|
||||||
|
|
||||||
type Result<T> = std::result::Result<T, Error>;
|
type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
@ -120,6 +121,9 @@ impl<T: BeaconChainTypes> ForkChoice<T> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Process an attestation.
|
||||||
|
///
|
||||||
|
/// Assumes the attestation is valid.
|
||||||
pub fn process_attestation(
|
pub fn process_attestation(
|
||||||
&self,
|
&self,
|
||||||
state: &BeaconState<T::EthSpec>,
|
state: &BeaconState<T::EthSpec>,
|
||||||
@ -162,6 +166,26 @@ impl<T: BeaconChainTypes> ForkChoice<T> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Determines whether or not the given attestation contains a latest messages.
|
||||||
|
pub fn should_process_attestation(&self, state: &BeaconState<T::EthSpec>, attestation: &Attestation) -> bool {
|
||||||
|
let validator_indices = common::get_attesting_indices_unsorted(
|
||||||
|
state,
|
||||||
|
&attestation.data,
|
||||||
|
&attestation.aggregation_bitfield,
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
let target_slot = attestation.data.target_epoch.start_slot(T::EthSpec::slots_per_epoch());
|
||||||
|
|
||||||
|
validator_indices
|
||||||
|
.iter()
|
||||||
|
.find(|&&v| {
|
||||||
|
match self.backend.latest_message(v) {
|
||||||
|
Some((_, slot)) => target_slot > slot,
|
||||||
|
None => true
|
||||||
|
}
|
||||||
|
}).is_some()
|
||||||
|
}
|
||||||
|
|
||||||
/// Inform the fork choice that the given block (and corresponding root) have been finalized so
|
/// Inform the fork choice that the given block (and corresponding root) have been finalized so
|
||||||
/// it may prune it's storage.
|
/// it may prune it's storage.
|
||||||
///
|
///
|
||||||
|
@ -45,5 +45,5 @@ pub trait LmdGhost<S: Store, E: EthSpec>: Send + Sync {
|
|||||||
) -> Result<()>;
|
) -> Result<()>;
|
||||||
|
|
||||||
/// Returns the latest message for a given validator index.
|
/// Returns the latest message for a given validator index.
|
||||||
fn latest_message(&mut self, validator_index: usize) -> Option<(Hash256, Slot)>;
|
fn latest_message(&self, validator_index: usize) -> Option<(Hash256, Slot)>;
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ where
|
|||||||
.map_err(|e| format!("update_finalized_root failed: {:?}", e))
|
.map_err(|e| format!("update_finalized_root failed: {:?}", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn latest_message(&mut self, validator_index: usize) -> Option<(Hash256, Slot)> {
|
fn latest_message(&self, validator_index: usize) -> Option<(Hash256, Slot)> {
|
||||||
self.core
|
self.core
|
||||||
.write()
|
.write()
|
||||||
.latest_message(validator_index)
|
.latest_message(validator_index)
|
||||||
|
Loading…
Reference in New Issue
Block a user