diff --git a/docs/recipes/opstack.md b/docs/recipes/opstack.md
index 9e2b687f..bec9e2aa 100644
--- a/docs/recipes/opstack.md
+++ b/docs/recipes/opstack.md
@@ -19,6 +19,7 @@ Deploy an OP stack.
```mermaid
graph LR
+ bootnode["bootnode
rpc:30303"]
el["el
rpc:30303
http:8545
ws:8546
authrpc:8551
metrics:9090"]
el_healthmon["el_healthmon"]
beacon["beacon
p2p:9000
p2p:9000
quic-p2p:9100
http:3500"]
@@ -29,10 +30,12 @@ graph LR
op_node["op-node
metrics:7300
http:8549
p2p:9003
p2p:9003"]
op_batcher["op-batcher"]
+ el -->|rpc| bootnode
el_healthmon -->|http| el
beacon -->|authrpc| el
beacon_healthmon -->|http| beacon
validator -->|http| beacon
+ op_geth -->|rpc| bootnode
op_geth_healthmon -->|http| op_geth
op_node -->|http| el
op_node -->|http| beacon
diff --git a/playground/catalog.go b/playground/catalog.go
index 4b1170f2..55fecf45 100644
--- a/playground/catalog.go
+++ b/playground/catalog.go
@@ -26,4 +26,5 @@ func init() {
register(&WebsocketProxy{})
register(&BuilderHub{})
register(&ChainMonitor{})
+ register(&Bootnode{})
}
diff --git a/playground/components.go b/playground/components.go
index a0e1997d..f701ef11 100644
--- a/playground/components.go
+++ b/playground/components.go
@@ -100,7 +100,7 @@ func (o *OpRbuilder) Apply(ctx *ExContext) *Component {
})
if ctx.Bootnode != nil {
- service.WithArgs("--trusted-peers", ctx.Bootnode.Connect())
+ service.WithArgs("--bootnodes", ctx.Bootnode.Connect())
}
if o.Flashblocks {
@@ -170,7 +170,7 @@ func (f *FlashblocksRPC) Apply(ctx *ExContext) *Component {
if ctx.Bootnode != nil {
service.WithArgs(
- "--trusted-peers", ctx.Bootnode.Connect(),
+ "--bootnodes", ctx.Bootnode.Connect(),
)
}
@@ -509,6 +509,10 @@ func (r *RethEL) Apply(ctx *ExContext) *Component {
WithArtifact("/data/jwtsecret", "jwtsecret").
WithVolume("data", "/data_reth", true)
+ if ctx.Bootnode != nil {
+ svc.WithArgs("--bootnodes", ctx.Bootnode.Connect())
+ }
+
UseHealthmon(component, svc, healthmonExecution)
if r.UseNativeReth {
@@ -1053,6 +1057,47 @@ func registerBuilderHook(ctx context.Context, exCtx *ExContext, manifest *Manife
return nil
}
+type BootnodeProtocol string
+
+const (
+ BootnodeProtocolV5 BootnodeProtocol = "v5"
+)
+
+type Bootnode struct {
+ Protocol BootnodeProtocol
+ Enode *EnodeAddr
+}
+
+func (b *Bootnode) Apply(ctx *ExContext) *Component {
+ component := NewComponent("bootnode")
+
+ b.Enode = ctx.Output.GetEnodeAddr()
+ svc := component.NewService("bootnode").
+ WithImage("ghcr.io/paradigmxyz/reth").
+ WithTag("v1.9.3").
+ WithEntrypoint("/usr/local/bin/reth").
+ WithArgs(
+ "p2p", "bootnode",
+ "--addr", `0.0.0.0:{{Port "rpc" 30303}}`,
+ "--p2p-secret-key", "/data/p2p_key.txt",
+ "-vvvv",
+ "--color", "never",
+ ).
+ WithArtifact("/data/p2p_key.txt", b.Enode.Artifact)
+
+ if b.Protocol == BootnodeProtocolV5 {
+ svc.WithArgs("--v5")
+ }
+
+ // Mutate the execution context by setting the bootnode.
+ ctx.Bootnode = &BootnodeRef{
+ Service: "bootnode",
+ ID: b.Enode.NodeID(),
+ }
+
+ return component
+}
+
const (
healthmonBeacon = "beacon"
healthmonExecution = "execution"
diff --git a/playground/components_test.go b/playground/components_test.go
index ed29e115..45d65a99 100644
--- a/playground/components_test.go
+++ b/playground/components_test.go
@@ -228,7 +228,7 @@ func (tt *testFramework) test(component ComponentGen, args []string) *Manifest {
exCtx := &ExContext{
Output: o,
- LogLevel: LevelDebug,
+ LogLevel: LevelTrace,
Contender: &ContenderContext{
Enabled: false,
},
diff --git a/playground/recipe_opstack.go b/playground/recipe_opstack.go
index 34ac763a..916bb3d6 100644
--- a/playground/recipe_opstack.go
+++ b/playground/recipe_opstack.go
@@ -81,6 +81,7 @@ func (o *OpRecipe) Artifacts() *ArtifactsBuilder {
func (o *OpRecipe) Apply(ctx *ExContext) *Component {
component := NewComponent("op-recipe")
+ component.AddComponent(ctx, &Bootnode{})
component.AddComponent(ctx, &RethEL{})
component.AddComponent(ctx, &LighthouseBeaconNode{
@@ -94,14 +95,6 @@ func (o *OpRecipe) Apply(ctx *ExContext) *Component {
externalBuilderRef := o.externalBuilder
peers := []string{}
- opGeth := &OpGeth{}
- component.AddComponent(ctx, opGeth)
-
- ctx.Bootnode = &BootnodeRef{
- Service: "op-geth",
- ID: opGeth.Enode.NodeID(),
- }
-
if o.externalBuilder == "op-reth" {
// Add a new op-reth service and connect it to Rollup-boost
component.AddComponent(ctx, &OpReth{})
@@ -176,6 +169,7 @@ func (o *OpRecipe) Apply(ctx *ExContext) *Component {
})
}
+ component.AddService(ctx, &OpGeth{})
component.AddComponent(ctx, &OpNode{
L1Node: "el",
L1Beacon: "beacon",