diff --git a/lnd.go b/lnd.go index 9cf61e5cb..14016b9e4 100644 --- a/lnd.go +++ b/lnd.go @@ -163,14 +163,6 @@ type ListenerWithSignal struct { // Ready will be closed by the server listening on Listener. Ready chan struct{} - - // ExternalRPCSubserverCfg is optional and specifies the registration - // callback and permissions to register external gRPC subservers. - ExternalRPCSubserverCfg *RPCSubserverConfig - - // ExternalRestRegistrar is optional and specifies the registration - // callback to register external REST subservers. - ExternalRestRegistrar RestRegistrar } // ListenerCfg is a wrapper around custom listeners that can be passed to lnd @@ -183,6 +175,14 @@ type ListenerCfg struct { // RPCListener can be set to the listener to use for the RPC server. If // nil a regular network listener will be created. RPCListener *ListenerWithSignal + + // ExternalRPCSubserverCfg is optional and specifies the registration + // callback and permissions to register external gRPC subservers. + ExternalRPCSubserverCfg *RPCSubserverConfig + + // ExternalRestRegistrar is optional and specifies the registration + // callback to register external REST subservers. + ExternalRestRegistrar RestRegistrar } // rpcListeners is a function type used for closures that fetches a set of RPC @@ -752,7 +752,8 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error { cfg, server, macaroonService, cfg.SubRPCServers, serverOpts, restDialOpts, restProxyDest, atplManager, server.invoices, tower, restListen, rpcListeners, chainedAcceptor, - interceptorChain, + interceptorChain, lisCfg.ExternalRPCSubserverCfg, + lisCfg.ExternalRestRegistrar, ) if err != nil { err := fmt.Errorf("unable to create RPC server: %v", err) diff --git a/rpcserver.go b/rpcserver.go index 954a72216..0d355e002 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -541,6 +541,14 @@ type rpcServer struct { // interceptorChain is the the interceptor added to our gRPC server. interceptorChain *rpcperms.InterceptorChain + + // extSubserverCfg is optional and specifies the registration + // callback and permissions to register external gRPC subservers. + extSubserverCfg *RPCSubserverConfig + + // extRestRegistrar is optional and specifies the registration + // callback to register external REST subservers. + extRestRegistrar RestRegistrar } // A compile time check to ensure that rpcServer fully implements the @@ -559,7 +567,9 @@ func newRPCServer(cfg *Config, s *server, macService *macaroons.Service, tower *watchtower.Standalone, restListen func(net.Addr) (net.Listener, error), getListeners rpcListeners, chanPredicate *chanacceptor.ChainedAcceptor, - interceptorChain *rpcperms.InterceptorChain) (*rpcServer, error) { + interceptorChain *rpcperms.InterceptorChain, + extSubserverCfg *RPCSubserverConfig, extRestRegistrar RestRegistrar) ( + *rpcServer, error) { // Set up router rpc backend. channelGraph := s.localChanDB.ChannelGraph() @@ -682,31 +692,28 @@ func newRPCServer(cfg *Config, s *server, macService *macaroons.Service, // External subserver possibly need to register their own permissions // and macaroon validator. - for _, lis := range listeners { - extSubserver := lis.ExternalRPCSubserverCfg - if extSubserver != nil { - macValidator := extSubserver.MacaroonValidator - for method, ops := range extSubserver.Permissions { - err := interceptorChain.AddPermission(method, ops) - if err != nil { - return nil, err - } + if extSubserverCfg != nil { + macValidator := extSubserverCfg.MacaroonValidator + for method, ops := range extSubserverCfg.Permissions { + err := interceptorChain.AddPermission(method, ops) + if err != nil { + return nil, err + } - // Give the external subservers the possibility - // to also use their own validator to check any - // macaroons attached to calls to this method. - // This allows them to have their own root key - // ID database and permission entities. - if macValidator != nil { - err := macService.RegisterExternalValidator( - method, macValidator, - ) - if err != nil { - return nil, fmt.Errorf("could "+ - "not register "+ - "external macaroon "+ - "validator: %v", err) - } + // Give the external subservers the possibility + // to also use their own validator to check any + // macaroons attached to calls to this method. + // This allows them to have their own root key + // ID database and permission entities. + if macValidator != nil { + err := macService.RegisterExternalValidator( + method, macValidator, + ) + if err != nil { + return nil, fmt.Errorf("could "+ + "not register "+ + "external macaroon "+ + "validator: %v", err) } } } @@ -732,6 +739,8 @@ func newRPCServer(cfg *Config, s *server, macService *macaroons.Service, macService: macService, selfNode: selfNode.PubKeyBytes, interceptorChain: interceptorChain, + extSubserverCfg: extSubserverCfg, + extRestRegistrar: extRestRegistrar, } lnrpc.RegisterLightningServer(grpcServer, rootRPCServer) @@ -768,32 +777,27 @@ func (r *rpcServer) Start() error { } } + // Before actually listening on the gRPC listener, give external + // subservers the chance to register to our gRPC server. Those external + // subservers (think GrUB) are responsible for starting/stopping on + // their own, we just let them register their services to the same + // server instance so all of them can be exposed on the same + // port/listener. + if r.extSubserverCfg != nil && r.extSubserverCfg.Registrar != nil { + registerer := r.extSubserverCfg.Registrar + err := registerer.RegisterGrpcSubserver(r.grpcServer) + if err != nil { + rpcsLog.Errorf("error registering external gRPC "+ + "subserver: %v", err) + } + } + // With all the sub-servers started, we'll spin up the listeners for // the main RPC server itself. for _, lis := range r.listeners { go func(lis *ListenerWithSignal) { rpcsLog.Infof("RPC server listening on %s", lis.Addr()) - // Before actually listening on the gRPC listener, give - // external subservers the chance to register to our - // gRPC server. Those external subservers (think GrUB) - // are responsible for starting/stopping on their own, - // we just let them register their services to the same - // server instance so all of them can be exposed on the - // same port/listener. - extSubCfg := lis.ExternalRPCSubserverCfg - if extSubCfg != nil && extSubCfg.Registrar != nil { - registerer := extSubCfg.Registrar - err := registerer.RegisterGrpcSubserver( - r.grpcServer, - ) - if err != nil { - rpcsLog.Errorf("error registering "+ - "external gRPC subserver: %v", - err) - } - } - // Close the ready chan to indicate we are listening. close(lis.Ready) _ = r.grpcServer.Serve(lis) @@ -853,16 +857,14 @@ func (r *rpcServer) Start() error { // Before listening on any of the interfaces, we also want to give the // external subservers a chance to register their own REST proxy stub // with our mux instance. - for _, lis := range r.listeners { - if lis.ExternalRestRegistrar != nil { - err := lis.ExternalRestRegistrar.RegisterRestSubserver( - restCtx, restMux, r.restProxyDest, - r.restDialOpts, - ) - if err != nil { - rpcsLog.Errorf("error registering "+ - "external REST subserver: %v", err) - } + if r.extRestRegistrar != nil { + err := r.extRestRegistrar.RegisterRestSubserver( + restCtx, restMux, r.restProxyDest, + r.restDialOpts, + ) + if err != nil { + rpcsLog.Errorf("error registering "+ + "external REST subserver: %v", err) } }