Commit 692f201
fix(forkchoice-viz): expose all role overlaps per block (lambdaclass#341)
## 🗒️ Description / Motivation
Each block in the fork choice tree can hold multiple roles at the same
time - the latest block is usually both the head and the safe target,
for instance. Until now the visualization only painted one color per
block, picked by a fixed priority (head > safe target > justified >
finalized), so whichever roles weren't on top got silently dropped. That
made it impossible to tell from the visualisation that a block was both
head and safe target, or to find the safe target at all when it
coincided with the head.
This PR makes every role visible. The primary color (the inner filled
circle) now follows a different priority - **finalized > justified >
safe target > head** (strongest commitment first) and any additional
roles the block holds are drawn as concentric rings around the primary
one, each in that role's color. The tooltip's `status:` line lists all
the roles, with each name colored to match its ring.
**Preview:**
<img width="427" height="473" alt="Screenshot 2026-05-01 at 16 43 16"
src="https://github.com/user-attachments/assets/f674d31f-853c-4dc7-b290-3130d60da024"
/>
<img width="474" height="780" alt="Screenshot 2026-05-01 at 17 10 44"
src="https://github.com/user-attachments/assets/8b88af48-01a8-473a-8327-094e604c1bcd"
/>
<img width="301" height="170" alt="Screenshot 2026-05-01 at 17 10 51"
src="https://github.com/user-attachments/assets/46bf1695-8514-4664-9013-5941dd88745d"
/>
## What Changed
- **New `nodeRoles(node, data)` helper** returning all roles a block
holds, ordered by *natural priority* (`finalized > justified >
safeTarget > head` — strongest commitment first). The first entry drives
the primary color; the rest become halo rings.
- **Concentric halo rings** outside the primary ring, one per secondary
role, in that role's color. Always present in the DOM (transparent when
unused) so role changes between polls just update stroke. Offsets `[6,
12, 18]` give comfortable spacing.
- **Tooltip `status:` line** lists all roles for the hovered block, each
colored with its role color (e.g., `safe target, head` rendered in
yellow + orange).
## Correctness / Behavior Guarantees
- **Viz-only change.** No consensus or weight-computation changes.
- **Primary color priority flipped** vs. main: previously `head >
safe_target > justified > finalized`; now `finalized > justified >
safeTarget > head`. A block that is both head + safe_target (the common
case) now renders **yellow primary with an orange halo** rather than the
previous pure-orange (which shadowed safe_target).
## Tests Added / Run
- No tests (client-side rendering only).
- Manual: ran a local single-node devnet (4 validators), confirmed halos
render correctly when head + safe_target overlap, tooltip lists multiple
colored roles, justified-only and finalized-only blocks render as
expected, no layout shift between polls.
## Related Issues / PRs
- Closes lambdaclass#334
---------
Co-authored-by: Pablo Deymonnaz <pdeymon@fi.uba.ar>1 parent e60b96b commit 692f201
1 file changed
Lines changed: 98 additions & 27 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
100 | 100 | | |
101 | 101 | | |
102 | 102 | | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
103 | 109 | | |
104 | 110 | | |
105 | 111 | | |
| |||
205 | 211 | | |
206 | 212 | | |
207 | 213 | | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
208 | 229 | | |
209 | 230 | | |
210 | 231 | | |
| |||
233 | 254 | | |
234 | 255 | | |
235 | 256 | | |
236 | | - | |
237 | | - | |
238 | | - | |
239 | | - | |
240 | | - | |
241 | | - | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
242 | 267 | | |
243 | 268 | | |
244 | 269 | | |
| |||
333 | 358 | | |
334 | 359 | | |
335 | 360 | | |
336 | | - | |
337 | | - | |
338 | | - | |
339 | | - | |
340 | | - | |
341 | | - | |
342 | | - | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
343 | 373 | | |
344 | 374 | | |
345 | 375 | | |
| |||
367 | 397 | | |
368 | 398 | | |
369 | 399 | | |
370 | | - | |
371 | | - | |
372 | | - | |
373 | | - | |
374 | | - | |
375 | | - | |
| 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 | + | |
376 | 427 | | |
377 | 428 | | |
378 | | - | |
| 429 | + | |
379 | 430 | | |
380 | | - | |
| 431 | + | |
381 | 432 | | |
382 | 433 | | |
383 | 434 | | |
| |||
539 | 590 | | |
540 | 591 | | |
541 | 592 | | |
542 | | - | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
543 | 606 | | |
544 | 607 | | |
545 | | - | |
| 608 | + | |
546 | 609 | | |
547 | 610 | | |
548 | 611 | | |
549 | | - | |
| 612 | + | |
550 | 613 | | |
551 | 614 | | |
552 | 615 | | |
553 | 616 | | |
554 | 617 | | |
555 | | - | |
556 | | - | |
| 618 | + | |
| 619 | + | |
557 | 620 | | |
558 | 621 | | |
559 | 622 | | |
| |||
580 | 643 | | |
581 | 644 | | |
582 | 645 | | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
583 | 654 | | |
584 | 655 | | |
585 | 656 | | |
586 | 657 | | |
587 | 658 | | |
588 | 659 | | |
589 | | - | |
| 660 | + | |
590 | 661 | | |
591 | 662 | | |
592 | 663 | | |
| |||
0 commit comments