From 86d51fa1cb9d7a43faa42689ba8e1bddd7f40e09 Mon Sep 17 00:00:00 2001 From: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com> Date: Mon, 24 Aug 2020 16:11:32 +0300 Subject: [PATCH] [NOD-1307] Fix duplicate connections (#897) * [NOD-1307] Lock peersMutex in methods that don't. * [NOD-1307] Fix duplicate connections. * [NOD-1307] Use RLock instead of Lock. * [NOD-1307] Simplify IsEqual. --- app/protocol/flowcontext/flow_context.go | 4 ++-- app/protocol/flowcontext/ibd.go | 6 ++++++ app/protocol/flowcontext/network.go | 6 +++--- infrastructure/network/netadapter/id/id.go | 11 +++++------ 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/app/protocol/flowcontext/flow_context.go b/app/protocol/flowcontext/flow_context.go index fa75e303e..4086b0615 100644 --- a/app/protocol/flowcontext/flow_context.go +++ b/app/protocol/flowcontext/flow_context.go @@ -39,7 +39,7 @@ type FlowContext struct { startIBDMutex sync.Mutex ibdPeer *peerpkg.Peer - peers map[*id.ID]*peerpkg.Peer + peers map[id.ID]*peerpkg.Peer peersMutex sync.RWMutex } @@ -57,7 +57,7 @@ func New(cfg *config.Config, dag *blockdag.BlockDAG, addressManager *addressmana txPool: txPool, sharedRequestedTransactions: relaytransactions.NewSharedRequestedTransactions(), sharedRequestedBlocks: blockrelay.NewSharedRequestedBlocks(), - peers: make(map[*id.ID]*peerpkg.Peer), + peers: make(map[id.ID]*peerpkg.Peer), transactionsToRebroadcast: make(map[daghash.TxID]*util.Tx), } } diff --git a/app/protocol/flowcontext/ibd.go b/app/protocol/flowcontext/ibd.go index 19b5eb9de..63ce09d56 100644 --- a/app/protocol/flowcontext/ibd.go +++ b/app/protocol/flowcontext/ibd.go @@ -37,6 +37,9 @@ func (f *FlowContext) IsInIBD() bool { // selectPeerForIBD returns the first peer whose selected tip // hash is not in our DAG func (f *FlowContext) selectPeerForIBD(dag *blockdag.BlockDAG) *peerpkg.Peer { + f.peersMutex.RLock() + defer f.peersMutex.RUnlock() + for _, peer := range f.peers { peerSelectedTipHash := peer.SelectedTipHash() if !dag.IsInDAG(peerSelectedTipHash) { @@ -59,6 +62,9 @@ func (f *FlowContext) isDAGTimeCurrent() bool { } func (f *FlowContext) requestSelectedTips() { + f.peersMutex.RLock() + defer f.peersMutex.RUnlock() + for _, peer := range f.peers { peer.RequestSelectedTipIfRequired() } diff --git a/app/protocol/flowcontext/network.go b/app/protocol/flowcontext/network.go index 922c24fa1..d0dca1697 100644 --- a/app/protocol/flowcontext/network.go +++ b/app/protocol/flowcontext/network.go @@ -24,11 +24,11 @@ func (f *FlowContext) AddToPeers(peer *peerpkg.Peer) error { f.peersMutex.Lock() defer f.peersMutex.Unlock() - if _, ok := f.peers[peer.ID()]; ok { + if _, ok := f.peers[*peer.ID()]; ok { return errors.Wrapf(common.ErrPeerWithSameIDExists, "peer with ID %s already exists", peer.ID()) } - f.peers[peer.ID()] = peer + f.peers[*peer.ID()] = peer return nil } @@ -38,7 +38,7 @@ func (f *FlowContext) RemoveFromPeers(peer *peerpkg.Peer) { f.peersMutex.Lock() defer f.peersMutex.Unlock() - delete(f.peers, peer.ID()) + delete(f.peers, *peer.ID()) } // readyPeerConnections returns the NetConnections of all the ready peers. diff --git a/infrastructure/network/netadapter/id/id.go b/infrastructure/network/netadapter/id/id.go index b55e5df74..93b350cdf 100644 --- a/infrastructure/network/netadapter/id/id.go +++ b/infrastructure/network/netadapter/id/id.go @@ -12,7 +12,7 @@ const IDLength = 16 // ID identifies a network connection type ID struct { - bytes []byte + bytes [IDLength]byte } // GenerateID generates a new ID @@ -27,23 +27,22 @@ func GenerateID() (*ID, error) { // IsEqual returns whether id equals to other. func (id *ID) IsEqual(other *ID) bool { - return bytes.Equal(id.bytes, other.bytes) + return *id == *other } func (id *ID) String() string { - return hex.EncodeToString(id.bytes) + return hex.EncodeToString(id.bytes[:]) } // Deserialize decodes a block from r into the receiver. func (id *ID) Deserialize(r io.Reader) error { - id.bytes = make([]byte, IDLength) - _, err := io.ReadFull(r, id.bytes) + _, err := io.ReadFull(r, id.bytes[:]) return err } // Serialize serializes the receiver into the given writer. func (id *ID) Serialize(w io.Writer) error { - _, err := w.Write(id.bytes) + _, err := w.Write(id.bytes[:]) return err }