Check proposer index during block production (#2740)

## Issue Addressed

Resolves #2612 

## Proposed Changes

Implements both the checks mentioned in the original issue. 
1. Verifies the `randao_reveal` in the beacon node
2. Cross checks the proposer index after getting back the block from the beacon node.

## Additional info
The block production time increases by ~10x because of the signature verification on the beacon node (based on the `beacon_block_production_process_seconds` metric) when running on a local testnet.
This commit is contained in:
Pawan Dhananjay 2021-11-01 07:44:40 +00:00
parent ffb04e1a9e
commit 4499adc7fd
3 changed files with 18 additions and 2 deletions

View File

@ -2889,7 +2889,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
&mut state, &mut state,
&block, &block,
None, None,
BlockSignatureStrategy::NoVerification, BlockSignatureStrategy::VerifyRandao,
&self.spec, &self.spec,
)?; )?;
drop(process_timer); drop(process_timer);

View File

@ -46,6 +46,8 @@ pub enum BlockSignatureStrategy {
NoVerification, NoVerification,
/// Validate each signature individually, as its object is being processed. /// Validate each signature individually, as its object is being processed.
VerifyIndividual, VerifyIndividual,
/// Validate only the randao reveal signature.
VerifyRandao,
/// Verify all signatures in bulk at the beginning of block processing. /// Verify all signatures in bulk at the beginning of block processing.
VerifyBulk, VerifyBulk,
} }
@ -115,6 +117,7 @@ pub fn per_block_processing<T: EthSpec>(
} }
BlockSignatureStrategy::VerifyIndividual => VerifySignatures::True, BlockSignatureStrategy::VerifyIndividual => VerifySignatures::True,
BlockSignatureStrategy::NoVerification => VerifySignatures::False, BlockSignatureStrategy::NoVerification => VerifySignatures::False,
BlockSignatureStrategy::VerifyRandao => VerifySignatures::False,
}; };
let proposer_index = process_block_header(state, block, spec)?; let proposer_index = process_block_header(state, block, spec)?;
@ -123,11 +126,16 @@ pub fn per_block_processing<T: EthSpec>(
verify_block_signature(state, signed_block, block_root, spec)?; verify_block_signature(state, signed_block, block_root, spec)?;
} }
let verify_randao = if let BlockSignatureStrategy::VerifyRandao = block_signature_strategy {
VerifySignatures::True
} else {
verify_signatures
};
// Ensure the current and previous epoch caches are built. // Ensure the current and previous epoch caches are built.
state.build_committee_cache(RelativeEpoch::Previous, spec)?; state.build_committee_cache(RelativeEpoch::Previous, spec)?;
state.build_committee_cache(RelativeEpoch::Current, spec)?; state.build_committee_cache(RelativeEpoch::Current, spec)?;
process_randao(state, block, verify_signatures, spec)?; process_randao(state, block, verify_randao, spec)?;
process_eth1_data(state, block.body().eth1_data())?; process_eth1_data(state, block.body().eth1_data())?;
process_operations(state, block.body(), proposer_index, verify_signatures, spec)?; process_operations(state, block.body(), proposer_index, verify_signatures, spec)?;

View File

@ -259,6 +259,7 @@ impl<T: SlotClock + 'static, E: EthSpec> BlockService<T, E> {
let randao_reveal_ref = &randao_reveal; let randao_reveal_ref = &randao_reveal;
let self_ref = &self; let self_ref = &self;
let proposer_index = self.validator_store.validator_index(&validator_pubkey);
let validator_pubkey_ref = &validator_pubkey; let validator_pubkey_ref = &validator_pubkey;
let signed_block = self let signed_block = self
.beacon_nodes .beacon_nodes
@ -274,6 +275,13 @@ impl<T: SlotClock + 'static, E: EthSpec> BlockService<T, E> {
.data; .data;
drop(get_timer); drop(get_timer);
if proposer_index != Some(block.proposer_index()) {
return Err(
"Proposer index does not match block proposer. Beacon chain re-orged"
.to_string(),
);
}
let signed_block = self_ref let signed_block = self_ref
.validator_store .validator_store
.sign_block(*validator_pubkey_ref, block, current_slot) .sign_block(*validator_pubkey_ref, block, current_slot)