Skip to content

DavidB-77/Vexor

Repository files navigation

██╗   ██╗███████╗██╗  ██╗ ██████╗ ██████╗
██║   ██║██╔════╝╚██╗██╔╝██╔═══██╗██╔══██╗
██║   ██║█████╗   ╚███╔╝ ██║   ██║██████╔╝
╚██╗ ██╔╝██╔══╝   ██╔██╗ ██║   ██║██╔══██╗
 ╚████╔╝ ███████╗██╔╝ ██╗╚██████╔╝██║  ██║
  ╚═══╝  ╚══════╝╚═╝  ╚═╝ ╚═════╝ ╚═╝  ╚═╝

A custom Solana validator client written in Zig.

Testnet Epoch Status Built with Zig


What is Vexor?

Vexor is an independent Solana validator client written from scratch in Zig. It is not a fork of Agave or Firedancer — it is a ground-up implementation of the Solana consensus and execution protocol.

Currently running on testnet:

  • Identity: 3J2jADiEoKMaooCQbkyr9aLnjAb5ApDWfVvKgzyK2fbP
  • Server: AMD EPYC 9374F (32 cores), 503 GB RAM, 3.6 TB NVMe, Broadcom 10G NICs
  • Epoch 933 — actively voting, zero STATE-DIVERGENCE, votes landing on-chain
  • 36 leader slots assigned for epoch 934

Current Status

Component Status
Gossip / TVU / TPU ✅ Running
Shred assembly (AF_XDP copy-mode) ✅ Running
Transaction replay ✅ Running
Bank hash (SIMD-215 two-step LtHash) ✅ Correct
Native SBPF v0 VM ✅ Running (no C dependency)
Vote submission (TowerSync) ✅ Landing on-chain
Block production (leader slots) ✅ Implemented
VEXstore LSM storage engine 🔧 In development
CPI (cross-program invocation) 🔧 RPC shadow bridge (interim)
Mainnet 📋 Planned

Architecture

┌─────────────────────────────────────────────────────────────────┐
│                         VEXOR VALIDATOR                          │
├──────────────┬──────────────┬─────────────────┬─────────────────┤
│   NETWORK    │   CONSENSUS  │    EXECUTION     │    STORAGE      │
│              │              │                  │                 │
│  AF_XDP      │  Tower BFT   │  SBPF v0 VM     │  AccountsDb     │
│  copy-mode   │  Fork Choice │  (native Zig)   │  (in-memory +   │
│  10G NICs    │  Vote Submit │                  │   NVMe)         │
│              │              │  RPC Shadow BPF  │                 │
│  Gossip      │  Leader Sched│  (CPI fallback)  │  VEXstore LSM   │
│  TVU / TPU   │  Epoch Stakes│                  │  (WiscKey-style)│
│  Turbine     │              │  ELF Loader      │                 │
└──────────────┴──────────────┴─────────────────┴─────────────────┘

Native Zig SBPF VM

Vexor includes a complete native Zig implementation of the Solana BPF virtual machine — no Firedancer C library, no external dependencies:

  • Full SBPF v0 instruction set: all ALU64/ALU32, load/store, jump, and LDDW instructions
  • Correct Solana memory model: four virtual address regions (0x100000000 program, 0x200000000 stack, 0x300000000 heap, 0x400000000 input), each with host-pointer translation and write-protection
  • 27 syscalls: sol_log_, sol_memcpy_, sol_memcmp_, sol_memset_, sol_sha256, sol_keccak256, sol_blake3, sol_create_program_address_, sol_try_find_program_address, and more — all syscall IDs computed as murmur3_32(name, 0) and verified against Agave
  • CPI fallback: sol_invoke_signed returns CpiRequired; the executor transparently falls back to an RPC shadow that fetches confirmed account state for that slot

Bank Hash

Implements SIMD-215 two-step formula:

step1 = SHA256(parent_hash || sig_count_u64_LE || last_blockhash)
bank_hash = SHA256(step1 || lthash_2048_bytes)

LtHash uses Blake3 XOF → 2048 bytes per account, with element-wise u16 add/subtract for account updates. Matches the network exactly — zero STATE-DIVERGENCE since deployment.

Storage

  • Legacy backend: in-memory HashMap with NVMe persistence, used in production
  • VEXstore: custom WiscKey-inspired LSM engine (2,500+ lines), being integrated as primary backend. Separates keys (index in SSTable) from values (NVMe value log), avoiding write amplification on large account data

Networking

AF_XDP copy-mode on enp5s0f0np0 (Broadcom BCM57416, 10G). Zero-copy mode (xsk_umem_register) is not supported by this NIC's bnxt_en driver — copy-mode is the correct configuration. Shred repair runs on enp5s0f1np1 (.155).


Hardware

The testnet validator runs on dedicated bare metal:

Component Spec
CPU AMD EPYC 9374F (32 cores, Zen 4)
RAM 503 GB DDR5
NVMe 3.6 TB
NICs Dual Broadcom BCM57416 10G (enp5s0f0np0 + enp5s0f1np1)
OS Debian 12, kernel 6.12.74
Compiler Zig 0.14.0

CPU pinning: cores 6–19 for Vexor (14 cores), cores 2–5 for IRQ affinity.


Build

# Standard build (for your local machine)
zig build -Doptimize=ReleaseFast

# Production build (AMD EPYC / znver4)
zig build -Doptimize=ReleaseFast -Dcpu=znver4

# Optional: future Firedancer VM comparison (not required)
zig build -Doptimize=ReleaseFast -Dcpu=znver4 \
    -Dfiredancer_src=/path/to/firedancer/src

# Optional build flags
-Dstorage_backend=vexstore    # use VEXstore as primary backend
-Dvexstore_shadow=true        # shadow writes to VEXstore alongside legacy

Requirements: Zig 0.14.0. No other build dependencies.


Running on Testnet

./vexor-launch.sh testnet

Key flags used in production:

--bootstrap --testnet
--identity ****
--vote-account ****
--ledger /mnt/ledger/vexor-testnet
--accounts /mnt/ramdisk/vexor-testnet
--snapshots /mnt/snapshots/vexor-testnet
--public-ip 38.58.183.154
--gossip-port 8001 --tvu-port 8003 --repair-port 8002
--repair-bind-addr 38.58.183.155
--expected-genesis-hash 4uhcVJyU9pJkvQyS88uRDiswHXSCkY3zQawwpjk2NsNY
--known-validator [4 testnet validators]
--entrypoint [3 testnet entrypoints]
--enable-af-xdp --interface enp5s0f0np0
--enable-fec-recovery --enable-io-uring
--limit-ledger-size 50000000

Do not use --xdp-zero-copy — not supported by bnxt_en driver.


Monitoring

TPS Metrics

Vexor logs a rolling 60-slot TPS window every minute:

[METRICS] slot=397856000 | replay_TPS=4230 tx/s (last 60 slots, 101520 txns) |
          net_est=3750 tx/s | lifetime: 2847300 txns across 14230 slots |
          votes=28460 blocks=4 bad_shreds=0
  • replay_TPS: how fast Vexor's SBPF VM processes transactions (wall-clock)
  • net_est: estimated network-wide TPS from avg transactions per slot ÷ 0.4s
  • lifetime: cumulative totals since process start

Vote Confirmation

# Watch identity balance drain (5,000 lamports per vote)
solana balance 3J2jADiEoKMaooCQbkyr9aLnjAb5ApDWfVvKgzyK2fbP --url testnet

# Watch Vexor logs
tail -f /home/davidb/vexor_testnet.log | grep -E "VoteSubmitter|METRICS|HASH"

Log Patterns

Pattern Meaning
[VoteSubmitter] Attempting vote for slot N Vote being submitted
[METRICS] replay_TPS=N Rolling TPS report (every 60 slots)
[HASH-COMPARATOR] MATCHES Bank hash matches network
[RpcShadowBpf] N BPF accounts tracked, N changed CPI fallback active for slot
[BlockProducer] WE ARE LEADER Leader slot, producing block
[STATE-DIVERGENCE] ❌ Should not appear — means bank hash mismatch

Roadmap

Near term

  • Full CPI (cross-program invocation) in native Zig VM — eliminates RPC shadow dependency
  • VEXstore as primary storage backend (flat index elimination complete)
  • SIMD-0161 (SBPF v1) instruction set support
  • Prometheus /metrics HTTP endpoint

Medium term

  • Mainnet readiness: stake-weighted quality-of-service, stake delegation
  • Native secp256k1 recover syscall (currently returns error code 1)
  • Alpenglow consensus (SIMD-0236) — faster finality
  • QUIC TPU ingress

Long term

  • Full hardware zero-copy XDP (requires NIC with XDP_SETUP_XSK_POOL support)
  • Multi-validator cluster testing
  • Jito MEV integration

Key Files

src/
├── runtime/
│   ├── bank.zig              Bank state, LtHash, freeze(), RPC shadow injection
│   ├── replay_stage.zig      Shred assembly, TX replay, TPS metrics
│   ├── bootstrap.zig         Startup, snapshot load, vote loop
│   ├── vote_state_serde.zig  VoteState V1/V2/V3/V4 round-trip serde
│   ├── rpc_shadow_bpf.zig    CPI fallback: fetch confirmed BPF state from RPC
│   └── bpf/
│       ├── interpreter.zig   Native Zig SBPF v0 VM (virtual address memory model)
│       ├── syscalls.zig      27 syscalls, murmur3_32 dispatch, Zig 0.14 crypto
│       ├── sbpf_executor.zig Serialise accounts → run VM → deserialise mutations
│       └── elf_loader.zig    SBPF ELF → combined rodata buffer + entry_pc
├── consensus/
│   ├── tower.zig             Tower BFT, lockouts, timely vote credits (SIMD-033)
│   └── fork_choice.zig       Heaviest-subtree stake-weighted fork selection
├── storage/
│   ├── accounts.zig          AccountsDb, LtHash cache, top_votes, SIMD-0084
│   └── vexstore.zig          VEXstore WiscKey LSM engine (in development)
└── crypto/
    └── lthash.zig            Blake3 XOF → 2048-byte LtHash, u16 element add/sub

Credits & Attribution

Vexor is an independent implementation of the Solana protocol. In studying the protocol, the following open-source projects were invaluable references:

  • Firedancer (Jump Trading, Apache-2.0) — virtual machine architecture, memory region layout concepts, syscall dispatch approach
  • Agave / solana-rbpf (Solana Labs, MIT) — virtual address constants (MM_PROG_START etc.), calling convention, SBPF v0 specification
  • SIG (Syndica, MIT) — Zig patterns for Solana protocol implementation

Vexor's code is written from scratch in Zig. All syscall IDs are computed independently via murmur3_32(name, 0). The Solana protocol specification (SIMDs) are the authoritative reference for all consensus-critical behaviour.


Built with ❤️ and Zig. Running on Solana testnet.

About

A Solana Client

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors