mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 22:56:43 +00:00
p2p: add a 20 second warmup interval before dialing bootnodes
This commit is contained in:
parent
6afd4700b7
commit
7965e743aa
2 changed files with 30 additions and 4 deletions
14
p2p/dial.go
14
p2p/dial.go
|
|
@ -38,6 +38,10 @@ const (
|
|||
// once every few seconds.
|
||||
lookupInterval = 4 * time.Second
|
||||
|
||||
// If no peers are found for this amount of time, the initial bootnodes are
|
||||
// attempted to be connected.
|
||||
fallbackInterval = 20 * time.Second
|
||||
|
||||
// Endpoint resolution is throttled with bounded backoff.
|
||||
initialResolveDelay = 60 * time.Second
|
||||
maxResolveDelay = time.Hour
|
||||
|
|
@ -53,11 +57,13 @@ type dialstate struct {
|
|||
|
||||
lookupRunning bool
|
||||
dialing map[discover.NodeID]connFlag
|
||||
bootnodes []*discover.Node // default dials when there are no peers
|
||||
lookupBuf []*discover.Node // current discovery lookup results
|
||||
randomNodes []*discover.Node // filled from Table
|
||||
static map[discover.NodeID]*dialTask
|
||||
hist *dialHistory
|
||||
|
||||
start time.Time // time when the dialer was first used
|
||||
bootnodes []*discover.Node // default dials when there are no peers
|
||||
}
|
||||
|
||||
type discoverTable interface {
|
||||
|
|
@ -133,6 +139,10 @@ func (s *dialstate) removeStatic(n *discover.Node) {
|
|||
}
|
||||
|
||||
func (s *dialstate) newTasks(nRunning int, peers map[discover.NodeID]*Peer, now time.Time) []task {
|
||||
if s.start == (time.Time{}) {
|
||||
s.start = now
|
||||
}
|
||||
|
||||
var newtasks []task
|
||||
addDial := func(flag connFlag, n *discover.Node) bool {
|
||||
if err := s.checkDial(n, peers); err != nil {
|
||||
|
|
@ -175,7 +185,7 @@ func (s *dialstate) newTasks(nRunning int, peers map[discover.NodeID]*Peer, now
|
|||
// If we don't have any peers whatsoever, try to dial a random bootnode. This
|
||||
// scenario is useful for the testnet (and private networks) where the discovery
|
||||
// table might be full of mostly bad peers, making it hard to find good ones.
|
||||
if len(peers) == 0 && len(s.bootnodes) > 0 && needDynDials > 0 {
|
||||
if len(peers) == 0 && len(s.bootnodes) > 0 && needDynDials > 0 && now.Sub(s.start) > fallbackInterval {
|
||||
bootnode := s.bootnodes[0]
|
||||
s.bootnodes = append(s.bootnodes[:0], s.bootnodes[1:]...)
|
||||
s.bootnodes = append(s.bootnodes, bootnode)
|
||||
|
|
|
|||
|
|
@ -236,13 +236,29 @@ func TestDialStateDynDialBootnode(t *testing.T) {
|
|||
runDialTest(t, dialtest{
|
||||
init: newDialState(nil, bootnodes, table, 5, nil),
|
||||
rounds: []round{
|
||||
// 1 out of 3 bootnodes are dialed on no peers, 2 other dynamic dials
|
||||
// 2 dynamic dials attempted, bootnodes pending fallback interval
|
||||
{
|
||||
new: []task{
|
||||
&dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(4)}},
|
||||
&dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(5)}},
|
||||
&discoverTask{},
|
||||
},
|
||||
},
|
||||
// No dials succeed, bootnodes still pending fallback interval
|
||||
{
|
||||
done: []task{
|
||||
&dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(4)}},
|
||||
&dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(5)}},
|
||||
},
|
||||
},
|
||||
// No dials succeed, bootnodes still pending fallback interval
|
||||
{},
|
||||
// No dials succeed, 2 dynamic dials attempted and 1 bootnode too as fallback interval was reached
|
||||
{
|
||||
new: []task{
|
||||
&dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(1)}},
|
||||
&dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(4)}},
|
||||
&dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(5)}},
|
||||
&discoverTask{},
|
||||
},
|
||||
},
|
||||
// No dials succeed, 2nd bootnode is attempted
|
||||
|
|
|
|||
Loading…
Reference in a new issue