-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
multi+refactor: persistent peer manager #5700
Changes from 1 commit
252c36a
8e772db
082bc98
1f6da30
417991c
5221aaf
a5f03dc
6756734
194de63
73c105d
b7e26cf
cdcdfb6
e226516
a41637e
71b397d
c11367e
b7bd6f9
077d9ca
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,6 +52,11 @@ type PersistentPeerMgrConfig struct { | |
// AddrTypeIsSupported returns true if we can connect to this type of | ||
// address. | ||
AddrTypeIsSupported func(addr net.Addr) bool | ||
|
||
// FetchNodeAdvertisedAddrs can be used to fetch the advertised | ||
// addresses of a node that we have persisted. This should only ge used | ||
// to fetch an initial set of addresses for the peer. | ||
FetchNodeAdvertisedAddrs func(route.Vertex) ([]net.Addr, error) | ||
} | ||
|
||
// PersistentPeerManager manages persistent peers. | ||
|
@@ -193,11 +198,18 @@ func (m *PersistentPeerManager) Stop() { | |
func (m *PersistentPeerManager) AddPeer(pubKey *btcec.PublicKey, perm bool, | ||
addrs ...*lnwire.NetAddress) { | ||
|
||
peerKey := route.NewVertex(pubKey) | ||
|
||
// Fetch any stored addresses we may have for this peer. | ||
advertisedAddrs, err := m.cfg.FetchNodeAdvertisedAddrs(peerKey) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it possible to miss a graph update in between this fetch and adding the peer to the list of connections? Maybe safer to swap the order? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think it's safer to add it to the map and then update it with the fetched addrs otherwise i think it's possible that:
|
||
if err != nil { | ||
peerLog.Errorf("Unable to retrieve advertised address for "+ | ||
"node %s: %v", peerKey, err) | ||
} | ||
|
||
m.Lock() | ||
defer m.Unlock() | ||
|
||
peerKey := route.NewVertex(pubKey) | ||
|
||
backoff := m.cfg.MinBackoff | ||
if peer, ok := m.conns[peerKey]; ok { | ||
backoff = peer.backoff | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the peer is already being tracked, does the fetch call above still add something? Perhaps |
||
|
@@ -209,7 +221,7 @@ func (m *PersistentPeerManager) AddPeer(pubKey *btcec.PublicKey, perm bool, | |
backoff: backoff, | ||
} | ||
|
||
m.setPeerAddrsUnsafe(peerKey, nil, addrs) | ||
m.setPeerAddrsUnsafe(peerKey, advertisedAddrs, addrs) | ||
} | ||
|
||
// IsPersistentPeer returns true if the given peer is a peer that the | ||
|
@@ -263,29 +275,6 @@ func (m *PersistentPeerManager) PersistentPeers() []*btcec.PublicKey { | |
return peers | ||
} | ||
|
||
// AddPeerAddresses is used to add addresses to a peers existing list of | ||
// addresses. | ||
func (m *PersistentPeerManager) AddPeerAddresses(pubKey *btcec.PublicKey, | ||
addrs ...*lnwire.NetAddress) { | ||
|
||
m.Lock() | ||
defer m.Unlock() | ||
|
||
peerKey := route.NewVertex(pubKey) | ||
|
||
peer, ok := m.conns[peerKey] | ||
if !ok { | ||
return | ||
} | ||
|
||
peerAddrs := make([]*lnwire.NetAddress, 0, len(peer.addrs)) | ||
for _, addr := range peer.addrs { | ||
peerAddrs = append(peerAddrs, addr) | ||
} | ||
|
||
m.setPeerAddrsUnsafe(peerKey, nil, append(peerAddrs, addrs...)) | ||
} | ||
|
||
// NumPeerConnReqs returns the number of connection requests for the given peer. | ||
func (m *PersistentPeerManager) NumPeerConnReqs(pubKey *btcec.PublicKey) int { | ||
m.RLock() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1407,6 +1407,16 @@ func newServer(cfg *Config, listenAddrs []net.Addr, | |
|
||
return false | ||
}, | ||
FetchNodeAdvertisedAddrs: func( | ||
peer route.Vertex) ([]net.Addr, error) { | ||
|
||
node, err := s.graphDB.FetchLightningNode(peer) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return node.Addresses, nil | ||
}, | ||
}, | ||
) | ||
|
||
|
@@ -3660,63 +3670,6 @@ func (s *server) peerTerminationWatcher(p *peer.Brontide, ready chan struct{}) { | |
return | ||
} | ||
|
||
// Get the last address that we used to connect to the peer. | ||
addrs := []net.Addr{ | ||
p.NetAddress().Address, | ||
} | ||
|
||
// We'll ensure that we locate all the peers advertised addresses for | ||
// reconnection purposes. | ||
advertisedAddrs, err := s.fetchNodeAdvertisedAddrs(pubKey) | ||
switch { | ||
// We found advertised addresses, so use them. | ||
case err == nil: | ||
addrs = advertisedAddrs | ||
|
||
// The peer doesn't have an advertised address. | ||
case err == errNoAdvertisedAddr: | ||
// If it is an outbound peer then we fall back to the existing | ||
// peer address. | ||
if !p.Inbound() { | ||
break | ||
} | ||
|
||
// Fall back to the existing peer address if | ||
// we're not accepting connections over Tor. | ||
if s.torController == nil { | ||
break | ||
} | ||
|
||
// If we are, the peer's address won't be known | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think this changes the behavior since now the peermgr will attempt to connect to the incoming address - before this change, the attempt wasn't made. also, the original logic is slightly off. If we get an incoming connection and don't have any other addresses for the peer, we'll attempt to connect to the addr+port, but they may not actually be listening on the port given how tcp works. The issue seems to be that when we create a link node, we'll use the remote address as the address to store and expect to be able to connect to it |
||
// to us (we'll see a private address, which is | ||
// the address used by our onion service to dial | ||
// to lnd), so we don't have enough information | ||
// to attempt a reconnect. | ||
srvrLog.Debugf("Ignoring reconnection attempt "+ | ||
"to inbound peer %v without "+ | ||
"advertised address", p) | ||
return | ||
|
||
// We came across an error retrieving an advertised | ||
// address, log it, and fall back to the existing peer | ||
// address. | ||
default: | ||
srvrLog.Errorf("Unable to retrieve advertised "+ | ||
"address for node %x: %v", p.PubKey(), | ||
err) | ||
} | ||
|
||
// Add any missing addresses for this peer to persistentPeerAddr. | ||
for _, addr := range addrs { | ||
s.persistentPeerMgr.AddPeerAddresses( | ||
p.IdentityKey(), &lnwire.NetAddress{ | ||
IdentityKey: p.IdentityKey(), | ||
Address: addr, | ||
ChainNet: p.NetAddress().ChainNet, | ||
}, | ||
) | ||
} | ||
|
||
// Record the computed backoff in the backoff map. | ||
backoff := s.persistentPeerMgr.NextPeerBackoff(pubKey, p.StartTime()) | ||
|
||
|
@@ -4000,29 +3953,6 @@ func (s *server) Peers() []*peer.Brontide { | |
return peers | ||
} | ||
|
||
// errNoAdvertisedAddr is an error returned when we attempt to retrieve the | ||
// advertised address of a node, but they don't have one. | ||
var errNoAdvertisedAddr = errors.New("no advertised address found") | ||
|
||
// fetchNodeAdvertisedAddrs attempts to fetch the advertised addresses of a node. | ||
func (s *server) fetchNodeAdvertisedAddrs(pub *btcec.PublicKey) ([]net.Addr, error) { | ||
vertex, err := route.NewVertexFromBytes(pub.SerializeCompressed()) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
node, err := s.graphDB.FetchLightningNode(vertex) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if len(node.Addresses) == 0 { | ||
return nil, errNoAdvertisedAddr | ||
} | ||
|
||
return node.Addresses, nil | ||
} | ||
|
||
// fetchLastChanUpdate returns a function which is able to retrieve our latest | ||
// channel update for a target channel. | ||
func (s *server) fetchLastChanUpdate() func(lnwire.ShortChannelID) ( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a basic description of what is/makes a peer persistent?