Commit ae6ac42
authored
fix(state-transition): preserve monotonicity of latest_justified within a block (lambdaclass#390)
## Description
We recently found a bug in the spec and made a PR patching it:
leanEthereum/leanSpec#781. This PR updates our
code matching those changes.
## What changed
- `process_attestations` unconditionally assigned
`state.latest_justified = target` on every supermajority threshold
crossing. When a block carried multiple supermajority attestations whose
targets were not in increasing slot order, a later attestation clobbered
an earlier one and the post-state ended below the highest justified
target.
- The store latches `latest_justified` monotonically across all branches
(`crates/blockchain/src/store.rs:485-491`). Once any branch advanced the
store ahead of the canonical chain's post-state, every subsequent
proposal failed `JustifiedDivergenceNotClosed` and the chain froze
permanently.
- Fix: guard the assignment so `latest_justified` only advances.
`justified_slots` continues to be updated unconditionally — multiple
slots can be independently justified within a block.
## Observed failure
Devnet froze at slot 27969 (finalized) / 27978 (justified) / 27984
(head). Investigation:
- Canonical head `0xef43cf66` (slot 27984) carried 3 supermajority
attestations in body order targeting slots **27978, 27981, 27974** (all
justifiable from `source=27972`).
- After `process_attestations`, post-state `latest_justified = (27974,
...)` instead of `(27981, ...)`, because the last-applied attestation
overwrote the higher justifications.
- Meanwhile, fork block `0xe88cff27` at slot 27983 had advanced the
store's `latest_justified` to 27978.
- From then on, every proposer's `build_block` produced
`justified=27974` and failed the `JustifiedDivergenceNotClosed` check at
`crates/blockchain/src/store.rs:737`. **37,787** proposal failures
across 4 validators over 4 days before recovery.
## Test plan
- [x] New regression test
`latest_justified_does_not_regress_within_block` in
`state_transition/src/lib.rs`: 4-validator state, three supermajority
attestations in body order targeting slots 4 → 9 → 6. Fails on `main`
(ends at slot 6); passes with the fix (stays at slot 9).
- [x] `cargo test -p ethlambda-state-transition --lib` — 1/1 pass
- [x] `cargo test -p ethlambda-state-transition --test stf_spectests` —
51/51 pass
- [x] `cargo clippy -p ethlambda-state-transition --all-targets -- -D
warnings` — clean1 parent 7bb14c3 commit ae6ac42
3 files changed
Lines changed: 151 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
25 | 26 | | |
26 | 27 | | |
27 | 28 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
304 | 304 | | |
305 | 305 | | |
306 | 306 | | |
307 | | - | |
308 | | - | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
309 | 310 | | |
310 | 311 | | |
311 | 312 | | |
| |||
537 | 538 | | |
538 | 539 | | |
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 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
| 682 | + | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
0 commit comments