mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-07 00:42:42 +00:00
Fix race condition in VC block proposal service (#1282)
Closes #918 Closes #923
This commit is contained in:
@@ -10,9 +10,10 @@ pub type ValidatorDutyBytes = ValidatorDutyBase<PublicKeyBytes>;
|
||||
/// A validator duty with the pubkey represented as a `PublicKey`.
|
||||
pub type ValidatorDuty = ValidatorDutyBase<PublicKey>;
|
||||
|
||||
// NOTE: if you add or remove fields, please adjust `eq_ignoring_proposal_slots`
|
||||
#[derive(PartialEq, Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct ValidatorDutyBase<T> {
|
||||
/// The validator's BLS public key, uniquely identifying them. _48-bytes, hex encoded with 0x prefix, case insensitive._
|
||||
/// The validator's BLS public key, uniquely identifying them.
|
||||
pub validator_pubkey: T,
|
||||
/// The validator's index in `state.validators`
|
||||
pub validator_index: Option<u64>,
|
||||
@@ -25,7 +26,9 @@ pub struct ValidatorDutyBase<T> {
|
||||
/// The committee count at `attestation_slot`.
|
||||
pub committee_count_at_slot: Option<u64>,
|
||||
/// The slots in which a validator must propose a block (can be empty).
|
||||
pub block_proposal_slots: Vec<Slot>,
|
||||
///
|
||||
/// Should be set to `None` when duties are not yet known (before the current epoch).
|
||||
pub block_proposal_slots: Option<Vec<Slot>>,
|
||||
/// This provides the modulo: `max(1, len(committee) // TARGET_AGGREGATORS_PER_COMMITTEE)`
|
||||
/// which allows the validator client to determine if this duty requires the validator to be
|
||||
/// aggregate attestations.
|
||||
@@ -49,6 +52,20 @@ impl<T> ValidatorDutyBase<T> {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Return `true` if these validator duties are equal, ignoring their `block_proposal_slots`.
|
||||
pub fn eq_ignoring_proposal_slots(&self, other: &Self) -> bool
|
||||
where
|
||||
T: PartialEq,
|
||||
{
|
||||
self.validator_pubkey == other.validator_pubkey
|
||||
&& self.validator_index == other.validator_index
|
||||
&& self.attestation_slot == other.attestation_slot
|
||||
&& self.attestation_committee_index == other.attestation_committee_index
|
||||
&& self.attestation_committee_position == other.attestation_committee_position
|
||||
&& self.committee_count_at_slot == other.committee_count_at_slot
|
||||
&& self.aggregator_modulo == other.aggregator_modulo
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Serialize, Deserialize, Clone, Encode, Decode)]
|
||||
@@ -74,3 +91,29 @@ pub struct ValidatorSubscription {
|
||||
/// for this slot.
|
||||
pub is_aggregator: bool,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn eq_ignoring_proposal_slots() {
|
||||
let duty1 = ValidatorDuty {
|
||||
validator_pubkey: PublicKey::default(),
|
||||
validator_index: Some(10),
|
||||
attestation_slot: Some(Slot::new(50)),
|
||||
attestation_committee_index: Some(2),
|
||||
attestation_committee_position: Some(6),
|
||||
committee_count_at_slot: Some(4),
|
||||
block_proposal_slots: None,
|
||||
aggregator_modulo: Some(99),
|
||||
};
|
||||
let duty2 = ValidatorDuty {
|
||||
block_proposal_slots: Some(vec![Slot::new(42), Slot::new(45)]),
|
||||
..duty1.clone()
|
||||
};
|
||||
assert_ne!(duty1, duty2);
|
||||
assert!(duty1.eq_ignoring_proposal_slots(&duty2));
|
||||
assert!(duty2.eq_ignoring_proposal_slots(&duty1));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user