mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-11 04:31:51 +00:00
Consensus context with proposer index caching (#3604)
## Issue Addressed Closes https://github.com/sigp/lighthouse/issues/2371 ## Proposed Changes Backport some changes from `tree-states` that remove duplicated calculations of the `proposer_index`. With this change the proposer index should be calculated only once for each block, and then plumbed through to every place it is required. ## Additional Info In future I hope to add more data to the consensus context that is cached on a per-epoch basis, like the effective balances of validators and the base rewards. There are some other changes to remove indexing in tests that were also useful for `tree-states` (the `tree-states` types don't implement `Index`).
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
use crate::consensus_context::ConsensusContext;
|
||||
use errors::{BlockOperationError, BlockProcessingError, HeaderInvalid};
|
||||
use rayon::prelude::*;
|
||||
use safe_arith::{ArithError, SafeArith};
|
||||
@@ -90,9 +91,9 @@ pub enum VerifyBlockRoot {
|
||||
pub fn per_block_processing<T: EthSpec, Payload: ExecPayload<T>>(
|
||||
state: &mut BeaconState<T>,
|
||||
signed_block: &SignedBeaconBlock<T, Payload>,
|
||||
block_root: Option<Hash256>,
|
||||
block_signature_strategy: BlockSignatureStrategy,
|
||||
verify_block_root: VerifyBlockRoot,
|
||||
ctxt: &mut ConsensusContext<T>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), BlockProcessingError> {
|
||||
let block = signed_block.message();
|
||||
@@ -110,6 +111,8 @@ pub fn per_block_processing<T: EthSpec, Payload: ExecPayload<T>>(
|
||||
let verify_signatures = match block_signature_strategy {
|
||||
BlockSignatureStrategy::VerifyBulk => {
|
||||
// Verify all signatures in the block at once.
|
||||
let block_root = Some(ctxt.get_current_block_root(signed_block)?);
|
||||
let proposer_index = Some(ctxt.get_proposer_index(state, spec)?);
|
||||
block_verify!(
|
||||
BlockSignatureVerifier::verify_entire_block(
|
||||
state,
|
||||
@@ -117,6 +120,7 @@ pub fn per_block_processing<T: EthSpec, Payload: ExecPayload<T>>(
|
||||
|pk_bytes| pk_bytes.decompress().ok().map(Cow::Owned),
|
||||
signed_block,
|
||||
block_root,
|
||||
proposer_index,
|
||||
spec
|
||||
)
|
||||
.is_ok(),
|
||||
@@ -133,11 +137,12 @@ pub fn per_block_processing<T: EthSpec, Payload: ExecPayload<T>>(
|
||||
state,
|
||||
block.temporary_block_header(),
|
||||
verify_block_root,
|
||||
ctxt,
|
||||
spec,
|
||||
)?;
|
||||
|
||||
if verify_signatures.is_true() {
|
||||
verify_block_signature(state, signed_block, block_root, spec)?;
|
||||
verify_block_signature(state, signed_block, ctxt, spec)?;
|
||||
}
|
||||
|
||||
let verify_randao = if let BlockSignatureStrategy::VerifyRandao = block_signature_strategy {
|
||||
@@ -157,9 +162,9 @@ pub fn per_block_processing<T: EthSpec, Payload: ExecPayload<T>>(
|
||||
process_execution_payload(state, payload, spec)?;
|
||||
}
|
||||
|
||||
process_randao(state, block, verify_randao, spec)?;
|
||||
process_randao(state, block, verify_randao, ctxt, spec)?;
|
||||
process_eth1_data(state, block.body().eth1_data())?;
|
||||
process_operations(state, block.body(), proposer_index, verify_signatures, spec)?;
|
||||
process_operations(state, block.body(), verify_signatures, ctxt, spec)?;
|
||||
|
||||
if let Ok(sync_aggregate) = block.body().sync_aggregate() {
|
||||
process_sync_aggregate(
|
||||
@@ -179,6 +184,7 @@ pub fn process_block_header<T: EthSpec>(
|
||||
state: &mut BeaconState<T>,
|
||||
block_header: BeaconBlockHeader,
|
||||
verify_block_root: VerifyBlockRoot,
|
||||
ctxt: &mut ConsensusContext<T>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<u64, BlockOperationError<HeaderInvalid>> {
|
||||
// Verify that the slots match
|
||||
@@ -197,8 +203,8 @@ pub fn process_block_header<T: EthSpec>(
|
||||
);
|
||||
|
||||
// Verify that proposer index is the correct index
|
||||
let proposer_index = block_header.proposer_index as usize;
|
||||
let state_proposer_index = state.get_beacon_proposer_index(block_header.slot, spec)?;
|
||||
let proposer_index = block_header.proposer_index;
|
||||
let state_proposer_index = ctxt.get_proposer_index(state, spec)?;
|
||||
verify!(
|
||||
proposer_index == state_proposer_index,
|
||||
HeaderInvalid::ProposerIndexMismatch {
|
||||
@@ -222,11 +228,11 @@ pub fn process_block_header<T: EthSpec>(
|
||||
|
||||
// Verify proposer is not slashed
|
||||
verify!(
|
||||
!state.get_validator(proposer_index)?.slashed,
|
||||
!state.get_validator(proposer_index as usize)?.slashed,
|
||||
HeaderInvalid::ProposerSlashed(proposer_index)
|
||||
);
|
||||
|
||||
Ok(proposer_index as u64)
|
||||
Ok(proposer_index)
|
||||
}
|
||||
|
||||
/// Verifies the signature of a block.
|
||||
@@ -235,15 +241,18 @@ pub fn process_block_header<T: EthSpec>(
|
||||
pub fn verify_block_signature<T: EthSpec, Payload: ExecPayload<T>>(
|
||||
state: &BeaconState<T>,
|
||||
block: &SignedBeaconBlock<T, Payload>,
|
||||
block_root: Option<Hash256>,
|
||||
ctxt: &mut ConsensusContext<T>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), BlockOperationError<HeaderInvalid>> {
|
||||
let block_root = Some(ctxt.get_current_block_root(block)?);
|
||||
let proposer_index = Some(ctxt.get_proposer_index(state, spec)?);
|
||||
verify!(
|
||||
block_proposal_signature_set(
|
||||
state,
|
||||
|i| get_pubkey_from_state(state, i),
|
||||
block,
|
||||
block_root,
|
||||
proposer_index,
|
||||
spec
|
||||
)?
|
||||
.verify(),
|
||||
@@ -259,12 +268,21 @@ pub fn process_randao<T: EthSpec, Payload: ExecPayload<T>>(
|
||||
state: &mut BeaconState<T>,
|
||||
block: BeaconBlockRef<'_, T, Payload>,
|
||||
verify_signatures: VerifySignatures,
|
||||
ctxt: &mut ConsensusContext<T>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), BlockProcessingError> {
|
||||
if verify_signatures.is_true() {
|
||||
// Verify RANDAO reveal signature.
|
||||
let proposer_index = ctxt.get_proposer_index(state, spec)?;
|
||||
block_verify!(
|
||||
randao_signature_set(state, |i| get_pubkey_from_state(state, i), block, spec)?.verify(),
|
||||
randao_signature_set(
|
||||
state,
|
||||
|i| get_pubkey_from_state(state, i),
|
||||
block,
|
||||
Some(proposer_index),
|
||||
spec
|
||||
)?
|
||||
.verify(),
|
||||
BlockProcessingError::RandaoSignatureInvalid
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user