solana-validator-optimizer 2.2.1

Optimized Solana validator tool with snapshot prefetching, RPC caching, and Prometheus metrics.
Documentation
use crate::config::AppConfig;
use once_cell::sync::Lazy;
use prometheus::IntCounter;

#[cfg(feature = "metrics")]
use prometheus::{Encoder, TextEncoder};

/// Core metrics — registered globally.
///
/// These metrics belong to the public/open-source core crate.
/// Public metrics must not depend on private/pro crates because the public
/// crate must compile and publish independently on crates.io.
pub static REQUEST_COUNTER: Lazy<IntCounter> = Lazy::new(|| {
    prometheus::register_int_counter!("rpc_requests_total", "Total number of RPC requests handled")
        .expect("failed to register rpc_requests_total")
});

pub static CACHE_HIT_COUNTER: Lazy<IntCounter> = Lazy::new(|| {
    prometheus::register_int_counter!("rpc_cache_hits_total", "Total RPC cache hits")
        .expect("failed to register rpc_cache_hits_total")
});

pub static CACHE_MISS_COUNTER: Lazy<IntCounter> = Lazy::new(|| {
    prometheus::register_int_counter!("rpc_cache_misses_total", "Total RPC cache misses")
        .expect("failed to register rpc_cache_misses_total")
});

/// Public entry point.
///
/// When the `metrics` feature is enabled, this starts the HTTP metrics endpoint.
/// When the `metrics` feature is disabled, this is a no-op.
pub async fn start_metrics_server(config: &AppConfig) -> anyhow::Result<()> {
    start_metrics_server_impl(config).await
}

//
// ===== Feature: metrics HTTP server enabled =====
//

#[cfg(feature = "metrics")]
async fn start_metrics_server_impl(config: &AppConfig) -> anyhow::Result<()> {
    use axum::{routing::get, Router};
    use std::net::SocketAddr;
    use tokio::net::TcpListener;

    let app = Router::new().route("/metrics", get(serve_metrics));
    let addr = SocketAddr::from(([0, 0, 0, 0], config.metrics_port));

    println!("Metrics server running at http://{}/metrics", addr);

    let listener = TcpListener::bind(addr).await?;
    axum::serve(listener, app).await?;

    Ok(())
}

#[cfg(feature = "metrics")]
async fn serve_metrics() -> String {
    let encoder = TextEncoder::new();
    let metric_families = prometheus::gather();
    let mut buffer = Vec::new();

    encoder
        .encode(&metric_families, &mut buffer)
        .expect("failed to encode metrics");

    String::from_utf8(buffer).expect("failed to convert metrics to UTF-8")
}

//
// ===== No metrics feature: library-only mode =====
//

#[cfg(not(feature = "metrics"))]
async fn start_metrics_server_impl(_config: &AppConfig) -> anyhow::Result<()> {
    // No-op when the metrics feature is not enabled.
    Ok(())
}