merge with unstable

This commit is contained in:
realbigsean
2022-11-01 13:18:00 -04:00
143 changed files with 4773 additions and 1876 deletions

View File

@@ -123,10 +123,11 @@ where
decompressor: D,
block: &'a SignedBeaconBlock<T, Payload>,
block_root: Option<Hash256>,
verified_proposer_index: Option<u64>,
spec: &'a ChainSpec,
) -> Result<()> {
let mut verifier = Self::new(state, get_pubkey, decompressor, spec);
verifier.include_all_signatures(block, block_root)?;
verifier.include_all_signatures(block, block_root, verified_proposer_index)?;
verifier.verify()
}
@@ -135,9 +136,10 @@ where
&mut self,
block: &'a SignedBeaconBlock<T, Payload>,
block_root: Option<Hash256>,
verified_proposer_index: Option<u64>,
) -> Result<()> {
self.include_block_proposal(block, block_root)?;
self.include_all_signatures_except_proposal(block)?;
self.include_block_proposal(block, block_root, verified_proposer_index)?;
self.include_all_signatures_except_proposal(block, verified_proposer_index)?;
Ok(())
}
@@ -147,8 +149,9 @@ where
pub fn include_all_signatures_except_proposal<Payload: AbstractExecPayload<T>>(
&mut self,
block: &'a SignedBeaconBlock<T, Payload>,
verified_proposer_index: Option<u64>,
) -> Result<()> {
self.include_randao_reveal(block)?;
self.include_randao_reveal(block, verified_proposer_index)?;
self.include_proposer_slashings(block)?;
self.include_attester_slashings(block)?;
self.include_attestations(block)?;
@@ -164,12 +167,14 @@ where
&mut self,
block: &'a SignedBeaconBlock<T, Payload>,
block_root: Option<Hash256>,
verified_proposer_index: Option<u64>,
) -> Result<()> {
let set = block_proposal_signature_set(
self.state,
self.get_pubkey.clone(),
block,
block_root,
verified_proposer_index,
self.spec,
)?;
self.sets.push(set);
@@ -180,11 +185,13 @@ where
pub fn include_randao_reveal<Payload: AbstractExecPayload<T>>(
&mut self,
block: &'a SignedBeaconBlock<T, Payload>,
verified_proposer_index: Option<u64>,
) -> Result<()> {
let set = randao_signature_set(
self.state,
self.get_pubkey.clone(),
block.message(),
verified_proposer_index,
self.spec,
)?;
self.sets.push(set);

View File

@@ -1,4 +1,5 @@
use super::signature_sets::Error as SignatureSetError;
use crate::ContextError;
use merkle_proof::MerkleTreeError;
use safe_arith::ArithError;
use ssz::DecodeError;
@@ -72,6 +73,7 @@ pub enum BlockProcessingError {
found: u64,
},
ExecutionInvalid,
ConsensusContext(ContextError),
BlobVersionHashMismatch,
/// The number of commitments in blob transactions in the payload does not match the number
/// of commitments in the block.
@@ -122,6 +124,12 @@ impl From<SyncAggregateInvalid> for BlockProcessingError {
}
}
impl From<ContextError> for BlockProcessingError {
fn from(e: ContextError) -> Self {
BlockProcessingError::ConsensusContext(e)
}
}
impl From<BlockOperationError<HeaderInvalid>> for BlockProcessingError {
fn from(e: BlockOperationError<HeaderInvalid>) -> BlockProcessingError {
match e {
@@ -129,6 +137,7 @@ impl From<BlockOperationError<HeaderInvalid>> for BlockProcessingError {
BlockOperationError::BeaconStateError(e) => BlockProcessingError::BeaconStateError(e),
BlockOperationError::SignatureSetError(e) => BlockProcessingError::SignatureSetError(e),
BlockOperationError::SszTypesError(e) => BlockProcessingError::SszTypesError(e),
BlockOperationError::ConsensusContext(e) => BlockProcessingError::ConsensusContext(e),
BlockOperationError::ArithError(e) => BlockProcessingError::ArithError(e),
}
}
@@ -156,6 +165,7 @@ macro_rules! impl_into_block_processing_error_with_index {
BlockOperationError::BeaconStateError(e) => BlockProcessingError::BeaconStateError(e),
BlockOperationError::SignatureSetError(e) => BlockProcessingError::SignatureSetError(e),
BlockOperationError::SszTypesError(e) => BlockProcessingError::SszTypesError(e),
BlockOperationError::ConsensusContext(e) => BlockProcessingError::ConsensusContext(e),
BlockOperationError::ArithError(e) => BlockProcessingError::ArithError(e),
}
}
@@ -187,6 +197,7 @@ pub enum BlockOperationError<T> {
BeaconStateError(BeaconStateError),
SignatureSetError(SignatureSetError),
SszTypesError(ssz_types::Error),
ConsensusContext(ContextError),
ArithError(ArithError),
}
@@ -219,6 +230,12 @@ impl<T> From<ArithError> for BlockOperationError<T> {
}
}
impl<T> From<ContextError> for BlockOperationError<T> {
fn from(e: ContextError) -> Self {
BlockOperationError::ConsensusContext(e)
}
}
#[derive(Debug, PartialEq, Clone)]
pub enum HeaderInvalid {
ProposalSignatureInvalid,
@@ -228,14 +245,14 @@ pub enum HeaderInvalid {
block_slot: Slot,
},
ProposerIndexMismatch {
block_proposer_index: usize,
state_proposer_index: usize,
block_proposer_index: u64,
state_proposer_index: u64,
},
ParentBlockRootMismatch {
state: Hash256,
block: Hash256,
},
ProposerSlashed(usize),
ProposerSlashed(u64),
}
#[derive(Debug, PartialEq, Clone)]
@@ -330,6 +347,7 @@ impl From<BlockOperationError<IndexedAttestationInvalid>>
BlockOperationError::BeaconStateError(e) => BlockOperationError::BeaconStateError(e),
BlockOperationError::SignatureSetError(e) => BlockOperationError::SignatureSetError(e),
BlockOperationError::SszTypesError(e) => BlockOperationError::SszTypesError(e),
BlockOperationError::ConsensusContext(e) => BlockOperationError::ConsensusContext(e),
BlockOperationError::ArithError(e) => BlockOperationError::ArithError(e),
}
}

View File

@@ -12,23 +12,25 @@ use types::consts::altair::{PARTICIPATION_FLAG_WEIGHTS, PROPOSER_WEIGHT, WEIGHT_
pub fn process_operations<'a, T: EthSpec, Payload: AbstractExecPayload<T>>(
state: &mut BeaconState<T>,
block_body: BeaconBlockBodyRef<'a, T, Payload>,
proposer_index: u64,
verify_signatures: VerifySignatures,
ctxt: &mut ConsensusContext<T>,
spec: &ChainSpec,
) -> Result<(), BlockProcessingError> {
process_proposer_slashings(
state,
block_body.proposer_slashings(),
verify_signatures,
ctxt,
spec,
)?;
process_attester_slashings(
state,
block_body.attester_slashings(),
verify_signatures,
ctxt,
spec,
)?;
process_attestations(state, block_body, proposer_index, verify_signatures, spec)?;
process_attestations(state, block_body, verify_signatures, ctxt, spec)?;
process_deposits(state, block_body.deposits(), spec)?;
process_exits(state, block_body.voluntary_exits(), verify_signatures, spec)?;
Ok(())
@@ -45,12 +47,13 @@ pub mod base {
state: &mut BeaconState<T>,
attestations: &[Attestation<T>],
verify_signatures: VerifySignatures,
ctxt: &mut ConsensusContext<T>,
spec: &ChainSpec,
) -> Result<(), BlockProcessingError> {
// Ensure the previous epoch cache exists.
state.build_committee_cache(RelativeEpoch::Previous, spec)?;
let proposer_index = state.get_beacon_proposer_index(state.slot(), spec)? as u64;
let proposer_index = ctxt.get_proposer_index(state, spec)?;
// Verify and apply each attestation.
for (i, attestation) in attestations.iter().enumerate() {
@@ -87,10 +90,11 @@ pub mod altair {
pub fn process_attestations<T: EthSpec>(
state: &mut BeaconState<T>,
attestations: &[Attestation<T>],
proposer_index: u64,
verify_signatures: VerifySignatures,
ctxt: &mut ConsensusContext<T>,
spec: &ChainSpec,
) -> Result<(), BlockProcessingError> {
let proposer_index = ctxt.get_proposer_index(state, spec)?;
attestations
.iter()
.enumerate()
@@ -170,6 +174,7 @@ pub fn process_proposer_slashings<T: EthSpec>(
state: &mut BeaconState<T>,
proposer_slashings: &[ProposerSlashing],
verify_signatures: VerifySignatures,
ctxt: &mut ConsensusContext<T>,
spec: &ChainSpec,
) -> Result<(), BlockProcessingError> {
// Verify and apply proposer slashings in series.
@@ -186,6 +191,7 @@ pub fn process_proposer_slashings<T: EthSpec>(
state,
proposer_slashing.signed_header_1.message.proposer_index as usize,
None,
ctxt,
spec,
)?;
@@ -201,6 +207,7 @@ pub fn process_attester_slashings<T: EthSpec>(
state: &mut BeaconState<T>,
attester_slashings: &[AttesterSlashing<T>],
verify_signatures: VerifySignatures,
ctxt: &mut ConsensusContext<T>,
spec: &ChainSpec,
) -> Result<(), BlockProcessingError> {
for (i, attester_slashing) in attester_slashings.iter().enumerate() {
@@ -211,7 +218,7 @@ pub fn process_attester_slashings<T: EthSpec>(
get_slashable_indices(state, attester_slashing).map_err(|e| e.into_with_index(i))?;
for i in slashable_indices {
slash_validator(state, i as usize, None, spec)?;
slash_validator(state, i as usize, None, ctxt, spec)?;
}
}
@@ -222,13 +229,19 @@ pub fn process_attester_slashings<T: EthSpec>(
pub fn process_attestations<'a, T: EthSpec, Payload: AbstractExecPayload<T>>(
state: &mut BeaconState<T>,
block_body: BeaconBlockBodyRef<'a, T, Payload>,
proposer_index: u64,
verify_signatures: VerifySignatures,
ctxt: &mut ConsensusContext<T>,
spec: &ChainSpec,
) -> Result<(), BlockProcessingError> {
match block_body {
BeaconBlockBodyRef::Base(_) => {
base::process_attestations(state, block_body.attestations(), verify_signatures, spec)?;
base::process_attestations(
state,
block_body.attestations(),
verify_signatures,
ctxt,
spec,
)?;
}
BeaconBlockBodyRef::Altair(_)
| BeaconBlockBodyRef::Merge(_)
@@ -237,8 +250,8 @@ pub fn process_attestations<'a, T: EthSpec, Payload: AbstractExecPayload<T>>(
altair::process_attestations(
state,
block_body.attestations(),
proposer_index,
verify_signatures,
ctxt,
spec,
)?;
}

View File

@@ -76,6 +76,7 @@ pub fn block_proposal_signature_set<'a, T, F, Payload: AbstractExecPayload<T>>(
get_pubkey: F,
signed_block: &'a SignedBeaconBlock<T, Payload>,
block_root: Option<Hash256>,
verified_proposer_index: Option<u64>,
spec: &'a ChainSpec,
) -> Result<SignatureSet<'a>>
where
@@ -83,8 +84,12 @@ where
F: Fn(usize) -> Option<Cow<'a, PublicKey>>,
{
let block = signed_block.message();
let proposer_index = state.get_beacon_proposer_index(block.slot(), spec)? as u64;
let proposer_index = if let Some(proposer_index) = verified_proposer_index {
proposer_index
} else {
state.get_beacon_proposer_index(block.slot(), spec)? as u64
};
if proposer_index != block.proposer_index() {
return Err(Error::IncorrectBlockProposer {
block: block.proposer_index(),
@@ -156,13 +161,18 @@ pub fn randao_signature_set<'a, T, F, Payload: AbstractExecPayload<T>>(
state: &'a BeaconState<T>,
get_pubkey: F,
block: BeaconBlockRef<'a, T, Payload>,
verified_proposer_index: Option<u64>,
spec: &'a ChainSpec,
) -> Result<SignatureSet<'a>>
where
T: EthSpec,
F: Fn(usize) -> Option<Cow<'a, PublicKey>>,
{
let proposer_index = state.get_beacon_proposer_index(block.slot(), spec)?;
let proposer_index = if let Some(proposer_index) = verified_proposer_index {
proposer_index
} else {
state.get_beacon_proposer_index(block.slot(), spec)? as u64
};
let domain = spec.get_domain(
block.slot().epoch(T::slots_per_epoch()),
@@ -178,7 +188,7 @@ where
Ok(SignatureSet::single_pubkey(
block.body().randao_reveal(),
get_pubkey(proposer_index).ok_or(Error::ValidatorUnknown(proposer_index as u64))?,
get_pubkey(proposer_index as usize).ok_or(Error::ValidatorUnknown(proposer_index))?,
message,
))
}

View File

@@ -8,7 +8,7 @@ use crate::per_block_processing::errors::{
};
use crate::{
per_block_processing::{process_operations, verify_exit::verify_exit},
BlockSignatureStrategy, VerifyBlockRoot, VerifySignatures,
BlockSignatureStrategy, ConsensusContext, VerifyBlockRoot, VerifySignatures,
};
use beacon_chain::test_utils::{BeaconChainHarness, EphemeralHarnessType};
use lazy_static::lazy_static;
@@ -67,12 +67,13 @@ async fn valid_block_ok() {
.make_block_return_pre_state(state, slot + Slot::new(1))
.await;
let mut ctxt = ConsensusContext::new(block.slot());
let result = per_block_processing(
&mut state,
&block,
None,
BlockSignatureStrategy::VerifyIndividual,
VerifyBlockRoot::True,
&mut ctxt,
&spec,
);
@@ -91,12 +92,13 @@ async fn invalid_block_header_state_slot() {
let (mut block, signature) = signed_block.deconstruct();
*block.slot_mut() = slot + Slot::new(1);
let mut ctxt = ConsensusContext::new(block.slot());
let result = per_block_processing(
&mut state,
&SignedBeaconBlock::from_block(block, signature),
None,
BlockSignatureStrategy::VerifyIndividual,
VerifyBlockRoot::True,
&mut ctxt,
&spec,
);
@@ -122,12 +124,13 @@ async fn invalid_parent_block_root() {
let (mut block, signature) = signed_block.deconstruct();
*block.parent_root_mut() = Hash256::from([0xAA; 32]);
let mut ctxt = ConsensusContext::new(block.slot());
let result = per_block_processing(
&mut state,
&SignedBeaconBlock::from_block(block, signature),
None,
BlockSignatureStrategy::VerifyIndividual,
VerifyBlockRoot::True,
&mut ctxt,
&spec,
);
@@ -154,12 +157,13 @@ async fn invalid_block_signature() {
.await;
let (block, _) = signed_block.deconstruct();
let mut ctxt = ConsensusContext::new(block.slot());
let result = per_block_processing(
&mut state,
&SignedBeaconBlock::from_block(block, Signature::empty()),
None,
BlockSignatureStrategy::VerifyIndividual,
VerifyBlockRoot::True,
&mut ctxt,
&spec,
);
@@ -186,12 +190,13 @@ async fn invalid_randao_reveal_signature() {
})
.await;
let mut ctxt = ConsensusContext::new(signed_block.slot());
let result = per_block_processing(
&mut state,
&signed_block,
None,
BlockSignatureStrategy::VerifyIndividual,
VerifyBlockRoot::True,
&mut ctxt,
&spec,
);
@@ -386,11 +391,12 @@ async fn invalid_attestation_no_committee_for_index() {
head_block.to_mut().body_mut().attestations_mut()[0]
.data
.index += 1;
let mut ctxt = ConsensusContext::new(state.slot());
let result = process_operations::process_attestations(
&mut state,
head_block.body(),
head_block.proposer_index(),
VerifySignatures::True,
&mut ctxt,
&spec,
);
@@ -424,11 +430,12 @@ async fn invalid_attestation_wrong_justified_checkpoint() {
.data
.source = new_justified_checkpoint;
let mut ctxt = ConsensusContext::new(state.slot());
let result = process_operations::process_attestations(
&mut state,
head_block.body(),
head_block.proposer_index(),
VerifySignatures::True,
&mut ctxt,
&spec,
);
@@ -463,11 +470,12 @@ async fn invalid_attestation_bad_aggregation_bitfield_len() {
head_block.to_mut().body_mut().attestations_mut()[0].aggregation_bits =
Bitfield::with_capacity(spec.target_committee_size).unwrap();
let mut ctxt = ConsensusContext::new(state.slot());
let result = process_operations::process_attestations(
&mut state,
head_block.body(),
head_block.proposer_index(),
VerifySignatures::True,
&mut ctxt,
&spec,
);
@@ -495,11 +503,12 @@ async fn invalid_attestation_bad_signature() {
.0;
head_block.to_mut().body_mut().attestations_mut()[0].signature = AggregateSignature::empty();
let mut ctxt = ConsensusContext::new(state.slot());
let result = process_operations::process_attestations(
&mut state,
head_block.body(),
head_block.proposer_index(),
VerifySignatures::True,
&mut ctxt,
&spec,
);
// Expecting BadSignature because we're signing with invalid secret_keys
@@ -533,11 +542,12 @@ async fn invalid_attestation_included_too_early() {
.data
.slot = new_attesation_slot;
let mut ctxt = ConsensusContext::new(state.slot());
let result = process_operations::process_attestations(
&mut state,
head_block.body(),
head_block.proposer_index(),
VerifySignatures::True,
&mut ctxt,
&spec,
);
@@ -575,11 +585,12 @@ async fn invalid_attestation_included_too_late() {
.data
.slot = new_attesation_slot;
let mut ctxt = ConsensusContext::new(state.slot());
let result = process_operations::process_attestations(
&mut state,
head_block.body(),
head_block.proposer_index(),
VerifySignatures::True,
&mut ctxt,
&spec,
);
assert_eq!(
@@ -613,11 +624,12 @@ async fn invalid_attestation_target_epoch_slot_mismatch() {
.target
.epoch += Epoch::new(1);
let mut ctxt = ConsensusContext::new(state.slot());
let result = process_operations::process_attestations(
&mut state,
head_block.body(),
head_block.proposer_index(),
VerifySignatures::True,
&mut ctxt,
&spec,
);
assert_eq!(
@@ -640,10 +652,12 @@ async fn valid_insert_attester_slashing() {
let attester_slashing = harness.make_attester_slashing(vec![1, 2]);
let mut state = harness.get_current_state();
let mut ctxt = ConsensusContext::new(state.slot());
let result = process_operations::process_attester_slashings(
&mut state,
&[attester_slashing],
VerifySignatures::True,
&mut ctxt,
&spec,
);
@@ -660,10 +674,12 @@ async fn invalid_attester_slashing_not_slashable() {
attester_slashing.attestation_1 = attester_slashing.attestation_2.clone();
let mut state = harness.get_current_state();
let mut ctxt = ConsensusContext::new(state.slot());
let result = process_operations::process_attester_slashings(
&mut state,
&[attester_slashing],
VerifySignatures::True,
&mut ctxt,
&spec,
);
@@ -686,10 +702,12 @@ async fn invalid_attester_slashing_1_invalid() {
attester_slashing.attestation_1.attesting_indices = VariableList::from(vec![2, 1]);
let mut state = harness.get_current_state();
let mut ctxt = ConsensusContext::new(state.slot());
let result = process_operations::process_attester_slashings(
&mut state,
&[attester_slashing],
VerifySignatures::True,
&mut ctxt,
&spec,
);
@@ -715,10 +733,12 @@ async fn invalid_attester_slashing_2_invalid() {
attester_slashing.attestation_2.attesting_indices = VariableList::from(vec![2, 1]);
let mut state = harness.get_current_state();
let mut ctxt = ConsensusContext::new(state.slot());
let result = process_operations::process_attester_slashings(
&mut state,
&[attester_slashing],
VerifySignatures::True,
&mut ctxt,
&spec,
);
@@ -741,10 +761,12 @@ async fn valid_insert_proposer_slashing() {
let harness = get_harness::<MainnetEthSpec>(EPOCH_OFFSET, VALIDATOR_COUNT).await;
let proposer_slashing = harness.make_proposer_slashing(1);
let mut state = harness.get_current_state();
let mut ctxt = ConsensusContext::new(state.slot());
let result = process_operations::process_proposer_slashings(
&mut state,
&[proposer_slashing],
VerifySignatures::True,
&mut ctxt,
&spec,
);
// Expecting Ok(_) because we inserted a valid proposer slashing
@@ -760,10 +782,12 @@ async fn invalid_proposer_slashing_proposals_identical() {
proposer_slashing.signed_header_1.message = proposer_slashing.signed_header_2.message.clone();
let mut state = harness.get_current_state();
let mut ctxt = ConsensusContext::new(state.slot());
let result = process_operations::process_proposer_slashings(
&mut state,
&[proposer_slashing],
VerifySignatures::True,
&mut ctxt,
&spec,
);
@@ -787,10 +811,12 @@ async fn invalid_proposer_slashing_proposer_unknown() {
proposer_slashing.signed_header_2.message.proposer_index = 3_141_592;
let mut state = harness.get_current_state();
let mut ctxt = ConsensusContext::new(state.slot());
let result = process_operations::process_proposer_slashings(
&mut state,
&[proposer_slashing],
VerifySignatures::True,
&mut ctxt,
&spec,
);
@@ -811,10 +837,12 @@ async fn invalid_proposer_slashing_duplicate_slashing() {
let proposer_slashing = harness.make_proposer_slashing(1);
let mut state = harness.get_current_state();
let mut ctxt = ConsensusContext::new(state.slot());
let result_1 = process_operations::process_proposer_slashings(
&mut state,
&[proposer_slashing.clone()],
VerifySignatures::False,
&mut ctxt,
&spec,
);
assert!(result_1.is_ok());
@@ -823,6 +851,7 @@ async fn invalid_proposer_slashing_duplicate_slashing() {
&mut state,
&[proposer_slashing],
VerifySignatures::False,
&mut ctxt,
&spec,
);
// Expecting ProposerNotSlashable because we've already slashed the validator
@@ -842,10 +871,12 @@ async fn invalid_bad_proposal_1_signature() {
let mut proposer_slashing = harness.make_proposer_slashing(1);
proposer_slashing.signed_header_1.signature = Signature::empty();
let mut state = harness.get_current_state();
let mut ctxt = ConsensusContext::new(state.slot());
let result = process_operations::process_proposer_slashings(
&mut state,
&[proposer_slashing],
VerifySignatures::True,
&mut ctxt,
&spec,
);
@@ -866,10 +897,12 @@ async fn invalid_bad_proposal_2_signature() {
let mut proposer_slashing = harness.make_proposer_slashing(1);
proposer_slashing.signed_header_2.signature = Signature::empty();
let mut state = harness.get_current_state();
let mut ctxt = ConsensusContext::new(state.slot());
let result = process_operations::process_proposer_slashings(
&mut state,
&[proposer_slashing],
VerifySignatures::True,
&mut ctxt,
&spec,
);
@@ -891,10 +924,12 @@ async fn invalid_proposer_slashing_proposal_epoch_mismatch() {
proposer_slashing.signed_header_1.message.slot = Slot::new(0);
proposer_slashing.signed_header_2.message.slot = Slot::new(128);
let mut state = harness.get_current_state();
let mut ctxt = ConsensusContext::new(state.slot());
let result = process_operations::process_proposer_slashings(
&mut state,
&[proposer_slashing],
VerifySignatures::False,
&mut ctxt,
&spec,
);

View File

@@ -29,9 +29,7 @@ pub fn verify_deposit_signature(deposit_data: &DepositData, spec: &ChainSpec) ->
/// Returns a `Some(validator index)` if a pubkey already exists in the `validators`,
/// otherwise returns `None`.
///
/// ## Errors
///
/// Errors if the state's `pubkey_cache` is not current.
/// Builds the pubkey cache if it is not already built.
pub fn get_existing_validator_index<T: EthSpec>(
state: &mut BeaconState<T>,
pub_key: &PublicKeyBytes,