mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-17 20:02:43 +00:00
add consolidation processing
This commit is contained in:
@@ -4,6 +4,7 @@ use crate::common::{
|
||||
slash_validator,
|
||||
};
|
||||
use crate::per_block_processing::errors::{BlockProcessingError, IntoWithIndex};
|
||||
use crate::signature_sets::consolidation_signature_set;
|
||||
use crate::VerifySignatures;
|
||||
use types::consts::altair::{PARTICIPATION_FLAG_WEIGHTS, PROPOSER_WEIGHT, WEIGHT_DENOMINATOR};
|
||||
use types::typenum::U33;
|
||||
@@ -640,3 +641,161 @@ pub fn process_deposit_receipts<E: EthSpec>(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn process_consolidations<E: EthSpec>(
|
||||
state: &mut BeaconState<E>,
|
||||
consolidations: &[SignedConsolidation],
|
||||
verify_signatures: VerifySignatures,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), BlockProcessingError> {
|
||||
// If the pending consolidations queue is full, no consolidations are allowed in the block
|
||||
let pending_consolidations = state.pending_consolidations()?.len();
|
||||
let pending_consolidations_limit = E::pending_consolidations_limit();
|
||||
block_verify! {
|
||||
pending_consolidations < pending_consolidations_limit,
|
||||
BlockProcessingError::TooManyPendingConsolidations {
|
||||
consolidations: pending_consolidations,
|
||||
limit: pending_consolidations_limit
|
||||
}
|
||||
}
|
||||
|
||||
// If there is too little available consolidation churn limit, no consolidations are allowed in the block
|
||||
let churn_limit = state.get_consolidation_churn_limit(spec)?;
|
||||
block_verify! {
|
||||
churn_limit > spec.min_activation_balance,
|
||||
BlockProcessingError::ConsolidationChurnLimitTooLow {
|
||||
churn_limit,
|
||||
minimum: spec.min_activation_balance
|
||||
}
|
||||
}
|
||||
|
||||
for signed_consolidation in consolidations {
|
||||
let consolidation = signed_consolidation.message.clone();
|
||||
|
||||
// Verify that source != target, so a consolidation cannot be used as an exit.
|
||||
block_verify! {
|
||||
consolidation.source_index != consolidation.target_index,
|
||||
BlockProcessingError::MatchingSourceTargetConsolidation {
|
||||
index: consolidation.source_index
|
||||
}
|
||||
}
|
||||
|
||||
let source_validator = state
|
||||
.validators()
|
||||
.get(consolidation.source_index as usize)
|
||||
.ok_or(BeaconStateError::UnknownValidator(
|
||||
consolidation.source_index as usize,
|
||||
))?;
|
||||
let target_validator = state
|
||||
.validators()
|
||||
.get(consolidation.target_index as usize)
|
||||
.ok_or(BeaconStateError::UnknownValidator(
|
||||
consolidation.target_index as usize,
|
||||
))?;
|
||||
|
||||
// Verify the source and the target are active
|
||||
let current_epoch = state.current_epoch();
|
||||
block_verify! {
|
||||
source_validator.is_active_at(current_epoch),
|
||||
BlockProcessingError::InactiveConsolidationSource{
|
||||
index: consolidation.source_index,
|
||||
current_epoch
|
||||
}
|
||||
}
|
||||
block_verify! {
|
||||
target_validator.is_active_at(current_epoch),
|
||||
BlockProcessingError::InactiveConsolidationTarget{
|
||||
index: consolidation.target_index,
|
||||
current_epoch
|
||||
}
|
||||
}
|
||||
|
||||
// Verify exits for source and target have not been initiated
|
||||
block_verify! {
|
||||
source_validator.exit_epoch == spec.far_future_epoch,
|
||||
BlockProcessingError::SourceValidatorExiting{
|
||||
index: consolidation.source_index,
|
||||
}
|
||||
}
|
||||
block_verify! {
|
||||
target_validator.exit_epoch == spec.far_future_epoch,
|
||||
BlockProcessingError::TargetValidatorExiting{
|
||||
index: consolidation.target_index,
|
||||
}
|
||||
}
|
||||
|
||||
// Consolidations must specify an epoch when they become valid; they are not valid before then
|
||||
block_verify! {
|
||||
current_epoch >= consolidation.epoch,
|
||||
BlockProcessingError::FutureConsolidationEpoch {
|
||||
current_epoch,
|
||||
consolidation_epoch: consolidation.epoch
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the source and the target have Execution layer withdrawal credentials
|
||||
block_verify! {
|
||||
source_validator.has_execution_withdrawal_credential(spec),
|
||||
BlockProcessingError::NoSourceExecutionWithdrawalCredential {
|
||||
index: consolidation.source_index,
|
||||
}
|
||||
}
|
||||
block_verify! {
|
||||
target_validator.has_execution_withdrawal_credential(spec),
|
||||
BlockProcessingError::NoTargetExecutionWithdrawalCredential {
|
||||
index: consolidation.target_index,
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the same withdrawal address
|
||||
let source_address = source_validator
|
||||
.get_execution_withdrawal_address(spec)
|
||||
.ok_or(BeaconStateError::NonExecutionAddresWithdrawalCredential)?;
|
||||
let target_address = target_validator
|
||||
.get_execution_withdrawal_address(spec)
|
||||
.ok_or(BeaconStateError::NonExecutionAddresWithdrawalCredential)?;
|
||||
block_verify! {
|
||||
source_address == target_address,
|
||||
BlockProcessingError::MismatchedWithdrawalCredentials {
|
||||
source_address,
|
||||
target_address
|
||||
}
|
||||
}
|
||||
|
||||
if verify_signatures.is_true() {
|
||||
let signature_set = consolidation_signature_set(
|
||||
state,
|
||||
|i| get_pubkey_from_state(state, i),
|
||||
signed_consolidation,
|
||||
spec,
|
||||
)?;
|
||||
block_verify! {
|
||||
signature_set.verify(),
|
||||
BlockProcessingError::InavlidConsolidationSignature
|
||||
}
|
||||
}
|
||||
let exit_epoch = state.compute_consolidation_epoch_and_update_churn(
|
||||
source_validator.effective_balance,
|
||||
spec,
|
||||
)?;
|
||||
let source_validator = state
|
||||
.validators_mut()
|
||||
.get_mut(consolidation.source_index as usize)
|
||||
.ok_or(BeaconStateError::UnknownValidator(
|
||||
consolidation.source_index as usize,
|
||||
))?;
|
||||
// Initiate source validator exit and append pending consolidation
|
||||
source_validator.exit_epoch = exit_epoch;
|
||||
source_validator.withdrawable_epoch = source_validator
|
||||
.exit_epoch
|
||||
.safe_add(spec.min_validator_withdrawability_delay)?;
|
||||
state
|
||||
.pending_consolidations_mut()?
|
||||
.push(PendingConsolidation {
|
||||
source_index: consolidation.source_index,
|
||||
target_index: consolidation.target_index,
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user