mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-27 17:53:42 +00:00
Gloas bid and preference verification (#9036)
Gossip verify and cache bids and proposer preferences. This PR also ensures we subscribe to new fork topics one epoch early instead of two slots early. This is required for proposer preferences. Co-Authored-By: Eitan Seri- Levi <eserilev@gmail.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{Address, ChainSpec, Epoch, ForkName};
|
||||
use crate::{Address, Epoch, ForkName};
|
||||
use bls::PublicKeyBytes;
|
||||
use context_deserialize::context_deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -24,12 +24,3 @@ pub struct Builder {
|
||||
pub deposit_epoch: Epoch,
|
||||
pub withdrawable_epoch: Epoch,
|
||||
}
|
||||
|
||||
impl Builder {
|
||||
/// Check if a builder is active in a state with `finalized_epoch`.
|
||||
///
|
||||
/// This implements `is_active_builder` from the spec.
|
||||
pub fn is_active_at_finalized_epoch(&self, finalized_epoch: Epoch, spec: &ChainSpec) -> bool {
|
||||
self.deposit_epoch < finalized_epoch && self.withdrawable_epoch == spec.far_future_epoch
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ use tree_hash_derive::TreeHash;
|
||||
use typenum::Unsigned;
|
||||
|
||||
use crate::{
|
||||
Address, ExecutionBlockHash, ExecutionPayloadBid, Withdrawal,
|
||||
Address, ExecutionBlockHash, ExecutionPayloadBid, ProposerPreferences, Withdrawal,
|
||||
attestation::{
|
||||
AttestationData, AttestationDuty, BeaconCommittee, Checkpoint, CommitteeIndex, PTC,
|
||||
ParticipationFlags, PendingAttestation,
|
||||
@@ -1349,6 +1349,43 @@ impl<E: EthSpec> BeaconState<E> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if the validator is the proposer for the given slot in the current or next epoch.
|
||||
pub fn is_valid_proposal_slot(
|
||||
&self,
|
||||
preferences: &ProposerPreferences,
|
||||
) -> Result<bool, BeaconStateError> {
|
||||
let current_epoch = self.current_epoch();
|
||||
let proposal_epoch = preferences.proposal_slot.epoch(E::slots_per_epoch());
|
||||
|
||||
if proposal_epoch < current_epoch {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
let next_epoch = current_epoch.saturating_add(1u64);
|
||||
if proposal_epoch > next_epoch {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
let epoch_offset = proposal_epoch.as_u64().safe_sub(current_epoch.as_u64())?;
|
||||
|
||||
let slot_in_epoch = preferences
|
||||
.proposal_slot
|
||||
.as_u64()
|
||||
.safe_rem(E::slots_per_epoch())?;
|
||||
|
||||
let index = epoch_offset
|
||||
.safe_mul(E::slots_per_epoch())
|
||||
.and_then(|v| v.safe_add(slot_in_epoch))?;
|
||||
|
||||
let proposer_lookahead = self.proposer_lookahead()?;
|
||||
|
||||
let proposer = proposer_lookahead
|
||||
.get(index as usize)
|
||||
.ok_or(BeaconStateError::ProposerLookaheadOutOfBounds { i: index as usize })?;
|
||||
|
||||
Ok(*proposer == preferences.validator_index)
|
||||
}
|
||||
|
||||
/// Returns the beacon proposer index for each `slot` in `epoch`.
|
||||
///
|
||||
/// The returned `Vec` contains one proposer index for each slot in the epoch.
|
||||
@@ -3259,6 +3296,38 @@ impl<E: EthSpec> BeaconState<E> {
|
||||
Ok(effective_balance.safe_mul(MAX_RANDOM_VALUE)?
|
||||
>= max_effective_balance.safe_mul(random_value)?)
|
||||
}
|
||||
|
||||
pub fn can_builder_cover_bid(
|
||||
&self,
|
||||
builder_index: BuilderIndex,
|
||||
bid_amount: u64,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<bool, BeaconStateError> {
|
||||
let builder = self.get_builder(builder_index)?;
|
||||
|
||||
let builder_balance = builder.balance;
|
||||
let pending_withdrawals_amount =
|
||||
self.get_pending_balance_to_withdraw_for_builder(builder_index)?;
|
||||
|
||||
let min_balance = spec
|
||||
.min_deposit_amount
|
||||
.safe_add(pending_withdrawals_amount)?;
|
||||
if builder_balance < min_balance {
|
||||
return Ok(false);
|
||||
}
|
||||
Ok(builder_balance.safe_sub(min_balance)? >= bid_amount)
|
||||
}
|
||||
|
||||
pub fn is_active_builder(
|
||||
&self,
|
||||
builder_index: BuilderIndex,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<bool, BeaconStateError> {
|
||||
let builder = self.get_builder(builder_index)?;
|
||||
|
||||
Ok(builder.deposit_epoch < self.finalized_checkpoint().epoch
|
||||
&& builder.withdrawable_epoch == spec.far_future_epoch)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> ForkVersionDecode for BeaconState<E> {
|
||||
|
||||
Reference in New Issue
Block a user