lnd: add server calls for disconnecting peers

Issue: 139

This commit contains client-side and server-side functionality
for disconnecting peers. rpc-client calls server side method and sends
message with pubKey.
This commit is contained in:
afederigo 2017-05-02 22:31:35 +03:00 committed by Olaoluwa Osuntokun
parent cf4da784f0
commit cf605c81ab
2 changed files with 87 additions and 3 deletions

View File

@ -240,6 +240,16 @@ func (r *rpcServer) ConnectPeer(ctx context.Context,
return &lnrpc.ConnectPeerResponse{}, nil
}
// DisconnectPeer attempts to disconnect one peer from another identified by a given pubKey.
func (r *rpcServer) DisconnectPeer(ctx context.Context, in *lnrpc.DisconnectPeerRequest) (*lnrpc.DisconnectPeerResponse, error) {
if err := r.server.DisconnectFromPeer(in.PubKey); err != nil {
return nil, fmt.Errorf("unable to disconnect peer: %v", err)
}
rpcsLog.Debugf("[disconnectpeer] from peer(%s)", in.PubKey)
return &lnrpc.DisconnectPeerResponse{}, nil
}
// OpenChannel attempts to open a singly funded channel specified in the
// request to a remote peer.
func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest,
@ -644,19 +654,19 @@ func (r *rpcServer) GetInfo(ctx context.Context,
pendingChannels, err := r.server.fundingMgr.NumPendingChannels()
if err != nil {
return nil, err
return nil, fmt.Errorf("unable to get number of pending channels: %v", err)
}
idPub := r.server.identityPriv.PubKey().SerializeCompressed()
bestHash, bestHeight, err := r.server.bio.GetBestBlock()
if err != nil {
return nil, err
return nil, fmt.Errorf("unable to get best block info: %v", err)
}
isSynced, err := r.server.lnwallet.IsSynced()
if err != nil {
return nil, err
return nil, fmt.Errorf("unable to sync PoV of the wallet with current best block in the main chain: %v", err)
}
activeChains := make([]string, registeredChains.NumActiveChains())

View File

@ -434,6 +434,7 @@ func (s *server) establishPersistentConnections() error {
}
}
pubStr := string(node.IdentityPub.SerializeCompressed())
nodeAddrs := &nodeAddresses{
pubKey: node.IdentityPub,
addresses: node.Addresses,
@ -947,6 +948,12 @@ type connectPeerMsg struct {
err chan error
}
type disconnectPeerMsg struct {
pubKey string
err chan error
}
// listPeersMsg is a message sent to the server in order to obtain a listing
// of all currently active channels.
type listPeersMsg struct {
@ -1057,6 +1064,8 @@ out:
}()
case query := <-s.queries:
switch msg := query.(type) {
case *disconnectPeerMsg:
s.handleDisconnectPeer(msg)
case *connectPeerMsg:
s.handleConnectPeer(msg)
case *listPeersMsg:
@ -1157,6 +1166,57 @@ func (s *server) handleConnectPeer(msg *connectPeerMsg) {
}
}
// handleDisconnectPeer attempts to disconnect one peer from another
func (s *server) handleDisconnectPeer(msg *disconnectPeerMsg) {
pubKey, err := hex.DecodeString(msg.pubKey)
if err != nil {
msg.err <- fmt.Errorf("unable to DecodeString public key: %v", err)
return
}
// Ensure we're already connected to this peer.
s.peersMtx.RLock()
peer, ok := s.peersByPub[string(pubKey)]
s.peersMtx.RUnlock()
if !ok {
msg.err <- fmt.Errorf("unable to find peer(%v) by public key(%v)", peer, msg.pubKey)
return
}
// Get all pending and active channels corresponding with current node.
allChannels, err := s.chanDB.FetchAllChannels()
if err != nil {
msg.err <- fmt.Errorf("unable to get opened channels: %v", err)
return
}
// Filter by public key all channels corresponding with the detached node.
var nodeChannels []*channeldb.OpenChannel
for _, channel := range allChannels {
if hex.EncodeToString(channel.IdentityPub.SerializeCompressed()) == msg.pubKey {
nodeChannels = append(nodeChannels, channel)
}
}
// Send server info logs containing channels id's and raise error about
// primary closing channels before start disconnecting peer.
if len(nodeChannels) > 0 {
for _, channel := range nodeChannels {
srvrLog.Infof("Before disconnect peer(%v) close channel: %v",
msg.pubKey, channel.ChanID)
}
msg.err <- fmt.Errorf("before disconnect peer(%v) you have to close "+
"active and pending channels corresponding to that peer; %v",
msg.pubKey, nodeChannels)
return
}
srvrLog.Infof("Disconnecting from %v", peer)
peer.Disconnect()
msg.err <- nil
}
// handleOpenChanReq first locates the target peer, and if found hands off the
// request to the funding manager allowing it to initiate the channel funding
// workflow.
@ -1214,6 +1274,20 @@ func (s *server) ConnectToPeer(addr *lnwire.NetAddress,
return <-errChan
}
// DisconnectFromPeer sends the request to server to close the connection
// with peer identified by public key.
func (s *server) DisconnectFromPeer(pubkey string) error {
errChan := make(chan error, 1)
s.queries <- &disconnectPeerMsg{
pubKey: pubkey,
err: errChan,
}
return <-errChan
}
// OpenChannel sends a request to the server to open a channel to the specified
// peer identified by ID with the passed channel funding paramters.
func (s *server) OpenChannel(peerID int32, nodeKey *btcec.PublicKey,