Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/lean_spec/spec/forks/lstar/block_production.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ def build_block(
if attestation_data.head.root not in known_block_roots:
continue

# Skip votes whose source slot is not the current justified checkpoint.
if attestation_data.source.slot != current_justified_checkpoint.slot:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought adding this would allow us to simplify the checks here. Otherwise, this just adds more code, right?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct, it's just easy to reason through it this way. I intentionally did not add any test to enforce it as it is optional and up to client implementation

continue

# Reject votes that do not match this chain.
#
# This also rejects any checkpoint past the chain view.
Expand Down
17 changes: 0 additions & 17 deletions src/lean_spec/spec/forks/lstar/validator_duties.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,23 +170,6 @@ def produce_block_with_signatures(
aggregated_payloads=store.latest_known_aggregated_payloads,
)

# Invariant: the produced block must close any justified divergence.
#
# The store may have advanced its justified checkpoint from attestations
# on a minority fork that the head state never processed. The fixed-point
# loop above must incorporate those attestations from the pool, advancing
# the block's justified checkpoint to at least match the store.
#
# Without this, other nodes processing the block would never see the
# justification advance, degrading consensus liveness: only nodes that
# happened to receive the minority fork would know justification moved.
block_justified = final_post_state.latest_justified.slot
store_justified = store.latest_justified.slot
assert block_justified >= store_justified, (
f"Produced block justified={block_justified} < store justified="
f"{store_justified}. Fixed-point attestation loop did not converge."
)

# Compute block hash for storage.
block_hash = hash_tree_root(final_block)

Expand Down
Loading