Browse Source

p2p: fix race by peer.Start() before peers.Add()

pull/491/head
Ethan Buchman 8 years ago
committed by Anton Kaliaev
parent
commit
16509ac3db
No known key found for this signature in database GPG Key ID: 7B6881D965918214
3 changed files with 14 additions and 11 deletions
  1. +1
    -3
      p2p/peer_set.go
  2. +12
    -8
      p2p/switch.go
  3. +1
    -0
      p2p/switch_test.go

+ 1
- 3
p2p/peer_set.go View File

@ -16,7 +16,6 @@ type IPeerSet interface {
// PeerSet is a special structure for keeping a table of peers. // PeerSet is a special structure for keeping a table of peers.
// Iteration over the peers is super fast and thread-safe. // Iteration over the peers is super fast and thread-safe.
// We also track how many peers per IP range and avoid too many
type PeerSet struct { type PeerSet struct {
mtx sync.Mutex mtx sync.Mutex
lookup map[string]*peerSetItem lookup map[string]*peerSetItem
@ -35,8 +34,7 @@ func NewPeerSet() *PeerSet {
} }
} }
// Returns false if peer with key (PubKeyEd25519) is already in set
// or if we have too many peers from the peer's IP range
// Returns false if peer with key (PubKeyEd25519) is already set
func (ps *PeerSet) Add(peer *Peer) error { func (ps *PeerSet) Add(peer *Peer) error {
ps.mtx.Lock() ps.mtx.Lock()
defer ps.mtx.Unlock() defer ps.mtx.Unlock()


+ 12
- 8
p2p/switch.go View File

@ -76,8 +76,7 @@ type Switch struct {
} }
var ( var (
ErrSwitchDuplicatePeer = errors.New("Duplicate peer")
ErrSwitchMaxPeersPerIPRange = errors.New("IP range has too many peers")
ErrSwitchDuplicatePeer = errors.New("Duplicate peer")
) )
func NewSwitch(config *cfg.P2PConfig) *Switch { func NewSwitch(config *cfg.P2PConfig) *Switch {
@ -221,12 +220,10 @@ func (sw *Switch) AddPeer(peer *Peer) error {
return err return err
} }
// Add the peer to .peers
// ignore if duplicate or if we already have too many for that IP range
if err := sw.peers.Add(peer); err != nil {
sw.Logger.Info("Ignoring peer", "error", err, "peer", peer)
peer.Stop()
return err
// Check for duplicate peer
if sw.peers.Has(peer.Key) {
return ErrSwitchDuplicatePeer
} }
// Start peer // Start peer
@ -234,6 +231,13 @@ func (sw *Switch) AddPeer(peer *Peer) error {
sw.startInitPeer(peer) sw.startInitPeer(peer)
} }
// Add the peer to .peers.
// We start it first so that a peer in the list is safe to Stop.
// It should not err since we already checked peers.Has()
if err := sw.peers.Add(peer); err != nil {
return err
}
sw.Logger.Info("Added peer", "peer", peer) sw.Logger.Info("Added peer", "peer", peer)
return nil return nil
} }


+ 1
- 0
p2p/switch_test.go View File

@ -279,6 +279,7 @@ func TestSwitchReconnectsToPersistentPeer(t *testing.T) {
// simulate failure by closing connection // simulate failure by closing connection
peer.CloseConn() peer.CloseConn()
// TODO: actually detect the disconnection and wait for reconnect
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
assert.NotZero(sw.Peers().Size()) assert.NotZero(sw.Peers().Size())


Loading…
Cancel
Save