diff --git a/op-devstack/shim/l2_cl.go b/op-devstack/shim/l2_cl.go index 16c4839fb22ae..bcf02f783553f 100644 --- a/op-devstack/shim/l2_cl.go +++ b/op-devstack/shim/l2_cl.go @@ -14,6 +14,8 @@ type L2CLNodeConfig struct { ID stack.L2CLNodeID Client client.RPC + UserRPC string + InteropEndpoint string InteropJwtSecret eth.Bytes32 } @@ -26,6 +28,8 @@ type rpcL2CLNode struct { p2pClient apis.P2PClient els locks.RWMap[stack.L2ELNodeID, stack.L2ELNode] + userRPC string + // Store interop ws endpoints and secrets to provide to the supervisor, // when reconnection happens using the supervisor's admin_addL2RPC method. // These fields are not intended for manual dial-in or initializing client.RPC @@ -44,6 +48,7 @@ func NewL2CLNode(cfg L2CLNodeConfig) stack.L2CLNode { client: cfg.Client, rollupClient: sources.NewRollupClient(cfg.Client), p2pClient: sources.NewP2PClient(cfg.Client), + userRPC: cfg.UserRPC, interopEndpoint: cfg.InteropEndpoint, interopJwtSecret: cfg.InteropJwtSecret, } @@ -73,6 +78,10 @@ func (r *rpcL2CLNode) ELs() []stack.L2ELNode { return stack.SortL2ELNodes(r.els.Values()) } +func (r *rpcL2CLNode) UserRPC() string { + return r.userRPC +} + func (r *rpcL2CLNode) InteropRPC() (endpoint string, jwtSecret eth.Bytes32) { return r.interopEndpoint, r.interopJwtSecret } diff --git a/op-devstack/stack/l2_cl.go b/op-devstack/stack/l2_cl.go index 062fbd20e1748..e5e5b042b3433 100644 --- a/op-devstack/stack/l2_cl.go +++ b/op-devstack/stack/l2_cl.go @@ -77,6 +77,7 @@ type L2CLNode interface { RollupAPI() apis.RollupClient P2PAPI() apis.P2PClient InteropRPC() (endpoint string, jwtSecret eth.Bytes32) + UserRPC() string // ELs returns the engine(s) that this L2CLNode is connected to. // This may be empty, if the L2CL is not connected to any. diff --git a/op-devstack/sysext/l2.go b/op-devstack/sysext/l2.go index 24a2ca8d5936b..571c60fda2bb9 100644 --- a/op-devstack/sysext/l2.go +++ b/op-devstack/sysext/l2.go @@ -119,11 +119,40 @@ func (o *Orchestrator) hydrateL2ELCL(node *descriptors.Node, l2Net stack.Extensi clService, ok := node.Services[CLServiceName] require.True(ok, "need L2 CL service for chain", l2ID) + var endpointString string + // Parse the endpoint from the service descriptor. + for proto, endpoint := range clService.Endpoints { + if proto == RPCProtocol { + port := endpoint.Port + if o.usePrivatePorts { + port = endpoint.PrivatePort + } + scheme := endpoint.Scheme + if scheme == "" { + scheme = HTTPProtocol + } + host := endpoint.Host + path := "" + if strings.Contains(host, "/") { + parts := strings.SplitN(host, "/", 2) + host = parts[0] + path = "/" + parts[1] + } + endpointString = fmt.Sprintf("%s://%s:%d%s", scheme, host, port, path) + break + } + } + + require.NotEmpty(endpointString, "no endpoint found for CL service", clService.Name) + + l2Net.Logger().Info("Found endpoint for CL service", "endpoint", endpointString) + clClient := o.rpcClient(l2Net.T(), clService, RPCProtocol, "/", opts...) l2CL := shim.NewL2CLNode(shim.L2CLNodeConfig{ ID: stack.NewL2CLNodeID(clService.Name, l2ID.ChainID()), CommonConfig: shim.NewCommonConfig(l2Net.T()), Client: clClient, + UserRPC: endpointString, }) l2Net.AddL2CLNode(l2CL) l2CL.(stack.LinkableL2CLNode).LinkEL(l2EL) diff --git a/op-devstack/sysgo/l2_cl_kona.go b/op-devstack/sysgo/l2_cl_kona.go index f1951dfab7618..d0640c4742518 100644 --- a/op-devstack/sysgo/l2_cl_kona.go +++ b/op-devstack/sysgo/l2_cl_kona.go @@ -54,6 +54,7 @@ func (k *KonaNode) hydrate(system stack.ExtensibleSystem) { CommonConfig: shim.NewCommonConfig(system.T()), ID: k.id, Client: rpcCl, + UserRPC: k.userRPC, InteropEndpoint: k.interopEndpoint, InteropJwtSecret: k.interopJwtSecret, }) @@ -107,7 +108,7 @@ func (k *KonaNode) Start() { k.p.Require().NoError(err, "Must start") var userRPCAddr string - k.p.Require().NoError(tasks.Await(k.p.Ctx(), userRPC, &k.userRPC), "need user RPC") + k.p.Require().NoError(tasks.Await(k.p.Ctx(), userRPC, &userRPCAddr), "need user RPC") k.userProxy.SetUpstream(ProxyAddr(k.p.Require(), userRPCAddr)) } @@ -197,7 +198,7 @@ func WithKonaNode(l2CLID stack.L2CLNodeID, l1CLID stack.L1CLNodeID, l1ELID stack //p.Require().NoError(err, os.WriteFile(tempSeqKeyPath, []byte(p2pKeyHex), 0o644)) envVars = append(envVars, "KONA_NODE_P2P_SEQUENCER_KEY="+p2pKeyHex, - "KONA_NODE_SEQUENCER_L1_CONFS=0", + "KONA_NODE_SEQUENCER_L1_CONFS=2", "KONA_NODE_MODE=Sequencer", ) } else { diff --git a/op-devstack/sysgo/l2_cl_opnode.go b/op-devstack/sysgo/l2_cl_opnode.go index d290496a57cfe..9fab9be3ca0c5 100644 --- a/op-devstack/sysgo/l2_cl_opnode.go +++ b/op-devstack/sysgo/l2_cl_opnode.go @@ -65,6 +65,7 @@ func (n *OpNode) hydrate(system stack.ExtensibleSystem) { CommonConfig: shim.NewCommonConfig(system.T()), ID: n.id, Client: rpcCl, + UserRPC: n.userRPC, InteropEndpoint: n.interopEndpoint, InteropJwtSecret: n.interopJwtSecret, })