Improve reduced tree fork choice

This commit is contained in:
Paul Hauner
2019-06-15 18:19:08 -04:00
parent 7756a658a7
commit f4621a9f1a
6 changed files with 225 additions and 107 deletions

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -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::{