@@ -437,11 +437,27 @@ def on_block(self, signed_block_with_attestation: SignedBlockWithAttestation) ->
437437 # Execute state transition function to compute post-block state
438438 post_state = copy .deepcopy (parent_state ).state_transition (block , valid_signatures )
439439
440+ # If the new post-state has a higher justified checkpoint, update the store's latest justified checkpoint.
441+ latest_justified = (
442+ post_state .latest_justified
443+ if post_state .latest_justified .slot > self .latest_justified .slot
444+ else self .latest_justified
445+ )
446+
447+ # If the new post-state has a higher finalized checkpoint, update the store's latest finalized checkpoint.
448+ latest_finalized = (
449+ post_state .latest_finalized
450+ if post_state .latest_finalized .slot > self .latest_finalized .slot
451+ else self .latest_finalized
452+ )
453+
440454 # Create new store with block and state
441455 store = self .model_copy (
442456 update = {
443457 "blocks" : self .blocks | {block_root : block },
444458 "states" : self .states | {block_root : post_state },
459+ "latest_justified" : latest_justified ,
460+ "latest_finalized" : latest_finalized ,
445461 }
446462 )
447463
@@ -589,64 +605,26 @@ def update_head(self) -> "Store":
589605
590606 Algorithm
591607 ---------
592- 1. **Justification**: Scan all states to find highest justified checkpoint
593- 2. **Fork Choice**: Run LMD-GHOST from justified root using attestation weights
594- 3. **Finalization**: Extract finalized checkpoint from selected head state
595- 4. **Return**: New Store instance with updated checkpoints and head
608+ 1. **Fork Choice**: Run LMD-GHOST from justified root using attestation weights
609+ 2. **Return**: New Store instance with updated head
596610
597611 Returns:
598- New Store with updated head, latest_justified, and latest_finalized .
612+ New Store with updated head.
599613
600614 """
601- # Find the Latest Justified Checkpoint
602- #
603- # We must first determine the anchor point for our fork choice algorithm.
604- # This anchor is the justified checkpoint (a block root and slot) with the
605- # highest slot number known across *all* known states.
606- #
607- # We find this by:
608- # a) Scanning all known states.
609- # b) Finding the state that contains the justified checkpoint with the
610- # highest slot number.
611- # c) Extracting that specific checkpoint object to use as our anchor.
612- #
613- # If there are no states to scan (e.g., at initialization), the
614- # operation would fail. In this case, we fall back to using the
615- # store's currently recorded justified checkpoint, preserving the
616- # last known good anchor.
617- latest_justified = (
618- max (self .states .values (), key = lambda s : s .latest_justified .slot ).latest_justified
619- if self .states
620- else self .latest_justified
621- )
622-
623615 # Run LMD-GHOST fork choice algorithm
624616 #
625617 # Selects canonical head by walking the tree from the justified root,
626618 # choosing the heaviest child at each fork based on attestation weights.
627619 new_head = self ._compute_lmd_ghost_head (
628- start_root = latest_justified .root ,
620+ start_root = self . latest_justified .root ,
629621 attestations = self .latest_known_attestations ,
630622 )
631623
632- # Extract finalized checkpoint from head state
633- #
634- # The head state tracks the highest finalized checkpoint. If the
635- # head changed, we may have a new finalized checkpoint.
636- #
637- # Fallback to current finalized if head state unavailable (defensive).
638- latest_finalized = (
639- self .states [new_head ].latest_finalized
640- if new_head in self .states
641- else self .latest_finalized
642- )
643-
644624 # Return new Store instance with updated values (immutable update)
645625 return self .model_copy (
646626 update = {
647627 "head" : new_head ,
648- "latest_justified" : latest_justified ,
649- "latest_finalized" : latest_finalized ,
650628 }
651629 )
652630
0 commit comments