net-rs: fix fork-mismatch sticking in chain selection
When the contiguity guard detects that all replay blocks have bodies but chain_tree.ancestors() doesn't reach the common ancestor, this means the replay chain goes through a different fork than the ancestor (stale PeerChain entries from an abandoned fork mixed with new ones). Previously this returned WaitingForBlocks and issued a range fetch that could never succeed (no blocks connect two different forks), causing nodes to loop forever on the same failing fetch. Now returns OrphanCandidate instead, and the OrphanCandidate handler always clears PeerChain entries and requests re-intersection. This forces ChainSync to rebuild from a fresh intersection point, resolving the stale-entry contamination. Cluster test (p=0.2, 25 nodes, 20 min): 24/25 nodes at tip with 289 blocks and 5104 fork switches, zero gap-to-ancestor events. Previous behavior: 6-10 permanently stuck nodes. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>