Skip to content

Commit fa1ed4c

Browse files
committed
feat: add chain-monitor
1 parent 66b7dac commit fa1ed4c

File tree

3 files changed

+97
-7
lines changed

3 files changed

+97
-7
lines changed

playground/catalog.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ func init() {
2727
register(&Contender{})
2828
register(&BProxy{})
2929
register(&WebsocketProxy{})
30+
register(&ChainMonitor{})
3031
}
3132

3233
func FindComponent(name string) ServiceGen {

playground/components.go

Lines changed: 74 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"
@@ -77,10 +78,18 @@ func (o *OpRbuilder) Run(service *Service, ctx *ExContext) {
7778
"--metrics", `0.0.0.0:{{Port "metrics" 9090}}`,
7879
"--port", `{{Port "rpc" 30303}}`,
7980
"--builder.enable-revert-protection",
81+
"--rollup.builder-secret-key", "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
8082
).
8183
WithArtifact("/data/jwtsecret", "jwtsecret").
8284
WithArtifact("/data/l2-genesis.json", "l2-genesis.json").
83-
WithVolume("data", "/data_op_reth")
85+
WithVolume("data", "/data_op_reth").
86+
WithReady(ReadyCheck{
87+
QueryURL: "http://localhost:8545",
88+
Interval: 1 * time.Second,
89+
Timeout: 10 * time.Second,
90+
Retries: 20,
91+
StartPeriod: 1 * time.Second,
92+
})
8493

8594
if ctx.Bootnode != nil {
8695
service.WithArgs("--trusted-peers", ctx.Bootnode.Connect())
@@ -225,6 +234,43 @@ func (w *WebsocketProxy) Name() string {
225234
return "websocket-proxy"
226235
}
227236

237+
type ChainMonitor struct {
238+
L1RPC string
239+
L2BlockTime string
240+
L2BuilderAddress string
241+
L2RPC string
242+
ServerListenAddress string
243+
}
244+
245+
func (c *ChainMonitor) Run(service *Service, ctx *ExContext) {
246+
serverListenAddress := c.ServerListenAddress
247+
if serverListenAddress == "" {
248+
serverListenAddress = "0.0.0.0:{{Port \"metrics\" 8080}}"
249+
}
250+
251+
// we need to extract the port to register this service as exposing metrics
252+
if _, portStr, err := net.SplitHostPort(serverListenAddress); err == nil {
253+
if portNum, err := strconv.Atoi(portStr); err == nil {
254+
service.WithPort("metrics", portNum)
255+
}
256+
}
257+
258+
service.WithImage("ghcr.io/flashbots/chain-monitor").
259+
WithTag("v0.0.54").
260+
WithArgs(
261+
"serve",
262+
"--l1-rpc", c.L1RPC,
263+
"--l2-block-time", c.L2BlockTime,
264+
"--l2-monitor-builder-address", c.L2BuilderAddress,
265+
"--l2-rpc", c.L2RPC,
266+
"--server-listen-address", serverListenAddress,
267+
)
268+
}
269+
270+
func (c *ChainMonitor) Name() string {
271+
return "chain-monitor"
272+
}
273+
228274
type OpBatcher struct {
229275
L1Node string
230276
L2Node string
@@ -275,6 +321,9 @@ func (o *OpNode) Run(service *Service, ctx *ExContext) {
275321
"--l1.http-poll-interval", "6s",
276322
"--l2", Connect(o.L2Node, "authrpc"),
277323
"--l2.jwt-secret", "/data/jwtsecret",
324+
"--metrics.enabled",
325+
"--metrics.addr", "0.0.0.0",
326+
"--metrics.port", `{{Port "metrics" 7300}}`,
278327
"--sequencer.enabled",
279328
"--sequencer.l1-confs", "0",
280329
"--verifier.l1-confs", "0",
@@ -287,9 +336,6 @@ func (o *OpNode) Run(service *Service, ctx *ExContext) {
287336
"--p2p.listen.udp", `{{PortUDP "p2p" 9003}}`,
288337
"--p2p.scoring.peers", "light",
289338
"--p2p.ban.peers", "true",
290-
"--metrics.enabled",
291-
"--metrics.addr", "0.0.0.0",
292-
"--metrics.port", `{{Port "metrics" 7300}}`,
293339
"--pprof.enabled",
294340
"--rpc.enable-admin",
295341
"--safedb.path", "/data_db",
@@ -375,7 +421,14 @@ func (o *OpGeth) Run(service *Service, ctx *ExContext) {
375421
WithVolume("data", "/data_opgeth").
376422
WithArtifact("/data/l2-genesis.json", "l2-genesis.json").
377423
WithArtifact("/data/jwtsecret", "jwtsecret").
378-
WithArtifact("/data/p2p_key.txt", o.Enode.Artifact)
424+
WithArtifact("/data/p2p_key.txt", o.Enode.Artifact).
425+
WithReady(ReadyCheck{
426+
QueryURL: "http://localhost:8545",
427+
Interval: 1 * time.Second,
428+
Timeout: 10 * time.Second,
429+
Retries: 20,
430+
StartPeriod: 1 * time.Second,
431+
})
379432
}
380433

381434
func (o *OpGeth) Name() string {
@@ -471,7 +524,14 @@ func (r *RethEL) Run(svc *Service, ctx *ExContext) {
471524
).
472525
WithArtifact("/data/genesis.json", "genesis.json").
473526
WithArtifact("/data/jwtsecret", "jwtsecret").
474-
WithVolume("data", "/data_reth")
527+
WithVolume("data", "/data_reth").
528+
WithReady(ReadyCheck{
529+
QueryURL: "http://localhost:8545",
530+
Interval: 1 * time.Second,
531+
Timeout: 10 * time.Second,
532+
Retries: 20,
533+
StartPeriod: 1 * time.Second,
534+
})
475535

476536
if r.UseNativeReth {
477537
// we need to use this otherwise the db cannot be binded
@@ -734,7 +794,14 @@ func (o *OpReth) Run(service *Service, ctx *ExContext) {
734794
"--port", `{{Port "rpc" 30303}}`).
735795
WithArtifact("/data/jwtsecret", "jwtsecret").
736796
WithArtifact("/data/l2-genesis.json", "l2-genesis.json").
737-
WithVolume("data", "/data_op_reth")
797+
WithVolume("data", "/data_op_reth").
798+
WithReady(ReadyCheck{
799+
QueryURL: "http://localhost:8545",
800+
Interval: 1 * time.Second,
801+
Timeout: 10 * time.Second,
802+
Retries: 20,
803+
StartPeriod: 1 * time.Second,
804+
})
738805
}
739806

740807
func (o *OpReth) Name() string {

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

@@ -175,6 +182,21 @@ func (o *OpRecipe) Apply(ctx *ExContext, artifacts *Artifacts) *Manifest {
175182
MaxChannelDuration: o.batcherMaxChannelDuration,
176183
})
177184

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

0 commit comments

Comments
 (0)