From 116322d72c451ff6edbae300ac089797cdb3baf7 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Wed, 15 Feb 2023 16:05:30 +0200 Subject: [PATCH] rpc_proxy: add hasStarted method to rpcProxy Add a `started` variable to the rpcProxy that is used to indicate if the proxy is ready to handle requests. This is because currently the webserver is dependent on the rpcProxy to start and we want to be able to start the webserver without being dependent on the rpcProxy so that it can be used to handle status requests in a future commit. So with this commit, we can now saftely start the webserver earlier on and then if requests come through for the rpcProxy, an error will be displayed to the user. --- rpc_proxy.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/rpc_proxy.go b/rpc_proxy.go index ab6d749a..53cea101 100644 --- a/rpc_proxy.go +++ b/rpc_proxy.go @@ -10,6 +10,7 @@ import ( "net" "net/http" "strings" + "sync/atomic" "time" "github.com/improbable-eng/grpc-web/go/grpcweb" @@ -37,6 +38,10 @@ const ( HeaderMacaroon = "Macaroon" ) +// ErrWaitingToStart is returned if Lit's rpcProxy is not yet ready to handle +// calls. +var ErrWaitingToStart = fmt.Errorf("waiting for the RPC server to start") + // proxyErr is an error type that adds more context to an error occurring in the // proxy. type proxyErr struct { @@ -147,6 +152,10 @@ func newRpcProxy(cfg *Config, validator macaroons.MacaroonValidator, type rpcProxy struct { litrpc.UnimplementedProxyServer + // started is set to 1 once the rpcProxy has successfully started. It + // must only ever be used atomically. + started int32 + cfg *Config basicAuth string permsMgr *perms.Manager @@ -218,9 +227,17 @@ func (p *rpcProxy) Start() error { } } + atomic.CompareAndSwapInt32(&p.started, 0, 1) + return nil } +// hasStarted returns true if the rpcProxy has started and is ready to handle +// requests. +func (p *rpcProxy) hasStarted() bool { + return atomic.LoadInt32(&p.started) == 1 +} + // Stop shuts down the lnd connection. func (p *rpcProxy) Stop() error { p.grpcServer.Stop() @@ -399,6 +416,10 @@ func (p *rpcProxy) UnaryServerInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + if !p.hasStarted() { + return nil, ErrWaitingToStart + } + uriPermissions, ok := p.permsMgr.URIPermissions(info.FullMethod) if !ok { return nil, fmt.Errorf("%s: unknown permissions "+ @@ -440,6 +461,10 @@ func (p *rpcProxy) StreamServerInterceptor(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + if !p.hasStarted() { + return ErrWaitingToStart + } + uriPermissions, ok := p.permsMgr.URIPermissions(info.FullMethod) if !ok { return fmt.Errorf("%s: unknown permissions required "+