From 418f836f63538645b44238db29b4daca52b96985 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Sat, 26 Feb 2022 09:16:10 +1100 Subject: [PATCH] Add first version of safe check --- consensus/fork_choice/src/fork_choice.rs | 39 +++++++++++++++++++ .../src/proto_array_fork_choice.rs | 15 ++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/consensus/fork_choice/src/fork_choice.rs b/consensus/fork_choice/src/fork_choice.rs index 957cfb4808..6f93407c06 100644 --- a/consensus/fork_choice/src/fork_choice.rs +++ b/consensus/fork_choice/src/fork_choice.rs @@ -910,6 +910,45 @@ where .is_descendant(self.fc_store.finalized_checkpoint().root, block_root) } + pub fn safe_to_import_optimistically( + &self, + current_slot: Slot, + block_slot: Slot, + block_parent_root: &Hash256, + spec: &ChainSpec, + ) -> Result> { + // If the block is sufficiently old, import it. + if block_slot + spec.safe_slots_to_import_optimistically > current_slot { + return Ok(true); + } + + // If the block has an ancestor with a verified parent, import this block. + // + // TODO(paul): this is not in the spec, add it. + // + // ## Note + // + // If `block_parent_root` is unknown this iter will always return `None`. + if self + .proto_array + .iter_nodes(block_parent_root) + .any(|node| node.execution_status.is_valid()) + { + return Ok(true); + } + + // If the justified block has execution enabled, then optimistically import any block. + if !self + .get_justified_block()? + .execution_status + .is_execution_enabled() + { + return Ok(true); + } + + Ok(false) + } + /// Return the current finalized checkpoint. pub fn finalized_checkpoint(&self) -> Checkpoint { *self.fc_store.finalized_checkpoint() diff --git a/consensus/proto_array/src/proto_array_fork_choice.rs b/consensus/proto_array/src/proto_array_fork_choice.rs index 891eafabe9..d640c89c9f 100644 --- a/consensus/proto_array/src/proto_array_fork_choice.rs +++ b/consensus/proto_array/src/proto_array_fork_choice.rs @@ -1,5 +1,5 @@ use crate::error::Error; -use crate::proto_array::{ProposerBoost, ProtoArray}; +use crate::proto_array::{Iter, ProposerBoost, ProtoArray}; use crate::ssz_container::SszContainer; use serde_derive::{Deserialize, Serialize}; use ssz::{Decode, Encode}; @@ -37,6 +37,14 @@ pub enum ExecutionStatus { } impl ExecutionStatus { + pub fn is_valid(&self) -> bool { + matches!(self, ExecutionStatus::Valid(_)) + } + + pub fn is_execution_enabled(&self) -> bool { + !matches!(self, ExecutionStatus::Irrelevant(_)) + } + pub fn irrelevant() -> Self { ExecutionStatus::Irrelevant(false) } @@ -302,6 +310,11 @@ impl ProtoArrayForkChoice { } } + /// See `ProtoArray::iter_nodes` + pub fn iter_nodes<'a>(&'a self, block_root: &Hash256) -> Iter<'a> { + self.proto_array.iter_nodes(block_root) + } + pub fn as_bytes(&self) -> Vec { SszContainer::from(self).as_ssz_bytes() }