Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 33 additions & 17 deletions crates/net/rpc/static/fork_choice.html
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@

let svg, gLinks, gNodes, gAxis;
let currentData = null;
let hoveredRoot = null;

function initSVG() {
svg = d3.select("#chart-container")
Expand All @@ -212,8 +213,17 @@
return COLORS.default;
}

function weightRatio(node, validatorCount) {
if (!validatorCount) return 0;
function nodeStroke(node, data) {
const color = nodeColor(node, data);
return d3.color(color).darker(0.5).toString();
}

function nodeRatio(node, data) {
// Finalized blocks have full support by definition — fill completely
// rather than scaling by fork-choice weight (which is 0 at the root).
if (node.slot <= data.finalized.slot) return 1;
const validatorCount = data.validator_count;
if (!validatorCount || validatorCount === 0) return 0;
return Math.max(0, Math.min(1, node.weight / validatorCount));
}

Expand Down Expand Up @@ -309,7 +319,8 @@
x: d.x,
y: d.y,
_color: nodeColor(d.data, data),
_ratio: weightRatio(d.data, data.validator_count)
_stroke: nodeStroke(d.data, data),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 _stroke is computed but never applied

_stroke is stored on each flat node but the render code references d._color for both the initial enter and the transition update of .node-outer. The nodeStroke function (and this property) are therefore dead code — the darker outline never actually appears.

Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/net/rpc/static/fork_choice.html
Line: 322

Comment:
**`_stroke` is computed but never applied**

`_stroke` is stored on each flat node but the render code references `d._color` for both the initial enter and the transition update of `.node-outer`. The `nodeStroke` function (and this property) are therefore dead code — the darker outline never actually appears.

How can I resolve this? If you propose a fix, please make it concise.

_ratio: nodeRatio(d.data, data)
}));

const links = [];
Expand All @@ -334,21 +345,26 @@
return { nodes: flatNodes, links, width: svgWidth, height: svgHeight, slots };
}

// Tracked so render() can refresh the tooltip on each poll without
// requiring the user to move the mouse.
let hoveredRoot = null;

function tooltipHtml(d, total) {
const pct = total ? parseFloat(((d.weight / total) * 100).toFixed(2)) : 0;
function tooltipHtml(d, data) {
const isFinalized = d.slot <= data.finalized.slot;
let lastLine;
if (isFinalized) {
lastLine = `<span class="tt-label">status:</span> finalized`;
} else {
const total = data.validator_count;
const pct = total ? parseFloat(((d.weight / total) * 100).toFixed(2)) : 0;
const suffix = total != null ? `/${total} (${pct}%)` : "";
lastLine = `<span class="tt-label">weight:</span> ${d.weight}${suffix}`;
}
return `<span class="tt-label">root:</span> ${truncateRoot(d.root)}<br>` +
`<span class="tt-label">slot:</span> ${d.slot}<br>` +
`<span class="tt-label">proposer:</span> ${d.proposer_index}<br>` +
`<span class="tt-label">weight:</span> ${d.weight}${total != null ? `/${total} (${pct}%)` : ''}`;
lastLine;
}

function showTooltip(event, d) {
function showTooltip(event, d, data) {
hoveredRoot = d.root;
tooltip.innerHTML = tooltipHtml(d, currentData?.validator_count);
tooltip.innerHTML = tooltipHtml(d, data);
tooltip.style.opacity = 1;
tooltip.style.left = (event.clientX + 14) + "px";
tooltip.style.top = (event.clientY - 14) + "px";
Expand Down Expand Up @@ -464,7 +480,7 @@
nodeEnter.append("circle")
.attr("class", "node-outer")
.attr("r", NODE_RADIUS)
.attr("stroke", d => d._color);
.attr("stroke", d => d._stroke);

// Invisible hit target so hover works regardless of fill level.
nodeEnter.append("circle")
Expand All @@ -479,8 +495,8 @@
const nodeMerged = nodeEnter.merge(nodeGroups);

nodeMerged
.on("mouseover", function (event, d) { showTooltip(event, d); })
.on("mousemove", function (event, d) { showTooltip(event, d); })
.on("mouseover", function (event, d) { showTooltip(event, d, data); })
.on("mousemove", function (event, d) { showTooltip(event, d, data); })
.on("mouseout", hideTooltip);

nodeMerged
Expand All @@ -505,15 +521,15 @@
.transition()
.delay(TRANSITION_DURATION)
.duration(100)
.attr("stroke", d => d._color);
.attr("stroke", d => d._stroke);

nodeMerged.select("text")
.text(d => truncateRoot(d.root));

// Keep the tooltip live while the user holds the mouse still over a node.
if (hoveredRoot) {
const hovered = layout.nodes.find(n => n.root === hoveredRoot);
if (hovered) tooltip.innerHTML = tooltipHtml(hovered, data.validator_count);
if (hovered) tooltip.innerHTML = tooltipHtml(hovered, data);
}

// Auto-scroll to head node
Expand Down