refactor(block_tree): compute reorg split via parent-walk LCA#1432
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughCompute reorg split with new ReorgSplit abstraction before pruning, validate fork-point against post-prune cache window, prune, derive fork/divergent suffixes from ReorgSplit, remove old prune helper and tests, and add integration assertions enforcing that reorg_event.fork_parent is the LCA. ChangesReorg fork-point refactoring
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
|
like that this yanks out a bunch of complexity |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/chain-tests/src/multi_node/fork_recovery.rs`:
- Around line 340-365: The current if let (Some(first_old), Some(first_new)) =
(reorg_event.old_fork.first(), reorg_event.new_fork.first()) can silently skip
LCA assertions when either fork is empty; instead assert that both
reorg_event.old_fork and reorg_event.new_fork are non-empty up front (e.g.,
assert!(!reorg_event.old_fork.is_empty(), ...) and
assert!(!reorg_event.new_fork.is_empty(), ...)) to fail the test immediately if
find_reorg_split contract is violated, then unwrap or call .first().unwrap() to
bind first_old/first_new and proceed with the existing fork_parent checks
(referencing reorg_event, old_fork, new_fork, fork_parent, and
find_reorg_split).
In `@crates/chain-tests/src/multi_node/mempool_tests.rs`:
- Around line 968-993: The test currently uses a defensive `if let
(Some(first_old), Some(first_new)) = (reorg_event.old_fork.first(),
reorg_event.new_fork.first())` which can silently skip LCA checks if either fork
is empty; instead, assert that both forks are non-empty up front (e.g.
assert!(!reorg_event.old_fork.is_empty()) and
assert!(!reorg_event.new_fork.is_empty())), then safely obtain
first_old/first_new (via unwrap() or by calling first() after the asserts) and
perform the existing assertions comparing reorg_event.fork_parent.block_hash and
height to first_old.header().previous_block_hash / first_old.header().height and
similarly for first_new; this ensures violations of the find_reorg_split
contract fail the test rather than being ignored.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 8725ec61-663a-4b5e-aa05-0d535d2387ba
📒 Files selected for processing (4)
crates/actors/src/block_tree_service.rscrates/chain-tests/src/multi_node/fork_recovery.rscrates/chain-tests/src/multi_node/mempool_tests.rscrates/domain/src/models/block_tree.rs
Describe the changes
Before: LCA derived from ChainState::Onchain flag scan via get_fork_blocks, fed into prune_chains_at_ancestor. Stale flags → wrong LCA →Err("common ancestor X not in new chain") → service exit.
After: BlockTree::find_reorg_split walks both lineages through previous_block_hash links, intersects them, returns LCA's sealed block + oldest-first LCA-exclusive divergent suffixes. Caller invokes it before cache.prune. prune_chains_at_ancestor deleted.
Related Issue(s)
Please link to the issue(s) that will be closed with this PR.
Checklist
Additional Context
Add any other context about the pull request here.
Summary by CodeRabbit
Improvements
Tests