rpc: ensure that calls that depend server are rejected if server not active

This commit adds a bit of a guard to a set of RPC calls. If an RPC call
needs to interact with the server but it hasn’t yet been started. Then
we’ll exit early in order to avoid blocking the call until the server
itself has started.

A recent change to the initialization order of sub-systems within lnd
results in a state where the daemon will wait for the wallet itself to
finish syncing _before_ the server is started. This was interpreted as
a bug by some users, so we’ll make the state of the server more
explicit by returning an error.
This commit is contained in:
Olaoluwa Osuntokun 2017-08-02 20:59:43 -07:00
parent c2aafe7e51
commit 006dff1207
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2

@ -247,13 +247,23 @@ func (r *rpcServer) VerifyMessage(ctx context.Context,
return nil, fmt.Errorf("failed to query graph: %v", err)
}
return &lnrpc.VerifyMessageResponse{Valid: active, Pubkey: pubKeyHex}, nil
return &lnrpc.VerifyMessageResponse{
Valid: active,
Pubkey: pubKeyHex,
}, nil
}
// ConnectPeer attempts to establish a connection to a remote peer.
func (r *rpcServer) ConnectPeer(ctx context.Context,
in *lnrpc.ConnectPeerRequest) (*lnrpc.ConnectPeerResponse, error) {
// The server hasn't yet started, so it won't be able to service any of
// our requests, so we'll bail early here.
if !r.server.Started() {
return nil, fmt.Errorf("chain backend is still syncing, server " +
"not active yet")
}
if in.Addr == nil {
return nil, fmt.Errorf("need: lnc pubkeyhash@hostname")
}
@ -310,6 +320,11 @@ func (r *rpcServer) DisconnectPeer(ctx context.Context,
rpcsLog.Debugf("[disconnectpeer] from peer(%s)", in.PubKey)
if !r.server.Started() {
return nil, fmt.Errorf("chain backend is still syncing, server " +
"not active yet")
}
// First we'll validate the string passed in within the request to
// ensure that it's a valid hex-string, and also a valid compressed
// public key.
@ -356,6 +371,11 @@ func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest,
"allocation(us=%v, them=%v)", in.TargetPeerId,
in.LocalFundingAmount, in.PushSat)
if !r.server.Started() {
return fmt.Errorf("chain backend is still syncing, server " +
"not active yet")
}
localFundingAmt := btcutil.Amount(in.LocalFundingAmount)
remoteInitialBalance := btcutil.Amount(in.PushSat)
@ -463,6 +483,14 @@ func (r *rpcServer) OpenChannelSync(ctx context.Context,
"allocation(us=%v, them=%v)", in.TargetPeerId,
in.LocalFundingAmount, in.PushSat)
// We don't allow new channels to be open while the server is still
// syncing, as otherwise we may not be able to obtain the relevant
// notifications.
if !r.server.Started() {
return nil, fmt.Errorf("chain backend is still syncing, server " +
"not active yet")
}
// Creation of channels before the wallet syncs up is currently
// disallowed.
isSynced, err := r.server.cc.wallet.IsSynced()
@ -1136,6 +1164,14 @@ func (r *rpcServer) SendPayment(paymentStream lnrpc.Lightning_SendPaymentServer)
errChan := make(chan error, 1)
payChan := make(chan *lnrpc.SendRequest)
// We don't allow payments to be sent while the daemon itself is still
// syncing as we may be trying to sent a payment over a "stale"
// channel.
if !r.server.Started() {
return fmt.Errorf("chain backend is still syncing, server " +
"not active yet")
}
// TODO(roasbeef): check payment filter to see if already used?
// In order to limit the level of concurrency and prevent a client from
@ -1285,6 +1321,14 @@ func (r *rpcServer) SendPayment(paymentStream lnrpc.Lightning_SendPaymentServer)
func (r *rpcServer) SendPaymentSync(ctx context.Context,
nextPayment *lnrpc.SendRequest) (*lnrpc.SendResponse, error) {
// We don't allow payments to be sent while the daemon itself is still
// syncing as we may be trying to sent a payment over a "stale"
// channel.
if !r.server.Started() {
return nil, fmt.Errorf("chain backend is still syncing, server " +
"not active yet")
}
var (
destPub *btcec.PublicKey
amt btcutil.Amount