A comprehensive tool for monitoring and visualizing client diversity in the SSV (Secret Shared Validators) network. This project helps ensure network health by tracking the distribution of different SSV client implementations.
This project consists of two main components:
- SSV Identifier (Rust): Network crawler that discovers SSV peers, identifies client types (Anchor, GoSSV, Unknown), and stores data in SQLite
- Dashboard (Node.js): Web-based visualization dashboard for real-time client diversity metrics
┌─────────────────────────────────────────────────────────────────┐
│ SSV Network │
│ (Distributed validators using libp2p) │
└────────────────────────┬────────────────────────────────────────┘
│ discovers & handshakes
▼
┌─────────────────────────────────────────────────────────────────┐
│ SSV Identifier (Rust Crawler) │
│ • Discovers peers via discv5 │
│ • Performs libp2p handshakes │
│ • Identifies client types & versions │
│ • Tracks subnet membership │
│ • Records network snapshots │
└────────────────────────┬────────────────────────────────────────┘
│ writes to
▼
┌─────────────────────────────────────────────────────────────────┐
│ SQLite Database (clients.db) │
│ • peers table │
│ • subnet_membership table │
│ • network_snapshots table │
└────────────────────────┬────────────────────────────────────────┘
│ reads from (read-only)
▼
┌─────────────────────────────────────────────────────────────────┐
│ Dashboard (Node.js + Nginx) │
│ • REST API for metrics │
│ • Real-time visualizations │
│ • Auto-refresh every 30s │
│ • Supermajority warnings │
└────────────────────────┬────────────────────────────────────────┘
│ displays to
▼
┌─────────────────────────────────────────────────────────────────┐
│ Browser (Users) │
│ http://localhost (or your domain) │
└─────────────────────────────────────────────────────────────────┘
- Peer Discovery: Uses discv5 to discover SSV network peers
- Client Identification: Detects Anchor and GoSSV clients via handshake analysis
- Version Tracking: Extracts semantic versions from client strings
- Subnet Monitoring: Tracks which subnets each peer participates in
- Historical Snapshots: Periodic network composition snapshots
- Persistent Storage: SQLite database for efficient querying
- Client Distribution: Horizontal bar chart showing Anchor vs GoSSV vs Unknown
- Version Analytics: Top 10 versions for each client type
- Historical Trends: 24-hour time-series of client diversity
- Subnet Participation: Peer distribution across top 20 subnets
git clone <repository-url>
cd ssv-client-diversityThe identifier discovers peers and populates the database.
# Navigate to identifier directory
cd ssv-identifier
# Build the project
cargo build --release
# Run the identifier
cargo run --releaseThe identifier will:
- Start discovering SSV network peers
- Perform handshakes to identify client types
- Store data in
~/.ssv-identifier/clients.db - Take periodic network snapshots
- Log activity to console and files
Let it run for at least 10-15 minutes to collect initial data before starting the dashboard.
# Open a new terminal
cd dashboard/app
# Install dependencies
npm install
# Start the development server
npm run dev
# Dashboard available at http://localhost:3000# Navigate to dashboard directory
cd dashboard
# Build and start containers
docker-compose up -d
# Dashboard available at http://localhostView logs:
docker-compose logs -fStop containers:
docker-compose downOpen your browser and navigate to:
- Development: http://localhost:3000
- Docker: http://localhost
You should see real-time metrics and visualizations of the SSV network client diversity!
The identifier can be configured via command-line arguments or environment variables.
# View all available options
cargo run --release -- --help
# Run with custom database path
cargo run --release -- --db-path /custom/path/ssv-peers.db
# Run with verbose logging
RUST_LOG=debug cargo run --release
# Run with custom snapshot interval
cargo run --release -- --snapshot-interval 600 # 10 minutesCreate a .env file in dashboard/app/:
NODE_ENV=production
PORT=3000
SSV_DB_PATH=~/.ssv-identifier/clients.db
CACHE_REFRESH_INTERVAL=60000Edit dashboard/docker-compose.yml to customize:
dashboard:
environment:
- PORT=3000
- SSV_DB_PATH=/app/data/clients.db
- CACHE_REFRESH_INTERVAL=60000 # 60 seconds
volumes:
# Mount custom data directory if identifier uses --data-dir
- /custom/path:/app/data:ro
ports:
- "8080:3000" # Change external port if neededcd ssv-identifier
# Debug build
cargo build
# Release build (optimized)
cargo build --release
# Run tests
cargo test
# Check code
cargo check
# Format code
cargo fmt
# Lint code
cargo clippycd dashboard/app
# Install dependencies
npm install
# Development mode (auto-reload)
npm run dev
# Production mode
npm start
# Build Docker image
cd ..
docker build -t ssv-dashboard .ssv-client-diversity/
├── ssv-identifier/ # Rust network crawler
│ ├── src/
│ │ ├── main.rs # Entry point
│ │ ├── network.rs # Network discovery
│ │ ├── database.rs # SQLite operations
│ │ ├── handshake.rs # Client identification
│ │ ├── metrics.rs # Network metrics
│ │ └── ...
│ ├── Cargo.toml # Rust dependencies
│ └── data/ # Optional custom data directory
│ └── clients.db # SQLite database (default: ~/.ssv-identifier/clients.db)
├── dashboard/ # Node.js dashboard
│ ├── app/
│ │ ├── server.js # Express API
│ │ ├── package.json # Node dependencies
│ │ ├── public/ # Static assets
│ │ │ ├── css/style.css
│ │ │ └── js/dashboard.js
│ │ └── views/
│ │ └── index.html # Main page
│ ├── nginx/
│ │ └── nginx.conf # Reverse proxy
│ ├── Dockerfile # Container image
│ ├── docker-compose.yml # Orchestration
│ └── README.md # Dashboard docs
└── README.md # This file
See dashboard/README.md for complete API documentation.
Quick reference:
GET /api/stats- Current network statisticsGET /api/client-versions- Version distributionsGET /api/historical-trends?hours=24- Time-series dataGET /api/subnet-stats- Subnet participationGET /health- Health check
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Built with ❤️ by Sigma Prime