Skip to main content

QUIC transport layer for Bittensor

Project description

Ligh𝞽ning

Rust QUIC transport layer for Bittensor

Persistent QUIC connections with sr25519 handshake authentication for validator-miner communication.

crates.io docs.rs PyPI

Python

pip install btlightning
from btlightning import Lightning

client = Lightning(wallet_hotkey="5GrwvaEF...")
client.set_python_signer(my_signer_callback)
client.initialize_connections([
    {"hotkey": "5FHneW46...", "ip": "192.168.1.1", "port": 8443}
])
response = client.query_axon(
    {"hotkey": "5FHneW46...", "ip": "192.168.1.1", "port": 8443},
    {"synapse_type": "MyQuery", "data": {"key": "value"}}
)

Rust

[dependencies]
btlightning = { version = "0.1", features = ["subtensor"] }

With the subtensor feature, the client discovers miners from the metagraph and keeps connections in sync automatically:

use btlightning::{LightningClient, LightningClientConfig, Sr25519Signer, MetagraphMonitorConfig};

let config = LightningClientConfig {
    metagraph: Some(MetagraphMonitorConfig::finney(YOUR_NETUID)),
    ..Default::default()
};
let mut client = LightningClient::with_config("5GrwvaEF...".into(), config)?;
client.set_signer(Box::new(Sr25519Signer::from_seed(seed)));
client.initialize_connections(vec![]).await?;

Without subtensor, pass miner addresses directly:

use btlightning::{LightningClient, Sr25519Signer, QuicAxonInfo};

let mut client = LightningClient::new("5GrwvaEF...".into());
client.set_signer(Box::new(Sr25519Signer::from_seed(seed)));
client.initialize_connections(vec![
    QuicAxonInfo::new("5FHneW46...".into(), "192.168.1.1".into(), 8443, 4)
]).await?;

Query a single miner by axon info and deserialize the response:

use btlightning::QuicRequest;
use serde::{Serialize, Deserialize};

#[derive(Serialize)]
struct MyQuery { prompt: String }

#[derive(Deserialize)]
struct MyResult { answer: String }

let request = QuicRequest::from_typed("MyQuery", &MyQuery { prompt: "hello".into() })?;
let response = client.query_axon(axon_info, request).await?.into_result()?;
let result: MyResult = response.deserialize_data()?;

Fan out to every QUIC miner on the subnet concurrently:

use std::sync::Arc;
use tokio::task::JoinSet;

let client = Arc::new(client);
let miners = metagraph.quic_miners();
let mut tasks = JoinSet::new();
for miner in miners {
    let req = QuicRequest::from_typed("MyQuery", &MyQuery { prompt: "hello".into() })?;
    let client = Arc::clone(&client);
    tasks.spawn(async move {
        (miner.hotkey.clone(), client.query_axon(miner, req).await)
    });
}
while let Some(Ok((hotkey, result))) = tasks.join_next().await {
    match result {
        Ok(resp) => { /* handle response from hotkey */ }
        Err(e) => { /* miner failed */ }
    }
}

Flood defense

The server applies two filters at the quinn::Incoming boundary, before any per-connection state is allocated. Both are operator-configurable on LightningServerConfig.

Field Default Effect
enforce_source_allowlist false When true, drops any connection whose source IP is not in the cached allowlist. Backed by the SourceAddressResolver trait; refresh interval source_allowlist_refresh_secs (default 300s). Drops use Incoming::ignore() so no response packet is emitted, eliminating reflection-amplification surface.
require_address_validation true When true, unvalidated peers are answered with a QUIC Retry packet via Incoming::retry(), forcing a token round-trip before connection state is allocated. Defeats spoofed-source Initial floods.

Observability:

  • info! Initial source-address allowlist resolution: N allowed IPs on startup
  • info! Refreshed source-address allowlist: N allowed IPs per refresh
  • warn! source-address allowlist is empty under enforce_source_allowlist=true; ALL connections will be silently dropped if the resolver returns empty or errors while enforcement is on
  • info! QUIC address validation enabled -- all clients must complete a Retry round-trip on startup when require_address_validation is on
  • LightningServer::get_allowed_source_count() returns the size of the cached allowlist for embedding in operator dashboards

Pre-flight numbers, measured locally with a quinn-driven flood at concurrency 64 over 10s:

Mode accepts/s handshakes_completed/s
no defenses 8,420 8,420
source allowlist only 640 0
address-validation only 8,710 8,297
both 638 0

Address validation alone provides limited mitigation against attackers using real reachable source IPs (the Retry round-trip completes); it is decisive against spoofed-source floods. Source allowlist enforcement reduces application-layer cost on flood traffic to zero. Both together provide defense in depth across the metagraph cold-start and resolver-failure windows.

This filter does not reduce inbound bandwidth or kernel UDP buffer pressure. Operators on saturated uplinks must combine these with upstream scrubbing or a kernel-level allowlist (e.g. nftables).

Build from source

cargo build -p btlightning
maturin develop --manifest-path crates/btlightning-py/Cargo.toml

Performance

Benchmarked on Apple Silicon (M-series), macOS, loopback networking. Echo handler returns input unchanged. Connection setup includes first request-response round trip. Lightning authenticates once at connection time and amortizes over all subsequent requests; bittensor signs and verifies every request. Bittensor payloads are base64-encoded (JSON has no binary type), adding ~33% wire overhead beyond the nominal payload size. Source: benchmarks/.

bittensor (dendrite/axon) lightning
Protocol HTTP/1.1 QUIC
Serialization JSON MessagePack
Transport encryption None TLS 1.3
Auth model Per-request Per-connection
Metric bittensor lightning (Python) lightning (Rust)
Connection setup (p50) 114.46 ms 2.68 ms 0.71 ms
Latency p50 (1KB) 24.01 ms 0.08 ms 0.05 ms
Latency p99 (1KB) 28.80 ms 0.09 ms 0.07 ms
Throughput (1KB) 41 req/s 26,539 req/s 68,650 req/s
Wire size (1KB payload) 2,032 bytes 1,052 bytes 1,052 bytes
Color System
bittensor bittensor
lightning-py lightning (Python)
lightning lightning (Rust)

[!NOTE] Charts use log10 scale. Refer to the tables below for raw values.

Latency p50

---
config:
    xyChart:
        plotReservedSpacePercent: 60
    themeVariables:
        xyChart:
            backgroundColor: "#000000"
            plotColorPalette: "#808080, #FF8C00, #FFE000"
            titleColor: "#ffffff"
            xAxisLabelColor: "#aaaaaa"
            xAxisTitleColor: "#cccccc"
            xAxisTickColor: "#666666"
            xAxisLineColor: "#444444"
            yAxisLabelColor: "#aaaaaa"
            yAxisTitleColor: "#cccccc"
            yAxisTickColor: "#666666"
            yAxisLineColor: "#444444"
---
xychart-beta
    x-axis ["256B", "1KB", "10KB", "100KB", "1MB"]
    y-axis "log10(us)" 0 --> 5
    bar "bittensor" [4.39, 4.38, 4.39, 4.42, 4.61]
    bar "lightning (Python)" [1.90, 1.90, 2.36, 3.27, 4.31]
    bar "lightning (Rust)" [1.70, 1.70, 2.04, 2.84, 3.87]

Throughput (req/s)

---
config:
    xyChart:
        plotReservedSpacePercent: 60
    themeVariables:
        xyChart:
            backgroundColor: "#000000"
            plotColorPalette: "#FFE000, #FF8C00, #808080"
            titleColor: "#ffffff"
            xAxisLabelColor: "#aaaaaa"
            xAxisTitleColor: "#cccccc"
            xAxisTickColor: "#666666"
            xAxisLineColor: "#444444"
            yAxisLabelColor: "#aaaaaa"
            yAxisTitleColor: "#cccccc"
            yAxisTickColor: "#666666"
            yAxisLineColor: "#444444"
---
xychart-beta
    x-axis ["256B", "1KB", "10KB", "100KB", "1MB"]
    y-axis "log10(req/s)" 0 --> 5
    bar "lightning (Rust)" [4.92, 4.84, 4.27, 3.26, 2.26]
    bar "lightning (Python)" [4.55, 4.42, 3.83, 2.94, 1.94]
    bar "bittensor" [1.61, 1.61, 1.60, 1.57, 1.40]
Full results (all payload sizes)

Latency (ms)

Payload System p50 p95 p99
256B bittensor 24.50 28.04 35.05
lightning (py) 0.08 0.19 0.23
lightning (rust) 0.05 0.06 0.07
1KB bittensor 24.01 25.57 28.80
lightning (py) 0.08 0.09 0.09
lightning (rust) 0.05 0.06 0.07
10KB bittensor 24.70 25.70 26.59
lightning (py) 0.23 0.24 0.26
lightning (rust) 0.11 0.12 0.13
100KB bittensor 26.13 27.31 29.42
lightning (py) 1.88 2.25 2.37
lightning (rust) 0.69 0.73 0.75
1MB bittensor 40.72 43.11 48.00
lightning (py) 20.55 22.48 23.31
lightning (rust) 7.40 12.36 17.02

Throughput (req/s)

Payload bittensor lightning (Python) lightning (Rust)
256B 41 35,181 83,460
1KB 41 26,539 68,650
10KB 40 6,729 18,686
100KB 38 875 1,819
1MB 25 88 181

Wire overhead (bytes)

Payload bittensor lightning
256B 1,008 284
1KB 2,032 1,052
10KB 14,321 10,268
100KB 137,202 102,430
1MB 1,398,771 1,048,606

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

btlightning-0.2.9.tar.gz (123.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

btlightning-0.2.9-cp312-cp312-manylinux_2_38_x86_64.whl (4.9 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.38+ x86-64

btlightning-0.2.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.5 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

btlightning-0.2.9-cp312-cp312-macosx_11_0_arm64.whl (4.5 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

File details

Details for the file btlightning-0.2.9.tar.gz.

File metadata

  • Download URL: btlightning-0.2.9.tar.gz
  • Upload date:
  • Size: 123.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for btlightning-0.2.9.tar.gz
Algorithm Hash digest
SHA256 1e7d7b136fd0c08ba7fb93c7fdd1d7dc3b573bee607f4e9c48514fc22457f68b
MD5 1627e3e29ddb8d93a397c6373477e19c
BLAKE2b-256 5cf133725c2b9383fd5445b20d46103afef6deacfbb275bd2b3760b225484ed5

See more details on using hashes here.

Provenance

The following attestation bundles were made for btlightning-0.2.9.tar.gz:

Publisher: release.yml on inference-labs-inc/btlightning

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file btlightning-0.2.9-cp312-cp312-manylinux_2_38_x86_64.whl.

File metadata

File hashes

Hashes for btlightning-0.2.9-cp312-cp312-manylinux_2_38_x86_64.whl
Algorithm Hash digest
SHA256 9b98efb30349eb355a546e18c8032b93448dd71c4cd18ae9f5ef95603a893ec2
MD5 91a7db39fc4281fc218dc1ed0d27f1a7
BLAKE2b-256 a123ac17a146bd5c839f8948903ad9c356d64bad6f3cfa9681fa7e41e15c6c3c

See more details on using hashes here.

Provenance

The following attestation bundles were made for btlightning-0.2.9-cp312-cp312-manylinux_2_38_x86_64.whl:

Publisher: release.yml on inference-labs-inc/btlightning

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file btlightning-0.2.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for btlightning-0.2.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 829c914dd4b246fc90ea3cbf2fe5737449fed2da6eed769f4464bf8a7d9e29b8
MD5 43f6d6aaf8f8945b90c3054b3e2a0d43
BLAKE2b-256 aa82c062ae059c939bc7167978c7025935cfad1080c715862a961718e3a3ba39

See more details on using hashes here.

Provenance

The following attestation bundles were made for btlightning-0.2.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on inference-labs-inc/btlightning

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file btlightning-0.2.9-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for btlightning-0.2.9-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3d52d25bfac443b39dde08ec4692e31478a8b836eeaa2fc4a7f216f8a2751efa
MD5 f1441ab1b4b23a208e93dca4c1de44ff
BLAKE2b-256 d8d3fe38d7511e482051078c0986608108e70f36e0b67de48e781a70d481eda0

See more details on using hashes here.

Provenance

The following attestation bundles were made for btlightning-0.2.9-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release.yml on inference-labs-inc/btlightning

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page