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
2 changes: 2 additions & 0 deletions .github/workflows/checks_docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ jobs:
steps:
- name: Checkout sources
uses: actions/checkout@v4
with:
submodules: recursive # required: mevcommit-proto reads vendor/mev-commit at build time

- name: Docker QEMU
uses: docker/setup-qemu-action@v3
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ jobs:

- uses: actions/checkout@v4
if: steps.platform-check.outputs.skip != 'true'
with:
submodules: recursive # required: mevcommit-proto reads vendor/mev-commit at build time

# Linux: Use Docker for reproducible builds
- name: Set up Docker Buildx
Expand Down Expand Up @@ -283,6 +285,8 @@ jobs:
steps:
- name: checkout sources
uses: actions/checkout@v4
with:
submodules: recursive # required: mevcommit-proto reads vendor/mev-commit at build time

- name: Download linux rbuilder binary
id: download-binary
Expand Down Expand Up @@ -376,6 +380,8 @@ jobs:
steps:
- name: checkout sources
uses: actions/checkout@v4
with:
submodules: recursive # required: mevcommit-proto reads vendor/mev-commit at build time

- name: docker buildx
uses: docker/setup-buildx-action@v3
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "mev-test-contract/lib/forge-std"]
path = mev-test-contract/lib/forge-std
url = https://github.com/foundry-rs/forge-std.git
[submodule "vendor/mev-commit"]
path = vendor/mev-commit
url = https://github.com/primev/mev-commit.git
10 changes: 10 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ members = [
"crates/rbuilder/src/test_utils",
"crates/rbuilder/src/telemetry/metrics_macros",
"crates/eth-sparse-mpt",
"crates/mevcommit-proto",
"crates/sysperf",
"crates/test-relay",
"crates/bid-scraper",
Expand Down Expand Up @@ -175,6 +176,7 @@ proptest = "1.5"

eth-sparse-mpt = { path = "crates/eth-sparse-mpt" }
bid-scraper = { path = "crates/bid-scraper" }
mevcommit-proto = { path = "crates/mevcommit-proto" }
rbuilder = { path = "crates/rbuilder" }
rbuilder-primitives = { path = "crates/rbuilder-primitives" }
rbuilder-utils = { path = "crates/rbuilder-utils" }
Expand Down
306 changes: 306 additions & 0 deletions DEPLOYMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,306 @@
# rbuilder — Deployment Guide

Deploying rbuilder is identical to upstream Flashbots rbuilder with two additions:

1. The `vendor/mev-commit` submodule must be initialized before building.
2. The config requires a `[mevcommit]` section pointing at a running mev-commit provider sidecar (**MEV-Commit release `v1.3.0-rc1` required**).

---

## Prerequisites

The following must already be running and reachable before rbuilder starts:


| Dependency | Purpose | Notes |
| ------------------------------- | ------------------------------------ | ------------------------------------- |
| **Reth** (EL node) | Chain state, mempool | IPC socket at `/tmp/reth.ipc` |
| **Beacon node** (CL node) | Slot events, validator registrations | HTTP, typically port 3500 |
| **MEV-Boost relay(s)** | Block submission | HTTPS endpoints from relay operators |
| **mev-commit provider sidecar** | Preconfirmation bid intake | gRPC on port 13524; deploy separately (requires MEV-Commit `v1.3.0-rc1`) |


rbuilder will start without the sidecar but will emit reconnect warnings and accept no preconf bids until it connects. If you do not have a provider running yet, see [MEV-Commit provider setup](#mev-commit-provider-sidecar-setup) at the end of this guide.

---

## Step 1 — Get the code

```bash
git clone https://github.com/shutter-network/rbuilder.git
cd rbuilder
git checkout mevcommit-integration

# Required: populate the mev-commit submodule before building
git submodule update --init --recursive
```

---

## Step 2 — Build the Docker image

```bash
docker build \
--target rbuilder-runtime \
-f docker/Dockerfile.rbuilder \
-t rbuilder-mev-commit:latest \
.
```

Build args (both optional):


| Arg | Default | Notes |
| -------------- | ---------- | ----------------------------------------------------------------------- |
| `FEATURES` | (none) | Comma-separated Cargo features, e.g. `redact-sensitive` |
| `RBUILDER_BIN` | `rbuilder` | Binary to build; change to `rbuilder-operator` for the operator variant |


The build uses `cargo-chef` for layer caching. First build takes ~10–20 minutes; subsequent builds are much faster if dependencies haven't changed.

---

## Step 3 — Create the config file

Copy the example and edit it:

```bash
cp examples/config/rbuilder/config-live-example.toml config.toml
```

The table below covers every section in the example. Work through it top-to-bottom before running.

### Top-level fields

| Field | Action | Notes |
|---|---|---|
| `log_json`, `log_level` | Keep | Leave as-is |
| `redacted_telemetry_server_port` / `full_telemetry_server_port` | Keep | 6061 (redacted, safe to expose) / 6060 (full, internal only) |
| `chain` | **Set** | `"mainnet"`, `"holesky"`, or `"hoodi"` |
| `reth_datadir` | **Set** | Path to your reth data dir, e.g. `/mnt/data/reth` |
| `coinbase_secret_key` | Keep as `"env:COINBASE_SECRET_KEY"` | Value comes from environment |
| `relay_secret_key` | Keep as `"env:RELAY_SECRET_KEY"` | Value comes from environment |
| `cl_node_url` | Keep as `["env:CL_NODE_URL"]` | Value comes from environment |
| `jsonrpc_server_port` | Keep | Orderflow port (8645) |
| `el_node_ipc_path` | **Set** | Path to reth IPC socket, e.g. `/tmp/reth.ipc` |
| `extra_data` | Optional | Builder tag embedded in blocks |
| `blocklist_file_path` | **Remove or comment out** | The example sets `"./blocklist.json"` — this file does NOT exist in the container and will crash rbuilder at startup. Remove the line entirely (no blocklist = all addresses allowed). |
| `ignore_cancellable_orders` | Keep | Leave as-is |
| `live_builders` | Keep | Leave as-is |
| `enabled_relays` | **Remove or update** | `["flashbots"]` enables the hardcoded Flashbots mainnet relay. Remove this line — all `[[relays]]` blocks you define below are always enabled automatically. |
| `subsidy` | Optional | Remove if not using subsidy logic |

### `[[subsidy_overrides]]`

**Remove** — references `"flashbots_test2"` which is a test relay. Delete this block.

### `[[relays]]`

**Remove both test blocks** (`flashbots_test`, `flashbots_test2`) — they point at `http://localhost:80` and will cause submission errors in production.

**Add your real relay(s):**

```toml
[[relays]]
name = "your-relay-name"
url = "https://<pubkey>@<relay-host>"
mode = "full"
```

Built-in relay names you can enable via `enabled_relays` without defining a block (already hardcoded in the binary): `flashbots`, `ultrasound-us`, `ultrasound-eu`, and others. If you use one of these names in `[[relays]]`, your config overrides the built-in URL.

### `[[builders]]`

Keep all three blocks (`mgp-ordering`, `mp-ordering`, `parallel`) as-is.

### `[[relay_bid_scrapers]]`

Keep or remove the two Ultrasound scraper entries — they provide competitive bid data but are not required to submit blocks.

### `[mevcommit]`

**Set these two fields:**

```toml
[mevcommit]
enabled = true
provider_grpc_addr = "http://<sidecar-host>:13524"
# The sidecar can run on any host reachable from this machine:
# same host: "http://127.0.0.1:13524"
# separate VM: "http://10.0.0.5:13524"
# DNS name: "http://mev-commit-provider.internal:13524"
```

Leave all other tuning fields commented out (defaults are production-safe).

---

The `"env:VAR"` syntax is resolved at startup from the process environment. Never put raw private key values in the file.

---

## Step 4 — Set environment variables

Export these in your shell, systemd unit, or container environment before running:

```bash
export COINBASE_SECRET_KEY=<hex-private-key> # builder signing key
export RELAY_SECRET_KEY=<hex-private-key> # relay submission key
export CL_NODE_URL=http://<beacon-node>:3500
```

Optional:

```bash
export RUST_LOG=info,rbuilder=debug # log verbosity
```

---

## Step 5 — Run

```bash
docker run \
--name rbuilder \
--restart unless-stopped \
--network host \
-e COINBASE_SECRET_KEY \
-e RELAY_SECRET_KEY \
-e CL_NODE_URL \
-e RUST_LOG \
-v $(pwd)/config.toml:/config/config.toml:ro \
-v /mnt/data/reth:/mnt/data/reth:ro \
-v /tmp/reth.ipc:/tmp/reth.ipc \
rbuilder-mev-commit:latest \
run --config /config/config.toml
```

Port reference (all on host network):

| Port | Expose? | Purpose |
| ------ | ------------- | ------------------------------------------------- |
| `6060` | Internal only | Full Prometheus metrics (contains sensitive data) |
| `6061` | Optional | Redacted Prometheus metrics |
| `8645` | Yes | JSON-RPC orderflow (searchers/bundlers) |
| `6071` | Yes | Optimistic V3 relay submission |


---

## Step 6 — Verify startup

Watch the logs:

```bash
docker logs -f rbuilder
```

Expected sequence:

```
# rbuilder core started — keys and relay loaded
INFO rbuilder: Builder coinbase address: 0x...
INFO rbuilder: Builder mev boost relay pubkey: ...
INFO rbuilder: Optimistic V3 is enabled for at least one relay, spawning server ...

# mev-commit integration started
INFO mevcommit: Starting mev-commit provider integration grpc_addr=http://... shutter_fetch_timeout_ms=2000

# sidecar handshake succeeded
INFO mevcommit: mev-commit sidecar connected grpc_addr=http://...
```

If the sidecar is not yet reachable (non-fatal, retries automatically):

```
WARN mevcommit: mev-commit bid stream session error error=... ; reconnecting
```

To see per-slot mev-commit state (debug level — requires `RUST_LOG=info,rbuilder=debug`):

```
DEBUG mevcommit: mev-commit slot state rotated slot=... target_block=... is_primev=true block_gas_limit=...
```

---

## Step 7 — Verify mev-commit integration

Check Prometheus metrics (redacted endpoint):

```bash
curl -s http://localhost:6061/metrics | grep mevcommit_
```

Expected in normal operation:

```
mevcommit_grpc_reconnects_total 0 # sidecar is stable
mevcommit_bids_received_total N # bids flowing (N > 0 once bidders connect)
mevcommit_blocks_suppressed_total 0 # slash protection not firing
```

---

## Updating

To deploy a new version:

```bash
# Pull latest code
git pull
git submodule update --recursive

# Rebuild
docker build --target rbuilder-runtime -f docker/Dockerfile.rbuilder -t rbuilder-mev-commit:latest .

# Replace running container
docker stop rbuilder && docker rm rbuilder
# re-run Step 5
```

---

## Rollback / disabling mev-commit

To disable the mev-commit integration without changing the binary:

```toml
[mevcommit]
enabled = false
```

Restart rbuilder. No sidecar connection is made; all `mevcommit_*` metrics stay at 0. rbuilder behaves identically to upstream Flashbots rbuilder.

---

## MEV-Commit Provider Sidecar Setup

The MEV-Commit provider runs as a **separate service**. Before enabling `[mevcommit]` in rbuilder, you must have a running, registered MEV-Commit provider node. rbuilder connects to it via `provider_grpc_addr` (gRPC, default port 13524).

### Install the provider node

Follow the official setup guide: [Manual start — mev-commit](https://docs.primev.xyz/v1.1.0/developers/manual-start-mev-commit).

**Important:** that guide downloads **v1.1.0**, which is **not compatible** with Shutterised Bids. Use **v1.3.0-rc1** instead:

- Release: [v1.3.0-rc1](https://github.com/primev/mev-commit/releases/tag/v1.3.0-rc1)

```bash
FILENAME="mev-commit_1.3.0-rc1_$(uname -s)_$(uname -m).tar.gz"
curl -L \
"https://github.com/primev/mev-commit/releases/download/v1.3.0-rc1/$FILENAME" \
| tar -xz -C .
```

The archive has no top-level directory — it extracts `mev-commit`, `LICENSE`, and `README.md` directly into the current directory.

After installing the correct binary, follow the remainder of the official guide unchanged (wallet setup, chain config, starting the provider node).

### Register and stake as a provider

Running the provider node alone is not sufficient. You must register and stake as a provider per the Primev docs:

[Registering a provider](https://docs.primev.xyz/v1.1.0/get-started/providers/registering-a-provider)

Once the provider is registered, running, and reachable, set `provider_grpc_addr` in rbuilder's `[mevcommit]` config to its gRPC endpoint.
Loading