mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-19 05:48:31 +00:00
Improve reduced tree fork choice
This commit is contained in:
@@ -87,7 +87,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
mut genesis_state: BeaconState<T::EthSpec>,
|
||||
genesis_block: BeaconBlock,
|
||||
spec: ChainSpec,
|
||||
fork_choice: ForkChoice<T>,
|
||||
) -> Result<Self, Error> {
|
||||
let state_root = genesis_state.canonical_root();
|
||||
store.put(&state_root, &genesis_state)?;
|
||||
@@ -110,14 +109,14 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
|
||||
Ok(Self {
|
||||
spec,
|
||||
store,
|
||||
slot_clock,
|
||||
op_pool: OperationPool::new(),
|
||||
state: RwLock::new(genesis_state),
|
||||
canonical_head,
|
||||
genesis_block_root,
|
||||
fork_choice,
|
||||
fork_choice: ForkChoice::new(store.clone(), genesis_block_root),
|
||||
metrics: Metrics::new()?,
|
||||
store,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -139,16 +138,15 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
spec.seconds_per_slot,
|
||||
);
|
||||
|
||||
// let fork_choice = T::ForkChoice::new(store.clone());
|
||||
// let fork_choice: ForkChoice<T::LmdGhost, T::EthSpec> = ForkChoice::new(store.clone());
|
||||
let last_finalized_root = p.canonical_head.beacon_state.finalized_root;
|
||||
|
||||
Ok(Some(BeaconChain {
|
||||
spec,
|
||||
slot_clock,
|
||||
fork_choice: ForkChoice::new(store.clone(), last_finalized_root),
|
||||
op_pool: OperationPool::default(),
|
||||
canonical_head: RwLock::new(p.canonical_head),
|
||||
state: RwLock::new(p.state),
|
||||
fork_choice: ForkChoice::new(store.clone()),
|
||||
genesis_block_root: p.genesis_block_root,
|
||||
metrics: Metrics::new()?,
|
||||
store,
|
||||
@@ -476,11 +474,22 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
.op_pool
|
||||
.insert_attestation(attestation, &*self.state.read(), &self.spec);
|
||||
|
||||
timer.observe_duration();
|
||||
|
||||
if result.is_ok() {
|
||||
self.metrics.attestation_processing_successes.inc();
|
||||
}
|
||||
|
||||
timer.observe_duration();
|
||||
// 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
|
||||
}
|
||||
|
||||
@@ -21,9 +21,9 @@ pub struct ForkChoice<T: BeaconChainTypes> {
|
||||
}
|
||||
|
||||
impl<T: BeaconChainTypes> ForkChoice<T> {
|
||||
pub fn new(store: Arc<T::Store>) -> Self {
|
||||
pub fn new(store: Arc<T::Store>, genesis_block_root: Hash256) -> Self {
|
||||
Self {
|
||||
backend: T::LmdGhost::new(store),
|
||||
backend: T::LmdGhost::new(store, genesis_block_root),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,29 @@ impl<T: BeaconChainTypes> ForkChoice<T> {
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn process_attestation(
|
||||
/// Process all attestations in the given `block`.
|
||||
///
|
||||
/// Assumes the block (and therefore it's attestations) are valid. It is a logic error to
|
||||
/// provide an invalid block.
|
||||
pub fn process_block(
|
||||
&self,
|
||||
state: &BeaconState<T::EthSpec>,
|
||||
block: &BeaconBlock,
|
||||
) -> Result<()> {
|
||||
// Note: we never count the block as a latest message, only attestations.
|
||||
//
|
||||
// I (Paul H) do not have an explicit reference to this, but I derive it from this
|
||||
// document:
|
||||
//
|
||||
// https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_fork-choice.md
|
||||
for attestation in &block.body.attestations {
|
||||
self.process_attestation_from_block(state, attestation)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn process_attestation_from_block(
|
||||
&self,
|
||||
state: &BeaconState<T::EthSpec>,
|
||||
attestation: &Attestation,
|
||||
@@ -94,28 +116,6 @@ impl<T: BeaconChainTypes> ForkChoice<T> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// A helper function which runs `self.process_attestation` on all `Attestation` in the given `BeaconBlock`.
|
||||
///
|
||||
/// Assumes the block (and therefore it's attestations) are valid. It is a logic error to
|
||||
/// provide an invalid block.
|
||||
pub fn process_block(
|
||||
&self,
|
||||
state: &BeaconState<T::EthSpec>,
|
||||
block: &BeaconBlock,
|
||||
) -> Result<()> {
|
||||
// Note: we never count the block as a latest message, only attestations.
|
||||
//
|
||||
// I (Paul H) do not have an explicit reference to this, however I derive it from this
|
||||
// document:
|
||||
//
|
||||
// https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_fork-choice.md
|
||||
for attestation in &block.body.attestations {
|
||||
self.process_attestation(state, attestation)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BeaconStateError> for Error {
|
||||
|
||||
@@ -9,6 +9,7 @@ mod persisted_beacon_chain;
|
||||
pub use self::beacon_chain::{BeaconChain, BeaconChainTypes, BlockProcessingOutcome};
|
||||
pub use self::checkpoint::CheckPoint;
|
||||
pub use self::errors::{BeaconChainError, BlockProductionError};
|
||||
pub use lmd_ghost;
|
||||
pub use parking_lot;
|
||||
pub use slot_clock;
|
||||
pub use state_processing::per_block_processing::errors::{
|
||||
|
||||
Reference in New Issue
Block a user