mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 07:06:42 +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.
|
// once every few seconds.
|
||||||
lookupInterval = 4 * time.Second
|
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.
|
// Endpoint resolution is throttled with bounded backoff.
|
||||||
initialResolveDelay = 60 * time.Second
|
initialResolveDelay = 60 * time.Second
|
||||||
maxResolveDelay = time.Hour
|
maxResolveDelay = time.Hour
|
||||||
|
|
@ -53,11 +57,13 @@ type dialstate struct {
|
||||||
|
|
||||||
lookupRunning bool
|
lookupRunning bool
|
||||||
dialing map[discover.NodeID]connFlag
|
dialing map[discover.NodeID]connFlag
|
||||||
bootnodes []*discover.Node // default dials when there are no peers
|
|
||||||
lookupBuf []*discover.Node // current discovery lookup results
|
lookupBuf []*discover.Node // current discovery lookup results
|
||||||
randomNodes []*discover.Node // filled from Table
|
randomNodes []*discover.Node // filled from Table
|
||||||
static map[discover.NodeID]*dialTask
|
static map[discover.NodeID]*dialTask
|
||||||
hist *dialHistory
|
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 {
|
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 {
|
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
|
var newtasks []task
|
||||||
addDial := func(flag connFlag, n *discover.Node) bool {
|
addDial := func(flag connFlag, n *discover.Node) bool {
|
||||||
if err := s.checkDial(n, peers); err != nil {
|
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
|
// 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
|
// 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.
|
// 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]
|
bootnode := s.bootnodes[0]
|
||||||
s.bootnodes = append(s.bootnodes[:0], s.bootnodes[1:]...)
|
s.bootnodes = append(s.bootnodes[:0], s.bootnodes[1:]...)
|
||||||
s.bootnodes = append(s.bootnodes, bootnode)
|
s.bootnodes = append(s.bootnodes, bootnode)
|
||||||
|
|
|
||||||
|
|
@ -236,13 +236,29 @@ func TestDialStateDynDialBootnode(t *testing.T) {
|
||||||
runDialTest(t, dialtest{
|
runDialTest(t, dialtest{
|
||||||
init: newDialState(nil, bootnodes, table, 5, nil),
|
init: newDialState(nil, bootnodes, table, 5, nil),
|
||||||
rounds: []round{
|
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{
|
new: []task{
|
||||||
&dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(1)}},
|
&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(4)}},
|
||||||
&dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(5)}},
|
&dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(5)}},
|
||||||
&discoverTask{},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// No dials succeed, 2nd bootnode is attempted
|
// No dials succeed, 2nd bootnode is attempted
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue