Skip to content

Commit 37f129c

Browse files
authored
V2 (#42)
1 parent f148b7f commit 37f129c

27 files changed

+18414
-1306
lines changed

.github/workflows/checks.yaml

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,15 @@ on:
99

1010
jobs:
1111
test:
12-
name: E2E test
12+
name: E2E test (${{ matrix.flags }})
1313
runs-on: ubuntu-latest
14+
strategy:
15+
matrix:
16+
flags:
17+
- "l1"
18+
- "l1 --use-native-reth"
19+
- "opstack"
20+
- "opstack --external-builder http://host.docker.internal:4444"
1421
steps:
1522
- name: Check out code
1623
uses: actions/checkout@v2
@@ -20,11 +27,14 @@ jobs:
2027
with:
2128
go-version: 1.24
2229

23-
- name: Run playground
24-
run: go run main.go --output /tmp/playground & > /tmp/playground.log 2>&1
30+
- name: Install docker compose
31+
run: ./scripts/ci-setup-docker-compose.sh
32+
33+
- name: Build playground utils
34+
run: ./scripts/ci-build-playground-utils.sh
2535

26-
- name: Validate that blocks are created
27-
run: go run main.go watch-payloads --validate-payloads
36+
- name: Run playground
37+
run: go run main.go cook ${{ matrix.flags }} --output /tmp/playground --timeout 2m --watchdog
2838

2939
- name: Move playground logs
3040
if: ${{ failure() }}
@@ -34,23 +44,6 @@ jobs:
3444
uses: actions/upload-artifact@v4
3545
if: ${{ failure() }}
3646
with:
37-
name: playground-logs
47+
name: playground-logs-${{ matrix.flags }}
3848
path: /tmp/playground/logs
3949
retention-days: 5
40-
artifacts:
41-
name: Artifacts
42-
strategy:
43-
matrix:
44-
os: [ubuntu-latest, macos-13]
45-
runs-on: ${{ matrix.os }}
46-
steps:
47-
- name: Check out code
48-
uses: actions/checkout@v2
49-
50-
- name: Set up Go
51-
uses: actions/setup-go@v2
52-
with:
53-
go-version: 1.24
54-
55-
- name: Download and test artifacts
56-
run: go run main.go download-artifacts --validate
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: docker-utils-release
2+
# This action is used to update the utils docker image
3+
# whenever there is a change in the utils repo that lands on main
4+
5+
on:
6+
workflow_dispatch:
7+
push:
8+
branches:
9+
- main
10+
11+
jobs:
12+
docker:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v4
17+
18+
- name: Set up Docker Buildx
19+
uses: docker/setup-buildx-action@v3
20+
21+
- name: Login to Docker Hub
22+
uses: docker/login-action@v3
23+
with:
24+
username: ${{ secrets.DOCKERHUB_USERNAME }}
25+
password: ${{ secrets.DOCKERHUB_TOKEN }}
26+
27+
- name: Build and push
28+
uses: docker/build-push-action@v5
29+
with:
30+
context: .
31+
push: true
32+
tags: |
33+
docker.io/flashbots/playground-utils:latest
34+
docker.io/flashbots/playground-utils:${{ github.sha }}
35+
cache-from: type=gha
36+
cache-to: type=gha,mode=max

Dockerfile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
FROM golang:1.24
2+
WORKDIR /app
3+
4+
# Install build dependencies required for CGo
5+
RUN apt-get update && apt-get install -y gcc musl-dev
6+
7+
# Copy go mod files first
8+
COPY go.* ./
9+
RUN go mod download
10+
11+
# Copy the rest of the source code
12+
COPY . .
13+
14+
# Build all applications with CGo enabled
15+
RUN go build -o /usr/local/bin/cl-proxy ./cl-proxy/cmd/main.go && \
16+
go build -o /usr/local/bin/mev-boost-relay ./mev-boost-relay/cmd/main.go

README.md

Lines changed: 107 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,129 @@
11
# Builder Playground
22

3-
The builder playground is a tool to deploy an end-to-end environment to locally test an Ethereum L1 builder. It deploys:
3+
The builder playground is a tool to deploy an end-to-end environment to locally test EVM block builders.
4+
5+
## Usage
6+
7+
Clone the repository and use the `cook` command to deploy a specific recipe:
8+
9+
```bash
10+
$ builder-playground cook <recipe>
11+
```
12+
13+
Currently available recipes:
14+
15+
### L1 Recipe
16+
17+
Deploys a complete L1 environment with:
418

519
- A beacon node + validator client ([lighthouse](https://github.com/sigp/lighthouse)).
620
- An execution client ([reth](https://github.com/paradigmxyz/reth)).
721
- An in-memory [mev-boost-relay](https://github.com/flashbots/mev-boost-relay).
822

9-
## Usage
23+
```bash
24+
$ builder-playground cook l1 [flags]
25+
```
26+
27+
Flags:
28+
29+
- `--latest-fork`: Enable the latest fork at startup
30+
- `--use-reth-for-validation`: Use Reth EL for block validation in mev-boost.
31+
- `--secondary-el`: Port to use for a secondary el (enables the internal cl-proxy proxy)
32+
- `--use-native-reth`: Run the Reth EL binary on the host instead of docker (recommended to bind to the Reth DB)
33+
34+
### OpStack Recipe
1035

11-
Clone the repository and run the following command:
36+
Deploys an L2 environment with:
37+
38+
- Complete L1 setup (as above minus mev-boost)
39+
- A complete sequencer with op-node, op-geth and op-batcher
1240

1341
```bash
14-
$ go run main.go
42+
$ builder-playground cook opstack [flags]
1543
```
1644

17-
The playground performs the following steps:
45+
Flags:
46+
47+
- `--external-builder`: URL of an external builder to use (enables rollup-boost)
48+
49+
## Common Options
1850

19-
1. It attempts to download the `lighthouse` and `reth` binaries from the GitHub releases page if they are not found locally.
20-
2. It generates the genesis artifacts for the chain.
21-
- 100 validators with 32 ETH each.
22-
- 10 prefunded accounts with 100 ETH each, generated with the mnemonic `test test test test test test test test test test test junk`.
23-
- It enables the Deneb fork at startup.
24-
- It creates a chain with ID `1337`
25-
3. It deploys the chain services and the relay.
26-
- `Reth` node.
27-
- `Lighthouse` beacon node.
28-
- `Lighthouse` validator client.
29-
- `Mev-boost-relay`.
51+
- `--output` (string): The directory where the chain data and artifacts are stored. Defaults to `$HOME/.playground/devnet`
52+
- `--genesis-delay` (int): The delay in seconds before the genesis block is created. Defaults to `10` seconds
53+
- `--watchdog` (bool): Enable the watchdog service to monitor the specific chain
54+
- `--dry-run` (bool): Generates the artifacts and manifest but does not deploy anything (also enabled with the `--mise-en-place` flag)
3055

3156
To stop the playground, press `Ctrl+C`.
3257

33-
The `EL` instance is deployed with this deterministic enode address:
58+
## Internals
59+
60+
### Execution Flow
61+
62+
The playground executes in three main phases:
3463

64+
1. **Artifact Generation**: Creates all necessary files and configurations (genesis files, keys, etc.)
65+
2. **Manifest Generation**: The recipe creates a manifest describing all services to be deployed, their ports, and configurations
66+
3. **Deployment**: Uses Docker Compose to deploy the services described in the manifest
67+
68+
When running in dry-run mode (`--dry-run` flag), only the first two phases are executed. This is useful for alternative deployment targets - while the playground uses Docker Compose by default, the manifest could be used to deploy to other platforms like Kubernetes.
69+
70+
### System Architecture
71+
72+
The playground is structured in two main layers:
73+
74+
#### Components
75+
76+
Components are the basic building blocks of the system. Each component implements the `Service` interface:
77+
78+
```go
79+
type Service interface {
80+
Run(service *service)
81+
}
3582
```
36-
enode://3479db4d9217fb5d7a8ed4d61ac36e120b05d36c2eefb795dc42ff2e971f251a2315f5649ea1833271e020b9adc98d5db9973c7ed92d6b2f1f2223088c3d852f@127.0.0.1:30303
83+
84+
Components represent individual compute resources like:
85+
86+
- Execution clients (Reth)
87+
- Consensus clients (Lighthouse)
88+
- Sidecar applications (MEV-Boost Relay)
89+
90+
Each component, given its input parameters, outputs a Docker container description with its specific configuration.
91+
92+
#### Recipes
93+
94+
Recipes combine components in specific ways to create complete environments. They implement this interface:
95+
96+
```go
97+
type Recipe interface {
98+
Apply(artifacts *Artifacts) *Manifest
99+
}
37100
```
38101

39-
Options:
102+
The key output of a recipe is a `Manifest`, which represents a complete description of the environment to be deployed. A Manifest contains:
103+
104+
- A list of services to deploy
105+
- Their interconnections and dependencies
106+
- Port mappings and configurations
107+
- Volume mounts and environment variables
108+
109+
While the current recipes (L1 and OpStack) are relatively simple, this architecture allows for more complex setups. For example, you could create recipes for:
110+
111+
- Multiple execution clients with a shared bootnode
112+
- Testing specific MEV scenarios
113+
- Interop L2 testing environments
114+
115+
The separation between components and recipes makes it easy to create new environments by reusing and combining existing components in different ways. The Manifest provides an abstraction between the recipe's description of what should be deployed and how it actually gets deployed (Docker Compose, Kubernetes, etc.).
116+
117+
## Design Philosophy
118+
119+
The Builder Playground is focused exclusively on block building testing and development. Unlike general-purpose tools like Kurtosis that support any Ethereum setup, we take an opinionated approach optimized for block building workflows.
120+
121+
We deliberately limit configuration options and client diversity to keep the tool simple and maintainable. This focused approach allows us to provide a smooth developer experience for block building testing scenarios while keeping the codebase simple and maintainable.
122+
123+
This means we make specific choices:
40124

41-
- `--output` (string): The directory where the chain data and artifacts are stored. It defaults to `$HOME/.playground/devnet`.
42-
- `--continue` (bool): Whether to restart the chain from a previous run if the output folder is not empty. It defaults to `false`.
43-
- `--use-bin-path` (bool): Whether to use the binaries from the local path instead of downloading them. It defaults to `false`.
44-
- `--genesis-delay` (int): The delay in seconds before the genesis block is created. It is used to account for the delay between the creation of the artifacts and the running of the services. It defaults to `10` seconds.
45-
- `--electra`: (bool): If enabled, it enables the Electra fork at startup. It defaults to `false`.
125+
- Fixed client implementations (Lighthouse, Reth)
126+
- Recipe-based rather than modular configurations
127+
- Pre-backed configurations
46128

47-
Unless the `--continue` flag is set, the playground will delete the output directory and start a new chain from scratch on every run.
129+
For use cases outside our scope, consider using a more general-purpose tool like Kurtosis.

0 commit comments

Comments
 (0)