Skip to content
Draft
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
44 changes: 44 additions & 0 deletions docs/recipes/l1-multi-builder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# l1-multi-builder Recipe

Deploy a full L1 stack with multiple builders and relays.

## Flags

- `block-time` (duration): Block time to use for the L1. Default to '12s'.
- `builders` (int): number of rbuilder instances to run; must be >= 1. Default to '2'.
- `latest-fork` (bool): use the latest fork. Default to 'false'.
- `relays` (int): number of mev-boost-relay instances to run; must be >= 1. Default to '2'.
- `use-reth-for-validation` (bool): use reth for validation. Default to 'false'.

## Architecture Diagram

```mermaid
graph LR
el["el<br/>rpc:30303<br/>http:8545<br/>ws:8546<br/>authrpc:8551<br/>metrics:9090"]
el_healthmon["el_healthmon"]
beacon["beacon<br/>p2p:9000<br/>p2p:9000<br/>quic-p2p:9100<br/>http:3500"]
beacon_healthmon["beacon_healthmon"]
validator["validator"]
mev_boost_relay_1["mev-boost-relay-1<br/>http:5555"]
mev_boost_relay_2["mev-boost-relay-2<br/>http:5555"]
mev_boost["mev-boost<br/>http:18550"]
rbuilder_1["rbuilder-1<br/>rpc:8645"]
rbuilder_2["rbuilder-2<br/>rpc:8645"]

el_healthmon -->|http| el
beacon -->|authrpc| el
beacon -->|http| mev_boost
beacon_healthmon -->|http| beacon
validator -->|http| beacon
mev_boost_relay_1 -->|http| beacon
mev_boost_relay_2 -->|http| beacon
mev_boost -->|http| mev_boost_relay_1
mev_boost -->|http| mev_boost_relay_2
mev_boost_relay_1 -.->|depends_on| beacon
mev_boost_relay_2 -.->|depends_on| beacon
rbuilder_1 -.->|depends_on| el
rbuilder_1 -.->|depends_on| beacon
rbuilder_2 -.->|depends_on| el
rbuilder_2 -.->|depends_on| beacon
```

7 changes: 7 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,12 @@ func runIt(recipe playground.Recipe) error {
overrides[parts[0]] = parts[1]
}

if v, ok := recipe.(interface{ Validate() error }); ok {
if err := v.Validate(); err != nil {
return err
}
}

slog.Debug("Building artifacts...")
builder := recipe.Artifacts()
builder.GenesisDelay(genesisDelayFlag)
Expand All @@ -800,6 +806,7 @@ func runIt(recipe playground.Recipe) error {
ExtraArgs: contenderArgs,
TargetChain: contenderTarget,
},
GenesisTimestamp: uint64(builder.GenesisTime().Unix()),
}

components := recipe.Apply(exCtx)
Expand Down
5 changes: 5 additions & 0 deletions mev-boost-relay/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
var (
apiListenAddr string
apiListenPort uint64
apiSecretKey string
beaconClientAddr string
validationServerAddr string
)
Expand All @@ -27,6 +28,7 @@ var rootCmd = &cobra.Command{
func main() {
rootCmd.Flags().StringVar(&apiListenAddr, "api-listen-addr", "127.0.0.1", "")
rootCmd.Flags().Uint64Var(&apiListenPort, "api-listen-port", 5555, "")
rootCmd.Flags().StringVar(&apiSecretKey, "api-secret-key", "", "BLS secret key (hex) used to sign relay bids; defaults to the playground-wide default")
rootCmd.Flags().StringVar(&beaconClientAddr, "beacon-client-addr", "http://localhost:3500", "")
rootCmd.Flags().StringVar(&validationServerAddr, "validation-server-addr", "", "")

Expand All @@ -42,6 +44,9 @@ func runMevBoostRelay() error {
cfg.ApiListenPort = apiListenPort
cfg.BeaconClientAddr = beaconClientAddr
cfg.ValidationServerAddr = validationServerAddr
if apiSecretKey != "" {
cfg.ApiSecretKey = apiSecretKey
}

relay, err := mevboostrelay.New(cfg)
if err != nil {
Expand Down
7 changes: 7 additions & 0 deletions playground/artifacts.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ type ArtifactsBuilder struct {
// Extra files to copy to artifacts (artifactName -> sourcePath)
extraFiles map[string]string
predeploysFile string

genesisTime time.Time
}

func (b *ArtifactsBuilder) GenesisTime() time.Time {
return b.genesisTime
}

func NewArtifactsBuilder() *ArtifactsBuilder {
Expand Down Expand Up @@ -249,6 +255,7 @@ func (b *ArtifactsBuilder) Build(out *output) error {
}

genesisTime := time.Now().Add(time.Duration(b.genesisDelay) * time.Second)
b.genesisTime = genesisTime
config := params.BeaconConfig()
config.ElectraForkEpoch = 0

Expand Down
8 changes: 8 additions & 0 deletions playground/cmd_validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ func ValidateRecipe(recipe Recipe, baseRecipes []Recipe) *ValidationResult {
return result
}

// Run recipe-level validation before Apply (e.g. flag-value checks).
if v, ok := recipe.(interface{ Validate() error }); ok {
if err := v.Validate(); err != nil {
result.AddError("recipe validation failed: %v", err)
return result
}
}

// Build a minimal manifest to validate structure
exCtx := &ExContext{
LogLevel: LevelInfo,
Expand Down
Loading