Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions consensus/fork_choice/src/fork_choice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::metrics::{self, scrape_for_metrics};
use crate::{ForkChoiceStore, InvalidationOperation};
use logging::crit;
use proto_array::{
Block as ProtoBlock, DisallowedReOrgOffsets, ExecutionStatus, JustifiedBalances,
Block as ProtoBlock, DisallowedReOrgOffsets, ExecutionStatus, JustifiedBalances, LatestMessage,
ProposerHeadError, ProposerHeadInfo, ProtoArrayForkChoice, ReOrgThreshold,
};
use ssz::{Decode, Encode};
Expand Down Expand Up @@ -240,6 +240,7 @@ pub struct QueuedAttestation {
attesting_indices: Vec<u64>,
block_root: Hash256,
target_epoch: Epoch,
payload_present: bool,
}

impl<'a, E: EthSpec> From<IndexedAttestationRef<'a, E>> for QueuedAttestation {
Expand All @@ -249,6 +250,8 @@ impl<'a, E: EthSpec> From<IndexedAttestationRef<'a, E>> for QueuedAttestation {
attesting_indices: a.attesting_indices_to_vec(),
block_root: a.data().beacon_block_root,
target_epoch: a.data().target.epoch,
// FIXME(sproul): replace by func?
payload_present: a.data().index == 1,
}
}
}
Expand Down Expand Up @@ -1101,10 +1104,13 @@ where

if attestation.data().slot < self.fc_store.get_current_slot() {
for validator_index in attestation.attesting_indices_iter() {
// FIXME(sproul): backwards compat/fork abstraction
let payload_present = attestation.data().index == 1;
self.proto_array.process_attestation(
*validator_index as usize,
attestation.data().beacon_block_root,
attestation.data().target.epoch,
attestation.data().slot,
payload_present,
)?;
}
} else {
Expand Down Expand Up @@ -1224,10 +1230,12 @@ where
&mut self.queued_attestations,
) {
for validator_index in attestation.attesting_indices.iter() {
// FIXME(sproul): backwards compat/fork abstraction
self.proto_array.process_attestation(
*validator_index as usize,
attestation.block_root,
attestation.target_epoch,
attestation.slot,
attestation.payload_present,
)?;
}
}
Expand Down Expand Up @@ -1357,13 +1365,15 @@ where

/// Returns the latest message for a given validator, if any.
///
/// Returns `(block_root, block_slot)`.
/// Returns `block_root, block_slot, payload_present`.
///
/// ## Notes
///
/// It may be prudent to call `Self::update_time` before calling this function,
/// since some attestations might be queued and awaiting processing.
pub fn latest_message(&self, validator_index: usize) -> Option<(Hash256, Epoch)> {
///
/// This function is only used in tests.
pub fn latest_message(&self, validator_index: usize) -> Option<LatestMessage> {
self.proto_array.latest_message(validator_index)
}

Expand Down
3 changes: 3 additions & 0 deletions consensus/proto_array/src/bin.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* FIXME(sproul)
use proto_array::fork_choice_test_definition::*;
use std::fs::File;

Expand All @@ -24,3 +25,5 @@ fn write_test_def_to_yaml(filename: &str, def: ForkChoiceTestDefinition) {
let file = File::create(filename).expect("Should be able to open file");
serde_yaml::to_writer(file, &def).expect("Should be able to write YAML to file");
}
*/
fn main() {}
5 changes: 4 additions & 1 deletion consensus/proto_array/src/fork_choice_test_definition.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* FIXME(sproul) fix these tests later
mod execution_status;
mod ffg_updates;
mod no_votes;
Expand Down Expand Up @@ -226,13 +227,14 @@ impl ForkChoiceTestDefinition {
});
check_bytes_round_trip(&fork_choice);
}
// FIXME(sproul): update with payload_present
Operation::ProcessAttestation {
validator_index,
block_root,
target_epoch,
} => {
fork_choice
.process_attestation(validator_index, block_root, target_epoch)
.process_attestation(validator_index, block_root, target_epoch, false)
.unwrap_or_else(|_| {
panic!(
"process_attestation op at index {} returned error",
Expand Down Expand Up @@ -322,3 +324,4 @@ fn check_bytes_round_trip(original: &ProtoArrayForkChoice) {
"fork choice should encode and decode without change"
);
}
*/
4 changes: 2 additions & 2 deletions consensus/proto_array/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ mod ssz_container;
pub use crate::justified_balances::JustifiedBalances;
pub use crate::proto_array::{InvalidationOperation, calculate_committee_fraction};
pub use crate::proto_array_fork_choice::{
Block, DisallowedReOrgOffsets, DoNotReOrg, ExecutionStatus, ProposerHeadError,
ProposerHeadInfo, ProtoArrayForkChoice, ReOrgThreshold,
Block, DisallowedReOrgOffsets, DoNotReOrg, ExecutionStatus, LatestMessage, PayloadStatus,
ProposerHeadError, ProposerHeadInfo, ProtoArrayForkChoice, ReOrgThreshold,
};
pub use error::Error;

Expand Down
2 changes: 1 addition & 1 deletion consensus/proto_array/src/proto_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ pub struct ProtoNode {
#[ssz(with = "four_byte_option_usize")]
pub best_descendant: Option<usize>,
/// Indicates if an execution node has marked this block as valid. Also contains the execution
/// block hash.
/// block hash. This is only used pre-Gloas.
pub execution_status: ExecutionStatus,
#[ssz(with = "four_byte_option_checkpoint")]
pub unrealized_justified_checkpoint: Option<Checkpoint>,
Expand Down
41 changes: 34 additions & 7 deletions consensus/proto_array/src/proto_array_fork_choice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,23 @@ use types::{
pub const DEFAULT_PRUNE_THRESHOLD: usize = 256;

#[derive(Default, PartialEq, Clone, Encode, Decode)]
// FIXME(sproul): the "next" naming here is a bit odd
// FIXME(sproul): version this type?
pub struct VoteTracker {
current_root: Hash256,
next_root: Hash256,
next_epoch: Epoch,
next_slot: Slot,
next_payload_present: bool,
}

/// Represents the verification status of an execution payload.
// FIXME(sproul): version this type
pub struct LatestMessage {
slot: Slot,
root: Hash256,
payload_present: bool,
}

/// Represents the verification status of an execution payload pre-Gloas.
#[derive(Clone, Copy, Debug, PartialEq, Encode, Decode, Serialize, Deserialize)]
#[ssz(enum_behaviour = "union")]
pub enum ExecutionStatus {
Expand All @@ -48,6 +58,16 @@ pub enum ExecutionStatus {
Irrelevant(bool),
}

/// Represents the status of an execution payload post-Gloas.
#[derive(Clone, Copy, Debug, PartialEq, Encode, Decode, Serialize, Deserialize)]
#[ssz(enum_behaviour = "tag")]
#[repr(u8)]
pub enum PayloadStatus {
Pending = 0,
Empty = 1,
Full = 2,
}

impl ExecutionStatus {
pub fn is_execution_enabled(&self) -> bool {
!matches!(self, ExecutionStatus::Irrelevant(_))
Expand Down Expand Up @@ -487,13 +507,15 @@ impl ProtoArrayForkChoice {
&mut self,
validator_index: usize,
block_root: Hash256,
target_epoch: Epoch,
attestation_slot: Slot,
payload_present: bool,
) -> Result<(), String> {
let vote = self.votes.get_mut(validator_index);

if target_epoch > vote.next_epoch || *vote == VoteTracker::default() {
if attestation_slot > vote.next_slot || *vote == VoteTracker::default() {
vote.next_root = block_root;
vote.next_epoch = target_epoch;
vote.next_slot = attestation_slot;
vote.next_payload_present = payload_present;
}

Ok(())
Expand Down Expand Up @@ -906,14 +928,18 @@ impl ProtoArrayForkChoice {
.is_finalized_checkpoint_or_descendant::<E>(descendant_root, best_finalized_checkpoint)
}

pub fn latest_message(&self, validator_index: usize) -> Option<(Hash256, Epoch)> {
pub fn latest_message(&self, validator_index: usize) -> Option<LatestMessage> {
if validator_index < self.votes.0.len() {
let vote = &self.votes.0[validator_index];

if *vote == VoteTracker::default() {
None
} else {
Some((vote.next_root, vote.next_epoch))
Some(LatestMessage {
root: vote.next_root,
slot: vote.next_slot,
payload_present: vote.next_payload_present,
})
}
} else {
None
Expand Down Expand Up @@ -999,6 +1025,7 @@ impl ProtoArrayForkChoice {
/// - If a value in `indices` is greater to or equal to `indices.len()`.
/// - If some `Hash256` in `votes` is not a key in `indices` (except for `Hash256::zero()`, this is
/// always valid).
// FIXME(sproul): implement get-weight changes here
fn compute_deltas(
indices: &HashMap<Hash256, usize>,
votes: &mut ElasticList<VoteTracker>,
Expand Down
Loading