mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-07 08:52:54 +00:00
Avoid looking up pre-finalization blocks (#2909)
## Issue Addressed
This PR fixes the unnecessary `WARN Single block lookup failed` messages described here:
https://github.com/sigp/lighthouse/pull/2866#issuecomment-1008442640
## Proposed Changes
Add a new cache to the `BeaconChain` that tracks the block roots of blocks from before finalization. These could be blocks from the canonical chain (which might need to be read from disk), or old pre-finalization blocks that have been forked out.
The cache also stores a set of block roots for in-progress single block lookups, which duplicates some of the information from sync's `single_block_lookups` hashmap:
a836e180f9/beacon_node/network/src/sync/manager.rs (L192-L196)
On a live node you can confirm that the cache is working by grepping logs for the message: `Rejected attestation to finalized block`.
This commit is contained in:
@@ -5,7 +5,7 @@ use beacon_chain::{
|
||||
test_utils::{
|
||||
test_spec, AttestationStrategy, BeaconChainHarness, BlockStrategy, EphemeralHarnessType,
|
||||
},
|
||||
BeaconChain, BeaconChainTypes, WhenSlotSkipped,
|
||||
BeaconChain, BeaconChainError, BeaconChainTypes, WhenSlotSkipped,
|
||||
};
|
||||
use int_to_bytes::int_to_bytes32;
|
||||
use lazy_static::lazy_static;
|
||||
@@ -991,6 +991,81 @@ fn attestation_that_skips_epochs() {
|
||||
.expect("should gossip verify attestation that skips slots");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn attestation_to_finalized_block() {
|
||||
let harness = get_harness(VALIDATOR_COUNT);
|
||||
|
||||
// Extend the chain out a few epochs so we have some chain depth to play with.
|
||||
harness.extend_chain(
|
||||
MainnetEthSpec::slots_per_epoch() as usize * 4 + 1,
|
||||
BlockStrategy::OnCanonicalHead,
|
||||
AttestationStrategy::AllValidators,
|
||||
);
|
||||
|
||||
let finalized_checkpoint = harness
|
||||
.chain
|
||||
.with_head(|head| Ok::<_, BeaconChainError>(head.beacon_state.finalized_checkpoint()))
|
||||
.unwrap();
|
||||
assert!(finalized_checkpoint.epoch > 0);
|
||||
|
||||
let current_slot = harness.get_current_slot();
|
||||
|
||||
let earlier_slot = finalized_checkpoint
|
||||
.epoch
|
||||
.start_slot(MainnetEthSpec::slots_per_epoch())
|
||||
- 1;
|
||||
let earlier_block = harness
|
||||
.chain
|
||||
.block_at_slot(earlier_slot, WhenSlotSkipped::Prev)
|
||||
.expect("should not error getting block at slot")
|
||||
.expect("should find block at slot");
|
||||
let earlier_block_root = earlier_block.canonical_root();
|
||||
assert_ne!(earlier_block_root, finalized_checkpoint.root);
|
||||
|
||||
let mut state = harness
|
||||
.chain
|
||||
.get_state(&earlier_block.state_root(), Some(earlier_slot))
|
||||
.expect("should not error getting state")
|
||||
.expect("should find state");
|
||||
|
||||
while state.slot() < current_slot {
|
||||
per_slot_processing(&mut state, None, &harness.spec).expect("should process slot");
|
||||
}
|
||||
|
||||
let state_root = state.update_tree_hash_cache().unwrap();
|
||||
|
||||
let (attestation, subnet_id) = harness
|
||||
.get_unaggregated_attestations(
|
||||
&AttestationStrategy::AllValidators,
|
||||
&state,
|
||||
state_root,
|
||||
earlier_block_root,
|
||||
current_slot,
|
||||
)
|
||||
.first()
|
||||
.expect("should have at least one committee")
|
||||
.first()
|
||||
.cloned()
|
||||
.expect("should have at least one attestation in committee");
|
||||
assert_eq!(attestation.data.beacon_block_root, earlier_block_root);
|
||||
|
||||
// Attestation should be rejected for attesting to a pre-finalization block.
|
||||
let res = harness
|
||||
.chain
|
||||
.verify_unaggregated_attestation_for_gossip(&attestation, Some(subnet_id));
|
||||
assert!(
|
||||
matches!(res, Err(AttnError:: HeadBlockFinalized { beacon_block_root })
|
||||
if beacon_block_root == earlier_block_root
|
||||
)
|
||||
);
|
||||
|
||||
// Pre-finalization block cache should contain the block root.
|
||||
assert!(harness
|
||||
.chain
|
||||
.pre_finalization_block_cache
|
||||
.contains(earlier_block_root));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verify_aggregate_for_gossip_doppelganger_detection() {
|
||||
let harness = get_harness(VALIDATOR_COUNT);
|
||||
|
||||
Reference in New Issue
Block a user