Skip to content

Commit 036658b

Browse files
tcoratgerclaude
andauthored
refactor(testing): derive tiebreaker weights from the spec (leanEthereum#863)
* refactor(testing): derive tiebreaker weights from the spec The lexicographic head check re-derived per-fork attestation weights by walking ancestors manually, duplicating the fork choice weight rule. A spec change to weight accounting would silently diverge from the re-derivation and the check would assert against stale logic. The check now asks the spec for its block weights directly, so it can never drift from the rule it validates. The unused per-fork slot bookkeeping disappears with the manual walk. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(testing): polish store checks documentation Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 38287b1 commit 036658b

1 file changed

Lines changed: 10 additions & 29 deletions

File tree

packages/testing/src/consensus_testing/test_types/store_checks.py

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -580,43 +580,24 @@ def _validate_lexicographic_head(
580580
f"to test tiebreaker behavior, got {len(fork_labels)}: {fork_labels}"
581581
)
582582

583-
# Resolve all fork labels to roots and compute their weights
584-
fork_data: dict[str, tuple[Bytes32, Slot, int]] = {}
583+
# Resolve all fork labels to roots and compute their weights.
584+
spec_block_weights = LstarSpec().compute_block_weights(store)
585+
586+
fork_data: dict[str, tuple[Bytes32, int]] = {}
585587
for label in fork_labels:
586588
if label not in block_registry:
587589
raise ValueError(
588590
f"Step {step_index}: lexicographic_head_among label '{label}' "
589591
f"not found in block registry. Available: {list(block_registry.keys())}"
590592
)
591593

592-
block = block_registry[label]
593-
root = hash_tree_root(block)
594-
slot = block.slot
595-
596-
spec = LstarSpec()
597-
known_attestations = spec.extract_attestations_from_aggregated_payloads(
598-
store, store.latest_known_aggregated_payloads
599-
)
600-
weight = 0
601-
for attestation in known_attestations.values():
602-
attestation_head_root = attestation.head.root
603-
if attestation_head_root == root:
604-
weight += 1
605-
elif attestation_head_root in store.blocks:
606-
ancestor_root = attestation_head_root
607-
while ancestor_root in store.blocks and store.blocks[ancestor_root].slot > slot:
608-
parent = store.blocks[ancestor_root].parent_root
609-
if parent == root:
610-
weight += 1
611-
break
612-
ancestor_root = parent
613-
614-
fork_data[label] = (root, slot, weight)
594+
fork_root = hash_tree_root(block_registry[label])
595+
fork_data[label] = (fork_root, spec_block_weights.get(fork_root, 0))
615596

616597
# Verify all forks have equal weight
617-
weights = [weight for _, _, weight in fork_data.values()]
598+
weights = [weight for _, weight in fork_data.values()]
618599
if len(set(weights)) > 1:
619-
weight_info = {label: weight for label, (_, _, weight) in fork_data.items()}
600+
weight_info = {label: weight for label, (_, weight) in fork_data.items()}
620601
raise AssertionError(
621602
f"Step {step_index}: lexicographic_head_among forks have "
622603
f"unequal weights: {weight_info}. All forks must have equal "
@@ -625,7 +606,7 @@ def _validate_lexicographic_head(
625606
f"applies when competing forks have identical weight."
626607
)
627608

628-
fork_roots = {label: root for label, (root, _, _) in fork_data.items()}
609+
fork_roots = {label: root for label, (root, _) in fork_data.items()}
629610
expected_head_root = max(fork_roots.values())
630611

631612
actual_head_root = store.head
@@ -639,7 +620,7 @@ def _validate_lexicographic_head(
639620
)
640621
fork_info = "\n".join(
641622
f" {label}: root=0x{root.hex()} weight={weight}"
642-
for label, (root, _, weight) in sorted(fork_data.items())
623+
for label, (root, weight) in sorted(fork_data.items())
643624
)
644625
raise AssertionError(
645626
f"Step {step_index}: lexicographic tiebreaker failed.\n"

0 commit comments

Comments
 (0)