Skip to content

Commit a434f62

Browse files
committed
feat: add chain-monitor
# Conflicts: # playground/components.go # Conflicts: # playground/catalog.go
1 parent ff2f868 commit a434f62

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
@@ -28,4 +28,5 @@ func init() {
2828
register(&BProxy{})
2929
register(&WebsocketProxy{})
3030
register(&BuilderHub2{})
31+
register(&ChainMonitor{})
3132
}

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())
@@ -212,6 +221,47 @@ func (w *WebsocketProxy) Apply(manifest *Manifest) {
212221
)
213222
}
214223

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

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

457521
if r.UseNativeReth {
458522
// we need to use this otherwise the db cannot be binded
@@ -693,7 +757,14 @@ func (o *OpReth) Apply(manifest *Manifest) {
693757
}).
694758
WithArtifact("/data/jwtsecret", "jwtsecret").
695759
WithArtifact("/data/l2-genesis.json", "l2-genesis.json").
696-
WithVolume("data", "/data_op_reth")
760+
WithVolume("data", "/data_op_reth").
761+
WithReady(ReadyCheck{
762+
QueryURL: "http://localhost:8545",
763+
Interval: 1 * time.Second,
764+
Timeout: 10 * time.Second,
765+
Retries: 20,
766+
StartPeriod: 1 * time.Second,
767+
})
697768
}
698769

699770
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)