mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-10 04:01:51 +00:00
Add comments to block_processing code
This commit is contained in:
@@ -3,7 +3,10 @@ use ssz::TreeHash;
|
||||
use types::beacon_state::helpers::*;
|
||||
use types::*;
|
||||
|
||||
/// Validate an attestation, checking the aggregate signature.
|
||||
/// Indicates if an `Attestation` is valid to be included in a block in the current epoch of the
|
||||
/// given state.
|
||||
///
|
||||
/// Returns `Ok(())` if the `Attestation` is valid, otherwise indicates the reason for invalidity.
|
||||
///
|
||||
/// Spec v0.4.0
|
||||
pub fn validate_attestation(
|
||||
@@ -14,7 +17,10 @@ pub fn validate_attestation(
|
||||
validate_attestation_signature_optional(state, attestation, spec, true)
|
||||
}
|
||||
|
||||
/// Validate an attestation, without checking the aggregate signature.
|
||||
/// Indicates if an `Attestation` is valid to be included in a block in the current epoch of the
|
||||
/// given state, without validating the aggregate signature.
|
||||
///
|
||||
/// Returns `Ok(())` if the `Attestation` is valid, otherwise indicates the reason for invalidity.
|
||||
///
|
||||
/// Spec v0.4.0
|
||||
pub fn validate_attestation_without_signature(
|
||||
@@ -25,7 +31,9 @@ pub fn validate_attestation_without_signature(
|
||||
validate_attestation_signature_optional(state, attestation, spec, false)
|
||||
}
|
||||
|
||||
/// Validate an attestation, optionally checking the aggregate signature.
|
||||
/// Indicates if an `Attestation` is valid to be included in a block in the current epoch of the
|
||||
/// given state, optionally validating the aggregate signature.
|
||||
///
|
||||
///
|
||||
/// Spec v0.4.0
|
||||
fn validate_attestation_signature_optional(
|
||||
@@ -37,19 +45,23 @@ fn validate_attestation_signature_optional(
|
||||
// Verify that `attestation.data.slot >= GENESIS_SLOT`.
|
||||
verify!(
|
||||
attestation.data.slot >= spec.genesis_slot,
|
||||
Invalid::PreGenesis
|
||||
Invalid::PreGenesis(spec.genesis_slot, attestation.data.slot)
|
||||
);
|
||||
|
||||
// Verify that `attestation.data.slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot`.
|
||||
verify!(
|
||||
attestation.data.slot + spec.min_attestation_inclusion_delay <= state.slot,
|
||||
Invalid::IncludedTooEarly
|
||||
Invalid::IncludedTooEarly(
|
||||
state.slot,
|
||||
spec.min_attestation_inclusion_delay,
|
||||
attestation.data.slot
|
||||
)
|
||||
);
|
||||
|
||||
// Verify that `state.slot < attestation.data.slot + SLOTS_PER_EPOCH`.
|
||||
verify!(
|
||||
state.slot < attestation.data.slot + spec.slots_per_epoch,
|
||||
Invalid::IncludedTooLate
|
||||
Invalid::IncludedTooLate(state.slot, attestation.data.slot)
|
||||
);
|
||||
|
||||
// Verify that `attestation.data.justified_epoch` is equal to `state.justified_epoch` if
|
||||
@@ -58,29 +70,37 @@ fn validate_attestation_signature_optional(
|
||||
if (attestation.data.slot + 1).epoch(spec.slots_per_epoch) >= state.current_epoch(spec) {
|
||||
verify!(
|
||||
attestation.data.justified_epoch == state.justified_epoch,
|
||||
Invalid::WrongJustifiedSlot
|
||||
Invalid::WrongJustifiedEpoch(
|
||||
attestation.data.justified_epoch,
|
||||
state.justified_epoch,
|
||||
false
|
||||
)
|
||||
);
|
||||
} else {
|
||||
verify!(
|
||||
attestation.data.justified_epoch == state.previous_justified_epoch,
|
||||
Invalid::WrongJustifiedSlot
|
||||
Invalid::WrongJustifiedEpoch(
|
||||
attestation.data.justified_epoch,
|
||||
state.previous_justified_epoch,
|
||||
true
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Verify that `attestation.data.justified_block_root` is equal to `get_block_root(state,
|
||||
// get_epoch_start_slot(attestation.data.justified_epoch))`.
|
||||
let justified_block_root = *state
|
||||
.get_block_root(
|
||||
attestation
|
||||
.data
|
||||
.justified_epoch
|
||||
.start_slot(spec.slots_per_epoch),
|
||||
&spec,
|
||||
)
|
||||
.ok_or(BeaconStateError::InsufficientBlockRoots)?;
|
||||
verify!(
|
||||
attestation.data.justified_block_root
|
||||
== *state
|
||||
.get_block_root(
|
||||
attestation
|
||||
.data
|
||||
.justified_epoch
|
||||
.start_slot(spec.slots_per_epoch),
|
||||
&spec
|
||||
)
|
||||
.ok_or(BeaconStateError::InsufficientBlockRoots)?,
|
||||
Invalid::WrongJustifiedRoot
|
||||
attestation.data.justified_block_root == justified_block_root,
|
||||
Invalid::WrongJustifiedRoot(justified_block_root, attestation.data.justified_block_root)
|
||||
);
|
||||
|
||||
// Verify that either:
|
||||
@@ -106,7 +126,12 @@ fn validate_attestation_signature_optional(
|
||||
.get_crosslink_committees_at_slot(attestation.data.slot, spec)?
|
||||
.iter()
|
||||
.find(|(_committee, shard)| *shard == attestation.data.shard)
|
||||
.ok_or_else(|| Error::Invalid(Invalid::NoCommitteeForShard))?;
|
||||
.ok_or_else(|| {
|
||||
Error::Invalid(Invalid::NoCommitteeForShard(
|
||||
attestation.data.shard,
|
||||
attestation.data.slot,
|
||||
))
|
||||
})?;
|
||||
|
||||
// Custody bitfield is all zeros (phase 0 requirement).
|
||||
verify!(
|
||||
@@ -115,8 +140,8 @@ fn validate_attestation_signature_optional(
|
||||
);
|
||||
// Custody bitfield length is correct.
|
||||
verify!(
|
||||
verify_bitfield_length(&attestation.aggregation_bitfield, committee.len()),
|
||||
Invalid::BadCustodyBitfieldLength
|
||||
verify_bitfield_length(&attestation.custody_bitfield, committee.len()),
|
||||
Invalid::BadCustodyBitfieldLength(committee.len(), attestation.custody_bitfield.len())
|
||||
);
|
||||
// Aggregation bitfield isn't empty.
|
||||
verify!(
|
||||
@@ -126,7 +151,10 @@ fn validate_attestation_signature_optional(
|
||||
// Aggregation bitfield length is correct.
|
||||
verify!(
|
||||
verify_bitfield_length(&attestation.aggregation_bitfield, committee.len()),
|
||||
Invalid::BadAggregationBitfieldLength
|
||||
Invalid::BadAggregationBitfieldLength(
|
||||
committee.len(),
|
||||
attestation.aggregation_bitfield.len()
|
||||
)
|
||||
);
|
||||
|
||||
if verify_signature {
|
||||
|
||||
@@ -2,10 +2,10 @@ use super::verify_slashable_attestation::verify_slashable_attestation;
|
||||
use crate::errors::{AttesterSlashingInvalid as Invalid, AttesterSlashingValidationError as Error};
|
||||
use types::*;
|
||||
|
||||
/// Returns `Ok(())` if some `AttesterSlashing` is valid to be included in some `BeaconState`,
|
||||
/// otherwise returns an `Err`.
|
||||
/// Indicates if an `AttesterSlashing` is valid to be included in a block in the current epoch of the given
|
||||
/// state.
|
||||
///
|
||||
/// Returns the slashable indices from the `AttesterSlashing`.
|
||||
/// Returns `Ok(())` if the `AttesterSlashing` is valid, otherwise indicates the reason for invalidity.
|
||||
///
|
||||
/// Spec v0.4.0
|
||||
pub fn verify_attester_slashing(
|
||||
@@ -36,7 +36,7 @@ pub fn verify_attester_slashing(
|
||||
let validator = state
|
||||
.validator_registry
|
||||
.get(*i as usize)
|
||||
.ok_or_else(|| Error::Invalid(Invalid::UnknownValidator))?;
|
||||
.ok_or_else(|| Error::Invalid(Invalid::UnknownValidator(*i)))?;
|
||||
|
||||
if slashable_attestation_1.validator_indices.contains(&i) & !validator.slashed {
|
||||
slashable_indices.push(*i);
|
||||
|
||||
@@ -1,22 +1,26 @@
|
||||
use crate::errors::{DepositInvalid as Invalid, DepositValidationError as Error};
|
||||
use ssz::TreeHash;
|
||||
use types::beacon_state::helpers::verify_bitfield_length;
|
||||
use types::*;
|
||||
|
||||
/// Verify validity of ``slashable_attestation`` fields.
|
||||
/// Indicates if a `Deposit` is valid to be included in a block in the current epoch of the given
|
||||
/// state.
|
||||
///
|
||||
/// Returns `Ok(())` if all fields are valid.
|
||||
/// Returns `Ok(())` if the `Deposit` is valid, otherwise indicates the reason for invalidity.
|
||||
///
|
||||
/// Note: this function is incomplete.
|
||||
///
|
||||
/// Spec v0.4.0
|
||||
pub fn verify_deposit(
|
||||
state: &BeaconState,
|
||||
deposit: &Deposit,
|
||||
spec: &ChainSpec,
|
||||
_spec: &ChainSpec,
|
||||
) -> Result<(), Error> {
|
||||
// TODO: verify serialized deposit data.
|
||||
|
||||
// TODO: verify deposit index.
|
||||
verify!(deposit.index == state.deposit_index, Invalid::BadIndex);
|
||||
verify!(
|
||||
deposit.index == state.deposit_index,
|
||||
Invalid::BadIndex(state.deposit_index, deposit.index)
|
||||
);
|
||||
|
||||
// TODO: verify merkle branch.
|
||||
|
||||
|
||||
@@ -2,9 +2,10 @@ use crate::errors::{ExitInvalid as Invalid, ExitValidationError as Error};
|
||||
use ssz::SignedRoot;
|
||||
use types::*;
|
||||
|
||||
/// Verify validity of ``slashable_attestation`` fields.
|
||||
/// Indicates if an `Exit` is valid to be included in a block in the current epoch of the given
|
||||
/// state.
|
||||
///
|
||||
/// Returns `Ok(())` if all fields are valid.
|
||||
/// Returns `Ok(())` if the `Exit` is valid, otherwise indicates the reason for invalidity.
|
||||
///
|
||||
/// Spec v0.4.0
|
||||
pub fn verify_exit(
|
||||
@@ -15,7 +16,9 @@ pub fn verify_exit(
|
||||
let validator = state
|
||||
.validator_registry
|
||||
.get(exit.validator_index as usize)
|
||||
.ok_or(Error::Invalid(Invalid::ValidatorUnknown))?;
|
||||
.ok_or(Error::Invalid(Invalid::ValidatorUnknown(
|
||||
exit.validator_index,
|
||||
)))?;
|
||||
|
||||
verify!(
|
||||
validator.exit_epoch
|
||||
@@ -25,7 +28,7 @@ pub fn verify_exit(
|
||||
|
||||
verify!(
|
||||
state.current_epoch(spec) >= exit.epoch,
|
||||
Invalid::FutureEpoch
|
||||
Invalid::FutureEpoch(state.current_epoch(spec), exit.epoch)
|
||||
);
|
||||
|
||||
let message = exit.signed_root();
|
||||
|
||||
@@ -2,8 +2,10 @@ use crate::errors::{ProposerSlashingInvalid as Invalid, ProposerSlashingValidati
|
||||
use ssz::SignedRoot;
|
||||
use types::*;
|
||||
|
||||
/// Returns `Ok(())` if some `ProposerSlashing` is valid to be included in some `BeaconState`,
|
||||
/// otherwise returns an `Err`.
|
||||
/// Indicates if a `ProposerSlashing` is valid to be included in a block in the current epoch of the given
|
||||
/// state.
|
||||
///
|
||||
/// Returns `Ok(())` if the `ProposerSlashing` is valid, otherwise indicates the reason for invalidity.
|
||||
///
|
||||
/// Spec v0.4.0
|
||||
pub fn verify_proposer_slashing(
|
||||
@@ -14,21 +16,32 @@ pub fn verify_proposer_slashing(
|
||||
let proposer = state
|
||||
.validator_registry
|
||||
.get(proposer_slashing.proposer_index as usize)
|
||||
.ok_or(Error::Invalid(Invalid::ProposerUnknown))?;
|
||||
.ok_or(Error::Invalid(Invalid::ProposerUnknown(
|
||||
proposer_slashing.proposer_index,
|
||||
)))?;
|
||||
|
||||
verify!(
|
||||
proposer_slashing.proposal_1.slot == proposer_slashing.proposal_2.slot,
|
||||
Invalid::ProposalSlotMismatch
|
||||
Invalid::ProposalSlotMismatch(
|
||||
proposer_slashing.proposal_1.slot,
|
||||
proposer_slashing.proposal_2.slot
|
||||
)
|
||||
);
|
||||
|
||||
verify!(
|
||||
proposer_slashing.proposal_1.shard == proposer_slashing.proposal_2.shard,
|
||||
Invalid::ProposalShardMismatch
|
||||
Invalid::ProposalShardMismatch(
|
||||
proposer_slashing.proposal_1.shard,
|
||||
proposer_slashing.proposal_2.shard
|
||||
)
|
||||
);
|
||||
|
||||
verify!(
|
||||
proposer_slashing.proposal_1.block_root != proposer_slashing.proposal_2.block_root,
|
||||
Invalid::ProposalBlockRootMismatch
|
||||
Invalid::ProposalBlockRootMismatch(
|
||||
proposer_slashing.proposal_1.block_root,
|
||||
proposer_slashing.proposal_2.block_root
|
||||
)
|
||||
);
|
||||
|
||||
verify!(!proposer.slashed, Invalid::ProposerAlreadySlashed);
|
||||
@@ -55,6 +68,9 @@ pub fn verify_proposer_slashing(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Verifies the signature of a proposal.
|
||||
///
|
||||
/// Returns `true` if the signature is valid.
|
||||
fn verify_proposal_signature(
|
||||
proposal: &Proposal,
|
||||
pubkey: &PublicKey,
|
||||
|
||||
@@ -5,9 +5,10 @@ use ssz::TreeHash;
|
||||
use types::beacon_state::helpers::verify_bitfield_length;
|
||||
use types::*;
|
||||
|
||||
/// Verify validity of ``slashable_attestation`` fields.
|
||||
/// Indicates if a `SlashableAttestation` is valid to be included in a block in the current epoch of the given
|
||||
/// state.
|
||||
///
|
||||
/// Returns `Ok(())` if all fields are valid.
|
||||
/// Returns `Ok(())` if the `SlashableAttestation` is valid, otherwise indicates the reason for invalidity.
|
||||
///
|
||||
/// Spec v0.4.0
|
||||
pub fn verify_slashable_attestation(
|
||||
@@ -27,7 +28,7 @@ pub fn verify_slashable_attestation(
|
||||
if slashable_attestation.validator_indices[i]
|
||||
>= slashable_attestation.validator_indices[i + 1]
|
||||
{
|
||||
invalid!(Invalid::BadValidatorIndicesOrdering);
|
||||
invalid!(Invalid::BadValidatorIndicesOrdering(i));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,12 +36,18 @@ pub fn verify_slashable_attestation(
|
||||
&slashable_attestation.custody_bitfield,
|
||||
slashable_attestation.validator_indices.len(),
|
||||
) {
|
||||
invalid!(Invalid::BadCustodyBitfieldLength);
|
||||
invalid!(Invalid::BadCustodyBitfieldLength(
|
||||
slashable_attestation.validator_indices.len(),
|
||||
slashable_attestation.custody_bitfield.len()
|
||||
));
|
||||
}
|
||||
|
||||
if slashable_attestation.validator_indices.len() > spec.max_indices_per_slashable_vote as usize
|
||||
{
|
||||
invalid!(Invalid::MaxIndicesExceed);
|
||||
invalid!(Invalid::MaxIndicesExceed(
|
||||
spec.max_indices_per_slashable_vote as usize,
|
||||
slashable_attestation.validator_indices.len()
|
||||
));
|
||||
}
|
||||
|
||||
// TODO: this signature verification could likely be replaced with:
|
||||
@@ -62,7 +69,7 @@ pub fn verify_slashable_attestation(
|
||||
Some(validator) => {
|
||||
aggregate_pubs[custody_bit as usize].add(&validator.pubkey);
|
||||
}
|
||||
None => invalid!(Invalid::UnknownValidator),
|
||||
None => invalid!(Invalid::UnknownValidator(*v)),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
use crate::errors::{TransferInvalid as Invalid, TransferValidationError as Error};
|
||||
use ssz::TreeHash;
|
||||
use types::beacon_state::helpers::verify_bitfield_length;
|
||||
use types::*;
|
||||
|
||||
/// Verify validity of ``slashable_attestation`` fields.
|
||||
/// Indicates if a `Transfer` is valid to be included in a block in the current epoch of the given
|
||||
/// state.
|
||||
///
|
||||
/// Returns `Ok(())` if all fields are valid.
|
||||
/// Returns `Ok(())` if the `Transfer` is valid, otherwise indicates the reason for invalidity.
|
||||
///
|
||||
/// Note: this function is incomplete.
|
||||
///
|
||||
/// Spec v0.4.0
|
||||
pub fn verify_transfer(
|
||||
state: &BeaconState,
|
||||
transfer: &Transfer,
|
||||
spec: &ChainSpec,
|
||||
_state: &BeaconState,
|
||||
_transfer: &Transfer,
|
||||
_spec: &ChainSpec,
|
||||
) -> Result<(), Error> {
|
||||
// TODO: verify transfer.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user