diff --git a/beacon_node/beacon_chain/src/canonical_head.rs b/beacon_node/beacon_chain/src/canonical_head.rs index 709382f05..655948798 100644 --- a/beacon_node/beacon_chain/src/canonical_head.rs +++ b/beacon_node/beacon_chain/src/canonical_head.rs @@ -719,6 +719,9 @@ impl BeaconChain { drop(old_cached_head); // If the finalized checkpoint changed, perform some updates. + // + // The `after_finalization` function will take a write-lock on `fork_choice`, therefore it + // is a dead-lock risk to hold any other lock on fork choice at this point. if new_view.finalized_checkpoint != old_view.finalized_checkpoint { if let Err(e) = self.after_finalization(&new_cached_head, new_view, finalized_proto_block) @@ -878,6 +881,9 @@ impl BeaconChain { /// Perform updates to caches and other components after the finalized checkpoint has been /// changed. + /// + /// This function will take a write-lock on `canonical_head.fork_choice`, therefore it would be + /// unwise to hold any lock on fork choice while calling this function. fn after_finalization( self: &Arc, new_cached_head: &CachedHead, @@ -966,6 +972,9 @@ impl BeaconChain { self.head_tracker.clone(), )?; + // Take a write-lock on the canonical head and signal for it to prune. + self.canonical_head.fork_choice_write_lock().prune()?; + Ok(()) }