Skip to content
Open
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
19 changes: 0 additions & 19 deletions .direnv/bin/nix-direnv-reload

This file was deleted.

13 changes: 13 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.git
.claude
.direnv
.vscode
.DS_Store
.env
.env.local
.env.*.local
.envrc
Lightbringer.toml
target
secrets
shred-store
10 changes: 9 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
/target

.direnv
Lightbringer.toml
Lightbringer.toml
.env
.env.local
.env.*.local

/secrets/*
!/secrets/.gitignore
!/secrets/*.example
!/secrets/*.example.*
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ solana-streamer = { git = "https://github.com/Overclock-Validator/agave.git", re
solana-ledger = { git = "https://github.com/Overclock-Validator/agave.git", rev = "bb110d1fad7f1523c13709dcd1a0336f9f9975b4" }
solana-entry = "3.0.14"
solana-net-utils = { git = "https://github.com/Overclock-Validator/agave.git", rev = "bb110d1fad7f1523c13709dcd1a0336f9f9975b4", features = ["agave-unstable-api"] }
solana-quic-definitions = "=3.0.0"
solana-rpc-client-types = "3.0.14"
solana-epoch-info = "3.0.0"
solana-core = { git = "https://github.com/Overclock-Validator/agave.git", rev = "bb110d1fad7f1523c13709dcd1a0336f9f9975b4" }
solana-packet = "3.0.0"
solana-commitment-config = "3.1.0"
# pins because obviously someone doesn't want to follow semver
# Keep these transitive Solana crates pinned to the exact versions required by
# the Agave revision above.
solana-sysvar = { version = "=3.0.0", features = ["serde"] }
solana-hash = { version = "=3.0.0", features = ["serde"] }
solana-blake3-hasher = "=3.0.0"
Expand Down Expand Up @@ -65,7 +67,7 @@ uluru = "3.1.0"
circular-buffer = "0.1.9"
lrumap = "0.1.0"

# grpc streaming related
# gRPC streaming dependencies.
tokio = { version = "1.0", features = ["rt", "sync", "time", "net", "fs"] }
tokio-stream = { version = "0.1", features = ["sync"] }
tonic = "0.14"
Expand All @@ -78,4 +80,4 @@ tokio-util = { version = "0.7.16", features = ["time"] }
tonic-prost-build = "0.14"

[features]
debug = []
debug = []
58 changes: 58 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# syntax=docker/dockerfile:1.7

ARG RUST_VERSION=1.92.0

FROM rust:${RUST_VERSION}-bookworm AS builder

WORKDIR /usr/src/lightbringer

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential \
ca-certificates \
clang \
cmake \
git \
libclang-dev \
libssl-dev \
libudev-dev \
pkg-config \
protobuf-compiler \
zlib1g-dev \
&& rm -rf /var/lib/apt/lists/*

COPY Cargo.toml Cargo.lock rust-toolchain.toml build.rs ./
COPY pb ./pb
COPY src ./src

RUN cargo build --release --bin lightbringer

FROM builder AS tester

COPY decoded_shreds.json stored_shreds.json ./

RUN cargo test --all-targets

FROM debian:bookworm-slim AS runtime

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
libgcc-s1 \
libnghttp2-14 \
libssl3 \
libstdc++6 \
libudev1 \
zlib1g \
&& rm -rf /var/lib/apt/lists/*

RUN useradd --system --create-home --home-dir /var/lib/lightbringer --shell /usr/sbin/nologin lightbringer \
&& mkdir -p /var/lib/lightbringer/shred-store \
&& chown -R lightbringer:lightbringer /var/lib/lightbringer

COPY --from=builder /usr/src/lightbringer/target/release/lightbringer /usr/local/bin/lightbringer

USER lightbringer
WORKDIR /var/lib/lightbringer

ENTRYPOINT ["lightbringer"]
36 changes: 21 additions & 15 deletions Lightbringer.example.toml
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
# entrypoint to solana gossip (must be a remote addr)
gossip_entrypoint = "177.177.177.177:8000"
# Replace this TEST-NET address with a real Solana gossip entrypoint.
gossip_entrypoint = "203.0.113.10:8000"

# folder for storing shreds (optional, default = "./shred-store")
# Shred storage path.
storage = "./shred-store"

# Debugging RPC address (optional, default = "127.0.0.1:3000")
# Local debug RPC address.
rpc_addr = "127.0.0.1:3000"

# gRPC slot stream (optional, default = "127.0.0.1:3001")
# gRPC slot stream address.
grpc_addr = "127.0.0.1:3001"

# optional, fallback to mock metrics if not set
[gossip]
gossip_port = 65400
port_range_start = 65401
port_range_end = 65500

# Compose mounts the InfluxDB token here.
# Remove this section when running without InfluxDB.
[influxdb]
host = "http://localhost:8181"
database = "test"
token = "xyz"
host = "http://127.0.0.1:18181"
database = "lightbringer"
token_file = "/run/secrets/influxdb-admin-token"

# optional, grpc streams confirmed blocks if set
[block_confirmation]
rpc_http = "http://localhost:8900"
rpc_websocket = "ws://localhost:8900"
# Enable only when a local RPC node is available.
# [block_confirmation]
# rpc_http = "http://localhost:8900"
# rpc_websocket = "ws://localhost:8900"

# optional, suppress info/debug log lines (only warnings and errors are emitted)
# Suppress info/debug logs.
[log]
quiet = false
quiet = false
193 changes: 193 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
name: lightbringer

services:
secrets-preflight:
image: influxdb:3.9.2-core
restart: "no"
user: "0:0"
network_mode: none
cap_drop:
- ALL
read_only: true
security_opt:
- no-new-privileges:true
entrypoint:
- /bin/sh
- /docker-secrets/check-readable.sh
secrets:
- source: influxdb_admin_token
target: influxdb-admin-token
- source: grafana_admin_password
target: grafana-admin-password
volumes:
- ./docker/secrets/check-readable.sh:/docker-secrets/check-readable.sh:ro

lightbringer-config-preflight:
profiles:
- lightbringer
image: influxdb:3.9.2-core
restart: "no"
user: "0:0"
network_mode: none
cap_drop:
- ALL
read_only: true
security_opt:
- no-new-privileges:true
entrypoint:
- /bin/sh
- /docker-secrets/check-readable.sh
environment:
LIGHTBRINGER_CONFIG_FILE: /docker-config/Lightbringer.toml
secrets:
- source: influxdb_admin_token
target: influxdb-admin-token
- source: grafana_admin_password
target: grafana-admin-password
volumes:
- ./docker/secrets/check-readable.sh:/docker-secrets/check-readable.sh:ro
- ./Lightbringer.toml:/docker-config/Lightbringer.toml:ro

influxdb3:
image: influxdb:3.9.2-core
restart: unless-stopped
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
depends_on:
secrets-preflight:
condition: service_completed_successfully
command:
- influxdb3
- serve
- --node-id=lightbringer-node
- --object-store=file
- --data-dir=/var/lib/influxdb3/data
- --admin-token-file=/run/secrets/influxdb-admin-token
- --disable-authz=health,ping
ports:
- "127.0.0.1:18181:8181"
healthcheck:
test:
[
"CMD-SHELL",
"token=$$(sed -n 's/.*\"token\"[[:space:]]*:[[:space:]]*\"\\([^\"]*\\)\".*/\\1/p' /run/secrets/influxdb-admin-token | head -n 1); [ -n \"$$token\" ] && INFLUXDB3_AUTH_TOKEN=\"$$token\" influxdb3 show databases --host http://127.0.0.1:8181 >/dev/null",
]
interval: 10s
timeout: 5s
retries: 12
start_period: 20s
secrets:
- source: influxdb_admin_token
target: influxdb-admin-token
volumes:
- influxdb3-data:/var/lib/influxdb3

influxdb3-init:
image: influxdb:3.9.2-core
restart: "no"
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
depends_on:
influxdb3:
condition: service_healthy
entrypoint:
- /bin/sh
- /docker-entrypoint-initdb.d/init-database.sh
environment:
INFLUXDB_ADMIN_TOKEN_FILE: /run/secrets/influxdb-admin-token
INFLUXDB_DATABASE: lightbringer
INFLUXDB_URL: http://influxdb3:8181
secrets:
- source: influxdb_admin_token
target: influxdb-admin-token
volumes:
- ./docker/influxdb/init-database.sh:/docker-entrypoint-initdb.d/init-database.sh:ro

grafana:
build:
context: .
dockerfile: docker/grafana/Dockerfile
args:
GRAFANA_VERSION: 13.0.1-security-01
restart: unless-stopped
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
depends_on:
influxdb3-init:
condition: service_completed_successfully
environment:
GF_AUTH_ANONYMOUS_ENABLED: "false"
GF_SECURITY_ADMIN_USER: admin
GF_SECURITY_ADMIN_PASSWORD__FILE: /run/secrets/grafana-admin-password
INFLUXDB_ADMIN_TOKEN_FILE: /run/secrets/influxdb-admin-token
INFLUXDB_DATABASE: lightbringer
INFLUXDB_URL: http://influxdb3:8181
ports:
- "127.0.0.1:3300:3000"
healthcheck:
test: ["CMD", "curl", "-fsS", "http://127.0.0.1:3000/api/health"]
interval: 10s
timeout: 5s
retries: 12
start_period: 20s
secrets:
- source: influxdb_admin_token
target: influxdb-admin-token
- source: grafana_admin_password
target: grafana-admin-password
volumes:
- grafana-data:/var/lib/grafana
- ./docker/grafana/provisioning:/etc/grafana/provisioning:ro
- ./docker/grafana/dashboards:/var/lib/grafana/dashboards:ro

lightbringer:
profiles:
- lightbringer
build:
context: .
dockerfile: Dockerfile
restart: unless-stopped
depends_on:
influxdb3-init:
condition: service_completed_successfully
lightbringer-config-preflight:
condition: service_completed_successfully
network_mode: host
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
- seccomp=unconfined
ulimits:
memlock:
soft: -1
hard: -1
secrets:
- source: influxdb_admin_token
target: influxdb-admin-token
configs:
- source: lightbringer_config
target: /var/lib/lightbringer/Lightbringer.toml
volumes:
- lightbringer-shred-store:/var/lib/lightbringer/shred-store

configs:
lightbringer_config:
file: ./Lightbringer.toml

secrets:
influxdb_admin_token:
file: ./secrets/influxdb-admin-token.json
grafana_admin_password:
file: ./secrets/grafana-admin-password

volumes:
grafana-data:
influxdb3-data:
lightbringer-shred-store:
Loading