[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.
This commit is contained in:
stasatdaglabs 2020-08-24 16:11:32 +03:00 committed by GitHub
parent 8dd7b95423
commit 86d51fa1cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 16 additions and 11 deletions

View File

@ -39,7 +39,7 @@ type FlowContext struct {
startIBDMutex sync.Mutex startIBDMutex sync.Mutex
ibdPeer *peerpkg.Peer ibdPeer *peerpkg.Peer
peers map[*id.ID]*peerpkg.Peer peers map[id.ID]*peerpkg.Peer
peersMutex sync.RWMutex peersMutex sync.RWMutex
} }
@ -57,7 +57,7 @@ func New(cfg *config.Config, dag *blockdag.BlockDAG, addressManager *addressmana
txPool: txPool, txPool: txPool,
sharedRequestedTransactions: relaytransactions.NewSharedRequestedTransactions(), sharedRequestedTransactions: relaytransactions.NewSharedRequestedTransactions(),
sharedRequestedBlocks: blockrelay.NewSharedRequestedBlocks(), sharedRequestedBlocks: blockrelay.NewSharedRequestedBlocks(),
peers: make(map[*id.ID]*peerpkg.Peer), peers: make(map[id.ID]*peerpkg.Peer),
transactionsToRebroadcast: make(map[daghash.TxID]*util.Tx), transactionsToRebroadcast: make(map[daghash.TxID]*util.Tx),
} }
} }

View File

@ -37,6 +37,9 @@ func (f *FlowContext) IsInIBD() bool {
// selectPeerForIBD returns the first peer whose selected tip // selectPeerForIBD returns the first peer whose selected tip
// hash is not in our DAG // hash is not in our DAG
func (f *FlowContext) selectPeerForIBD(dag *blockdag.BlockDAG) *peerpkg.Peer { func (f *FlowContext) selectPeerForIBD(dag *blockdag.BlockDAG) *peerpkg.Peer {
f.peersMutex.RLock()
defer f.peersMutex.RUnlock()
for _, peer := range f.peers { for _, peer := range f.peers {
peerSelectedTipHash := peer.SelectedTipHash() peerSelectedTipHash := peer.SelectedTipHash()
if !dag.IsInDAG(peerSelectedTipHash) { if !dag.IsInDAG(peerSelectedTipHash) {
@ -59,6 +62,9 @@ func (f *FlowContext) isDAGTimeCurrent() bool {
} }
func (f *FlowContext) requestSelectedTips() { func (f *FlowContext) requestSelectedTips() {
f.peersMutex.RLock()
defer f.peersMutex.RUnlock()
for _, peer := range f.peers { for _, peer := range f.peers {
peer.RequestSelectedTipIfRequired() peer.RequestSelectedTipIfRequired()
} }

View File

@ -24,11 +24,11 @@ func (f *FlowContext) AddToPeers(peer *peerpkg.Peer) error {
f.peersMutex.Lock() f.peersMutex.Lock()
defer f.peersMutex.Unlock() 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()) 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 return nil
} }
@ -38,7 +38,7 @@ func (f *FlowContext) RemoveFromPeers(peer *peerpkg.Peer) {
f.peersMutex.Lock() f.peersMutex.Lock()
defer f.peersMutex.Unlock() defer f.peersMutex.Unlock()
delete(f.peers, peer.ID()) delete(f.peers, *peer.ID())
} }
// readyPeerConnections returns the NetConnections of all the ready peers. // readyPeerConnections returns the NetConnections of all the ready peers.

View File

@ -12,7 +12,7 @@ const IDLength = 16
// ID identifies a network connection // ID identifies a network connection
type ID struct { type ID struct {
bytes []byte bytes [IDLength]byte
} }
// GenerateID generates a new ID // GenerateID generates a new ID
@ -27,23 +27,22 @@ func GenerateID() (*ID, error) {
// IsEqual returns whether id equals to other. // IsEqual returns whether id equals to other.
func (id *ID) IsEqual(other *ID) bool { func (id *ID) IsEqual(other *ID) bool {
return bytes.Equal(id.bytes, other.bytes) return *id == *other
} }
func (id *ID) String() string { func (id *ID) String() string {
return hex.EncodeToString(id.bytes) return hex.EncodeToString(id.bytes[:])
} }
// Deserialize decodes a block from r into the receiver. // Deserialize decodes a block from r into the receiver.
func (id *ID) Deserialize(r io.Reader) error { 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 return err
} }
// Serialize serializes the receiver into the given writer. // Serialize serializes the receiver into the given writer.
func (id *ID) Serialize(w io.Writer) error { func (id *ID) Serialize(w io.Writer) error {
_, err := w.Write(id.bytes) _, err := w.Write(id.bytes[:])
return err return err
} }