-
Notifications
You must be signed in to change notification settings - Fork 51
feat: small improvements to BuilderNet recipe #386
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
0154391
feat: add optional argument to prepare.sh to point to vm image location
fkondej e99b1a3
feat: add support for non kvm machines
fkondej d52855c
chore: print more info when prepare and start vm
fkondej 4d70e5f
feat: start buildernet VM differently
fkondej 33dfd5a
feat: add extra data validation argument to test command
fkondej f8bed14
chore: address code review comments
fkondej 20fa218
chore: make ./prepare.sh a manual step
fkondej 53466fb
feat: update BuilderNet recipe usage instructions
fkondej f71b9a6
fix: code review comments
fkondej 89b794b
feat: re-add init section using BUILDERNET_IMAGE env
fkondej cd598d7
feat: stop VM as part of prepare.sh and remove redundand rm
fkondej File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,106 +1,162 @@ | ||
| # BuilderNet VM Scripts | ||
| # BuilderNet VM for Playground | ||
|
|
||
| Temporary bash scripts for running BuilderNet VM alongside builder-playground. | ||
| Feel free to translate them to Go and integrate into the CLI. | ||
| Run a BuilderNet VM alongside builder-playground's L1 network. The playground manages the L1 stack (Reth, Lighthouse, mev-boost-relay, builder-hub) in Docker, while a BuilderNet VM runs in QEMU and proposes blocks to the network. | ||
|
|
||
| ## Information: | ||
| > **Important:** The VM image must be built with the `playground` mkosi profile. Production images are hardened and will not work with this setup. | ||
|
|
||
| Changes are made in two repos: | ||
| - [flashbots-images](https://github.com/flashbots/flashbots-images/tree/fryd/mkosi-playground) on `fryd/mkosi-playground` branch, | ||
| - [builder-playground](https://github.com/flashbots/builder-playground/tree/fryd/mkosi-playground) on `fryd/mkosi-playground` branch, | ||
| ## Prerequisites | ||
|
|
||
| There are no plans of using [buildernet-playground](https://github.com/flashbots/buildernet-playground) repo. | ||
| - **Linux with KVM** (macOS is not supported) | ||
| - **Docker** (for the L1 network stack) | ||
| - **QEMU** with KVM support (`qemu-system-x86_64`) | ||
| - **UEFI firmware** (`edk2-ovmf` or equivalent) | ||
| - **socat** (for VM console access) | ||
| - **jq**, **curl** | ||
|
|
||
| ## Start playground | ||
|
|
||
| Start playground with: `--bind-external` (expose ports to the VM) and `--contender` (create transactions) | ||
| Verify KVM is available: | ||
|
|
||
| ```bash | ||
| builder-playground \ | ||
| start buildernet \ | ||
| --bind-external \ | ||
| --output ".playground-home" \ | ||
| --contender \ | ||
| --detached fryd-vm-builder | ||
| ls /dev/kvm | ||
| ``` | ||
|
|
||
| ## First Time Setup | ||
| ## Quick Start | ||
|
|
||
| ```bash | ||
| ./sync.sh # Clone / fetch flashbots-images repo | ||
| ./build.sh # Build VM image with mkosi | ||
| ./prepare.sh # Extract image + create data disk | ||
| # 1. Install builder-playground | ||
| curl -sSfL https://raw.githubusercontent.com/flashbots/builder-playground/main/install.sh | bash | ||
|
|
||
| # 2. Create project dir and generate recipe files | ||
| mkdir buildernet-dev && cd buildernet-dev | ||
| builder-playground generate buildernet/mkosi | ||
|
|
||
| # 3. Point to the VM image binary | ||
| # - alternatively you can edit playground.yaml | ||
| # - you can point to local disk or URL | ||
| export BUILDERNET_IMAGE=flashbots-images/path/buildernet-playground.qcow2 | ||
|
|
||
| # 4. Start | ||
| builder-playground start playground.yaml --bind-external --detached | ||
|
|
||
| # 5. Verify by sending transaction | ||
| builder-playground test --rpc http://localhost:18645 --el-rpc http://localhost:8545 | ||
| ``` | ||
|
|
||
| `sync.sh` clones/updates the `fryd/mkosi-playground` branch of flashbots-images. | ||
| If the test transaction is included in a block, the full pipeline is working: transaction reaches rbuilder inside the VM, rbuilder builds a block, and it lands on the L1 chain. | ||
|
|
||
| ## Run VM | ||
| ## Using Your Own Image | ||
|
|
||
| ```bash | ||
| ./start.sh # Start VM (background) | ||
| ./console.sh # Open console to the VM | ||
| ./ssh.sh # SSH into running VM (requires SSH key setup) | ||
| ./stop.sh # Stop VM | ||
| For developers working on [flashbots-images](https://github.com/flashbots/flashbots-images) who want to test VM changes against a local network. | ||
|
|
||
| Build the image in your flashbots-images checkout using the **playground** mkosi profile, then point `BUILDERNET_IMAGE` to it: | ||
|
|
||
| ```yaml | ||
| # In playground.yaml, under builder > env: | ||
| env: | ||
| BUILDERNET_IMAGE: "/path/to/buildernet-qemu_latest.qcow2" | ||
| ``` | ||
|
|
||
| ## Builder Hub | ||
| Or override via environment variable: | ||
|
|
||
| ```bash | ||
| ./builderhub-configure.sh # Register VM with builder-hub and update config for the VM | ||
| ./builderhub-get-config.sh # Get configuration for the VM | ||
| export BUILDERNET_IMAGE=/path/to/buildernet-qemu_latest.qcow2 | ||
| ``` | ||
|
|
||
| ## Operator API | ||
| See the [flashbots-images](https://github.com/flashbots/flashbots-images) repository for build environment setup, available profiles, and customization options. | ||
|
|
||
| Scripts to interact with the operator-api service running inside the VM. | ||
| ## VM Management | ||
|
|
||
| > **Note:** Actions and File Uploads could potentially be used for various things, like injecting genesis config instead of BuilderHub - still exploring this functionality. | ||
| ### Lifecycle | ||
|
|
||
| ```bash | ||
| ./operator-api-health.sh # Check if operator-api is healthy | ||
| ./operator-api-logs.sh # Get event logs | ||
| ./operator-api-action.sh <action> # Execute an action | ||
| ./scripts/stop.sh # Stop the VM (Docker L1 stack keeps running) | ||
| ./scripts/prepare.sh <path-or-url> # Reset VM to fresh state | ||
| ./scripts/start.sh # Start the VM | ||
| ``` | ||
|
|
||
| Available actions: | ||
| - `reboot` - Reboot the system | ||
| - `rbuilder_restart` - Restart rbuilder-operator service | ||
| - `rbuilder_stop` - Stop rbuilder-operator service | ||
| - `fetch_config` - Fetch config from BuilderHub | ||
| - `rbuilder_bidding_restart` - Restart rbuilder-bidding service | ||
| - `ssh_stop` - Stop SSH service | ||
| - `ssh_start` - Start SSH service | ||
| - `haproxy_restart` - Restart HAProxy service | ||
| ### Access | ||
|
|
||
| ### File Uploads | ||
| ```bash | ||
| ./scripts/console.sh # Serial console (exit: Ctrl+]) | ||
| ``` | ||
|
|
||
| Upload files to predefined paths. Only whitelisted names from `[file_uploads]` config are allowed: | ||
| ### Environment Variables | ||
|
|
||
| ```toml | ||
| [file_uploads] | ||
| rbuilder_blocklist = "/var/lib/persistent/rbuilder-operator/rbuilder.blocklist.json" | ||
| ``` | ||
| | Variable | Default | Description | | ||
| |----------|---------|-------------| | ||
| | `BUILDERNET_IMAGE` | *(set in playground.yaml)* | Path or URL to the VM qcow2 image | | ||
| | `QEMU_CPU` | `8` | Number of CPU cores | | ||
| | `QEMU_RAM` | `32G` | Memory allocation | | ||
| | `QEMU_ACCEL` | `kvm` | Acceleration (`kvm` or `tcg`) | | ||
|
|
||
| Environment variables override values defined in `playground.yaml`. | ||
|
|
||
| ## Operator API | ||
|
|
||
| The operator-api runs inside the VM and is exposed on port 13535: | ||
|
|
||
| ```bash | ||
| # Stores local blocklist.json content to the configured remote path | ||
| curl -k --data-binary "@blocklist.json" https://localhost:13535/api/v1/file-upload/rbuilder_blocklist | ||
| ./scripts/operator-api-health.sh # Health check | ||
| ./scripts/operator-api-logs.sh # Event logs | ||
| ./scripts/operator-api-action.sh <action> # Execute an action | ||
| ``` | ||
|
|
||
| ### Customization | ||
|
|
||
| To add more actions or file uploads, modify the config template: | ||
| https://github.com/flashbots/flashbots-images/blob/fryd/mkosi-playground/mkosi.profiles/playground/mkosi.extra/usr/lib/mustache-templates/etc/operator-api/config.toml.mustache | ||
| Available actions: `reboot`, `rbuilder_restart`, `rbuilder_stop`, `fetch_config`, `rbuilder_bidding_restart`, `ssh_stop`, `ssh_start`, `haproxy_restart`. | ||
|
|
||
| ## Maintenance | ||
| ## Stopping | ||
|
|
||
| ```bash | ||
| ./sync.sh # Update flashbots-images to latest | ||
| ./clean.sh # Clean build artifacts + runtime files | ||
| # Stop just the VM (Docker keeps running) | ||
| ./scripts/stop.sh | ||
|
|
||
| # Stop everything | ||
| builder-playground stop <session-name> | ||
|
|
||
| # Full cleanup | ||
| builder-playground clean <session-name> | ||
| ./scripts/clean.sh | ||
| ``` | ||
|
|
||
| Use `builder-playground list` to find the session name. | ||
|
|
||
| ## Ports | ||
|
|
||
| | Port | Service | | ||
| |------|---------| | ||
| | 2222 | SSH (maps to VM:40192) | | ||
| | 13535 | Operator API (maps to VM:3535) | | ||
| ### VM (QEMU host forwarding) | ||
|
|
||
| | Host Port | VM Port | Service | | ||
| |-----------|---------|---------| | ||
| | 2222 | 40192 | SSH | | ||
| | 13535 | 3535 | Operator API | | ||
| | 18645 | 8645 | rbuilder JSON-RPC | | ||
| | 10080 | 80 | HAProxy HTTP | | ||
| | 10443 | 443 | HAProxy HTTPS | | ||
|
|
||
| ### Playground (Docker) | ||
|
|
||
| Use `builder-playground port <service> <port-name>` to look up host ports. Common services: `el` (Reth), `beacon` (Lighthouse), `mev-boost-relay`. | ||
|
|
||
| ## File Structure | ||
|
|
||
| After `builder-playground generate buildernet/mkosi`: | ||
|
|
||
| ``` | ||
| buildernet-dev/ | ||
| ├── playground.yaml # Recipe (L1 stack + VM lifecycle hooks) | ||
| ├── config/ # configs used by the BuilderNet setup | ||
| └── scripts/ | ||
| ├── prepare.sh # Download/copy image + create data disk | ||
| ├── start.sh # Start the QEMU VM | ||
| ├── stop.sh # Stop the QEMU VM | ||
| ├── console.sh # Serial console | ||
| ├── clean.sh # Remove runtime files | ||
| └── operator-api-*.sh # Operator API helpers | ||
| ``` | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| **"KVM not available"** — Ensure `/dev/kvm` exists. You may need: `sudo usermod -aG kvm $USER` | ||
|
|
||
| **"OVMF not found"** — Install UEFI firmware: `sudo apt install ovmf` (Debian/Ubuntu) or `sudo dnf install edk2-ovmf` (Fedora) | ||
|
|
||
| **VM boots but doesn't connect** — Ensure playground was started with `--bind-external` so the VM can reach Docker services via `10.0.2.2` (QEMU user-mode networking gateway). | ||
|
|
||
| **Console shows login prompt** — The image was not built with the `playground` mkosi profile. Rebuild with the profile enabled. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,31 +1,57 @@ | ||
| #!/usr/bin/env bash | ||
| # Extract VM image and create data disk | ||
| # | ||
| # Usage: | ||
| # ./prepare.sh /path/to/image.qcow2 # Use local image | ||
| # ./prepare.sh https://example.com/img.qcow2 # Download from URL | ||
| # | ||
| # Environment: | ||
| # BUILDERNET_IMAGE - Path or URL to VM image (overridden by $1 argument) | ||
| set -eu -o pipefail | ||
|
|
||
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| PROJECT_DIR="${SCRIPT_DIR}/.." | ||
|
|
||
| FLASHBOTS_IMAGES_DIR="${PROJECT_DIR}/.flashbots-images" | ||
| RUNTIME_DIR="${PROJECT_DIR}/.runtime" | ||
|
|
||
| QEMU_QCOW2="${FLASHBOTS_IMAGES_DIR}/mkosi.output/buildernet-qemu_latest.qcow2" | ||
|
|
||
| VM_IMAGE="${RUNTIME_DIR}/buildernet-vm.qcow2" | ||
| VM_DATA_DISK="${RUNTIME_DIR}/persistent.raw" | ||
|
|
||
| if [[ ! -f "${QEMU_QCOW2}" ]]; then | ||
| echo "Error: QEMU qcow2 image not found: ${QEMU_QCOW2}" | ||
| echo "Run ./scripts/build.sh first." | ||
| # Determine source image: $1 > $BUILDERNET_IMAGE > error | ||
| SOURCE="${1:-${BUILDERNET_IMAGE:-}}" | ||
|
|
||
| if [[ -z "${SOURCE}" ]]; then | ||
| echo "Error: no VM image specified." | ||
| echo "Set BUILDERNET_IMAGE or pass a path/URL as argument." | ||
| echo "Usage: ./scripts/prepare.sh [/path/to/image.qcow2 | https://url/to/image.qcow2]" | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "prepare.sh: PROJECT_DIR=${PROJECT_DIR}" | ||
| echo "prepare.sh: RUNTIME_DIR=${RUNTIME_DIR}" | ||
| echo "prepare.sh: SOURCE=${SOURCE}" | ||
|
|
||
| # Ensure the VM is stopped before replacing runtime files (PID file, disk images). | ||
| "${SCRIPT_DIR}/stop.sh" | ||
|
|
||
| rm -rf "${RUNTIME_DIR}" | ||
| mkdir -p "${RUNTIME_DIR}" | ||
|
|
||
| rm -f "${VM_IMAGE}" | ||
| cp --sparse=always "${QEMU_QCOW2}" "${VM_IMAGE}" | ||
| if [[ "${SOURCE}" =~ ^https?:// ]]; then | ||
| echo "prepare.sh: downloading from URL..." | ||
| TMP_IMAGE="${VM_IMAGE}.tmp" | ||
| curl -fSL -o "${TMP_IMAGE}" "${SOURCE}" | ||
| mv "${TMP_IMAGE}" "${VM_IMAGE}" | ||
| elif [[ -f "${SOURCE}" ]]; then | ||
| echo "prepare.sh: copying local file ($(du -h "${SOURCE}" | cut -f1))..." | ||
| cp --sparse=always "${SOURCE}" "${VM_IMAGE}" | ||
| else | ||
| echo "Error: VM image not found: ${SOURCE}" | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "prepare.sh: creating data disk..." | ||
| qemu-img create -f raw "${VM_DATA_DISK}" 100G | ||
|
|
||
| echo "Runtime ready: ${RUNTIME_DIR}" | ||
| echo "prepare.sh: runtime ready" | ||
| ls -lah "${RUNTIME_DIR}" |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.