network: fix MaxPeers, introduce AttemptConnPeers

Our node didn't respect the MaxPeers setting, fix it with a drop of random
connection when this limit is reached (to give a chance for newcomers to
communicate), but also introduce AttemptConnPeers setting to tune the number
of attempted connections.

This also raises the default MaxPeers for testnet/mainnet to 100, because
neo-go nodes love making friends.
This commit is contained in:
Roman Khimov 2019-11-06 15:17:20 +03:00
parent 31954bb20c
commit 7cf9a40468
11 changed files with 57 additions and 15 deletions

View file

@ -72,6 +72,7 @@ type (
DialTimeout time.Duration `yaml:"DialTimeout"`
ProtoTickInterval time.Duration `yaml:"ProtoTickInterval"`
MaxPeers int `yaml:"MaxPeers"`
AttemptConnPeers int `yaml:"AttemptConnPeers"`
MinPeers int `yaml:"MinPeers"`
Monitoring metrics.PrometheusConfig `yaml:"Monitoring"`
RPC RPCConfig `yaml:"RPC"`

View file

@ -46,7 +46,8 @@ ApplicationConfiguration:
Relay: true
DialTimeout: 3
ProtoTickInterval: 2
MaxPeers: 50
MaxPeers: 100
AttemptConnPeers: 20
MinPeers: 5
RPC:
Enabled: true

View file

@ -34,7 +34,8 @@ ApplicationConfiguration:
Relay: true
DialTimeout: 3
ProtoTickInterval: 2
MaxPeers: 50
MaxPeers: 10
AttemptConnPeers: 5
MinPeers: 3
RPC:
Enabled: true

View file

@ -31,7 +31,8 @@ ApplicationConfiguration:
Relay: true
DialTimeout: 3
ProtoTickInterval: 2
MaxPeers: 50
MaxPeers: 10
AttemptConnPeers: 5
MinPeers: 3
RPC:
Enabled: true

View file

@ -31,7 +31,8 @@ ApplicationConfiguration:
Relay: true
DialTimeout: 3
ProtoTickInterval: 2
MaxPeers: 50
MaxPeers: 10
AttemptConnPeers: 5
MinPeers: 3
RPC:
Enabled: true

View file

@ -31,7 +31,8 @@ ApplicationConfiguration:
Relay: true
DialTimeout: 3
ProtoTickInterval: 2
MaxPeers: 50
MaxPeers: 10
AttemptConnPeers: 5
MinPeers: 3
RPC:
Enabled: true

View file

@ -37,7 +37,8 @@ ApplicationConfiguration:
Relay: true
DialTimeout: 3
ProtoTickInterval: 2
MaxPeers: 50
MaxPeers: 10
AttemptConnPeers: 5
MinPeers: 3
RPC:
Enabled: true

View file

@ -46,7 +46,8 @@ ApplicationConfiguration:
Relay: true
DialTimeout: 3
ProtoTickInterval: 2
MaxPeers: 50
MaxPeers: 100
AttemptConnPeers: 20
MinPeers: 5
RPC:
Enabled: true

View file

@ -37,6 +37,7 @@ ApplicationConfiguration:
DialTimeout: 3
ProtoTickInterval: 2
MaxPeers: 50
AttemptConnPeers: 5
MinPeers: 1
RPC:
Enabled: true

View file

@ -19,7 +19,8 @@ import (
const (
// peer numbers are arbitrary at the moment.
defaultMinPeers = 5
maxPeers = 20
defaultAttemptConnPeers = 20
defaultMaxPeers = 100
maxBlockBatch = 200
maxAddrsToSend = 200
minPoolCount = 30
@ -30,6 +31,7 @@ var (
errIdenticalID = errors.New("identical node id")
errInvalidHandshake = errors.New("invalid handshake")
errInvalidNetwork = errors.New("invalid network")
errMaxPeers = errors.New("max peers reached")
errServerShutdown = errors.New("server shutdown")
errInvalidInvType = errors.New("invalid inventory type")
)
@ -86,6 +88,22 @@ func NewServer(config ServerConfig, chain core.Blockchainer) *Server {
s.MinPeers = defaultMinPeers
}
if s.MaxPeers <= 0 {
log.WithFields(log.Fields{
"MaxPeers configured": s.MaxPeers,
"MaxPeers actual": defaultMaxPeers,
}).Info("bad MaxPeers configured, using the default value")
s.MaxPeers = defaultMaxPeers
}
if s.AttemptConnPeers <= 0 {
log.WithFields(log.Fields{
"AttemptConnPeers configured": s.AttemptConnPeers,
"AttemptConnPeers actual": defaultAttemptConnPeers,
}).Info("bad AttemptConnPeers configured, using the default value")
s.AttemptConnPeers = defaultAttemptConnPeers
}
s.transport = NewTCPTransport(s, fmt.Sprintf(":%d", config.ListenTCP))
s.discovery = NewDefaultDiscovery(
s.DialTimeout,
@ -137,9 +155,8 @@ func (s *Server) BadPeers() []string {
func (s *Server) run() {
for {
c := s.PeerCount()
if c < s.ServerConfig.MinPeers {
s.discovery.RequestRemote(maxPeers - c)
if s.PeerCount() < s.MinPeers {
s.discovery.RequestRemote(s.AttemptConnPeers)
}
if s.discovery.PoolCount() < minPoolCount {
select {
@ -170,6 +187,16 @@ func (s *Server) run() {
log.WithFields(log.Fields{
"addr": p.RemoteAddr(),
}).Info("new peer connected")
peerCount := s.PeerCount()
if peerCount > s.MaxPeers {
s.lock.RLock()
// Pick a random peer and drop connection to it.
for peer := range s.peers {
peer.Disconnect(errMaxPeers)
break
}
s.lock.RUnlock()
}
updatePeersConnectedMetric(s.PeerCount())
case drop := <-s.unregister:

View file

@ -15,6 +15,11 @@ type (
// connect with some new ones.
MinPeers int
// AttemptConnPeers it the number of connection to try to
// establish when the connection count drops below the MinPeers
// value.
AttemptConnPeers int
// MaxPeers it the maximum numbers of peers that can
// be connected to the server.
MaxPeers int
@ -64,6 +69,7 @@ func NewServerConfig(cfg config.Config) ServerConfig {
DialTimeout: appConfig.DialTimeout * time.Second,
ProtoTickInterval: appConfig.ProtoTickInterval * time.Second,
MaxPeers: appConfig.MaxPeers,
AttemptConnPeers: appConfig.AttemptConnPeers,
MinPeers: appConfig.MinPeers,
}
}