mirror of
https://github.com/sigp/lighthouse.git
synced 2026-07-02 04:14:33 +00:00
Resolve merge conflicts
This commit is contained in:
@@ -11,7 +11,7 @@ use state_processing::{
|
||||
per_block_processing::errors::AttesterSlashingValidationError, per_epoch_processing,
|
||||
};
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::marker::PhantomData;
|
||||
use std::time::Duration;
|
||||
use superstruct::superstruct;
|
||||
@@ -285,12 +285,12 @@ fn compute_start_slot_at_epoch<E: EthSpec>(epoch: Epoch) -> Slot {
|
||||
/// information about the attestation.
|
||||
#[derive(Clone, PartialEq, Encode, Decode)]
|
||||
pub struct QueuedAttestation {
|
||||
slot: Slot,
|
||||
attesting_indices: Vec<u64>,
|
||||
block_root: Hash256,
|
||||
target_epoch: Epoch,
|
||||
pub slot: Slot,
|
||||
pub attesting_indices: Vec<u64>,
|
||||
pub block_root: Hash256,
|
||||
pub target_epoch: Epoch,
|
||||
/// Per Gloas spec: `payload_present = attestation.data.index == 1`.
|
||||
payload_present: bool,
|
||||
pub payload_present: bool,
|
||||
}
|
||||
|
||||
/// Legacy queued attestation without payload_present (pre-Gloas, schema V28).
|
||||
@@ -314,25 +314,22 @@ impl<'a, E: EthSpec> From<IndexedAttestationRef<'a, E>> for QueuedAttestation {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns all values in `self.queued_attestations` that have a slot that is earlier than the
|
||||
/// current slot. Also removes those values from `self.queued_attestations`.
|
||||
fn dequeue_attestations(
|
||||
/// Returns all attestations in `queued_attestations` with a slot earlier than the current slot,
|
||||
/// removing them from the queue.
|
||||
pub fn dequeue_attestations(
|
||||
current_slot: Slot,
|
||||
queued_attestations: &mut Vec<QueuedAttestation>,
|
||||
) -> Vec<QueuedAttestation> {
|
||||
let remaining = queued_attestations.split_off(
|
||||
queued_attestations
|
||||
.iter()
|
||||
.position(|a| a.slot >= current_slot)
|
||||
.unwrap_or(queued_attestations.len()),
|
||||
);
|
||||
queued_attestations: &mut BTreeMap<Slot, Vec<QueuedAttestation>>,
|
||||
) -> BTreeMap<Slot, Vec<QueuedAttestation>> {
|
||||
let remaining = queued_attestations.split_off(¤t_slot);
|
||||
let due = std::mem::replace(queued_attestations, remaining);
|
||||
|
||||
let dequeued_count: usize = due.values().map(Vec::len).sum();
|
||||
metrics::inc_counter_by(
|
||||
&metrics::FORK_CHOICE_DEQUEUED_ATTESTATIONS,
|
||||
queued_attestations.len() as u64,
|
||||
dequeued_count as u64,
|
||||
);
|
||||
|
||||
std::mem::replace(queued_attestations, remaining)
|
||||
due
|
||||
}
|
||||
|
||||
/// Denotes whether an attestation we are processing was received from a block or from gossip.
|
||||
@@ -377,8 +374,9 @@ pub struct ForkChoice<T, E> {
|
||||
fc_store: T,
|
||||
/// The underlying representation of the block DAG.
|
||||
proto_array: ProtoArrayForkChoice,
|
||||
/// Attestations that arrived at the current slot and must be queued for later processing.
|
||||
queued_attestations: Vec<QueuedAttestation>,
|
||||
/// Attestations that arrived at the current slot and must be queued for later processing,
|
||||
/// keyed by their slot.
|
||||
queued_attestations: BTreeMap<Slot, Vec<QueuedAttestation>>,
|
||||
/// Stores a cache of the values required to be sent to the execution layer.
|
||||
forkchoice_update_parameters: ForkchoiceUpdateParameters,
|
||||
_phantom: PhantomData<E>,
|
||||
@@ -475,7 +473,7 @@ where
|
||||
let mut fork_choice = Self {
|
||||
fc_store,
|
||||
proto_array,
|
||||
queued_attestations: vec![],
|
||||
queued_attestations: BTreeMap::new(),
|
||||
// This will be updated during the next call to `Self::get_head`.
|
||||
forkchoice_update_parameters: ForkchoiceUpdateParameters {
|
||||
head_hash: None,
|
||||
@@ -1367,8 +1365,11 @@ where
|
||||
// Attestations can only affect the fork choice of subsequent slots.
|
||||
// Delay consideration in the fork choice until their slot is in the past.
|
||||
// ```
|
||||
let queued_attestation = QueuedAttestation::from(attestation);
|
||||
self.queued_attestations
|
||||
.push(QueuedAttestation::from(attestation));
|
||||
.entry(queued_attestation.slot)
|
||||
.or_default()
|
||||
.push(queued_attestation);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -1560,10 +1561,11 @@ where
|
||||
/// Processes and removes from the queue any queued attestations which may now be eligible for
|
||||
/// processing due to the slot clock incrementing.
|
||||
fn process_attestation_queue(&mut self) -> Result<(), Error<T::Error>> {
|
||||
for attestation in dequeue_attestations(
|
||||
let dequeued = dequeue_attestations(
|
||||
self.fc_store.get_current_slot(),
|
||||
&mut self.queued_attestations,
|
||||
) {
|
||||
);
|
||||
for attestation in dequeued.into_values().flatten() {
|
||||
for validator_index in attestation.attesting_indices.iter() {
|
||||
self.proto_array.process_attestation(
|
||||
*validator_index as usize,
|
||||
@@ -1826,8 +1828,8 @@ where
|
||||
&self.fc_store
|
||||
}
|
||||
|
||||
/// Returns a reference to the currently queued attestations.
|
||||
pub fn queued_attestations(&self) -> &[QueuedAttestation] {
|
||||
/// Returns a reference to the currently queued attestations, keyed by slot.
|
||||
pub fn queued_attestations(&self) -> &BTreeMap<Slot, Vec<QueuedAttestation>> {
|
||||
&self.queued_attestations
|
||||
}
|
||||
|
||||
@@ -1912,7 +1914,7 @@ where
|
||||
let mut fork_choice = Self {
|
||||
fc_store,
|
||||
proto_array,
|
||||
queued_attestations: vec![],
|
||||
queued_attestations: BTreeMap::new(),
|
||||
// Will be updated in the following call to `Self::get_head`.
|
||||
forkchoice_update_parameters: ForkchoiceUpdateParameters {
|
||||
head_hash: None,
|
||||
@@ -2025,20 +2027,33 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_queued_attestations() -> Vec<QueuedAttestation> {
|
||||
(1..4)
|
||||
.map(|i| QueuedAttestation {
|
||||
slot: Slot::new(i),
|
||||
fn queue_from_slots(
|
||||
slots: impl IntoIterator<Item = u64>,
|
||||
) -> BTreeMap<Slot, Vec<QueuedAttestation>> {
|
||||
let mut queued: BTreeMap<Slot, Vec<QueuedAttestation>> = BTreeMap::new();
|
||||
for i in slots {
|
||||
let slot = Slot::new(i);
|
||||
queued.entry(slot).or_default().push(QueuedAttestation {
|
||||
slot,
|
||||
attesting_indices: vec![],
|
||||
block_root: Hash256::zero(),
|
||||
target_epoch: Epoch::new(0),
|
||||
payload_present: false,
|
||||
})
|
||||
.collect()
|
||||
});
|
||||
}
|
||||
queued
|
||||
}
|
||||
|
||||
fn get_slots(queued_attestations: &[QueuedAttestation]) -> Vec<u64> {
|
||||
queued_attestations.iter().map(|a| a.slot.into()).collect()
|
||||
fn get_queued_attestations() -> BTreeMap<Slot, Vec<QueuedAttestation>> {
|
||||
queue_from_slots(1..4)
|
||||
}
|
||||
|
||||
fn get_slots(queued_attestations: &BTreeMap<Slot, Vec<QueuedAttestation>>) -> Vec<u64> {
|
||||
queued_attestations
|
||||
.values()
|
||||
.flatten()
|
||||
.map(|a| a.slot.into())
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn test_queued_attestations(current_time: Slot) -> (Vec<u64>, Vec<u64>) {
|
||||
@@ -2070,4 +2085,25 @@ mod tests {
|
||||
assert!(queued.is_empty());
|
||||
assert_eq!(dequeued, vec![1, 2, 3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dequeue_attestations_out_of_order() {
|
||||
// A future-slot vote enqueued before a vote that becomes due sooner must not block the
|
||||
// due vote from being released.
|
||||
let mut queued = queue_from_slots([4, 3]);
|
||||
|
||||
// At slot 4, the slot-3 vote is due (3 < 4) and must be released.
|
||||
let dequeued = dequeue_attestations(Slot::new(4), &mut queued);
|
||||
|
||||
assert_eq!(
|
||||
get_slots(&dequeued),
|
||||
vec![3],
|
||||
"slot-3 vote must be dequeued at slot 4"
|
||||
);
|
||||
assert_eq!(
|
||||
get_slots(&queued),
|
||||
vec![4],
|
||||
"only the not-yet-due slot-4 vote should remain"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ pub use crate::fork_choice::{
|
||||
AttestationFromBlock, Error, ForkChoice, ForkChoiceView, ForkchoiceUpdateParameters,
|
||||
InvalidAttestation, InvalidBlock, InvalidPayloadAttestation, ParentImportStatus,
|
||||
PayloadVerificationStatus, PersistedForkChoice, PersistedForkChoiceV28, PersistedForkChoiceV29,
|
||||
QueuedAttestation, ResetPayloadStatuses,
|
||||
QueuedAttestation, ResetPayloadStatuses, dequeue_attestations,
|
||||
};
|
||||
pub use fork_choice_store::ForkChoiceStore;
|
||||
pub use proto_array::{
|
||||
|
||||
@@ -49,7 +49,11 @@ pub static FORK_CHOICE_ON_ATTESTER_SLASHING_TIMES: LazyLock<Result<Histogram>> =
|
||||
pub fn scrape_for_metrics<T: ForkChoiceStore<E>, E: EthSpec>(fork_choice: &ForkChoice<T, E>) {
|
||||
set_gauge(
|
||||
&FORK_CHOICE_QUEUED_ATTESTATIONS,
|
||||
fork_choice.queued_attestations().len() as i64,
|
||||
fork_choice
|
||||
.queued_attestations()
|
||||
.values()
|
||||
.map(Vec::len)
|
||||
.sum::<usize>() as i64,
|
||||
);
|
||||
set_gauge(
|
||||
&FORK_CHOICE_NODES,
|
||||
|
||||
Reference in New Issue
Block a user