mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-07 00:42:42 +00:00
Enshrine head state shuffling in the shuffling_cache (#4296)
## Issue Addressed #4281 ## Proposed Changes - Change `ShufflingCache` implementation from using `LruCache` to a custom cache that removes entry with lowest epoch instead of oldest insertion time. - Protect the "enshrined" head shufflings when inserting new committee cache entries. The shuffling ids matching the head's previous, current, and future epochs will never be ejected from the cache during `Self::insert_cache_item`. ## Additional Info There is a bonus point on shuffling preferences in the issue description that hasn't been implemented yet, as I haven't figured out a good way to do this: > However I'm not convinced since there are some complexities around tie-breaking when two entries have the same epoch. Perhaps preferring entries in the canonical chain is best? We should be able to check if a block is on the canonical chain by: ```rust canonical_head .fork_choice_read_lock() .contains_block(root) ``` However we need to interleave the shuffling and fork choice locks, which may cause deadlocks if we're not careful (mentioned by @paulhauner). Alternatively, we could use the `state.block_roots` field of the `chain.canonical_head.snapshot.beacon_state`, which avoids deadlock but requires more work. I'd like to get some feedback on review & testing before I dig deeper into the preferences stuff, as having the canonical head preference may already be quite useful in preventing the issue raised. Co-authored-by: Jimmy Chen <jimmy@sigmaprime.io>
This commit is contained in:
@@ -31,7 +31,9 @@
|
||||
//! the head block root. This is unacceptable for fast-responding functions like the networking
|
||||
//! stack.
|
||||
|
||||
use crate::beacon_chain::ATTESTATION_CACHE_LOCK_TIMEOUT;
|
||||
use crate::persisted_fork_choice::PersistedForkChoice;
|
||||
use crate::shuffling_cache::BlockShufflingIds;
|
||||
use crate::{
|
||||
beacon_chain::{
|
||||
BeaconForkChoice, BeaconStore, OverrideForkchoiceUpdate,
|
||||
@@ -846,6 +848,35 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
);
|
||||
});
|
||||
|
||||
match BlockShufflingIds::try_from_head(
|
||||
new_snapshot.beacon_block_root,
|
||||
&new_snapshot.beacon_state,
|
||||
) {
|
||||
Ok(head_shuffling_ids) => {
|
||||
self.shuffling_cache
|
||||
.try_write_for(ATTESTATION_CACHE_LOCK_TIMEOUT)
|
||||
.map(|mut shuffling_cache| {
|
||||
shuffling_cache.update_head_shuffling_ids(head_shuffling_ids)
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
error!(
|
||||
self.log,
|
||||
"Failed to obtain cache write lock";
|
||||
"lock" => "shuffling_cache",
|
||||
"task" => "update head shuffling decision root"
|
||||
);
|
||||
});
|
||||
}
|
||||
Err(e) => {
|
||||
error!(
|
||||
self.log,
|
||||
"Failed to get head shuffling ids";
|
||||
"error" => ?e,
|
||||
"head_block_root" => ?new_snapshot.beacon_block_root
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
observe_head_block_delays(
|
||||
&mut self.block_times_cache.write(),
|
||||
&new_head_proto_block,
|
||||
|
||||
Reference in New Issue
Block a user