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.
This commit is contained in:
Elle Mouton 2023-02-15 16:05:30 +02:00 committed by positiveblue
parent 73c36ac9b9
commit 116322d72c
No known key found for this signature in database
GPG key ID: 4FFF2510928804DC

View file

@ -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 "+