Skip to content

ReserveGrid OS v1.0.0

Choose a tag to compare

@LeavesJ LeavesJ released this 12 Mar 08:45

ReserveGrid OS v1.0.0 — Forge

First stable release of ReserveGrid OS. Full template verification pipeline, three deployment modes, Stratum V2 gateway with Noise encryption, operator dashboard, and production security hardening across 14 workspace crates and 9 Docker services.

Scope

ReserveGrid OS sits between a mining pool's block template source (bitcoind or relay) and its Stratum V2 gateway. It verifies every candidate block template against a configurable policy before the template reaches miners, giving pool operators real time visibility into template quality and the ability to enforce standards on what their miners work on.

The system is designed for progressive deployment. Operators start in shadow mode (read only evaluation), move to observe mode (non enforcing with live pool data), and graduate to inline mode (full enforcement in the block construction pipeline).

Architecture

Core pipeline:

bitcoind → template-manager → pool-verifier → sv2-gateway → miners

Services

Service Role
pool-verifier Template verification engine with configurable TOML policy
sv2-gateway Stratum V2 gateway with Noise NX encryption and share lifecycle
template-manager bitcoind RPC integration for block templates
rg-auth Authentication, license keys, per endpoint rate limiting
rg-dashboard Operator dashboard with embedded React frontend and API proxy
rg-demo-feed Synthetic GBT generator for shadow mode evaluation
rg-feed-adapter WebSocket to JSON RPC bridge
rg-feed-server Authenticated template feed relay for observe mode
rg-load-test HTTP load generator for benchmarking

Libraries

  • rg-protocol — shared wire types, TemplatePropose/TemplateVerdict, and canonical reason codes
  • reservegrid-common — reason code registry, config parsing, CSV/NDJSON/Prometheus exports
  • sv2-bridge — Stratum V2 protocol bridge with Noise NX handshake
  • reservegrid-gateway — legacy gateway (superseded by sv2-gateway in v1.0.0)

Deployment modes

Mode Risk Data Source Enforcement
Shadow None Synthetic (rg-demo-feed) Read only
Observe None Live pool (rg-feed-server) Logging only
Inline Production bitcoind (direct) Full enforcement

Shadow mode runs entirely offline against synthetic templates generated by rg-demo-feed. Observe mode connects to a live pool's template stream through rg-feed-server with HMAC authentication but never touches the block construction path. Inline mode sits directly in the pipeline between template-manager and sv2-gateway and can reject templates before they reach miners.

Stratum V2 gateway

Connection lifecycle

Miners connect over TCP with Noise NX encryption negotiated on the first handshake. Each connection opens a standard mining channel. The gateway validates share submissions against the current job, enforces per channel rate limits, and forwards accepted shares upstream.

Share verification

Every submitted share is checked for nonce uniqueness (HMAC replay protection), job freshness, difficulty target, and version mask compliance. Invalid shares receive a structured rejection with a canonical reason_code and human readable reason_detail.

Rate limiting

  • Per channel token bucket for share submission rate
  • Per IP TCP accept rate limiting at the listener level
  • Both configurable via environment variables

Reason codes

19 gateway share and connection reason codes covering: share_accepted, share_rejected_low_difficulty, share_rejected_stale_job, share_rejected_duplicate_nonce, share_rejected_invalid_version_mask, connection_rejected_rate_limit, and others. All codes are canonical snake_case and stable across Prometheus labels and structured logs.

Template verification

Policy engine

The pool-verifier evaluates every TemplatePropose against a flat TOML policy. 15 verdict reason codes cover economic checks (fee delta, tx count, coinbase value), structural checks (version, prevhash, merkle root), and consensus safety checks (weight ratio, template staleness, sigops budget).

Evaluation order

Safety checks run after the 8 economic and structural checks in a fixed, deterministic order. evaluate_dynamic accepts an explicit now_ms: u64 parameter for testability. The production wrapper evaluate() calls now_unix_ms() internally, preserving existing call sites.

Enforced checks

  • weight_ratio_exceeded — activates when template weight divided by max block weight (4,000,000 WU) exceeds safety.max_weight_ratio
  • template_stale — activates when current time minus created_at_unix_ms exceeds safety.max_template_age_ms
  • Each check gated by safety.enforce_weight_ratio and safety.enforce_template_age booleans in policy TOML, both default false
  • When enforce = false, structured warning log emitted with metric values but verdict stays accept

Observed checks (log and dashboard only)

  • Sigops headroom: warns when total_sigops exceeds safety.warn_sigops_ratio of the 80,000 consensus limit
  • Coinbase sigops anomaly: warns when coinbase_sigops exceeds safety.warn_coinbase_sigops_max
  • Both thresholds configurable under [policy.safety]
  • Warnings carry full policy context for traceability

New environment variables

  • VELDRA_TLS_CERT — path to PEM certificate file
  • VELDRA_TLS_KEY — path to PEM private key file
  • VELDRA_TLS_SELF_SIGNED — set to 1 to auto-generate a self-signed cert for dev
  • VELDRA_API_KEY — bearer token required for non-health endpoints (localhost bypasses)
  • VELDRA_POLICY_FILE — path to policy TOML file

Verification and observability

15 template verdict reason codes and 19 gateway share/connection reason codes. All canonical snake_case, stable across protocol, verifier, Prometheus labels, NDJSON WAL, CSV exports, and dashboard queries.

Every rejection is 100% traceable: machine readable reason_code plus human readable reason_detail, with full policy context in structured logs.

Exports

  • Prometheus metrics with reason_code labels on all verdict and share counters
  • NDJSON event stream (crash durable write ahead log)
  • CSV verdict history via /verdicts.csv
  • Embedded dashboard with 3 second live polling

Readiness probes

/ready returns 200 when the verifier is operationally healthy, 503 when degraded. Response is JSON:

{
  "ready": true,
  "policy_loaded": true,
  "mempool_reachable": true,
  "mempool_last_ok_age_secs": 2
}

/health remains a simple liveness probe returning "ok" unconditionally. Both endpoints bypass API key authentication.

Dashboard

Built-in operator dashboard

rg-dashboard serves an embedded React frontend proxied behind the same auth layer as the API. Live verdict stream, reason code aggregates with collapsible drill-down, consensus safety panel (weight utilization gauge, sigops headroom bar, template age, coinbase sigops), and tier cards for mempool context.

Observe mode public dashboard

The public observe mode dashboard (veldra-site-v3) reaches full feature parity with the built-in dashboard. Enforcement mode badges, mempool context bar, CSV/NDJSON export links, and stale data overlay across all panels. Auth bypass restricted to localhost only.

Security

  • Noise NX encryption on all miner connections (Stratum V2)
  • Native TLS via VELDRA_TLS_CERT and VELDRA_TLS_KEY environment variables (rustls)
  • Self-signed cert generation for dev via VELDRA_TLS_SELF_SIGNED=1
  • mTLS support for remote verifier channel
  • HMAC nonce replay protection on share submissions
  • Per channel share rate limiting (token bucket)
  • Per IP TCP accept rate limiting
  • Per endpoint auth rate limiting (sliding window, fail closed)
  • API key authentication via VELDRA_API_KEY (Bearer token, localhost bypasses)
  • Argon2id password hashing for rg-auth accounts
  • Constant time API key comparison
  • CORS wildcard hard error at startup
  • SQL parameterization enforced (no string interpolation with user input)
  • unsafe_code = "deny" across entire workspace

Policy configuration

All verification thresholds configurable via a flat TOML [policy] table. 18 policy keys across [policy] and [policy.safety]. No code changes required to adjust thresholds. Switch policy files by setting the VELDRA_POLICY_FILE environment variable.

Policy TOML keys under [policy.safety]

  • max_weight_ratio — float, default 0.999
  • max_template_age_ms — maximum acceptable template age in milliseconds
  • enforce_weight_ratio — boolean, default false
  • enforce_template_age — boolean, default false
  • warn_sigops_ratio — float, default 0.95 (warn at 95% of consensus limit)
  • warn_coinbase_sigops_max — integer, default 400

Policy profiles included

  • policy-strict.toml — all enforcement enabled, strict thresholds
  • demo-open-policy.toml — permissive policy for demo/evaluation
  • demo-showcase-policy.toml — balanced policy for live demonstrations
  • demo-strict-policy.toml — aggressive policy for rejection showcase

Authentication (rg-auth)

Standalone auth service with Argon2id password hashing, JWT session tokens, license key validation, and per endpoint sliding window rate limiting that fails closed on threshold breach. Supports account creation, login, token refresh, and key activation flows.

CI and quality

Full GitHub Actions matrix: build, test, clippy pedantic, rustfmt, cargo audit, cargo deny, cargo vet, gitleaks secrets scan. Integration test suites for all three deployment modes.

Suite Tests
Inline mode smoke 14
Observe mode smoke 9
Auth lifecycle 20
Endpoint contracts 22
Shadow integration CI job

Performance

Release build benchmarks on single machine loopback (Docker Compose):

Scenario Connections TPS Avg p99 Max
Baseline valid 10 100 5.34ms 15ms 60ms
Stress valid 50 1,000 3.66ms 9ms 30ms
High concurrency burst 100 2,000 5.14ms 35ms 75ms
100% rejection (prevhash) 10 100 5.10ms 16ms 17ms
Mixed 30% rejection 10 100 5.20ms 14ms 15ms

All scenarios remain under the 100ms SLA target. The rejection path adds no measurable latency overhead compared to the acceptance path. At 10x load (50 connections, 1,000 TPS) average latency decreases to 3.66ms due to connection pooling amortization.

Dependencies

Key runtime dependencies:

  • axum 0.8 with tokio runtime
  • axum-server 0.7 with tls-rustls feature
  • serde / serde_json for all serialization
  • tracing / tracing-subscriber for structured logging
  • clap for CLI argument parsing
  • rcgen 0.13 for self-signed certificate generation
  • argon2 for password hashing
  • bitcoincore-rpc 0.18.0 for getblocktemplate integration

Requirements

  • Rust 1.92+ (2024 edition)
  • Docker and Docker Compose
  • bitcoind (for inline mode)

Getting started

git clone https://github.com/LeavesJ/veldra.git
cd veldra
cp .env.example .env
# Edit .env with your settings
docker compose up -d

See the README for full setup instructions including all three deployment modes.

Known limitations

  • Extended channels (multiple jobs per connection) are deferred to v1.1
  • Variable difficulty (vardiff) is deferred to v1.1
  • Grafana dashboard JSON provisioning is not yet included (embedded dashboard is functional)
  • Rate limiter state is in process only (acceptable for single instance, shared state deferred to v1.1)
  • Sustained load testing (hours, not seconds) has not been performed
  • Two host deployment with network latency has not been benchmarked

License

Veldra Source Available License v1.0. See LICENSE for terms.