Commit 3bd2cd5
fix(forkchoice): derive finalized from canonical head, not an independent max (leanEthereum#1001)
* fix(forkchoice): derive finalized from canonical head, not an independent max
The store advanced latest_finalized by an independent monotonic max over every
imported block's post-state, decoupling it from the head. A fork that finalized
a higher slot but then lost head selection left its finalized checkpoint latched
in the store. get_attestation_target derives the attestation target against
store.latest_finalized, while the state transition validates targets against the
canonical state's latest_finalized; once the two finalized slots diverged,
is_justifiable_after disagreed and every advancing target was rejected, so
finalization froze.
Derive the finalized checkpoint from the canonical head's chain instead, in
update_head, so it is recomputed on every head change -- block import, acceptance
ticks, and proposals: take the finalized slot named by the head state and recover
its root as the head's own ancestor at that slot. The checkpoint then always lies
on the head chain, store.latest_finalized.slot matches the slot the state
transition validates against, and a checkpoint-sync anchor survives because the
head descends from it (its state cannot name its own block, so the root is
recovered as the head's ancestor). This restores the 3sf-mini reference, where a
staker reads latest_finalized from post_states[head], not a max over states.
Block production carried a second copy of the same independent max: it advanced
store.latest_finalized from the produced block's own state and pruned against it,
stranding -- and over-pruning -- when the proposal lost head selection. Remove
that write; update_head, which get_proposal_head runs just before each proposal,
owns the finalized checkpoint.
The fork choice is not clamped to finalized descendants: leanSpec finalization is
order dependent, so a fork that finalizes a higher slot can still lose head
selection, and clamping would latch the head onto that losing fork. The
attestation source keeps using store.latest_justified (the LMD anchor), matching
3sf-mini's get_latest_justified_hash and the deliberate choice in leanEthereum#595.
* Update src/lean_spec/spec/forks/lstar/fork_choice.py
Co-authored-by: Thomas Coratger <60488569+tcoratger@users.noreply.github.com>
* Update src/lean_spec/spec/forks/lstar/fork_choice.py
Co-authored-by: Thomas Coratger <60488569+tcoratger@users.noreply.github.com>
* refactor(forkchoice): address review -- inline finalized helper, tidy comments
Inline the single-use _finalized_on_head_chain into update_head, folding the head
and finalized updates into one model_copy; trim the verbose comments in
update_head and produce_block. No behavior change.
* fix(forkchoice): guard the finalized walk against a checkpoint-sync boot
The ancestor walk in head recomputation assumed every parent was already in the
store. On a fresh checkpoint-synced node the store holds only the anchor block,
whose state's finalized slot sits below the anchor block slot, so the first head
recompute stepped to a parent root absent from the store and raised KeyError.
The vectors missed it because the test anchor rebases its finalized up to the
anchor slot, so the loop never iterated.
Guard the walk as the other ancestor walks in this file do, stop when the parent
is absent, and keep the trusted anchor when no block sits exactly at the
finalized slot (which also covers a skipped finalized slot).
Add a regression vector: a mid-chain anchor whose finalized stays at genesis,
below the anchor slot, no longer crashes head recomputation.
* test(forkchoice): cover the proposer path not pinning a higher finalized
Build genesis -> block_1 -> block_2 justifying slot 1, then produce block_3 whose
own state finalizes slot 1. Block production does not advance its own head, so
block_3 stays off the head while the head remains block_2, finalized at the
genesis boundary. Assert the store's finalized tracks the head state, not
block_3's higher finalized, and the counted pool is left untouched.
Fails on the pre-fix advance-and-prune in block production, passes on the fix.
---------
Co-authored-by: Thomas Coratger <60488569+tcoratger@users.noreply.github.com>1 parent 003968f commit 3bd2cd5
5 files changed
Lines changed: 362 additions & 20 deletions
File tree
- src/lean_spec/spec/forks/lstar
- tests
- consensus/lstar/fork_choice
- node/validator
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
596 | 596 | | |
597 | 597 | | |
598 | 598 | | |
599 | | - | |
| 599 | + | |
600 | 600 | | |
601 | 601 | | |
602 | 602 | | |
603 | 603 | | |
604 | 604 | | |
605 | 605 | | |
606 | 606 | | |
607 | | - | |
608 | 607 | | |
609 | 608 | | |
610 | 609 | | |
| |||
625 | 624 | | |
626 | 625 | | |
627 | 626 | | |
628 | | - | |
629 | 627 | | |
630 | 628 | | |
631 | 629 | | |
| |||
830 | 828 | | |
831 | 829 | | |
832 | 830 | | |
833 | | - | |
| 831 | + | |
| 832 | + | |
| 833 | + | |
| 834 | + | |
| 835 | + | |
| 836 | + | |
| 837 | + | |
| 838 | + | |
| 839 | + | |
| 840 | + | |
| 841 | + | |
| 842 | + | |
| 843 | + | |
| 844 | + | |
| 845 | + | |
| 846 | + | |
| 847 | + | |
| 848 | + | |
834 | 849 | | |
835 | 850 | | |
836 | 851 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
199 | 199 | | |
200 | 200 | | |
201 | 201 | | |
202 | | - | |
203 | | - | |
204 | | - | |
205 | | - | |
206 | | - | |
207 | | - | |
208 | | - | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
209 | 206 | | |
210 | | - | |
211 | | - | |
212 | | - | |
213 | | - | |
214 | 207 | | |
215 | 208 | | |
216 | 209 | | |
217 | 210 | | |
218 | 211 | | |
219 | | - | |
220 | 212 | | |
221 | 213 | | |
222 | 214 | | |
223 | | - | |
224 | | - | |
225 | | - | |
226 | | - | |
227 | 215 | | |
Lines changed: 49 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
82 | 82 | | |
83 | 83 | | |
84 | 84 | | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
85 | 134 | | |
86 | 135 | | |
87 | 136 | | |
| |||
Lines changed: 189 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
387 | 387 | | |
388 | 388 | | |
389 | 389 | | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
| 542 | + | |
| 543 | + | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
0 commit comments