mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-03 00:31:50 +00:00
Add an additional defensive expected proposer check
This commit is contained in:
@@ -106,6 +106,9 @@ impl<T: BeaconChainTypes> GossipVerifiedEnvelope<T> {
|
||||
|
||||
// Check that we've seen the beacon block for this envelope and that it passes validation.
|
||||
// TODO(EIP-7732): We might need some type of status table in order to differentiate between:
|
||||
// If we have a block_processing_table, we could have a Processed(Bid, bool) state that is only
|
||||
// entered post adding to fork choice. That way, we could potentially need only a single call to make
|
||||
// sure the block is valid and to do all consequent checks with the bid
|
||||
//
|
||||
// 1. Blocks we haven't seen (IGNORE), and
|
||||
// 2. Blocks we've seen that are invalid (REJECT).
|
||||
@@ -147,7 +150,7 @@ impl<T: BeaconChainTypes> GossipVerifiedEnvelope<T> {
|
||||
|
||||
// Verify the envelope signature.
|
||||
//
|
||||
// For self-build envelopes, we can use the proposer cache for the fork and the
|
||||
// For self-built envelopes, we can use the proposer cache for the fork and the
|
||||
// validator pubkey cache for the proposer's pubkey, avoiding a state load from disk.
|
||||
// For external builder envelopes, we must load the state to access the builder registry.
|
||||
let builder_index = envelope.builder_index;
|
||||
@@ -157,7 +160,7 @@ impl<T: BeaconChainTypes> GossipVerifiedEnvelope<T> {
|
||||
proto_block.proposer_shuffling_root_for_child_block(block_epoch, ctx.spec);
|
||||
|
||||
let (signature_is_valid, opt_snapshot) = if builder_index == BUILDER_INDEX_SELF_BUILD {
|
||||
// Fast path: self-build envelopes can be verified without loading the state.
|
||||
// Fast path: self-built envelopes can be verified without loading the state.
|
||||
let envelope_ref = signed_envelope.as_ref();
|
||||
let mut opt_snapshot = None;
|
||||
let proposer = beacon_proposer_cache::with_proposer_cache(
|
||||
@@ -176,8 +179,16 @@ impl<T: BeaconChainTypes> GossipVerifiedEnvelope<T> {
|
||||
Ok::<_, EnvelopeError>((snapshot.state_root, snapshot.pre_state))
|
||||
},
|
||||
)?;
|
||||
let expected_proposer = proposer.index;
|
||||
let fork = proposer.fork;
|
||||
|
||||
if block.message().proposer_index() != expected_proposer as u64 {
|
||||
return Err(EnvelopeError::IncorrectBlockProposer {
|
||||
block: block.message().proposer_index(),
|
||||
local_shuffling: expected_proposer as u64,
|
||||
});
|
||||
}
|
||||
|
||||
let pubkey_cache = ctx.validator_pubkey_cache.read();
|
||||
let pubkey = pubkey_cache
|
||||
.get(block.message().proposer_index() as usize)
|
||||
|
||||
@@ -206,6 +206,11 @@ pub enum EnvelopeError {
|
||||
committed_bid: ExecutionBlockHash,
|
||||
envelope: ExecutionBlockHash,
|
||||
},
|
||||
// The block's proposer_index does not match the locally computed proposer
|
||||
IncorrectBlockProposer {
|
||||
block: u64,
|
||||
local_shuffling: u64,
|
||||
},
|
||||
// The slot belongs to a block that is from a slot prior than
|
||||
// the most recently finalized slot
|
||||
PriorToFinalization {
|
||||
|
||||
Reference in New Issue
Block a user