diff --git a/chanrestore.go b/chanrestore.go index 7aaada2f..bb1ba680 100644 --- a/chanrestore.go +++ b/chanrestore.go @@ -156,6 +156,14 @@ var _ chanbackup.ChannelRestorer = (*chanDBRestorer)(nil) // // NOTE: Part of the chanbackup.PeerConnector interface. func (s *server) ConnectPeer(nodePub *btcec.PublicKey, addrs []net.Addr) error { + // Before we connect to the remote peer, we'll remove any connections + // to ensure the new connection is created after this new link/channel + // is known. + if err := s.DisconnectPeer(nodePub); err != nil { + ltndLog.Infof("Peer(%v) is already connected, proceeding "+ + "with chan restore", nodePub.SerializeCompressed()) + } + // For each of the known addresses, we'll attempt to launch a // persistent connection to the (pub, addr) pair. In the event that any // of them connect, all the other stale requests will be cancelled. @@ -171,7 +179,16 @@ func (s *server) ConnectPeer(nodePub *btcec.PublicKey, addrs []net.Addr) error { // Attempt to connect to the peer using this full address. If // we're unable to connect to them, then we'll try the next // address in place of it. - if err := s.ConnectToPeer(netAddr, true); err != nil { + err := s.ConnectToPeer(netAddr, true) + + // If we're already connected to this peer, then we don't + // consider this an error, so we'll exit here. + if _, ok := err.(*errPeerAlreadyConnected); ok { + return nil + + } else if err != nil { + // Otherwise, something else happened, so we'll try the + // next address. ltndLog.Errorf("unable to connect to %v to "+ "complete SCB restore: %v", netAddr, err) continue diff --git a/htlcswitch/link.go b/htlcswitch/link.go index 076415b2..d6041266 100644 --- a/htlcswitch/link.go +++ b/htlcswitch/link.go @@ -574,7 +574,7 @@ func (l *channelLink) syncChanStates() error { return fmt.Errorf("unable to generate chan sync message for "+ "ChannelPoint(%v)", l.channel.ChannelPoint()) } - if err := l.cfg.Peer.SendMessage(false, localChanSyncMsg); err != nil { + if err := l.cfg.Peer.SendMessage(true, localChanSyncMsg); err != nil { return fmt.Errorf("Unable to send chan sync message for "+ "ChannelPoint(%v)", l.channel.ChannelPoint()) } diff --git a/server.go b/server.go index 81bb55c9..85bc531b 100644 --- a/server.go +++ b/server.go @@ -89,6 +89,19 @@ var ( validColorRegexp = regexp.MustCompile("^#[A-Fa-f0-9]{6}$") ) +// errPeerAlreadyConnected is an error returned by the server when we're +// commanded to connect to a peer, but they're already connected. +type errPeerAlreadyConnected struct { + peer *peer +} + +// Error returns the human readable version of this error type. +// +// NOTE: Part of the error interface. +func (e *errPeerAlreadyConnected) Error() string { + return fmt.Sprintf("already connected to peer: %v", e.peer) +} + // server is the main server of the Lightning Network Daemon. The server houses // global state pertaining to the wallet, database, and the rpcserver. // Additionally, the server is also used as a central messaging bus to interact @@ -2875,7 +2888,7 @@ func (s *server) ConnectToPeer(addr *lnwire.NetAddress, perm bool) error { peer, err := s.findPeerByPubStr(targetPub) if err == nil { s.mu.Unlock() - return fmt.Errorf("already connected to peer: %v", peer) + return &errPeerAlreadyConnected{peer: peer} } // Peer was not found, continue to pursue connection with peer.