Skip to content

Commit e337dda

Browse files
StephenButtolphDan Laine
andauthored
Remove duplicate networking check (#2204)
Signed-off-by: Dan Laine <daniel.laine@avalabs.org> Co-authored-by: Dan Laine <daniel.laine@avalabs.org>
1 parent 020e802 commit e337dda

File tree

1 file changed

+31
-21
lines changed

1 file changed

+31
-21
lines changed

network/network.go

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,14 @@ type UptimeResult struct {
115115
WeightedAveragePercentage float64
116116
}
117117

118+
// To avoid potential deadlocks, we maintain that locks must be grabbed in the
119+
// following order:
120+
//
121+
// 1. peersLock
122+
// 2. manuallyTrackedIDsLock
123+
//
124+
// If a higher lock (e.g. manuallyTrackedIDsLock) is held when trying to grab a
125+
// lower lock (e.g. peersLock) a deadlock could occur.
118126
type network struct {
119127
config *Config
120128
peerConfig *peer.Config
@@ -154,11 +162,14 @@ type network struct {
154162
// connect to. An entry is added to this set when we first start attempting
155163
// to connect to the peer. An entry is deleted from this set once we have
156164
// finished the handshake.
157-
trackedIPs map[ids.NodeID]*trackedIP
158-
manuallyTrackedIDs set.Set[ids.NodeID]
159-
connectingPeers peer.Set
160-
connectedPeers peer.Set
161-
closing bool
165+
trackedIPs map[ids.NodeID]*trackedIP
166+
connectingPeers peer.Set
167+
connectedPeers peer.Set
168+
closing bool
169+
170+
// Tracks special peers that the network should always track
171+
manuallyTrackedIDsLock sync.RWMutex
172+
manuallyTrackedIDs set.Set[ids.NodeID]
162173

163174
// router is notified about all peer [Connected] and [Disconnected] events
164175
// as well as all non-handshake peer messages.
@@ -459,9 +470,7 @@ func (n *network) Connected(nodeID ids.NodeID) {
459470
// of peers, then it should only connect if this node is a validator, or the
460471
// peer is a validator/beacon.
461472
func (n *network) AllowConnection(nodeID ids.NodeID) bool {
462-
return !n.config.RequireValidatorToConnect ||
463-
n.config.Validators.Contains(constants.PrimaryNetworkID, n.config.MyNodeID) ||
464-
n.WantsConnection(nodeID)
473+
return !n.config.RequireValidatorToConnect || n.WantsConnection(nodeID)
465474
}
466475

467476
func (n *network) Track(peerID ids.NodeID, claimedIPPorts []*ips.ClaimedIPPort) ([]*p2p.PeerAck, error) {
@@ -792,23 +801,24 @@ func (n *network) Dispatch() error {
792801
}
793802

794803
func (n *network) WantsConnection(nodeID ids.NodeID) bool {
795-
n.peersLock.RLock()
796-
defer n.peersLock.RUnlock()
804+
if n.config.Validators.Contains(constants.PrimaryNetworkID, nodeID) {
805+
return true
806+
}
797807

798-
return n.wantsConnection(nodeID)
799-
}
808+
n.manuallyTrackedIDsLock.RLock()
809+
defer n.manuallyTrackedIDsLock.RUnlock()
800810

801-
func (n *network) wantsConnection(nodeID ids.NodeID) bool {
802-
return n.config.Validators.Contains(constants.PrimaryNetworkID, nodeID) ||
803-
n.manuallyTrackedIDs.Contains(nodeID)
811+
return n.manuallyTrackedIDs.Contains(nodeID)
804812
}
805813

806814
func (n *network) ManuallyTrack(nodeID ids.NodeID, ip ips.IPPort) {
815+
n.manuallyTrackedIDsLock.Lock()
816+
n.manuallyTrackedIDs.Add(nodeID)
817+
n.manuallyTrackedIDsLock.Unlock()
818+
807819
n.peersLock.Lock()
808820
defer n.peersLock.Unlock()
809821

810-
n.manuallyTrackedIDs.Add(nodeID)
811-
812822
_, connected := n.connectedPeers.GetByID(nodeID)
813823
if connected {
814824
// If I'm currently connected to [nodeID] then they will have told me
@@ -949,7 +959,7 @@ func (n *network) disconnectedFromConnecting(nodeID ids.NodeID) {
949959
// The peer that is disconnecting from us didn't finish the handshake
950960
tracked, ok := n.trackedIPs[nodeID]
951961
if ok {
952-
if n.wantsConnection(nodeID) {
962+
if n.WantsConnection(nodeID) {
953963
tracked := tracked.trackNewIP(tracked.ip)
954964
n.trackedIPs[nodeID] = tracked
955965
n.dial(nodeID, tracked)
@@ -972,7 +982,7 @@ func (n *network) disconnectedFromConnected(peer peer.Peer, nodeID ids.NodeID) {
972982
n.connectedPeers.Remove(nodeID)
973983

974984
// The peer that is disconnecting from us finished the handshake
975-
if n.wantsConnection(nodeID) {
985+
if n.WantsConnection(nodeID) {
976986
prevIP := n.peerIPs[nodeID]
977987
tracked := newTrackedIP(prevIP.IPPort)
978988
n.trackedIPs[nodeID] = tracked
@@ -1028,7 +1038,7 @@ func (n *network) authenticateIPs(ips []*ips.ClaimedIPPort) ([]*ipAuth, error) {
10281038
func (n *network) peerIPStatus(nodeID ids.NodeID, ip *ips.ClaimedIPPort) (*ips.ClaimedIPPort, bool, bool, bool) {
10291039
prevIP, previouslyTracked := n.peerIPs[nodeID]
10301040
shouldUpdateOurIP := previouslyTracked && prevIP.Timestamp < ip.Timestamp
1031-
shouldDial := !previouslyTracked && n.wantsConnection(nodeID)
1041+
shouldDial := !previouslyTracked && n.WantsConnection(nodeID)
10321042
return prevIP, previouslyTracked, shouldUpdateOurIP, shouldDial
10331043
}
10341044

@@ -1074,7 +1084,7 @@ func (n *network) dial(nodeID ids.NodeID, ip *trackedIP) {
10741084
// trackedIPs and this goroutine. This prevents a memory leak when
10751085
// the tracked nodeID leaves the validator set and is never able to
10761086
// be connected to.
1077-
if !n.wantsConnection(nodeID) {
1087+
if !n.WantsConnection(nodeID) {
10781088
// Typically [n.trackedIPs[nodeID]] will already equal [ip], but
10791089
// the reference to [ip] is refreshed to avoid any potential
10801090
// race conditions before removing the entry.

0 commit comments

Comments
 (0)