Skip to content
Merged
Show file tree
Hide file tree
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
20 changes: 14 additions & 6 deletions app/network/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,26 @@

import React from 'react';
import { LightClientSyncIndicator } from '@/src/components/network/LightClientSyncIndicator';
import { NetworkGraph } from '@/src/components/network/NetworkGraph';

export default function NetworkStatus() {
return (
<div className="p-8 max-w-4xl mx-auto">
<div className="p-8 max-w-7xl mx-auto">
<h1 className="text-3xl font-bold mb-8 text-zinc-900 dark:text-zinc-50">Network Status</h1>

<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
<div className="bg-white dark:bg-zinc-900 rounded-xl p-6 shadow-sm border border-zinc-200 dark:border-zinc-800 flex items-center justify-center h-full min-h-[300px]">
<p className="text-zinc-500">Other Network Health Panel</p>
<div className="grid grid-cols-1 gap-8">
<div className="bg-white dark:bg-zinc-900 rounded-xl p-6 shadow-sm border border-zinc-200 dark:border-zinc-800">
<h2 className="mb-4 text-xl font-semibold text-zinc-900 dark:text-zinc-50">Validator topology</h2>
<NetworkGraph />
</div>

<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
<div className="bg-white dark:bg-zinc-900 rounded-xl p-6 shadow-sm border border-zinc-200 dark:border-zinc-800 flex items-center justify-center h-full min-h-[300px]">
<p className="text-zinc-500">Other Network Health Panel</p>
</div>

<LightClientSyncIndicator />
</div>

<LightClientSyncIndicator />
</div>
</div>
);
Expand Down
28 changes: 28 additions & 0 deletions e2e/topology-performance.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { test, expect } from '@playwright/test'

test('10,000 node topology keeps p95 frame time below 33ms', async ({ page }) => {
await page.goto('/network')
await page.getByLabel('High-density validator topology canvas').waitFor()

const p95 = await page.evaluate(async () => {
const samples: number[] = []
let last = performance.now()
const deadline = performance.now() + 30_000
return await new Promise<number>((resolve) => {
const sample = (now: number) => {
samples.push(now - last)
last = now
window.dispatchEvent(new WheelEvent('wheel', { deltaY: Math.sin(now / 500) * 12 }))
if (now >= deadline) {
samples.sort((a, b) => a - b)
resolve(samples[Math.floor(samples.length * 0.95)] ?? 0)
return
}
requestAnimationFrame(sample)
}
requestAnimationFrame(sample)
})
})

expect(p95).toBeLessThan(33)
})
10 changes: 10 additions & 0 deletions src/components/network/NetworkGraph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use client'

import { NodeTopologyMap } from '@/src/components/network/NodeTopologyMap'
import { useNodeTopology } from '@/src/hooks/useNodeTopology'

/** Compatibility wrapper that routes the legacy graph surface to canvas rendering. */
export function NetworkGraph() {
const topology = useNodeTopology()
return <NodeTopologyMap nodes={topology.nodes.map((node) => ({ ...node, x: node.x ?? 0, y: node.y ?? 0 }))} edges={topology.edges} />
}
Loading
Loading