Skip to content

Commit 69bd9b7

Browse files
committed
feat: add chain-monitor
# Conflicts: # playground/components.go # Conflicts: # playground/catalog.go # Conflicts: # playground/catalog.go
1 parent 467132c commit 69bd9b7

File tree

3 files changed

+101
-7
lines changed

3 files changed

+101
-7
lines changed

playground/catalog.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,5 @@ func init() {
2525
register(&BProxy{})
2626
register(&WebsocketProxy{})
2727
register(&BuilderHub{})
28+
register(&ChainMonitor{})
2829
}

playground/components.go

Lines changed: 78 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"io"
7+
"net"
78
"strconv"
89
"strings"
910
"time"
@@ -74,10 +75,18 @@ func (o *OpRbuilder) Apply(manifest *Manifest) {
7475
"--metrics", `0.0.0.0:{{Port "metrics" 9090}}`,
7576
"--port", `{{Port "rpc" 30303}}`,
7677
"--builder.enable-revert-protection",
78+
"--rollup.builder-secret-key", "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
7779
).
7880
WithArtifact("/data/jwtsecret", "jwtsecret").
7981
WithArtifact("/data/l2-genesis.json", "l2-genesis.json").
80-
WithVolume("data", "/data_op_reth")
82+
WithVolume("data", "/data_op_reth").
83+
WithReady(ReadyCheck{
84+
QueryURL: "http://localhost:8545",
85+
Interval: 1 * time.Second,
86+
Timeout: 10 * time.Second,
87+
Retries: 20,
88+
StartPeriod: 1 * time.Second,
89+
})
8190

8291
if manifest.ctx.Bootnode != nil {
8392
service.WithArgs("--trusted-peers", manifest.ctx.Bootnode.Connect())
@@ -211,6 +220,47 @@ func (w *WebsocketProxy) Apply(manifest *Manifest) {
211220
)
212221
}
213222

223+
func (w *WebsocketProxy) Name() string {
224+
return "websocket-proxy"
225+
}
226+
227+
type ChainMonitor struct {
228+
L1RPC string
229+
L2BlockTime string
230+
L2BuilderAddress string
231+
L2RPC string
232+
ServerListenAddress string
233+
}
234+
235+
func (c *ChainMonitor) Run(service *Service, ctx *ExContext) {
236+
serverListenAddress := c.ServerListenAddress
237+
if serverListenAddress == "" {
238+
serverListenAddress = "0.0.0.0:{{Port \"metrics\" 8080}}"
239+
}
240+
241+
// we need to extract the port to register this service as exposing metrics
242+
if _, portStr, err := net.SplitHostPort(serverListenAddress); err == nil {
243+
if portNum, err := strconv.Atoi(portStr); err == nil {
244+
service.WithPort("metrics", portNum)
245+
}
246+
}
247+
248+
service.WithImage("ghcr.io/flashbots/chain-monitor").
249+
WithTag("v0.0.54").
250+
WithArgs(
251+
"serve",
252+
"--l1-rpc", c.L1RPC,
253+
"--l2-block-time", c.L2BlockTime,
254+
"--l2-monitor-builder-address", c.L2BuilderAddress,
255+
"--l2-rpc", c.L2RPC,
256+
"--server-listen-address", serverListenAddress,
257+
)
258+
}
259+
260+
func (c *ChainMonitor) Name() string {
261+
return "chain-monitor"
262+
}
263+
214264
type OpBatcher struct {
215265
L1Node string
216266
L2Node string
@@ -257,6 +307,9 @@ func (o *OpNode) Apply(manifest *Manifest) {
257307
"--l1.http-poll-interval", "6s",
258308
"--l2", Connect(o.L2Node, "authrpc"),
259309
"--l2.jwt-secret", "/data/jwtsecret",
310+
"--metrics.enabled",
311+
"--metrics.addr", "0.0.0.0",
312+
"--metrics.port", `{{Port "metrics" 7300}}`,
260313
"--sequencer.enabled",
261314
"--sequencer.l1-confs", "0",
262315
"--verifier.l1-confs", "0",
@@ -269,9 +322,6 @@ func (o *OpNode) Apply(manifest *Manifest) {
269322
"--p2p.listen.udp", `{{PortUDP "p2p" 9003}}`,
270323
"--p2p.scoring.peers", "light",
271324
"--p2p.ban.peers", "true",
272-
"--metrics.enabled",
273-
"--metrics.addr", "0.0.0.0",
274-
"--metrics.port", `{{Port "metrics" 7300}}`,
275325
"--pprof.enabled",
276326
"--rpc.enable-admin",
277327
"--safedb.path", "/data_db",
@@ -355,7 +405,14 @@ func (o *OpGeth) Apply(manifest *Manifest) {
355405
WithReadyFn(opGethReadyFn).
356406
WithArtifact("/data/l2-genesis.json", "l2-genesis.json").
357407
WithArtifact("/data/jwtsecret", "jwtsecret").
358-
WithArtifact("/data/p2p_key.txt", o.Enode.Artifact)
408+
WithArtifact("/data/p2p_key.txt", o.Enode.Artifact).
409+
WithReady(ReadyCheck{
410+
QueryURL: "http://localhost:8545",
411+
Interval: 1 * time.Second,
412+
Timeout: 10 * time.Second,
413+
Retries: 20,
414+
StartPeriod: 1 * time.Second,
415+
})
359416
}
360417

361418
func opGethReadyFn(ctx context.Context, instance *instance) error {
@@ -451,7 +508,14 @@ func (r *RethEL) Apply(manifest *Manifest) {
451508
}).
452509
WithArtifact("/data/genesis.json", "genesis.json").
453510
WithArtifact("/data/jwtsecret", "jwtsecret").
454-
WithVolume("data", "/data_reth")
511+
WithVolume("data", "/data_reth").
512+
WithReady(ReadyCheck{
513+
QueryURL: "http://localhost:8545",
514+
Interval: 1 * time.Second,
515+
Timeout: 10 * time.Second,
516+
Retries: 20,
517+
StartPeriod: 1 * time.Second,
518+
})
455519

456520
if r.UseNativeReth {
457521
// we need to use this otherwise the db cannot be binded
@@ -639,7 +703,14 @@ func (o *OpReth) Apply(manifest *Manifest) {
639703
}).
640704
WithArtifact("/data/jwtsecret", "jwtsecret").
641705
WithArtifact("/data/l2-genesis.json", "l2-genesis.json").
642-
WithVolume("data", "/data_op_reth")
706+
WithVolume("data", "/data_op_reth").
707+
WithReady(ReadyCheck{
708+
QueryURL: "http://localhost:8545",
709+
Interval: 1 * time.Second,
710+
Timeout: 10 * time.Second,
711+
Retries: 20,
712+
StartPeriod: 1 * time.Second,
713+
})
643714
}
644715

645716
type MevBoost struct {

playground/recipe_opstack.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package playground
22

33
import (
4+
"fmt"
45
flag "github.com/spf13/pflag"
56
)
67

78
var _ Recipe = &OpRecipe{}
89

10+
const defaultL2BuilderAddress = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
11+
912
// OpRecipe is a recipe that deploys an OP stack
1013
type OpRecipe struct {
1114
// externalBuilder is the URL of the external builder to use. If enabled, the recipe deploys
@@ -36,6 +39,9 @@ type OpRecipe struct {
3639

3740
// whether to enable websocket proxy
3841
enableWebsocketProxy bool
42+
43+
// whether to enable chain-monitor
44+
enableChainMonitor bool
3945
}
4046

4147
func (o *OpRecipe) Name() string {
@@ -56,6 +62,7 @@ func (o *OpRecipe) Flags() *flag.FlagSet {
5662
flags.BoolVar(&o.baseOverlay, "base-overlay", false, "Whether to use base implementation for flashblocks-rpc")
5763
flags.StringVar(&o.flashblocksBuilderURL, "flashblocks-builder", "", "External URL of builder flashblocks stream")
5864
flags.BoolVar(&o.enableWebsocketProxy, "enable-websocket-proxy", false, "Whether to enable websocket proxy")
65+
flags.BoolVar(&o.enableChainMonitor, "chain-monitor", false, "Whether to enable chain-monitor")
5966
return flags
6067
}
6168

@@ -174,6 +181,21 @@ func (o *OpRecipe) Apply(svcManager *Manifest) {
174181
MaxChannelDuration: o.batcherMaxChannelDuration,
175182
})
176183

184+
if o.enableChainMonitor {
185+
l2BlockTime := fmt.Sprintf("%ds", o.blockTime)
186+
187+
svcManager.AddService("chain-monitor", &ChainMonitor{
188+
L1RPC: Connect("el", "http"),
189+
L2BlockTime: l2BlockTime,
190+
L2BuilderAddress: defaultL2BuilderAddress,
191+
L2RPC: Connect("op-geth", "http"),
192+
})
193+
194+
svcManager.MustGetService("chain-monitor").
195+
DependsOnHealthy("el").
196+
DependsOnHealthy("op-geth")
197+
}
198+
177199
if svcManager.ctx.Contender.TargetChain == "" {
178200
svcManager.ctx.Contender.TargetChain = "op-geth"
179201
}

0 commit comments

Comments
 (0)