{"id":20433851,"url":"https://github.com/flashbots/builder-playground","last_synced_at":"2026-04-02T11:47:49.919Z","repository":{"id":250839066,"uuid":"835357885","full_name":"flashbots/builder-playground","owner":"flashbots","description":"A fast, self-contained environment for end-to-end block building on L1s and L2s.","archived":false,"fork":false,"pushed_at":"2026-03-24T03:51:03.000Z","size":2124,"stargazers_count":128,"open_issues_count":19,"forks_count":51,"subscribers_count":7,"default_branch":"main","last_synced_at":"2026-03-25T03:29:49.584Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flashbots.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2024-07-29T17:06:28.000Z","updated_at":"2026-03-24T03:48:43.000Z","dependencies_parsed_at":"2024-08-25T11:46:12.137Z","dependency_job_id":"91538738-8b44-4599-8533-9ad8e44043f4","html_url":"https://github.com/flashbots/builder-playground","commit_stats":null,"previous_names":["flashbots/builder-playground"],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/flashbots/builder-playground","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flashbots%2Fbuilder-playground","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flashbots%2Fbuilder-playground/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flashbots%2Fbuilder-playground/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flashbots%2Fbuilder-playground/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flashbots","download_url":"https://codeload.github.com/flashbots/builder-playground/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flashbots%2Fbuilder-playground/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31305809,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T09:48:21.550Z","status":"ssl_error","status_checked_at":"2026-04-02T09:48:19.196Z","response_time":89,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-15T08:21:49.518Z","updated_at":"2026-04-02T11:47:49.911Z","avatar_url":"https://github.com/flashbots.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Builder Playground\n\n[![Goreport status](https://goreportcard.com/badge/github.com/flashbots/builder-playground)](https://goreportcard.com/report/github.com/flashbots/builder-playground)\n[![Test status](https://github.com/flashbots/builder-playground/actions/workflows/checks.yaml/badge.svg?branch=main)](https://github.com/flashbots/builder-playground/actions?query=workflow%3A%22Checks%22)\n\nBuilder Playground is a CLI tool for spinning up self-contained Ethereum development networks for end-to-end block building. With a single command, it deploys complete L1 and L2 stacks—including EL and CL nodes, mev-boost, relays, and builder infrastructure. Designed for speed, determinism, and ease of use, it serves as the foundation for testing block-builder software, BuilderNet VM images, and integration tests across chains.\n\nRecipes (e.g. `l1`, `opstack`) assemble opinionated components and pre-baked configs to bring a full blockchain stack online within seconds. This makes it ideal for:\n\n- Developing and testing block-building pipelines\n- Validating builder/relay behavior against real consensus flows\n- Running repeatable CI and e2e scenarios\n- Experimenting with fork configurations and client combinations\n\n## Installation\n\n### Install with script (recommended)\n\nOn Linux and macOS, you can install the latest version to `/usr/local/bin` with:\n\n```bash\ncurl -sSfL https://raw.githubusercontent.com/flashbots/builder-playground/main/install.sh | bash\n```\n\nIf you need to install a specific version, you can use the `VERSION` env var in the beginning like:\n```bash\nVERSION=1.2.3 curl -sSfL https://raw.githubusercontent.com/flashbots/builder-playground/main/install.sh | bash\n```\n\n### Install from repository\n\nExtend the `PATH` variable with `GOPATH/bin` (or `GOBIN` if set), then clone the repository and do:\n```bash\ngo install .\n```\n\n---\n\nThese commands install to different directories as mentioned above so make sure to verify with `which builder-playground` to avoid confusion!\n\n## Quick Examples\n\n```bash\n# L1 environment with mev-boost relay\nbuilder-playground start l1\n\n# L2 OpStack with external builder support\nbuilder-playground start opstack --external-builder http://localhost:4444\n```\n\n## CI / GitHub Actions\n\nUse [`flashbots/builder-playground-action`](https://github.com/flashbots/builder-playground-action) to spin up devnets in your CI pipelines:\n\n```yaml\n- name: Start Builder Playground\n  uses: flashbots/builder-playground-action@v1\n  with:\n    recipe: l1\n\n- name: Run tests\n  run: |\n    # Your tests here\n```\n\nYou can also use a custom recipe file and pin a specific version:\n\n```yaml\n- name: Start Builder Playground\n  uses: flashbots/builder-playground-action@v1\n  with:\n    version: v1.0.0\n    recipe: ./configs/my-recipe.yaml\n```\n\nSee the [builder-playground-action README](https://github.com/flashbots/builder-playground-action) for full documentation.\n\n## Getting started\n\nSee the available recipes from the `recipes` command:\n\n```\nBase Recipes:\n  l1\n    Deploy a full L1 stack with mev-boost\n    reth, lighthouse-beacon-node, lighthouse-validator-node, mev-boost-relay\n\n... (more base and custom recipes available in the original output)\n```\n\nUse the `start` command to deploy a specific recipe:\n\n```bash\n$ builder-playground start l1\n```\n\nand you can send a test transaction from prefunded accounts by using:\n\n```bash\n$ builder-playground test\n```\n\nIf you need to modify a recipe or build your own, make sure to check out the [custom recipes](docs/custom_recipes.md) documentation!\n\nBase recipes are also runnable with some flags and you can check out the documentation [here](docs/recipes) do find out.\n\nCurrently available recipes:\n\n### L1 Recipe\n\nDeploys a complete L1 environment with:\n\n- A beacon node + validator client ([lighthouse](https://github.com/sigp/lighthouse)).\n- An execution client ([reth](https://github.com/paradigmxyz/reth)).\n- An in-memory [mev-boost-relay](https://github.com/flashbots/mev-boost-relay).\n\n```bash\n$ builder-playground start l1 [flags]\n```\n\nFlags:\n\n- `--latest-fork`: Enable the latest fork at startup\n- `--block-time`: Change the default block time (`12s`), to be provided in duration format (e.g. `--block-time=1s`)\n- `--use-reth-for-validation`: Use Reth EL for block validation in mev-boost.\n- `--secondary-el`: Host or port to use for a secondary el (enables the internal cl-proxy proxy). Can be a port number (e.g., '8551') in which case the full URL is derived as `http://localhost:\u003cport\u003e` or a complete URL (e.g., `http://remote-host:8551`), use `http://host.docker.internal:\u003cport\u003e` to reach a secondary execution client that runs on your host and not within Docker.\n- `--use-native-reth`: Run the Reth EL binary on the host instead of docker (recommended to bind to the Reth DB)\n- `--use-separate-mev-boost`: Spins a seperate service for mev-boost in addition with mev-boost-relay\n\n### OpStack Recipe\n\nDeploys an L2 environment with:\n\n- Complete L1 setup (as above minus mev-boost)\n- A complete sequencer with op-node, op-geth and op-batcher\n\n```bash\n$ builder-playground start opstack [flags]\n```\n\nFlags:\n\n- `--external-builder`: URL of an external builder to use (enables rollup-boost)\n- `--enable-latest-fork` (int): Enables the latest fork (jovian) at startup (0) or n blocks after genesis.\n\n### Example Commands\n\nHere's a complete example showing how to run the L1 recipe with the latest fork enabled and custom output directory:\n\n```bash\n$ builder-playground start l1 --latest-fork --output ~/my-builder-testnet --genesis-delay 15 --log-level debug\n```\n\n### Generate transaction flow with contender\n\nbuilder-playground can generate transaction flow to its nodes with [contender](https://github.com/flashbots/contender). Just pass the `--contender` flag to send spam transactions that fill each block:\n\n```bash\ngo run main.go start l1 --contender\n```\n\nThe default contender flags are as follows:\n\n- `--min-balance \"10 ether\"` -- gives each spammer account 10 ETH.\n- `--tps 20` -- sends 20 transactions per second.\n- `--forever` -- runs spammer indefinitely.\n\nTo add or modify contender flags, use `--contender.arg`:\n\n```bash\n# run the builtin erc20 scenario instead of the default \"fill block\" scenario, at 100 TPS\ngo run main.go start l1 --contender \\\n  --contender.arg \"--tps 100\" \\\n  --contender.arg \"erc20\"\n```\n\nTo read about more contender flag options, see the [contender CLI docs](https://github.com/flashbots/contender/blob/main/docs/cli.md). To see all available flags, [install contender](https://github.com/flashbots/contender/blob/main/docs/installation.md) or [run it in docker](https://github.com/flashbots/contender?tab=readme-ov-file#docker-instructions), and run `contender --help`.\n\nTo see what contender is doing internally, check its docker logs:\n\n```bash\ndocker logs -f $(docker ps | grep contender | cut -d' ' -f1)\n```\n\n## Common Options\n\n- `--output` (string): The directory where the chain data and artifacts are stored. Defaults to `$HOME/.local/state/builder-playground/devnet`\n- `--detached` (bool): Run the recipes in the background. Defaults to `false`.\n- `--genesis-delay` (int): The delay in seconds before the genesis block is created. Defaults to `10` seconds\n- `--watchdog` (bool): Enable the watchdog service to monitor the specific chain\n- `--dry-run` (bool): Generates the artifacts and manifest but does not deploy anything (also enabled with the `--mise-en-place` flag)\n- `--log-level` (string): Log level to use (debug, info, warn, error, fatal). Defaults to `info`.\n- `--labels` (key=val): Custom labels to apply to your deployment.\n- `--disable-logs` (bool): Disable the logs for the services. Defaults to `false`.\n- `--prefunded-accounts` (string, repeated): Fund this account in addition to static prefunded accounts, the input should the account's private key in hexadecimal format prefixed with 0x, the account is added to L1 and to L2 (if present).\n- `--contender` (bool): Enable [contender](https://github.com/flashbots/contender) spammer. Required to use other contender flags.\n  - `--contender.arg` (string): Pass custom args to the contender CLI.\n    Example: `--contender.arg \"--tpb 20\"`\n  - `--contender.target` (string): Change the default target node to spam. On the `l1` recipe, the default is \"el\", and on `opstack` it's \"op-geth\".\n- `--with-prometheus` (bool); Whether to deploy a Prometheus server and gather metrics. Defaults to `false`.\n\nTo stop the playground, press `Ctrl+C`.\n\n### Static Prefunded Accounts\n\nThe following addresses are pre-funded on L1 and to L2 (if present), all with a balance of `0x10000000000000000000000 wei` (equivalent to `309485009.8213451 ETH`):\n\n- `0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266` (Private key `0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80`)\n- `0x70997970c51812dc3a010c7d01b50e0d17dc79c8` (Private key `0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d`)\n- `0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc` (Private key `0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a`)\n- `0x90f79bf6eb2c4f870365e785982e1f101e93b906` (Private key `0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6`)\n- `0x15d34aaf54267db7d7c367839aaf71a00a2c6a65` (Private key `0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a`)\n- `0x9965507d1a55bcc2695c58ba16fb37d819b0a4dc` (Private key `0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba`)\n- `0x976ea74026e726554db657fa54763abd0c3a0aa9` (Private key `0x92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e`)\n- `0x14dc79964da2c08b23698b3d3cc7ca32193d9955` (Private key `0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356`)\n- `0x23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f` (Private key `0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97`)\n- `0xa0ee7a142d267c1f36714e4a8f75612f20a79720` (Private key `0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6`)\n\n## Logs\n\n```bash\n$ builder-playground list\nsession: major-hornet\n--------\nmev-boost-relay\nbeacon\nel\nvalidator\n$ builder-playground logs validator\n```\n\nWith single session running, the commands are straightforward.\n\nWith multiple sessions running, it's easy to navigate:\n\n- listing: `list` -\u003e pick session `major-hornet` -\u003e `list major-hornet` -\u003e see service list\n- viewing logs: see service `validator` with `logs major-hornet validator`\n\n## Inspect\n\nBuilder-playground supports inspecting the connection of a service to a specific port.\n\n```bash\n$ builder-playground debug inspect \u003cservice\u003e \u003cport\u003e\n```\n\nExample:\n\n```bash\n$ builder-playground start opstack\n$ builder-playground inspect op-geth authrpc\n```\n\nThis command starts a `tcpflow` container in the same network interface as the service and captures the traffic to the specified port.\n\n## Port\n\nLook up the host port for a service:\n\n```bash\n$ builder-playground port el http\n8545\n```\n\nUse `--list` to show all available ports:\n\n```bash\n$ builder-playground port el --list\nauthrpc: 8551\nhttp: 8545\nmetrics: 9091\nrpc: 30303\nws: 8546\n```\n\n## Validate\n\nCheck a recipe for errors before running:\n\n```bash\n$ builder-playground validate my-recipe.yaml\n```\n\nThis validates dependencies, host paths, port conflicts, and service name uniqueness without starting any containers. Useful for catching configuration errors early, especially with custom recipes.\n\n## Stop\n\nStop local playground sessions and keep all Docker resources (containers/volumes/networks):\n\n```bash\n$ builder-playground stop major-hornet # stop with session name\nstop: major-hornet\n$ builder-playground stop all # or stop all\nstop: honest-opossum\nstop: sacred-giraffe\n```\n\n## Clean\n\nStop (if not stopped) and clean a session:\n\n```bash\n$ builder-playground stop all # or stop all\n```\n\nYou can also stop specific session:\n\n```bash\n$ builder-playground list\nhonest-opossum\nmajor-hornet\nsacred-giraffe\n$ builder-playground stop honest-opossum sacred-giraffe\nclean: honest-opossum\nclean: sacred-giraffe\n```\n\n## Telemetry\n\nThe Builder Playground includes built-in Prometheus metrics collection. When you run any recipe with the `--with-prometheus` flag, the system automatically deploys a Prometheus server and gathers metrics from all services in your deployment.\n\nPrometheus automatically discovers services by looking for a port with the metrics label. You can define a metrics port in your component like this:\n\n```go\nWithArgs(\"--metrics\", `0.0.0.0:{{Port \"metrics\" 9090}}`)\n```\n\nBy default, Prometheus scrapes the `/metrics` path, but services can override this by specifying a custom path with `WithLabel(\"metrics_path\", \"/custom/path\")`. All configured services are automatically registered as scrape targets.\n\n### Usage\n\nEnable Prometheus for any recipe:\n\n```bash\n$ builder-playground start l1 --with-prometheus\n$ builder-playground start opstack --with-prometheus\n```\n\n## Internals\n\n### Execution Flow\n\nThe playground executes in three main phases:\n\n1. **Artifact Generation**: Creates all necessary files and configurations (genesis files, keys, etc.)\n2. **Manifest Generation**: The recipe creates a manifest describing all services to be deployed, their ports, and configurations\n3. **Deployment**: Uses Docker Compose to deploy the services described in the manifest\n\nWhen 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.\n\n### System Architecture\n\nThe playground is structured in two main layers:\n\n#### Components\n\nComponents are the basic building blocks of the system. Each component implements the `Service` interface:\n\n```go\ntype Service interface {\n    Run(service *service)\n}\n```\n\nComponents represent individual compute resources like:\n\n- Execution clients (Reth)\n- Consensus clients (Lighthouse)\n- Sidecar applications (MEV-Boost Relay)\n\nEach component, given its input parameters, outputs a Docker container description with its specific configuration.\n\n#### Recipes\n\nRecipes combine components in specific ways to create complete environments. They implement this interface:\n\n```go\ntype Recipe interface {\n   Apply(artifacts *Artifacts) *Manifest\n}\n```\n\nThe key output of a recipe is a `Manifest`, which represents a complete description of the environment to be deployed. A Manifest contains:\n\n- A list of services to deploy\n- Their interconnections and dependencies\n- Port mappings and configurations\n- Volume mounts and environment variables\n\nWhile the current recipes (L1 and OpStack) are relatively simple, this architecture allows for more complex setups. For example, you could create recipes for:\n\n- Multiple execution clients with a shared bootnode\n- Testing specific MEV scenarios\n- Interop L2 testing environments\n\nThe 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.).\n\n## Design Philosophy\n\nThe 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.\n\nWe 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.\n\nThis means we make specific choices:\n\n- Fixed client implementations (Lighthouse, Reth)\n- Recipe-based rather than modular configurations\n- Pre-backed configurations\n\nFor use cases outside our scope, consider using a more general-purpose tool like Kurtosis.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflashbots%2Fbuilder-playground","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflashbots%2Fbuilder-playground","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflashbots%2Fbuilder-playground/lists"}