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
24 changes: 24 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ GETH_URL=http://127.0.0.1:8545
# Bind address for the proxy's HTTP listener (the .onion service forwards here).
BIND_ADDR=127.0.0.1:8080

# Bind address for the admin listener — `/health` and `/metrics`. Kept on a
# separate socket from BIND_ADDR so admin endpoints are NOT reachable
# through the Tor hidden service. Must be a loopback address; the daemon
# refuses to bind a non-loopback admin endpoint to prevent operators from
# accidentally exposing component state, request volume, and version.
ADMIN_BIND_ADDR=127.0.0.1:9001

# tracing-subscriber filter. Examples: `info`, `debug`, `torpc=trace,hyper=info`.
RUST_LOG=info

Expand All @@ -32,6 +39,9 @@ RUST_LOG=info
# Backwards-compatible alias for FLASHBOTS_RELAY_URL. Prefer the latter.
# FLASHBOTS_URL=https://relay.flashbots.net

# Per-attempt timeout for Flashbots relay POSTs, in seconds. Default 5.
# FLASHBOTS_REQUEST_TIMEOUT=5

# ----- Security -------------------------------------------------------------

# Maximum request body size in bytes. Default 1 MiB.
Expand All @@ -53,9 +63,23 @@ RATE_LIMIT_REQUESTS=100
# Window duration in seconds. Default 60.
RATE_LIMIT_WINDOW=60

# Strict per-method bucket for write methods (`eth_sendRawTransaction`,
# `eth_sendBundle`). These are far more sensitive than reads, so they get a
# tighter limit even when the global RATE_LIMIT_REQUESTS budget is healthy.
# WRITE_RATE_LIMIT_REQUESTS=10
# WRITE_RATE_LIMIT_WINDOW=60

# Max concurrent in-flight requests across the entire router. Default 256.
MAX_CONCURRENT_CONNECTIONS=256

# ----- Tor anonymity safety net --------------------------------------------

# Set to `1` to permit the daemon to start even when configs/torrc enables
# `HiddenServiceSingleHopMode 1` or `HiddenServiceNonAnonymousMode 1`.
# These flags strip Tor's anonymity guarantees and exist for benchmarks /
# CI only — never set this in production.
# TORPC_ALLOW_NON_ANONYMOUS=1

# ----- Discovery (client-side proxy only) -----------------------------------

# Enable the optional discovery server that wallet GUIs use to detect a
Expand Down
80 changes: 64 additions & 16 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,37 +23,85 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- name: cargo fmt --check (root)
run: cargo fmt --check
- name: cargo fmt --check (torpc-proxy workspace)
run: cargo fmt --check --manifest-path torpc-proxy/Cargo.toml --all
- name: cargo fmt --check
run: cargo fmt --all --check

# clippy and test cover the full workspace including the Tauri GUI crate.
# Tauri 1.x links against `libwebkit2gtk-4.0` + `libsoup2.4`, both of
# which Ubuntu 24.04 (the `ubuntu-latest` image) dropped in favor of -4.1
# / -3.0. Pin to `ubuntu-22.04` until the GUI migrates to Tauri 2.x —
# ubuntu-22.04 GH runner support extends well past that migration.
clippy:
name: clippy
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- uses: Swatinem/rust-cache@v2
- name: clippy (root)
run: cargo clippy --all-targets -- -D warnings
- name: clippy (torpc-proxy workspace)
run: cargo clippy --manifest-path torpc-proxy/Cargo.toml --workspace --all-targets -- -D warnings
with:
# rust-cache keys on `runner.os` ("Linux") which is shared
# between ubuntu-latest (24.04) and ubuntu-22.04. Without a
# per-image prefix, build-script binaries cached on 24.04
# (GLIBC 2.39) leak into 22.04 jobs (GLIBC 2.35) and fail with
# `version 'GLIBC_2.39' not found`. The `ImageOS` env var
# (ubuntu22 / ubuntu24 / etc.) gives us proper isolation.
prefix-key: "v0-rust-${{ env.ImageOS }}"
- name: install Tauri 1.x system deps
run: |
sudo apt-get update
sudo apt-get install -y \
libwebkit2gtk-4.0-dev \
libgtk-3-dev \
libayatana-appindicator3-dev \
librsvg2-dev \
libsoup2.4-dev
- name: clippy
run: cargo clippy --workspace --all-targets -- -D warnings

test:
name: test (no services)
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
# rust-cache keys on `runner.os` ("Linux") which is shared
# between ubuntu-latest (24.04) and ubuntu-22.04. Without a
# per-image prefix, build-script binaries cached on 24.04
# (GLIBC 2.39) leak into 22.04 jobs (GLIBC 2.35) and fail with
# `version 'GLIBC_2.39' not found`. The `ImageOS` env var
# (ubuntu22 / ubuntu24 / etc.) gives us proper isolation.
prefix-key: "v0-rust-${{ env.ImageOS }}"
- name: install Tauri 1.x system deps
run: |
sudo apt-get update
sudo apt-get install -y \
libwebkit2gtk-4.0-dev \
libgtk-3-dev \
libayatana-appindicator3-dev \
librsvg2-dev \
libsoup2.4-dev
- name: build
run: cargo build --workspace
- name: build torpc-proxy workspace
run: cargo build --manifest-path torpc-proxy/Cargo.toml --workspace
- name: fast tests
run: make test
- name: torpc-proxy workspace tests
run: cargo test --manifest-path torpc-proxy/Cargo.toml --workspace
- name: tests
run: cargo test --workspace --tests

# Mandatory: any new RUSTSEC vulnerability against a crate in `Cargo.lock`
# fails the pipeline. Default cargo-audit behavior treats unmaintained /
# unsound / yanked as informational warnings, which is the right balance
# here — the Tauri 1.x dep tree carries some unmaintained transitives that
# we'll clear when we migrate to 2.x; surfacing them as hard errors today
# would block the daemon from shipping for an unrelated reason.
audit:
name: cargo audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: install cargo-audit
run: cargo install --locked cargo-audit
- name: cargo audit
run: cargo audit
118 changes: 118 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
name: Release

on:
push:
tags:
- 'v*'

# Need write access to create the release and upload assets.
permissions:
contents: write

jobs:
build:
name: build (${{ matrix.target }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
# Linux x86_64
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
archive_ext: tar.gz
# macOS Intel
- os: macos-13
target: x86_64-apple-darwin
archive_ext: tar.gz
# macOS Apple Silicon
- os: macos-latest
target: aarch64-apple-darwin
archive_ext: tar.gz
# Windows x86_64
- os: windows-latest
target: x86_64-pc-windows-msvc
archive_ext: zip

steps:
- uses: actions/checkout@v4

- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}

- uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.target }}

# Build the daemon and the CLI client. The Tauri GUI is intentionally
# excluded from the release for now — bundling needs platform-specific
# post-build steps (DMG, AppImage, MSI) that we'll add when there's
# demand. Source build of the GUI is documented in the README.
- name: build daemon + CLI client
run: |
cargo build --release --target ${{ matrix.target }} --bin torpc
cargo build --release --target ${{ matrix.target }} --bin torpc-proxy

# Pack each binary into the platform-conventional archive. macOS and
# Linux get tar.gz; Windows gets zip. Strip is implicit via the
# workspace [profile.release] `strip = true` setting.
- name: package (Unix)
if: runner.os != 'Windows'
shell: bash
run: |
set -euo pipefail
mkdir -p dist
for bin in torpc torpc-proxy; do
archive="${bin}-${GITHUB_REF_NAME}-${{ matrix.target }}.tar.gz"
tar -C "target/${{ matrix.target }}/release" -czf "dist/${archive}" "${bin}"
(cd dist && shasum -a 256 "${archive}" > "${archive}.sha256")
done
ls -la dist/

- name: package (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path dist | Out-Null
foreach ($bin in @("torpc", "torpc-proxy")) {
$archive = "${bin}-${env:GITHUB_REF_NAME}-${{ matrix.target }}.zip"
$exe = "target/${{ matrix.target }}/release/${bin}.exe"
Compress-Archive -Path $exe -DestinationPath "dist/${archive}"
$hash = (Get-FileHash -Algorithm SHA256 "dist/${archive}").Hash.ToLower()
"$hash ${archive}" | Out-File -Encoding ascii "dist/${archive}.sha256"
}
Get-ChildItem dist

- name: upload artifacts
uses: actions/upload-artifact@v4
with:
name: dist-${{ matrix.target }}
path: dist/*
if-no-files-found: error

release:
name: publish release
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: collect artifacts
uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true

- name: list collected artifacts
run: ls -la dist/

# Use the tag annotation as the release body if present, else fall back
# to a generic message. softprops/action-gh-release auto-generates a
# release on the corresponding tag.
- name: publish release
uses: softprops/action-gh-release@v2
with:
files: dist/*
generate_release_notes: true
fail_on_unmatched_files: true
Loading
Loading