Skip to content
Merged
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
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.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ borsh = "1.5.1"
fern = { version = "0.6.2", features = ["colored"] }
trait-variant = "0.1.2"
toml = "0.8.19"
thiserror = "2.0.11"

[profile.release]
opt-level = 3
Expand Down
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ jito_url = "https://amsterdam.mainnet.block-engine.jito.wtf/api/v1/transactions?
kernel_tcp_bypass = true
kernel_tcp_bypass_engine = "af_xdp_or_dpdk_external"
kernel_bypass_socket_path = "/tmp/slotstrike-kernel-bypass.sock"
fpga_enabled = false
fpga_vendor = "generic"
fpga_ingress_mode = "auto"
fpga_direct_device_path = "/dev/slotstrike-fpga0"
fpga_dma_socket_path = "/tmp/slotstrike-fpga-dma.sock"

[telemetry]
enabled = true
Expand Down Expand Up @@ -76,7 +81,12 @@ slippage_pct = "1"
- `kernel_bypass_socket_path`: unix socket for external AF_XDP/DPDK bypass feed bridge.
- `fpga_enabled`: force FPGA ingress if available.
- `fpga_verbose`: verbose FPGA diagnostics.
- `fpga_vendor`: vendor label.
- `fpga_vendor`: `mock_dma`, `generic`, `exanic`, `xilinx`, `amd`, `solarflare`, or `napatech`.
- `fpga_ingress_mode`: `auto`, `mock_dma`, `direct_device`, or `external_socket`.
- `fpga_direct_device_path`: direct vendor-device ingest path (character device/FIFO/file) used by `direct_device`.
- `fpga_dma_socket_path`: unix socket for `external_socket` bridge mode.
- direct frame wire format: one frame per line. Preferred JSON: `{"payload_base64":"...","hardware_timestamp_ns":123}`.
Alternate wire format: base64 payload-only line.
- `replay_benchmark`: run synthetic replay instead of live strategy.
- `replay_event_count`: replay event count.
- `replay_burst_size`: replay burst size.
Expand All @@ -98,6 +108,17 @@ slippage_pct = "1"

Note: monetary/percentage rule values are strings and parsed via fixed-point/integer-safe logic to avoid float drift.

## FPGA Direct Mode

For production users integrating vendor devices directly:

1. Set `fpga_enabled = true`.
2. Set `fpga_ingress_mode = "direct_device"`.
3. Set `fpga_direct_device_path` to your driver/device export path.

Startup now fails fast if the direct device path is missing or not readable.
Full operator contract and wire format: `docs/operations/fpga_direct_ingress.md`.

Multiple mint addresses:

Use one `[[rules]]` block per mint address (the `rules` section is an array of tables).
Expand Down Expand Up @@ -169,6 +190,7 @@ Useful runtime flags:
- `--fpga-verbose`

If you set `kernel_tcp_bypass_engine = "openonload"`, run under Onload (or equivalent preload setup) to activate acceleration.
If you set `fpga_enabled = true`, startup now fails fast unless FPGA prerequisites are available for the selected mode.

Note: ingress feed transport and tx submission transport are separate concerns.
Ingress can use FPGA/kernel-bypass/websocket, while tx submission uses `direct` RPC or `jito` based on `tx_submission_mode`.
Expand Down Expand Up @@ -260,6 +282,7 @@ Tune with:
- On-call playbook: `docs/runbooks/oncall.md`
- Contribution guide: `CONTRIBUTING.md`
- FPGA NIC deployment/PTP/rollback: `docs/operations/fpga_nic_deployment.md`
- FPGA direct ingress contract: `docs/operations/fpga_direct_ingress.md`

## Disclaimer

Expand Down
73 changes: 73 additions & 0 deletions docs/operations/fpga_direct_ingress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# FPGA Direct Ingress Contract

## Purpose

This document defines the production contract for `fpga_ingress_mode = "direct_device"` in slotstrike.
It is intended for operators integrating a vendor FPGA/NIC driver directly into runtime ingress.

## Runtime Configuration

Set these `[runtime]` fields in `slotstrike.toml`:

```toml
fpga_enabled = true
fpga_vendor = "xilinx" # generic | exanic | xilinx | amd | solarflare | napatech | mock_dma
fpga_ingress_mode = "direct_device" # auto | mock_dma | direct_device | external_socket
fpga_direct_device_path = "/dev/slotstrike-fpga0"
fpga_dma_socket_path = "/tmp/slotstrike-fpga-dma.sock" # only used by external_socket mode
```

`auto` resolves to:

1. `mock_dma` backend when `fpga_vendor = "mock_dma"`.
2. `direct_device` backend for supported hardware vendors.

## Readiness Rules (Fail Fast)

At startup, slotstrike rejects FPGA mode when prerequisites fail:

1. Unsupported vendor/mode combination.
2. Missing `fpga_direct_device_path`.
3. Path exists but is not a char device, FIFO, or readable file.
4. Path exists but cannot be opened.

The process exits before wallet/RPC/rulebook initialization if ingress readiness fails.

## Direct Device Wire Format

The direct device reader consumes one frame per line.

Preferred line format (JSON):

```json
{"payload_base64":"c2lnbmF0dXJlPWFiYzEyMwo...","hardware_timestamp_ns":1730000000123456789}
```

Allowed alternatives:

1. JSON with `payload` (plain UTF-8 string) instead of `payload_base64`.
2. Payload-only base64 line (no JSON envelope).

Each payload is decoded by slotstrike's deterministic DMA parser and then passed through pool prefiltering.

## Payload Contract

Decoded payload must contain newline-separated fields:

```text
signature=<tx_signature>
has_error=<0|1|true|false>
log=<solana log line 1>
log=<solana log line 2>
...
```

If payload parsing fails, slotstrike drops that frame and continues reading.

## Operational Notes

1. Keep the device producer line-buffered to avoid burst latency from partial frames.
2. Use hardware timestamps where available and include `hardware_timestamp_ns` in the JSON envelope.
3. Prefer character device or FIFO paths over regular files in production.
4. For rollback, switch `fpga_enabled = false` and restart service.

3 changes: 3 additions & 0 deletions docs/operations/fpga_nic_deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ ethtool -i <nic_ifname>
```bash
fpga_enabled = true
fpga_vendor = "<vendor_name>"
fpga_ingress_mode = "direct_device"
fpga_direct_device_path = "/dev/slotstrike-fpga0"
fpga_dma_socket_path = "/tmp/slotstrike-fpga-dma.sock"
fpga_verbose = false
```

Expand Down
6 changes: 6 additions & 0 deletions slotstrike.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ kernel_bypass_socket_path = "/tmp/slotstrike-kernel-bypass.sock"
fpga_enabled = false
fpga_verbose = false
fpga_vendor = "generic"
# supported: "auto", "mock_dma", "direct_device", "external_socket"
fpga_ingress_mode = "auto"
# used when fpga_enabled=true and fpga_ingress_mode resolves to direct_device
fpga_direct_device_path = "/dev/slotstrike-fpga0"
# used when fpga_enabled=true and fpga_ingress_mode=external_socket
fpga_dma_socket_path = "/tmp/slotstrike-fpga-dma.sock"
replay_benchmark = false
replay_event_count = 50000
replay_burst_size = 512
Expand Down
Loading