Give peers a chance (#4268)

* Add decay function for peer badresponses count
* Activate peer decay in p2p
This commit is contained in:
Jim McDonald 2019-12-12 14:34:28 +00:00 committed by prylabs-bulldozer[bot]
parent 2e9c3895f4
commit 570efe3d04
5 changed files with 74 additions and 1 deletions

View File

@ -16,6 +16,7 @@ go_library(
"log.go",
"monitoring.go",
"options.go",
"peer_decay.go",
"rpc_topic_mappings.go",
"sender.go",
"service.go",

View File

@ -0,0 +1,25 @@
package p2p
import (
"context"
"time"
"github.com/prysmaticlabs/prysm/beacon-chain/p2p/peers"
)
// starPeerDecay starts a loop that periodically decays the bad response count of peers, giving reformed peers a chance to rejoin
// the network.
// This runs every hour.
func startPeerDecay(ctx context.Context, peers *peers.Status) {
go (func() {
for {
select {
case <-ctx.Done():
return
default:
peers.Decay()
time.Sleep(1 * time.Hour)
}
}
})()
}

View File

@ -303,6 +303,19 @@ func (p *Status) All() []peer.ID {
return pids
}
// Decay reduces the bad responses of all peers, giving reformed peers a chance to join the network.
// This can be run periodically, although note that each time it runs it does give all bad peers another chance as well to clog up
// the network with bad responses, so should not be run too frequently; once an hour would be reasonable.
func (p *Status) Decay() {
p.lock.Lock()
defer p.lock.Unlock()
for _, status := range p.status {
if status.badResponses > 0 {
status.badResponses--
}
}
}
// fetch is a helper function that fetches a peer status, possibly creating it.
func (p *Status) fetch(pid peer.ID) *peerStatus {
if _, ok := p.status[pid]; !ok {

View File

@ -302,8 +302,40 @@ func TestPeerConnectionStatuses(t *testing.T) {
}
}
func TestDecay(t *testing.T) {
maxBadResponses := 2
p := peers.NewStatus(maxBadResponses)
// Peer 1 has 0 bad responses.
pid1 := addPeer(t, p, peers.PeerConnected)
// Peer 2 has 1 bad response.
pid2 := addPeer(t, p, peers.PeerConnected)
p.IncrementBadResponses(pid2)
// Peer 3 has 2 bad response.
pid3 := addPeer(t, p, peers.PeerConnected)
p.IncrementBadResponses(pid3)
p.IncrementBadResponses(pid3)
// Decay the values
p.Decay()
// Ensure the new values are as expected
badResponses1, _ := p.BadResponses(pid1)
if badResponses1 != 0 {
t.Errorf("Unexpected bad responses for peer 0: expected 0, received %v", badResponses1)
}
badResponses2, _ := p.BadResponses(pid2)
if badResponses2 != 0 {
t.Errorf("Unexpected bad responses for peer 0: expected 0, received %v", badResponses2)
}
badResponses3, _ := p.BadResponses(pid3)
if badResponses3 != 1 {
t.Errorf("Unexpected bad responses for peer 0: expected 0, received %v", badResponses3)
}
}
// addPeer is a helper to add a peer with a given connection state)
func addPeer(t *testing.T, p *peers.Status, state peers.PeerConnectionState) {
func addPeer(t *testing.T, p *peers.Status, state peers.PeerConnectionState) peer.ID {
// Set up some peers with different states
mhBytes := []byte{0x11, 0x04}
idBytes := make([]byte, 4)
@ -315,4 +347,5 @@ func addPeer(t *testing.T, p *peers.Status, state peers.PeerConnectionState) {
}
p.Add(id, nil, network.DirUnknown)
p.SetConnectionState(id, state)
return id
}

View File

@ -204,6 +204,7 @@ func (s *Service) Start() {
}
startPeerWatcher(s.ctx, s.host, peersToWatch...)
startPeerDecay(s.ctx, s.peers)
registerMetrics(s)
multiAddrs := s.host.Network().ListenAddresses()
logIP4Addr(s.host.ID(), multiAddrs...)